Compare commits

..

617 Commits

Author SHA1 Message Date
R4SAS
3ab5ac66b6 modulize client protocols
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-05-03 17:20:19 +03:00
orignal
18cb3912e5 fixed imccorect termination 2022-05-02 15:05:44 -04:00
orignal
a818b0ba02 Merge pull request #1748 from voltamperoff/Refactor-I2CP-CreateSessionMessageHandler
Simple refactor of nested if-statements
2022-05-01 17:13:13 -04:00
R4SAS
3716b6f988 move TunnelHopVisitor inside Tunnel class
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-05-01 23:40:00 +03:00
R4SAS
c9e4e78f41 [webconsole] remove version from title, move tunnel chain print from Tunnel class
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-05-01 23:25:08 +03:00
R4SAS
9b4e8bf64b [webconsole] do not show registration block when token is not provided
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-05-01 18:12:43 +03:00
orignal
5aebefe73f connect through introducer 2022-05-01 10:33:25 -04:00
R4SAS
8f2124beab update reseeds
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-30 19:33:30 +03:00
R4SAS
8b8b43df28 [rpm] support rhel 9
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-30 17:54:52 +03:00
R4SAS
c42b991bc9 [rpm] pre-support rhel 9
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-30 17:04:08 +03:00
R4SAS
ec08333bf9 [rpm] fix build on fedora 37
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-30 16:45:53 +03:00
R4SAS
9e5b4e14c9 [rpm] fix build on fedora 37
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-30 16:39:36 +03:00
orignal
1f5ed89a88 set blinded signature type to RedDSA for EdDSA 2022-04-29 12:48:45 -04:00
R4SAS
2304a2bc2e remove android contrib files (moved to android repo)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-29 12:48:40 +03:00
orignal
dc82105226 check status code and verify RelayResponse signature 2022-04-28 20:41:06 -04:00
orignal
5221f3ddc9 one SSU2 session per remote router 2022-04-28 13:11:51 -04:00
orignal
e970deb92b check presense of introducers in SSU2 address 2022-04-28 11:43:33 -04:00
orignal
9db7ec6bb0 create and send RelayRequest 2022-04-27 18:52:44 -04:00
orignal
2e691b6655 check if next manage time is too long 2022-04-26 21:02:39 -04:00
orignal
f22e10537b fixed typo 2022-04-26 20:45:10 -04:00
orignal
6e532c494c create new published SSU2 addresses 2022-04-26 20:30:39 -04:00
orignal
f9ed0d4aa2 fixed crash 2022-04-26 20:01:32 -04:00
orignal
78b1afcc8c publish introducer cap for SSU2 address 2022-04-26 15:20:57 -04:00
orignal
40340cf9c2 handle RelayResponse 2022-04-26 13:59:59 -04:00
orignal
eb6437050f SSU2 introducers 2022-04-25 19:57:46 -04:00
orignal
45ebfe378b correct Ack range 2022-04-23 11:11:49 -04:00
R4SAS
1326597226 use ipv6 preference only when netinet headers not used (entware with musl workaround)'
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-23 13:50:34 +03:00
orignal
751da92c13 send relay response 2022-04-22 20:34:19 -04:00
orignal
e10ca637da handle RelayIntro 2022-04-22 15:03:49 -04:00
orignal
c5d9d71a8a create relay tag and relay request block 2022-04-21 15:47:36 -04:00
orignal
3e0f5d231d send queue after batch of packets 2022-04-18 15:47:35 -04:00
orignal
6990f177ba window size 2022-04-18 13:14:09 -04:00
orignal
98e713166b show port for non-published SSU addresses 2022-04-18 12:27:57 -04:00
orignal
4c91ae0085 check if end of list 2022-04-16 17:01:06 -04:00
orignal
43f74d4d5a resend packet with new packet number 2022-04-16 15:42:11 -04:00
orignal
8c3e716c3f ranges in ack block 2022-04-15 16:26:44 -04:00
orignal
05946125b5 handle single packet 2022-04-13 12:33:59 -04:00
orignal
1e2a0a4549 handle incoming packets in batch 2022-04-12 11:42:51 -04:00
R4SAS
f9f5084dd7 typo
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-11 11:26:10 +03:00
R4SAS
b7e7c6db7b UDP Client: ignore incomming traffic and error when stopping (prevent socket restarting)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-10 23:10:41 +03:00
orignal
f9d67b28ec handle fragmented SessionConfirmed 2022-04-09 19:56:57 -04:00
orignal
46b77cc280 increase RouterInfo buffer size 2022-04-09 14:40:38 -04:00
R4SAS
2f10decf56 daemon: make possible to set datadir before init
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-09 19:57:32 +03:00
orignal
678a1ae0fb send fragmented messages 2022-04-09 11:42:34 -04:00
orignal
51cbffd097 don't lookup session for every sinle packet 2022-04-07 10:57:57 -04:00
orignal
207b13dcab send correct acnt if gaps 2022-04-05 18:23:52 -04:00
orignal
3052dbd1e8 single receive thread for both ipv4 and ipv6 2022-04-05 16:27:52 -04:00
orignal
5891b1ceb2 separate receive thread 2022-04-05 16:14:13 -04:00
orignal
07e14ddda8 check if SSU2 enabled 2022-04-04 20:37:29 -04:00
orignal
db5e90787c update I2NP header after all fragments received 2022-04-04 13:25:08 -04:00
orignal
67e501f5c7 correct nonce for SessionCorfirmed part 2 2022-04-04 11:52:14 -04:00
orignal
2160001167 correct non for token request and retry encryption 2022-04-04 09:58:17 -04:00
orignal
f5f4150d17 fixed typo 2022-04-03 13:43:33 -04:00
R4SAS
887f292612 update install target to use correct share directory, skip dh_auto_install in debian
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-04-02 23:16:39 +03:00
orignal
f5f282af97 cost for published SSU2 address 2022-04-02 14:32:26 -04:00
orignal
82f9585b7a handle fragments 2022-04-02 13:05:11 -04:00
orignal
eb561bb0c2 handle Ack ranges 2022-04-01 15:09:35 -04:00
orignal
81207999eb check token in SessionRequest 2022-03-31 21:07:51 -04:00
orignal
2fef595b83 resend packets 2022-03-31 15:35:55 -04:00
orignal
2024e790ca send I2NP messages 2022-03-30 18:04:12 -04:00
orignal
f9925c7374 hanlde Ack block 2022-03-30 15:03:45 -04:00
orignal
dd774b8dfd store out of sequence packet numbers 2022-03-30 12:31:24 -04:00
orignal
064b8042a5 ssu2.published and update SSU2 ipv4 2022-03-29 14:56:57 -04:00
orignal
7923ed9567 publish SSU2 address 2022-03-29 13:56:56 -04:00
orignal
30b83414ef find SSU2 address by address type 2022-03-28 18:03:22 -04:00
orignal
990906c57f insert garlic tag in destination's thread 2022-03-28 12:15:40 -04:00
orignal
4c323a666a show SSU2 transports in web console 2022-03-27 19:29:50 -04:00
orignal
a3f165d374 handle and send termination 2022-03-27 16:39:58 -04:00
Volt Amperoff
4977f9e6b4 If-statements are simplified. Checks are rearranged for faster errors detection without unnecessary actions. 2022-03-27 18:05:37 +03:00
orignal
7d5f51e357 don't send instant Ack for out-of-sequence message 2022-03-27 09:26:45 -04:00
orignal
371a339b18 encrypt Data header 2022-03-27 07:47:25 -04:00
orignal
7e7aee27b6 handle I2NP message block 2022-03-26 21:59:21 -04:00
orignal
53148fe58f send Ack packet 2022-03-26 16:35:07 -04:00
orignal
56b6de6962 correct header decryption for Data message 2022-03-25 17:57:59 -04:00
orignal
44735681af KDF and process Data message 2022-03-25 15:34:43 -04:00
orignal
ee1c4f4fdc internal numeric id for families 2022-03-24 15:50:20 -04:00
orignal
fb6ecdde1e handle TokenRequest 2022-03-23 21:48:41 -04:00
orignal
861166d8a9 send TokenRequest message: 2022-03-23 19:13:44 -04:00
R4SAS
70dca81c40 dropped MESHNET build option
Dropping MESHNET build option due to lack of usage. That change won't
affect on usage with currently supported Yggdrasil network.

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-24 01:36:12 +03:00
R4SAS
2774d72888 [makefile] add install target for linux
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-24 01:36:12 +03:00
orignal
2440ffbfc9 handle SSU2 SessionConfirmed 2022-03-23 14:06:55 -04:00
orignal
77c5dde320 send SessionConfirmed 2022-03-21 21:06:14 -04:00
orignal
aa49cad279 correct encrypted payload size for MixHash 2022-03-21 13:21:08 -04:00
orignal
f56ae240ab don't delete peding endpoint if Retry received 2022-03-21 12:56:02 -04:00
orignal
e871a30a78 initialize connid in constructor 2022-03-20 16:53:32 -04:00
orignal
30e6984889 handle Retry message 2022-03-20 15:10:18 -04:00
orignal
324932c758 separate i and key fields for shared SSU address 2022-03-20 10:28:08 -04:00
orignal
421800bc8f recognize SSU address supporting SSU2 2022-03-19 17:34:07 -04:00
orignal
86fb47b2b4 Merge pull request #1744 from WaxySteelWorm/openssl
Added StormyCloud Inc family cert
2022-03-19 12:34:24 -04:00
WaxySteelWorm
715f83bf84 Create stormycloud.crt 2022-03-19 10:59:54 -05:00
orignal
87bf5c2418 cleanup pending sessions 2022-03-18 20:21:31 -04:00
orignal
5c9af1c613 MixHash with encrypted payload after decryption 2022-03-18 15:32:32 -04:00
orignal
765e0e5c6b correct 'i' size for SSU2 2022-03-18 13:33:33 -04:00
orignal
cc296e16dc don't make SSU2 address published is 'i' is presented 2022-03-18 13:02:59 -04:00
orignal
ab9901525b separated sockets for ipv4 and ipv6 2022-03-17 18:45:14 -04:00
orignal
3643a46a0c don't update SSU2 port 2022-03-17 14:47:00 -04:00
orignal
d467e6869d don't update address for SSU2 2022-03-17 13:21:51 -04:00
Dimitris Apostolou
db36018849 Fix typo 2022-03-17 10:41:39 +00:00
orignal
3c5c375f71 connect to SSU2 address 2022-03-16 21:11:48 -04:00
orignal
7473d8c9aa create and handle Address block 2022-03-16 13:13:31 -04:00
R4SAS
33645d7f09 [gha] XP: use make option for XP
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 04:29:02 +03:00
R4SAS
9f1106b14a [gha] XP: noconfirm for pacman
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 04:09:23 +03:00
R4SAS
3dd952b49b [gha] XP: noconfirm for pacman
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 04:03:26 +03:00
R4SAS
6b85bd2cb8 [gha] XP: fix MinGW repo url
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 03:54:32 +03:00
orignal
60b164c853 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2022-03-15 20:50:24 -04:00
orignal
40c8a1bc1d handle payload blocks 2022-03-15 20:49:41 -04:00
R4SAS
22de695f12 [gha] install git to XP builder
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 03:45:55 +03:00
R4SAS
e91f588cd7 [gha] build for winxp
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-16 03:42:10 +03:00
orignal
7b72d91549 receive incoming SSU2 packets 2022-03-14 19:25:59 -04:00
orignal
b3c2e86436 skip unknown address 2022-03-14 15:54:55 -04:00
orignal
908bdc7624 always publish intro key for SSU2 address 2022-03-13 21:55:03 -04:00
orignal
21c1ec9c8c enable SSU2 server 2022-03-13 21:34:11 -04:00
orignal
6d7d71bb16 don't show address:port for non-published addresses 2022-03-13 11:58:19 -04:00
orignal
6eba061c2a show local SSU2 address 2022-03-13 11:04:37 -04:00
orignal
f184f550b9 SSU2 address in config and RouterInfo 2022-03-12 21:51:17 -05:00
orignal
bb7c0fef20 SSU2 address in config and RouterInfo 2022-03-12 21:40:12 -05:00
orignal
5c15a12116 don't allocate buffer from netdb for LocalRouterInfo 2022-03-11 19:03:00 -05:00
orignal
68d015763e recognize SSU2 addresses 2022-03-11 16:17:44 -05:00
orignal
7faa732f38 send SessionCreated 2022-03-08 21:33:21 -05:00
orignal
11f9eeabf1 inbound.lengthVariance and outbound.lengthVariance 2022-03-07 22:20:11 -05:00
orignal
a152f36894 MixHash for SSU2 long header 2022-03-07 18:20:06 -05:00
orignal
d4ede6ff01 process SessionRequest 2022-03-05 18:39:27 -05:00
orignal
35542d803c KDF for session request 2022-03-04 21:51:40 -05:00
orignal
f6ba776c12 SSU2 keys 2022-03-01 21:23:08 -05:00
orignal
1511dcb309 store endpoint and send packet 2022-02-28 21:46:00 -05:00
R4SAS
35afa98112 [reseed] add new reseed
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-03-01 00:23:52 +03:00
R4SAS
df62b40ca7 [win32] return back service control code (#1733)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-28 23:02:19 +03:00
orignal
9f1a125ed9 decrypt connID for incoming packet 2022-02-27 20:15:14 -05:00
R4SAS
b7e20b9b86 2.41.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-20 16:57:58 +03:00
R4SAS
a5d6972913 [win] update build script license year
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-20 12:54:48 +03:00
R4SAS
e4cb42c599 [win] add binary signing support
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-20 12:53:31 +03:00
orignal
0a34f1f3ad 2.41.0 2022-02-19 17:21:11 -05:00
orignal
7bdeaa9611 don't pick own router for peer test 2022-02-19 08:15:49 -05:00
R4SAS
ab2577ce0a [daemon] print errors to stdout
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-18 21:00:16 +03:00
orignal
34544be423 Merge pull request #1732 from PurpleI2P/patch-1
Set of updates
2022-02-18 10:13:33 -05:00
R4SAS
6bf0fdd344 [webserver] use cancel instead shutdown for acceptor
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-18 09:45:35 +03:00
R4SAS
6a177cdd1c fix incorrect change in year
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-18 09:29:28 +03:00
R4SAS
a51ef0cfc6 set of updates:
* [webconsole] change error handling code to restart acceptor after any
error
* [webconsole] call shutdown vefore stopping acceptor on exit
* update license headers for modified files, change year to file
  creation year, not 2013 (when project started)

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-18 09:20:06 +03:00
orignal
48374d97df always use TCP/IP sockets for I2CP 2022-02-16 15:32:13 -05:00
R4SAS
bf3d7e74f5 [i2cp] use tcp/ip socket on android
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-16 16:27:59 +03:00
R4SAS
ab3f3890e4 [i2cp] use tcp/ip socket on android
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-16 16:13:15 +03:00
R4SAS
dceb0fb8c5 [cmake] add warning about MESHNET option
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-16 11:39:09 +03:00
R4SAS
05c1856389 [cmake] do not use CMAKE_OSX_ARCHITECTURES for check
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-14 23:53:55 +03:00
R4SAS
dc5cba60d1 [cmake] add MAC_OSX define for Mac
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-14 22:58:56 +03:00
orignal
70409dcdcc Merge pull request #1728 from eyedeekay/swig-binding-cleanup
Removes workaround for passing string arguments from Go
2022-02-14 14:32:23 -05:00
orignal
a92c29e04c drop routers older than 6 months on start 2022-02-13 15:42:06 -05:00
idk
c4b4dc79cf Remove janky workaround for argument passing from Go. This should allow other languages to use the binding more easily, and go-i2pd doesn't need the workaround anymore 2022-02-13 13:21:18 -05:00
orignal
510fe43ec4 create and encrypt SessionRequest 2022-02-11 19:21:04 -05:00
R4SAS
73e572b66b disable thread naming for PowerPC (#1726)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 22:17:38 +03:00
R4SAS
a272a2cb7e [cmake] update min version, drop PCH
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 07:23:33 +03:00
R4SAS
43b990afe6 [cmake] disable deprecation warning when OpenSSL 3 is used
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 07:00:30 +03:00
R4SAS
90130b5492 fix exception printing
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 00:38:29 +03:00
R4SAS
f22faaefeb remove duplicate definition
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 00:27:19 +03:00
R4SAS
ac25649425 cast pthread name to char* for apple sdk
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-11 00:05:07 +03:00
orignal
04388325a8 KDF and encryption for SessionRequest 2022-02-10 14:03:09 -05:00
orignal
61ec873842 fixed incorrect ret code 2022-02-10 13:07:29 -05:00
orignal
ea1f2d4e26 use i for intro key for SSU 2022-02-06 10:17:35 -05:00
orignal
4211c733a2 s and i keys for all addresses 2022-02-05 17:14:25 -05:00
orignal
450266818a Noise XK for SSU2 2022-02-05 15:58:39 -05:00
orignal
1e019157bb SSU2 initial commit 2022-02-04 15:01:18 -05:00
orignal
c9a1066f02 send SessionCreated before connection close if slock skew 2022-02-03 14:49:36 -05:00
R4SAS
0062f7d764 [reseed] dont do yggdrasill address check if option disabled
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-03 14:49:24 +03:00
orignal
95e994e171 pass incomplete I2NP message by move 2022-02-02 17:33:33 -05:00
R4SAS
31242401e5 [cmake] update TargetArch.cmake (#1724)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-02 06:07:01 +03:00
orignal
19cc1c3b3f adjust clock from SSU SessionCreated is time difference exceeds 15 seconds 2022-02-01 18:43:11 -05:00
R4SAS
03bcdceb9b [gha] add ucrt windows build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-01 15:42:57 +03:00
R4SAS
33ca836ad0 [gha] add ucrt windows build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-02-01 15:36:35 +03:00
R4SAS
53f19e4050 Use builtin bitswap for endian on windows
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-29 22:09:27 +03:00
R4SAS
54b7d46f5a reseeds update
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-28 18:39:21 +03:00
orignal
40e6d675c5 I2NP messages pool for I2CP 2022-01-25 13:02:27 -05:00
orignal
73b77c83b8 select compatible outbound tunnel 2022-01-24 13:25:47 -05:00
R4SAS
632d41e50c [rpm] try to fix fedora copr build [3]
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-24 03:20:43 +03:00
R4SAS
17acadbfb9 [rpm] try to fix fedora copr build [2]
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-24 03:14:50 +03:00
R4SAS
2ab5924ec9 [rpm] try to fix fedora copr build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-24 02:56:41 +03:00
R4SAS
ac09a4cf0f [i18n] update german translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-23 03:18:11 +03:00
orignal
c10ee59de3 cleanup memrory pools if no more streams 2022-01-21 21:34:50 -05:00
orignal
afad405ed9 check for duplicate destination 2022-01-19 12:08:56 -05:00
R4SAS
5a35de8dc9 [i18n] update uzbek translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-19 00:38:33 +03:00
orignal
58cf26c304 cleanup properties before update 2022-01-15 19:26:11 -05:00
orignal
a2de5564ac moved m_Properties to LocalRouterInfo 2022-01-15 18:54:02 -05:00
orignal
338b17ccf1 LocalRouterInfo for own router 2022-01-15 12:48:49 -05:00
orignal
843a968959 integer uptime 2022-01-09 19:07:10 -05:00
R4SAS
dc45c13eef [i18n] added german translation (thanks to mark22k@crowdin)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-09 23:42:13 +03:00
R4SAS
0d6e801595 [webconsole] change dark style colors
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-01-09 20:54:18 +03:00
orignal
2cd50ebaee fixed race condition 2022-01-07 13:39:12 -05:00
orignal
cb6f6a6596 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2022-01-03 16:28:17 -05:00
orignal
e4ab0acc92 create RouterInfo from shared pointer to Buffer 2022-01-03 16:27:28 -05:00
R4SAS
10237c41d3 Merge pull request #1717 from rex4539/typos
Fix typo
2022-01-03 20:23:09 +03:00
Dimitris Apostolou
ac2c6c6010 Fix typo 2022-01-02 12:14:12 +02:00
orignal
c6b2ce93c4 Memory pool for RouterInfo address 2022-01-01 15:12:59 -05:00
orignal
401b7fe883 send error message in quotes 2021-12-31 08:48:21 -05:00
orignal
f567417bb3 memory pool for RouterInfo buffer 2021-12-30 15:16:13 -05:00
orignal
ae5cb3bbe7 rollback 2021-12-28 08:00:03 -05:00
orignal
0eb8e15796 allocated actual buffer size for RouterInfo 2021-12-27 13:02:06 -05:00
orignal
1c95c7856f avoid duplicated addresses. Check presence of netId and version 2021-12-24 18:58:20 -05:00
orignal
daf7551e59 try another fllodfill if no compatible tunnels 2021-12-18 17:55:26 -05:00
orignal
5b63d3692e HidUser0's yggdrasil reseed added 2021-12-13 13:47:59 -05:00
R4SAS
5f9972af78 [addressbook] fix loading subscriptions from config
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-12-07 23:00:52 +03:00
R4SAS
1be4cce074 [addressbook] fix loading subscriptions from config
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-12-07 22:59:11 +03:00
orignal
935e93eb36 minimal send ack interval 2021-12-05 17:54:34 -05:00
orignal
5d924cd35a don't copy received datagram 2021-12-04 19:32:18 -05:00
R4SAS
27116b9f30 2.40.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-28 04:26:44 +03:00
R4SAS
8ac2ee49a8 [gha] fix build without pushing tag for pre-release debian packages
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-28 04:00:03 +03:00
R4SAS
8a8e328fcf [build] include contrib/webconsole to windows packages
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-28 03:50:05 +03:00
R4SAS
c4207e7672 [webconsole] update css
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-28 03:49:08 +03:00
R4SAS
73642703bd 2.40.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-28 03:46:53 +03:00
orignal
b3bd175e64 2.40.0 2021-11-27 18:01:13 -05:00
R4SAS
742032907a [gha] update freebsd action
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-27 23:46:03 +03:00
R4SAS
edc0162163 clean line trailing spaces and tabs
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-27 23:30:35 +03:00
R4SAS
94661f697b [log] update log messages (closes #1693)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-27 22:53:53 +03:00
R4SAS
4ecf36fab6 update bandwidth option description (closes #1704)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-27 21:08:05 +03:00
R4SAS
96cdb3bca3 reseeds update
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-21 20:20:23 +03:00
orignal
6c57ba36f7 lazy initialization or tunnel gateway's random buffer 2021-11-20 18:31:18 -05:00
orignal
cb61897236 Merge pull request #1708 from acetoneRu/openssl
--help small correction
2021-11-20 08:39:43 -05:00
acetone
8b931dd40b Transit traffic bandwidth limit 2021-11-20 08:37:36 -05:00
acetone
6b81478bd2 Merge branch 'PurpleI2P:openssl' into openssl 2021-11-20 05:47:32 -05:00
acetone
9d94eb83c1 --help
Traffic bandwidth -> Transit traffic bandwidth
2021-11-20 05:46:44 -05:00
R4SAS
13374f8b7b [gha] publish windows artifacts separately (#1707) 2021-11-18 16:17:28 +03:00
R4SAS
7bf7aae3d1 [i18n] fix type in translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-18 15:23:09 +03:00
R4SAS
e5f39d0caf [i18n] add armenian translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-18 15:15:34 +03:00
R4SAS
174983548d Merge pull request #1705 from rex4539/typos
Fix typos
2021-11-14 20:37:33 +03:00
orignal
a9ec4d916b Merge pull request #1706 from acetoneRu/openssl
Transit traffic bandwidth configuration
2021-11-14 08:21:16 -05:00
acetone
a55c346af5 Bandwidth configuration
Changed to 'Transit traffic bandwidth configuration'
2021-11-14 08:17:53 -05:00
acetone
8e0d8c96bb Merge branch 'PurpleI2P:openssl' into openssl 2021-11-14 08:16:36 -05:00
orignal
9abd383014 eliminate extra pointers for tunnel hops 2021-11-13 15:11:59 -05:00
Dimitris Apostolou
8ee9c437e1 Fix typos 2021-11-13 19:07:50 +02:00
orignal
4052b1ea6d pick compatible outbound tunnel for datagrams 2021-11-08 18:23:26 -05:00
R4SAS
fdde197c58 [webconsole] update stylesheet
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-08 07:40:39 +03:00
R4SAS
49883dc3ac [webconsole] update stylesheet (closes #1699)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-08 07:02:11 +03:00
orignal
d798faa1ca pick compatible ooutbound tunnel 2021-11-07 17:18:31 -05:00
orignal
3f63f15b16 copy compatible transports to new tunnel 2021-11-06 19:16:45 -04:00
orignal
f8c390cdd3 pick compatible tunnels 2021-11-06 15:44:56 -04:00
orignal
8f0978cfd6 all transports by default 2021-11-06 10:49:18 -04:00
orignal
1a8a32a773 select next tunnel with compatible transports 2021-11-05 14:51:24 -04:00
orignal
c0400bfd07 virtual destructor for TunnelConfig 2021-10-31 22:14:59 -04:00
R4SAS
c6e4758187 Revert "Merge pull request #1703 from simonvetter/simon/memory-and-multithreading-fixes"
This reverts commit 67863cfcf9, reversing
changes made to 4c5ec68ff1.

That change completly bloking transports thread on windows.

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-01 05:03:34 +03:00
orignal
56ec8fe95b eliminate local destination mutex 2021-10-31 21:20:16 -04:00
orignal
67863cfcf9 Merge pull request #1703 from simonvetter/simon/memory-and-multithreading-fixes
memory leak and concurrency fixes
2021-10-31 21:08:11 -04:00
R4SAS
4c5ec68ff1 [win] add menu item for opening datadir
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-11-01 02:47:53 +03:00
Simon Vetter
58b7b7d731 libi2pd: add missing locks to i2p::tunnel::TunnelPool 2021-10-31 23:26:52 +01:00
Simon Vetter
1de1c79d4f libi2pd: add missing locks to i2p::tunnel::Tunnels
m_InboundTunnelsMutex, m_OutboundTunnelsMutex and m_PoolsMutex
have been changed to recursive_mutexes since they can be
acquired multiple times by the same thread.
2021-10-31 23:14:28 +01:00
Simon Vetter
7073a6bf38 libi2pd: make Tunnel and TunnelConfig destructors virtual 2021-10-31 14:02:25 +01:00
orignal
26db88d89b check if sip key is available 2021-10-27 22:33:37 -04:00
orignal
876e98d91e check if sip key is available 2021-10-27 22:23:32 -04:00
orignal
8566f6c127 don't store EVP_PKEY sip keys 2021-10-27 21:18:21 -04:00
orignal
bb8dc67942 don't use openssl's SipHash from 3.0.0 due regression 2021-10-27 19:05:16 -04:00
orignal
9965d72990 don't store EVP_PKEY with EdDSA signer and verifier 2021-10-26 21:36:34 -04:00
orignal
921ec9ec12 fix build with openssl 3.0.0 2021-10-23 18:10:02 -04:00
orignal
f1990bc2ab use tunnel endpoint memroy pool to split to tunnel messages at gateway 2021-10-22 21:08:20 -04:00
orignal
cdc8e463b7 use memory pool for outgoing tunnel gateway messages 2021-10-22 19:18:45 -04:00
R4SAS
0a62a962d7 [debian] update upnp patch
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-10-22 05:57:04 +03:00
R4SAS
b0f043ec86 [make] USE_GIT_VERSION option to use commit info in version (closes #1702)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-10-22 05:35:01 +03:00
orignal
ae0cf2e831 use memory pool for tunnel messages 2021-10-20 21:05:22 -04:00
orignal
4ce7e192d6 Merge pull request #1701 from simonvetter/openssl
fix a few undefined behaviour/out of bounds issues
2021-10-19 18:25:06 -04:00
R4SAS
04ca916aac Merge pull request #1700 from xanoni/set-default-make-target
Makefile: set default target ("all")
2021-10-19 23:56:41 +03:00
Simon Vetter
a348e10620 libi2pd: fix undefined behaviour and memory overruns
This fixes the following issues (flagged by cppcheck):
[libi2pd/ECIESX25519AEADRatchetSession.cpp:537]: (error) Buffer is accessed out of bounds: m_NSREncodedKey
[libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: keys.publicKey
[libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: publicKey
[libi2pd/NetDb.cpp:70] -> [libi2pd/NetDb.cpp:69]: (error) Iterator 'it' used after element has been erased
[libi2pd/SSUData.cpp:186] -> [libi2pd/SSUData.cpp:187]: (warning) Shifting 32-bit value by 63 bits is undefined behaviour.
2021-10-19 22:27:12 +02:00
Simon Vetter
af794f901f libi2pd: minor logging fixes 2021-10-19 22:27:06 +02:00
R4SAS
8a58572b34 [webconsole] upload example dark style
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-10-19 18:24:49 +03:00
R4SAS
0c25e8f1eb [build] changes in windows build script
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-10-19 18:24:18 +03:00
xanoni
ff3d2db85e Darwin: allow calling make install more than once
This commit ensures that `gzip` does not overwrite any of the repo
files, because that prevents `make install` from executing more than
once.
2021-10-18 22:33:32 -04:00
xanoni
efd84a2404 Makefile: set default target ("all")
Fixes compilation on Darwin, see:
https://github.com/PurpleI2P/i2pd/pull/1698#issuecomment-946304938
2021-10-18 22:11:27 -04:00
orignal
278fd2d8d5 create tunnel I2NP message for tunnel data 2021-10-18 19:03:08 -04:00
orignal
197882a4c9 create I2NP depending on type in I2NP block 2021-10-17 15:30:24 -04:00
orignal
d310efcb5c pass I2NPMessage by move 2021-10-17 11:31:37 -04:00
orignal
1af9117b80 don't create new tunnel message for encryption/decryption 2021-10-15 14:01:41 -04:00
orignal
44e01b41f8 reserve address for 3 introducers 2021-10-12 13:28:16 -04:00
orignal
7def2fa6a3 use std::vector for address list 2021-10-10 09:53:21 -04:00
orignal
48131f4597 don't store full path with RouterInfo 2021-10-07 15:08:33 -04:00
orignal
49e8cf89d8 don't send short tunnel build messages for ElGamal only destinations 2021-10-06 12:42:32 -04:00
orignal
e6bcd04a36 short build message for re-created tunnels and far end transports 2021-10-05 19:38:33 -04:00
orignal
af133f4968 fixed crash if incorrect blinded signature type 2021-09-29 12:38:38 -04:00
R4SAS
d723faaaa3 [UDPTunnel] restart local listener on error
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-28 14:27:35 +03:00
orignal
cc75efcbca fixed build for C++11 2021-09-27 18:25:15 -04:00
orignal
2eded7cdd7 send ping every keealive interval for client tunnels 2021-09-26 16:25:12 -04:00
orignal
b10e5ce358 send ping 2021-09-26 11:20:20 -04:00
orignal
1bb1d89fab change back to map and unodered_map 2021-09-25 18:30:17 -04:00
orignal
b9dd4aee8d use flat_map for incompete messages 2021-09-24 19:12:12 -04:00
orignal
518e53a61c use flat_map for smaller tables 2021-09-24 14:23:39 -04:00
orignal
18b6ba80f2 cleanup RelayRequests 2021-09-22 19:09:56 -04:00
orignal
8debdc264c use common cleanup timer for all SSU sessions 2021-09-21 22:13:34 -04:00
orignal
31bdce1f1f cleanup received messages list by timestamp 2021-09-21 19:01:22 -04:00
orignal
317d8cdc48 don't allocate separate buffers for SessionRequest and SessionCreated 2021-09-18 15:44:43 -04:00
orignal
5b2b9e00a2 reuse receive buffer 2021-09-17 21:52:39 -04:00
R4SAS
3dd9e81296 [addressbook] check domain ending when processing subscriptions
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-17 02:53:30 +03:00
R4SAS
d2faec70be [gzip] do not initialize deflator if gzip is not enabled for tunnel
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-14 14:48:21 +03:00
R4SAS
e5c773a3eb [webconsole] move resources to separate header file
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-13 23:16:18 +03:00
R4SAS
ec86c4611d disable reload checks for UDP tunnels (TODO)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-13 23:16:18 +03:00
orignal
247b6a0ed2 memory pool for SSU packets 2021-09-13 13:13:27 -04:00
orignal
f7f36568ef set gzip compression to false by default 2021-09-12 14:29:43 -04:00
orignal
e054c6e82c memory pool for SSU messages and fragments 2021-09-11 18:58:27 -04:00
orignal
5e2e1a1e3d don't include old tunnel to LeaseSet if recreated 2021-09-10 19:57:38 -04:00
orignal
ad036de69d eliminate allocation of m_ExtendedBuffer 2021-09-09 21:19:52 -04:00
orignal
20652f7995 resseed if too few floodfills 2021-09-09 15:12:53 -04:00
R4SAS
2f88a75325 Merge pull request #1688 from yangfl/openssl
disable pthread_setname_np on GNU/Hurd
2021-09-05 21:00:19 +00:00
orignal
292fe94352 RouterContext is always ECIES 2021-09-05 11:16:41 -04:00
orignal
76dca1b46b don't handle ElGamal build record 2021-09-05 09:10:13 -04:00
orignal
a54b5c18c6 fixed crash 2021-09-05 09:08:29 -04:00
orignal
c763472914 select ECIES routers only for peer tests and introducers 2021-09-05 08:41:32 -04:00
orignal
3a77e7ba2d remove dependancy from localization 2021-09-04 18:55:51 -04:00
orignal
41d6c117ee make sure server tunnel is published 2021-09-04 18:45:32 -04:00
orignal
e8f4c42bfb moved current language from RouterContext to ClientContext 2021-09-04 14:01:57 -04:00
orignal
bce8469e59 eliminate extra error message 2021-09-04 08:53:39 -04:00
yangfl
3f46ca41ca disable pthread_setname_np on GNU/Hurd
which does not exist on GNU/Hurd
2021-09-04 15:07:09 +08:00
R4SAS
6b1ef6e1b9 tunnels reload changes: fix tcp tunnels reload
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-09-04 04:02:27 +03:00
orignal
349022ae42 don't select ElGamal routers for tunnels 2021-09-03 13:30:01 -04:00
orignal
bb518d3d51 don't pass BN_CTX to encrypt/decrypt functions 2021-08-31 18:51:40 -04:00
orignal
c45e202fab removed ElGamal encryption support for own router 2021-08-29 14:22:01 -04:00
orignal
541464b705 don't delete floodfill if number of remaining floodfills is less than minimal 2021-08-26 15:13:58 -04:00
R4SAS
c762acd780 Merge pull request #1687 from dbermond/fix-test-blinding
[tests] fix compilation of test-blinding
2021-08-24 10:24:31 +00:00
R4SAS
ec98ff297c Make blinding test runnable 2021-08-24 13:23:10 +03:00
R4SAS
af2c6c5575 [rpm] change if statement to cover fedora 35
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-24 03:16:28 +03:00
Daniel Bermond
7d220fb2eb [tests] fix compilation of test-blinding
test-blinding currently fails to build with the following error:

In file included from ../libi2pd/Timestamp.cpp:19:
../libi2pd/RouterContext.h:21:10: fatal error:
I18N_langs.h: No such file or directory
   21 | #include "I18N_langs.h"
      |          ^~~~~~~~~~~~~~
compilation terminated.
2021-08-23 17:22:28 -03:00
R4SAS
f0c49b58fb suppress inconsistent-missing-override warning message
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-23 19:29:55 +03:00
R4SAS
24eeadea76 [rpm] add changelog note
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-23 17:03:26 +03:00
R4SAS
455c71ff25 fix warning about ifr_name size
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-23 17:00:57 +03:00
orignal
96850da31e 2.39.0 2021-08-23 06:58:36 -04:00
R4SAS
6ba992dabd [rpm] try fix build on fedora rawhide [try 3]
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-22 23:41:36 +03:00
R4SAS
2bdfcedd0e [docs] add comma to description
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-22 23:38:04 +03:00
R4SAS
c93ab8f829 update changelog, i2pd.conf
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-22 23:36:08 +03:00
orignal
8abd08bd1b change log for 2.39.0 2021-08-22 15:58:46 -04:00
R4SAS
33355c0abe [rpm] try fix build on fedora rawhide
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-22 22:44:04 +03:00
R4SAS
b830babcf4 [rpm] try fix build on fedora rawhide
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-22 22:32:03 +03:00
R4SAS
97765ef895 [i18n] add namespace
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-18 23:04:52 +03:00
R4SAS
8943d212ee [i18n] add Uzbek translation (partial)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-18 22:55:14 +03:00
R4SAS
86e118f2b7 [i18n] change string in HTTPProxy
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-18 22:23:39 +03:00
R4SAS
8c3823fc92 [gha] build docker containers for arm/arm64
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-15 16:53:10 +03:00
orignal
b0874410f1 take first avalable resolved address if local address is not specified 2021-08-13 13:54:23 -04:00
orignal
797f5eb714 select compatible resolved address for server tunnel 2021-08-13 13:31:04 -04:00
orignal
fc29911ffd rollback 2021-08-13 11:36:04 -04:00
R4SAS
1e17ef2f21 [webconsole] show v4 status only ipv4 is enabled
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-13 09:17:27 +03:00
R4SAS
b3e7b1b5ac Squashed commit of the following:
commit 40ec4e8b59
Author: Simon Vetter <simon.vetter@runbox.com>
Date:   Fri Jul 30 21:23:27 2021 +0200

    libi2pd: mark additional ipv6 addresses/nets as reserved

    This adds :: (undefined address), ::1 (loopback address) as well as
    ff00::/8 (multicast prefix) to reservedIPv6Ranges.

    A bunch of nodes seem to be publishing bogus addresses (mostly ::1)
    in the netDB, resulting in unnecessary tunnel build failures.

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-13 09:11:56 +03:00
orignal
38a2d45a3c close all existing streams when command SAM socket got closed 2021-08-11 12:31:46 -04:00
orignal
49b3ac7f77 don't reschedule resend timer for terminated streams 2021-08-11 12:23:43 -04:00
orignal
d124d4cace allow ipv6 adresses for UDP server tunnels 2021-08-10 11:36:12 -04:00
R4SAS
ba369d9b30 [webconsole] fix style in css
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-07 17:31:26 +03:00
R4SAS
bef8587d8f [makefile] create object dirs on windres (race condition)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-07 01:38:35 +03:00
R4SAS
fcbc16f2fd [webconsole] fix style issues, clean external style in file was not found on reload
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-07 01:37:45 +03:00
r4sas
a3b172bbcb [makefile] change back directories creation, create them before compiling object files 2021-08-06 21:19:05 +00:00
R4SAS
2f945a4fce [makefile] dont build .so and .dll on default target
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-06 21:19:05 +00:00
R4SAS
dc9e5dc2f1 [makefile] suffix, not prefix
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-06 21:19:05 +00:00
R4SAS
9396827379 [makefile] build libraries on default target
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-06 21:19:05 +00:00
R4SAS
28a055bd78 [webconsole] add external CSS support (#1682)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-06 20:42:08 +03:00
orignal
37f1a55147 encryption type 0,4 by default for server tunnel 2021-08-06 12:32:21 -04:00
orignal
64ec7dd559 narrow down random range 2021-08-03 19:26:09 -04:00
orignal
367df4d0db RAND_bytes from random router selection 2021-08-03 15:43:58 -04:00
orignal
da7e41c188 use Tag<64> for ratechet tags 2021-08-01 18:42:13 -04:00
R4SAS
d88fe203e1 [tunnels] count outbound traffic for zero-hop tunnels
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-08-01 09:25:02 +03:00
orignal
1e01c30e63 set pool for zero-hops tunnels 2021-07-30 14:12:50 -04:00
TomasGl
b16b753ed2 Change default irc server to IRC ILITA (#1677) 2021-07-30 17:49:19 +03:00
orignal
7a55d1fc38 don't insert garlic tag for short tunnel build reply if the same router 2021-07-28 21:14:03 -04:00
orignal
f8623b6121 consistent path for explicit peers 2021-07-28 19:08:55 -04:00
orignal
9a3c22f47d don't encrypt ShortTunnelBuild and ShortTunnelBuildReply if on the same router 2021-07-28 15:06:24 -04:00
orignal
e68cff8bba try routers before random router 2021-07-27 18:35:30 -04:00
orignal
513493fa78 fixed typo 2021-07-26 18:46:29 -04:00
orignal
a6937c792f more precise router selection 2021-07-26 17:51:32 -04:00
orignal
99c7d5c23a don't create enryptor for ECIES record encryption 2021-07-25 22:30:54 -04:00
orignal
cd8e8970de NTP request through compatible address 2021-07-24 16:01:11 -04:00
orignal
26d5ced2ef optimal padding for one-time messages 2021-07-23 20:28:55 -04:00
orignal
c7234f705a let NTCP sync through ipv6 2021-07-23 18:34:51 -04:00
orignal
c153471c49 use short tunnel build if possible 2021-07-22 20:58:35 -04:00
R4SAS
28369faa00 [debian] fix tabulation in patch 2021-07-22 13:35:58 +00:00
R4SAS
445c5f47ae [debian] update patch for upnp 2021-07-22 13:24:42 +00:00
R4SAS
7078ca53c3 [debian] update patch for upnp 2021-07-22 13:23:05 +00:00
orignal
d6ce5f9fa1 Merge pull request #1669 from eyedeekay/c-wrapper-libi2pd-api
C wrapper for part of the libi2pd api
2021-07-22 08:54:59 -04:00
orignal
f28024cfe8 decline transit tunnels from short tunnel build message 2021-07-21 18:12:37 -04:00
orignal
911ab9813e handle encrypteed I2NPShortTunnelBuildReply in destination 2021-07-21 14:55:38 -04:00
orignal
cfbf5862f9 set pool for tunnel before build 2021-07-21 13:08:12 -04:00
orignal
5cb1f5986d use msgID from ECIESx25519 block 2021-07-20 22:00:06 -04:00
orignal
0b14c810fb handle ShortTunnelBuildReply 2021-07-20 19:38:36 -04:00
orignal
c2334db8f8 correct reply key for short tunnel build record 2021-07-20 18:02:48 -04:00
orignal
4807092df6 fixed typo 2021-07-20 15:17:58 -04:00
orignal
bdc1107c96 correct message type for ShortTunnelBuild 2021-07-20 14:35:02 -04:00
orignal
db9223b0d5 set minimal version for floodfill to 0.9.38 2021-07-19 17:50:55 -04:00
orignal
6ecfe0789f don't allocate payload buffer for every single ECIESx25519 message 2021-07-18 18:45:08 -04:00
orignal
a37cf058cd router with expired introducer is still valid 2021-07-16 20:12:41 -04:00
orignal
f4902e6642 eligble floodfill must be reachable by ipv4 2021-07-16 13:53:12 -04:00
orignal
5d022c25ba don't send datetime for one time key message 2021-07-16 09:44:22 -04:00
orignal
0cd9f1b002 precalculate padding sizes 2021-07-15 19:01:43 -04:00
orignal
cd0751d3f1 padding block for message for router 2021-07-15 18:30:32 -04:00
orignal
a1d1a5df74 datetime block for message for router 2021-07-15 18:18:55 -04:00
orignal
197f13f9c0 rollback 2021-07-15 14:02:20 -04:00
orignal
41bfc7899d keep own RouterInfo in netdb 2021-07-14 14:46:56 -04:00
orignal
2c129b6d39 create and handle short tunnel build reply 2021-07-12 19:40:40 -04:00
orignal
dbe427d5eb set reply code for short tunnel build messages 2021-07-11 19:29:16 -04:00
R4SAS
3e281d4790 Update README.md 2021-07-11 23:10:53 +03:00
orignal
15c3d46492 encrypt inbound tunnel build message for short tunnel build only 2021-07-10 17:28:18 -04:00
orignal
6a467a09bd fixed build error 2021-07-10 16:47:28 -04:00
orignal
ba1b8c7c2b WrapECIESX25519MessageForRouter wihout session 2021-07-10 16:15:15 -04:00
orignal
1e9eb30aa3 garlic encryption of inbound tunnel build message 2021-07-10 14:33:23 -04:00
orignal
d47bf1bada different tunnel build record size 2021-07-09 19:26:14 -04:00
orignal
59dd60f5cb genarate keys in CreateBuildRequestRecord 2021-07-09 19:24:28 -04:00
orignal
c02a0c4da9 process DELAY_REQUESTED option 2021-07-08 22:22:00 -04:00
orignal
84f6024cc9 locate record to build inside CreateBuildRequestRecord 2021-07-08 19:00:25 -04:00
orignal
d73b42b726 extract ret code per hop 2021-07-08 16:39:38 -04:00
orignal
ed0c2e68a5 DecryptRecord per tunnel hop 2021-07-07 21:16:30 -04:00
orignal
847225c6bf more yggdrasil reseeds added 2021-07-07 08:24:01 -04:00
orignal
a6294df9e8 decrypt one-time message encrypted with tag on router 2021-07-06 20:15:55 -04:00
orignal
431265a86a update orignal's certificate 2021-07-06 18:22:08 -04:00
orignal
4255c4901d orignal's reseed ceritifcate 2021-07-06 17:44:39 -04:00
orignal
9000b3df4e KDF for short tunnel build messages 2021-07-05 14:31:07 -04:00
orignal
a717542733 update yggdrasil reseed to 0.4 2021-07-04 07:33:28 -04:00
orignal
aace644815 added ShortECIESTunnelHopConfig 2021-07-02 22:06:24 -04:00
orignal
0ae170531e different ElGamal and ECIES hops configs 2021-07-02 15:41:33 -04:00
idk
5d01ee9581 Also add the languages to the linker flags in the api.go file 2021-07-02 13:20:28 -04:00
orignal
8b35ce3320 separate decryption between own record and other records 2021-07-02 13:20:24 -04:00
r4sas
ff0e23d2c4 [cmake] use GNUInstallDirs for libraries destination path (#1672)
Signed-off-by: r4sas <r4sas@i2pmail.org>
2021-07-02 16:43:41 +00:00
idk
d62d2ed269 resolve merge conflicts 2021-07-02 11:02:31 -04:00
idk
abee29719d fix go linking 2021-07-02 10:47:55 -04:00
orignal
5781335814 save and check last stream 2021-06-29 19:08:11 -04:00
R4SAS
f036b8df2d [i18n] update translatable strings (remove douplicates)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-28 12:45:28 +03:00
orignal
25f63ac22a create different I2NP tunnel messages for endpoint and non-endpoint 2021-06-27 15:49:57 -04:00
R4SAS
12d6f03dc9 [i18n] add language changing at runtime in webconsole
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-27 17:14:45 +03:00
R4SAS
6d2c9e367b remove unused CI and docker files
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-27 12:24:41 +03:00
orignal
66422d6d83 double size tunnel message 2021-06-26 21:44:51 -04:00
orignal
b9476791f4 eliminated extra I2NP messages for fragments 2021-06-26 17:40:25 -04:00
R4SAS
9fb8e8a582 [cmake] build translations as library
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-26 23:59:34 +03:00
R4SAS
377a50fa13 [make] build translations as library
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-26 23:45:55 +03:00
R4SAS
da20cae25c [webconsole] urldecode domain for registration string generator
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-26 18:59:48 +03:00
orignal
d0c5732e16 eliminate extra lookups for sequential fragments 2021-06-26 07:18:42 -04:00
idk
f9d9aa0306 move wrapper code to own directory 2021-06-24 09:35:42 -04:00
idk
f5db34b98b C_InitI2P is compatible with more things if it passes argv by reference, it would appear. So to pass arguments to InitI2P you need to turn them back into char* argv[] by tokenizing them and copying them into an array which you then pass to InitI2P from C_InitI2P. The Streaming and Destination Creation parts need to have wrappers for over Identity.h, Streaming.h to be useful so remove them. 2021-06-23 11:18:53 -04:00
orignal
3c07665479 use unordered_map for incomplete messages 2021-06-22 15:35:44 -04:00
orignal
f7f50d049b reduce short tunnel build record length 2021-06-22 13:11:02 -04:00
R4SAS
7d51b4c6ed [i18n] pull ukrainian translation from crowdin (closes #1666)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-21 21:16:46 +03:00
orignal
35ba16ff3b fixed #1665. cast to int64_t 2021-06-20 17:20:29 -04:00
R4SAS
6971b1e9da fix typo in config option description
Kudos @iBicha
https://github.com/PurpleI2P/i2pd/pull/1662#pullrequestreview-687850246

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-20 20:03:33 +03:00
R4SAS
84d987810f add afrikaans in config example 2021-06-20 09:36:14 +03:00
orignal
fed04c1a19 requsted router to send to if not in netdb 2021-06-19 14:44:33 -04:00
orignal
f5e7d87f5b don't disable floodfill if still reachable by ipv6 2021-06-19 14:25:50 -04:00
orignal
6ca28adcbb set address caps and available transports for new address 2021-06-18 18:19:05 -04:00
R4SAS
8e5d2e1b73 [readme] add gha container build badge 2021-06-18 17:26:18 +03:00
R4SAS
e8ad7b4f79 rework of storing certificates path (#1642)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-18 10:04:48 +03:00
R4SAS
d3a49e513c remove repeatable type definition, add include (#1642)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-18 06:45:12 +03:00
R4SAS
5bfab0a796 add certsdir option (#1642)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-18 06:38:10 +03:00
idk
739d1aa9e9 Merge branch 'c-wrapper-libi2pd-api' of github.com:eyedeekay/i2pd into c-wrapper-libi2pd-api 2021-06-17 23:32:47 -04:00
idk
e575c6e94d Merge branch 'PurpleI2P:openssl' into c-wrapper-libi2pd-api 2021-06-17 20:20:26 -07:00
idk
7bc2e74683 Get it to build from go build 2021-06-17 23:12:22 -04:00
orignal
2185019b59 check if router is reachable by transport before obtaining address 2021-06-17 19:46:05 -04:00
orignal
5d097651c1 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2021-06-17 19:11:28 -04:00
orignal
81c83f0d54 pick ECIES routers only for non-x64 2021-06-17 19:10:57 -04:00
idk
5013ce5649 Try and figure out why the C Compiler thinks it needs to find iostream when the C++ library has already been compiled. Make the makefile aware of variables in the environment 2021-06-17 18:25:55 -04:00
R4SAS
5e11a03f0a [docker] fallback to alpine 3.13
https://wiki.alpinelinux.org/wiki/Draft_Release_Notes_for_Alpine_3.14.0#faccessat2
2021-06-17 22:41:37 +03:00
R4SAS
e14d358420 [docker] add debug commands
Adding `g++ -dumpmachine` command on build stage to figure out why docker hub is unable to build container.
2021-06-17 22:11:46 +03:00
R4SAS
82bb3a9b25 [i18n] remove comment line in afrikaans
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-17 21:49:39 +03:00
R4SAS
669720d8f5 [gha] build and publish release containers 2021-06-17 21:37:48 +03:00
idk
45ef6cba9d Un-mangle Destination in case we need to somehow pass one to DestroyLocalDestination,RequestLeaseSet, etc 2021-06-17 13:46:57 -04:00
idk
3330d2bb0c Also Extern Identity, Destination, Streaming headers 2021-06-17 13:24:19 -04:00
R4SAS
a97d2bbb63 [gha] publish containers to docker hub 2021-06-17 20:07:10 +03:00
R4SAS
f56f75bb3f [gha] add docker building (#1664) 2021-06-17 19:37:47 +03:00
orignal
08a82a0bcd don't try to connect to a router not reachable from us 2021-06-17 12:12:06 -04:00
R4SAS
3dc19bfd31 [gha] docker - disable cache (test) 2021-06-17 11:07:56 +03:00
R4SAS
970f47ce33 [gha] remove context 2021-06-17 11:03:30 +03:00
R4SAS
2ee7ed8dda [gha] temporary build only amd64 container 2021-06-17 10:59:47 +03:00
R4SAS
d058b9a595 [gha] fix repository name to lowercase 2021-06-17 10:38:38 +03:00
R4SAS
1dda832e39 [gha] build docker containers
Build docker containers and publish them to GitHub Container Registry
2021-06-17 10:35:10 +03:00
orignal
a6af4908d5 use m_ReachableTransports bitmask 2021-06-16 18:14:33 -04:00
R4SAS
2c7fff077b [gha] add dist name in package changelog
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 22:06:48 +00:00
R4SAS
71df1fc4d6 [gha] do not check source archive for deb build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 21:45:14 +00:00
R4SAS
064ecdb5ec [gha] do no check source archive for deb build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 21:40:45 +00:00
R4SAS
8ec4783249 [gha] fetch all history of git repo for packages (needs for describe)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 21:34:59 +00:00
R4SAS
f9d378f1ce [gha] add deb building
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 21:19:19 +00:00
R4SAS
f07241bff7 add deb building
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 21:14:22 +00:00
R4SAS
a6be32392d update debian packaging files
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 20:41:41 +00:00
R4SAS
ac594dbd26 Update status badges in README 2021-06-16 19:12:05 +03:00
R4SAS
954711e980 [i18n] pull afrikaans translation from crowdin
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 17:57:20 +03:00
R4SAS
2ba3f4758a [i18n] move gettext translation template to contrib
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 17:57:20 +03:00
orignal
6be4d508f3 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2021-06-15 19:10:23 -04:00
orignal
dc75868bd3 check Alice's IP address in PeerTest 2021-06-15 19:09:36 -04:00
R4SAS
c06a560946 [i18n] use xgettext compatible function format for plural
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-16 00:13:26 +03:00
R4SAS
0bacd4df5f [i18n] update gettext description
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-15 23:44:23 +03:00
R4SAS
b91eaf5487 [i18n] update gettext description
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-15 23:30:28 +03:00
R4SAS
eebea7b342 [i18n] Add translation source in gettext format
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-15 23:22:59 +03:00
R4SAS
29c1173e14 [i18n] fixes in translations
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-15 23:22:11 +03:00
idk
b962a330ad Allow passing raw pointers to C wrapper functions, I think 2021-06-15 12:02:57 -04:00
R4SAS
1d973bc3ac [webconsole] remove extra line break
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-15 17:55:22 +03:00
orignal
631c8c9870 use correct address type for NTCP2 acceptors 2021-06-14 21:19:44 -04:00
orignal
bce6685d0c correct check of ipv4/ipv6 address 2021-06-14 12:36:54 -04:00
orignal
e412b17f70 don't publish slow tunnel in LeaseSet if possible 2021-06-11 08:34:56 -04:00
orignal
a92b93192d reg.i2p for subscriptions 2021-06-10 13:24:04 -04:00
R4SAS
8708a0076f fix build with boost < 1.55.0 (closes #1661)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-06-09 22:23:33 +03:00
orignal
83fd289e46 don't re-create noise state for every message 2021-06-09 12:49:50 -04:00
idk
ed53cbb7b7 OK that's my first working C wrapper, but I don't yet know how to do anything other than initialize, start, and stop a router 2021-06-08 16:25:45 -04:00
orignal
3b051dbba3 send OutboundTunnelBuildReply 2021-06-08 15:36:27 -04:00
acetone
8e4781b0f7 tbytes in WinApp (#1660) 2021-06-08 16:39:28 +03:00
acetone
d599502b1a 1000Gb+ display 2021-06-07 23:49:56 -04:00
orignal
8571830485 create transit tunnel and reply for short tunnel build 2021-06-07 18:28:36 -04:00
acetone
48d9a03aa8 tbytes in WinApp 2021-06-07 12:58:57 -04:00
orignal
5fb426b336 decrypt and encrypt reply for short tunnel build message 2021-06-06 13:55:38 -04:00
orignal
d752a83eb5 handle i2cp.dontPublishLeaseSet for all destinations 2021-06-04 18:28:30 -04:00
orignal
e740d5fc4f try to pick non-slow tunnel 2021-06-04 12:16:50 -04:00
orignal
8e3e35a36d decrypt short request record 2021-06-02 19:50:29 -04:00
orignal
5ce9c0f1e2 build new tunnels instead slow 2021-06-02 14:45:21 -04:00
orignal
ef8c4389e1 reachable transports added 2021-06-02 12:55:08 -04:00
R4SAS
0547d590e1 fix typo
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-31 00:24:54 +03:00
R4SAS
be31640010 fix ipv6 preference on linux
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-31 00:23:50 +03:00
R4SAS
39319853ab [i18n] add Turkmen translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-30 21:38:14 +03:00
R4SAS
ed42948051 prefer public ipv6 instead rfc4941 (closes #1251)
Wokrs only on linux-based systems. Not tested on other *nix systems, and
not works on windows.

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-30 03:25:13 +03:00
orignal
a0e545a6f1 always create new tunnel from exploratory pool 2021-05-28 12:11:24 -04:00
R4SAS
e77e383efa [docker] add UPnP at compile time (closes #1649) 2021-05-28 18:59:59 +03:00
orignal
8ce5ceef59 Correct transaltion for "Firewalled" 2021-05-27 17:47:59 -04:00
R4SAS
3a53e049bd [gha] switch ubuntu to 18.04
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 13:43:24 +03:00
R4SAS
5011ecaaa6 [i18n] fix language selection
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 13:27:13 +03:00
R4SAS
35b1842a72 [gha] add cmake build on ubuntu
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 13:21:15 +03:00
R4SAS
0292227a6b [cmake] switch to glob instead filling sources list
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 13:15:17 +03:00
R4SAS
ebce1e34d8 [i18n] enable Ukrainian in source
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 12:56:47 +03:00
R4SAS
cc1244126c [i18n] enable Ukrainian in source
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-26 10:50:02 +03:00
Artem M
bdf63cf82c [i18n] add Ukrainian (#1658) 2021-05-26 10:38:58 +03:00
Artem M
0275f7f574 [i18n] fix two typos in the russian translation (#1659) 2021-05-26 10:05:10 +03:00
R4SAS
779f2fa451 [i18n] rework localization system
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-25 22:03:29 +03:00
R4SAS
1a4250d8cc [i18n] update russian translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-25 00:22:35 +03:00
orignal
08fafe267a rekey all routers to ECIES 2021-05-23 17:27:14 -04:00
orignal
d06924b339 LeaseSet type 3 by default 2021-05-23 14:28:10 -04:00
orignal
585116a51f XMR added 2021-05-23 14:20:23 -04:00
R4SAS
b676d7034f [i18n] update translation
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 16:30:42 +03:00
orignal
69a0fe3040 pass arg as reference 2021-05-23 08:52:27 -04:00
R4SAS
5207dd4c9e [gha] update freebsd action 2021-05-23 15:43:04 +03:00
R4SAS
919bf4e144 [i18n] add cmake build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 15:39:29 +03:00
orignal
7ed440ba75 Merge pull request #1657 from PurpleI2P/i18n
I18n
2021-05-23 08:26:11 -04:00
R4SAS
2db035d23c [i18n] fix addresshelper
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 13:16:52 +03:00
R4SAS
a4b84517dc [i18n] rename Russian translation, fix typo
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 10:56:20 +03:00
R4SAS
e687773b41 [18n] translate webconsole
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 10:50:26 +03:00
R4SAS
df66c2d2dc [i18n] translate HTTP proxy
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-23 06:06:04 +03:00
orignal
f321eb66c0 rename DatabaseLookupTageSet to SymmetricKeyTagset 2021-05-22 18:41:25 -04:00
R4SAS
80b44fc9a9 Support multilang, update code
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-22 18:29:05 +03:00
R4SAS
0e68fe4a57 [i18n] start multilang support for webconsole
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-22 08:39:29 +03:00
orignal
59b471b9a2 i2cp.leaseSetPrivKey for HTTP and SOCKS proxy 2021-05-20 14:10:31 -04:00
orignal
f22eaa6db5 2.38.0 2021-05-16 14:26:00 -04:00
R4SAS
e37244fa0d remove deprecated options from config file example
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-15 16:35:38 +03:00
R4SAS
c359c6e634 update config file example, add v6 status to windows daemon window, code cleanup
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-05-15 16:31:53 +03:00
orignal
d299cbaabd Add/Remove subsession 2021-05-13 19:30:54 -04:00
orignal
2b22bfadbc show version in hidden content 2021-05-12 11:48:27 -04:00
orignal
baec22610e always set expiration time for NSR tagset 2021-05-12 07:57:37 -04:00
orignal
43b587636b delete tags of termiated session right away 2021-05-11 18:49:17 -04:00
orignal
c6cdb26f47 reduce range for extra tags 2021-05-10 20:20:25 -04:00
orignal
1285e30b3e more pre-calculated x25519 2021-05-10 18:55:39 -04:00
orignal
a8e1cd9a13 don't throw exception if local bind fails 2021-05-10 11:04:08 -04:00
orignal
d6f5640685 attach updated LeaseSet to ECIESx25519 incoming sessions 2021-05-09 07:33:26 -04:00
orignal
79dbf2a43e request encrypted LeaseSet if expired 2021-05-07 22:15:12 -04:00
orignal
5ad4c2a65e run ipv6 peer test again if still testing 2021-05-04 14:59:25 -04:00
orignal
fffa550bb0 SAM subsessions 2021-05-04 14:27:06 -04:00
orignal
0b9cb4e75b check identity and signature length for SessionConfirmed 2021-05-03 19:05:25 -04:00
orignal
7f143a7f23 support EdDSA for blinding 2021-05-02 15:02:52 -04:00
orignal
d8d8a68814 rekey all routers but floodfills 2021-04-30 15:19:31 -04:00
orignal
4018cf9d76 SAM single and master sessions 2021-04-26 21:11:36 -04:00
orignal
bd33ac202f handle hostname for STREAM CREATE 2021-04-26 18:21:00 -04:00
orignal
e091eba831 don't cleanup ipv6 introducers list twice 2021-04-25 17:55:13 -04:00
orignal
4a0dbec4fb recognize non-published NTCP2 address 2021-04-25 16:42:09 -04:00
orignal
90dee900f0 fixed crash 2021-04-25 10:57:31 -04:00
orignal
94555b9c43 don't select next introducers from existing sessions 2021-04-24 14:56:34 -04:00
orignal
db93a7315f find new introducers to connect 2021-04-24 11:11:12 -04:00
orignal
7a19533380 reuse current introducers if no more available 2021-04-23 12:17:48 -04:00
orignal
9d79b26506 check if port if specified 2021-04-22 19:32:47 -04:00
orignal
b43a9cc80d handle master session creation 2021-04-21 19:30:20 -04:00
orignal
b5618af308 find all introducers at the time 2021-04-21 15:41:04 -04:00
orignal
9c8c3b9174 select few introducers at the time 2021-04-21 10:56:39 -04:00
orignal
01e591b261 find ipv6 intrioducer session 2021-04-21 09:55:36 -04:00
orignal
060e30d283 select ipv6 random introducer 2021-04-21 08:16:13 -04:00
orignal
ad019da553 publish ipv6 introducers 2021-04-20 20:02:30 -04:00
orignal
69afd3a1da Merge pull request #1651 from acetoneRu/openssl
Уточнение про логирование в Windows
2021-04-19 07:29:33 -04:00
acetone
7978adc577 Уточнение про логирование в Windows 2021-04-19 06:43:51 -04:00
orignal
ca77ca6ef0 reseed from compatible address 2021-04-18 17:27:50 -04:00
orignal
d5b61ed544 select different routers for peer test 2021-04-17 14:33:53 -04:00
orignal
5edb256990 check if our external IP is valid 2021-04-16 19:31:49 -04:00
orignal
74d0c04314 ipv6 address for relay reponse and relay intro 2021-04-15 16:06:02 -04:00
orignal
39d4464be0 make sure that introducer or peer test router is reachable by SSU 2021-04-15 11:43:43 -04:00
orignal
be48dc6e87 pick correct local address for intro key 2021-04-13 15:11:37 -04:00
orignal
2783337284 require ipv4 for IBGW 2021-04-13 09:16:52 -04:00
orignal
727743979c Merge pull request #1648 from acetoneRu/openssl
SAM section fixed
2021-04-13 07:33:07 -04:00
acetone
4543e14c57 SAM section fixed 2021-04-13 02:43:42 -04:00
orignal
83fc1b0b8e support b32 and b33 addresses in STREAM CONNECT 2021-04-11 17:26:45 -04:00
orignal
df858d9143 publish iexp 2021-04-09 13:29:07 -04:00
orignal
ac47c9c673 don't check U cap 2021-04-09 10:56:46 -04:00
orignal
b9a2d5df02 send HolePunch back based on actual address type 2021-04-08 21:07:14 -04:00
orignal
3e873f88c9 don't drop introducers without iExp 2021-04-07 15:55:38 -04:00
orignal
277cef5ec4 eliminate cost field 2021-04-07 13:05:38 -04:00
orignal
5c9b478e46 published field for SSU addresses 2021-04-05 21:45:48 -04:00
orignal
ff89edf127 pick random introducer 2021-04-05 18:22:48 -04:00
orignal
2cc9791bf2 exclude already expired introducers 2021-04-04 10:36:22 -04:00
orignal
67b32005f6 check if host if unspecified 2021-04-03 22:18:09 -04:00
orignal
0f166973ca check ureachable cap and actual introducers separately 2021-04-03 20:03:19 -04:00
orignal
4f3333c841 don't check range ffor unspecified address 2021-04-03 19:24:07 -04:00
orignal
bea384abea recongnize v4 and v6 SSU addresses without host 2021-04-03 18:56:50 -04:00
orignal
43033695f6 select apropriate address for peer test 2021-04-02 21:31:14 -04:00
orignal
51ef7ef61c don't publish LeaseSet without tunnels 2021-04-01 13:37:21 -04:00
orignal
823b499a02 remove already expired LeaseSets 2021-04-01 11:45:50 -04:00
orignal
bb5ed0b40c assign correct 6 or 4 cap to unpublished address 2021-04-01 11:02:29 -04:00
orignal
94ca2514af set zero expiration timeout if no tunnels 2021-04-01 10:29:03 -04:00
orignal
5412352dec publish ipv6 introducers for ipv6 addresses 2021-03-31 13:42:57 -04:00
orignal
c94e8c7df4 Merge pull request #1646 from acetoneRu/openssl
reg.i2p to subscriptions
2021-03-31 12:28:59 -04:00
acetone
094541caa6 reg.i2p to subscriptions 2021-03-31 12:16:06 -04:00
orignal
8c59977e34 Merge pull request #1645 from acetoneRu/openssl
Configuration file example updated
2021-03-31 12:13:17 -04:00
acetone
881bca6ae3 Depricated "nat" deleted 2021-03-31 12:09:06 -04:00
acetone
22865f8ee4 reseed.yggurl and persist.addressbook added 2021-03-31 12:05:23 -04:00
acetone
f3b728d828 Yggdrasil configuration added
[meshnets] section
2021-03-31 08:45:56 -04:00
orignal
bd7328345f Don't change Yddrasil address if router becomes unreachable through ipv6 2021-03-30 19:27:40 -04:00
orignal
25eae3c116 return relay tag for ipv6 introducer 2021-03-30 11:31:11 -04:00
orignal
5cca5472e6 don't handle unsilicited HolePunch 2021-03-29 15:50:33 -04:00
orignal
8462d382f4 don't create SSU session for HolePunch 2021-03-29 15:16:39 -04:00
orignal
2b0d18a6d7 don't change router status from ipv6 2021-03-29 14:44:50 -04:00
orignal
edf3b7e2fc set X bandiwth for floodfill by default 2021-03-28 13:13:00 -04:00
orignal
167d3a0e3c don't create BN_CTX for ECIES tunnel build record decryption 2021-03-28 12:14:02 -04:00
orignal
86415bc61f publish introducer cap for ipv6 address 2021-03-27 18:49:35 -04:00
orignal
a6ea37a21e set ipv6 address caps depending on peer test 2021-03-27 15:16:56 -04:00
orignal
3695aa924b doesn't send peer test to a reserved address 2021-03-24 10:32:15 -04:00
orignal
9e050d1a23 peer test for ipv6 2021-03-23 15:36:57 -04:00
orignal
34eee2fc26 fixed #1644. check leaseset buffer size 2021-03-22 20:12:58 -04:00
orignal
ac10f3055d pick correct local SSU address for sending peer test 2021-03-19 21:51:45 -04:00
orignal
991b74f036 bind ipv6 or yggdrasil acceptor to specified address 2021-03-19 13:10:24 -04:00
orignal
589049ef0f connect to ipv6 address through introducer 2021-03-19 10:20:02 -04:00
orignal
6b0c7c2313 handle ipv6 address in RelayResponse 2021-03-18 21:29:39 -04:00
orignal
a9c7d0d598 common ExtractIPAddressAndPort 2021-03-18 20:11:24 -04:00
orignal
ef1dfb153c handle ipv6 address for RelayIntro 2021-03-18 18:37:02 -04:00
orignal
ff9ee5873f post LeaseSet creation to I2CP destnation's thread 2021-03-17 15:10:14 -04:00
orignal
a7b56bbbb7 publish Yggdrasil address when enabled 2021-03-17 11:26:52 -04:00
orignal
820a365474 select random peer for first hop for outbound tunnel if number of connections < 100 2021-03-16 18:45:51 -04:00
orignal
1d5d06f731 find actual router for peer 2021-03-16 15:23:00 -04:00
orignal
43d458cf72 publish and upublish NTCP2 and yggdrasil addresses separatly 2021-03-16 13:08:10 -04:00
178 changed files with 13364 additions and 5075 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
/build/build_mingw.cmd eol=crlf

View File

@@ -4,15 +4,16 @@ on: [push, pull_request]
jobs:
build:
runs-on: macos-latest
runs-on: macos-10.15
name: with UPnP
steps:
- uses: actions/checkout@v2
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0.1.2
uses: vmactions/freebsd-vm@v0.1.5
with:
usesh: true
mem: 2048
prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc
run: |
cd build

View File

@@ -8,14 +8,15 @@ defaults:
jobs:
build:
name: Building for ${{ matrix.arch }}
name: Building using ${{ matrix.arch }} toolchain
runs-on: windows-latest
strategy:
fail-fast: true
matrix:
include: [
{ msystem: MINGW64, arch: x86_64 },
{ msystem: MINGW32, arch: i686 }
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
{ msystem: MINGW64, arch: x86_64, arch_short: x64 },
{ msystem: MINGW32, arch: i686, arch_short: x86 }
]
steps:
- uses: actions/checkout@v2
@@ -25,11 +26,50 @@ jobs:
msystem: ${{ matrix.msystem }}
install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
update: true
- name: build application
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no -j3
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: i2pd-${{ matrix.arch_short }}.exe
path: i2pd.exe
build-xp:
name: Building for Windows XP
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW32
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
update: true
- name: Build WinXP-capable CRT packages
run: |
git clone https://github.com/msys2/MINGW-packages
pushd MINGW-packages
pushd mingw-w64-headers-git
sed -i 's/0x601/0x501/' PKGBUILD
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
pacman --noconfirm -U mingw-w64-i686-headers-git-*-any.pkg.tar.zst
popd
pushd mingw-w64-crt-git
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
pacman --noconfirm -U mingw-w64-i686-crt-git-*-any.pkg.tar.zst
popd
pushd mingw-w64-winpthreads-git
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
popd
popd
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: i2pd-xp.exe
path: i2pd.exe

View File

@@ -3,9 +3,9 @@ name: Build on Ubuntu
on: [push, pull_request]
jobs:
build:
name: With USE_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-16.04
build-make:
name: Make with USE_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-18.04
strategy:
fail-fast: true
matrix:
@@ -19,3 +19,70 @@ jobs:
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: make USE_UPNP=${{ matrix.with_upnp }} -j3
build-cmake:
name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-18.04
strategy:
fail-fast: true
matrix:
with_upnp: ['ON', 'OFF']
steps:
- uses: actions/checkout@v2
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential cmake libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: |
cd build
cmake -DWITH_UPNP=${{ matrix.with_upnp }} .
make -j3
build-deb-stretch:
name: Build package for stretch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-stretch" -b -M --distribution stretch "trunk build"
- uses: singingwolfboy/build-dpkg-stretch@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}
build-deb-buster:
name: Build package for buster
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-buster" -b -M --distribution buster "trunk build"
- uses: singingwolfboy/build-dpkg-buster@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}

63
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Build containers
on: [push]
jobs:
docker:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push trunk container
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7
push: true
tags: |
purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:latest
- name: Set env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Build and push release container
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7
push: true
tags: |
purplei2p/i2pd:latest
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
ghcr.io/purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}

6
.gitignore vendored
View File

@@ -7,8 +7,13 @@ netDb
/i2pd
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
/libi2pd.so
/libi2pdclient.so
/libi2pdlang.so
/libi2pd.dll
/libi2pdclient.dll
/libi2pdlang.dll
*.exe
@@ -255,6 +260,7 @@ docs/generated
build/Makefile
# debian stuff
debian/i2pd.1.gz
.pc/
# qt

View File

@@ -1,54 +0,0 @@
language: cpp
cache:
apt: true
os:
- linux
#- osx
dist: xenial
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

154
ChangeLog
View File

@@ -1,6 +1,134 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
## [2.41.0] - 2022-02-20
### Added
- Clock syncronization through SSU
- Drop routers older than 6 months on start
- Localization to German
- Don't send streaming ack too frequently
- Select compatible outbound tunnel for I2CP messages
- Restart webconsole's acceptor in case of exception
### Changed
- Use builtin bitswap for endian on windows
- Send SessionCreated before connection close if clock skew
- Try another floodfill for publishing if no compatible tunnels found
- Reduce memory usage for RouterInfo structures
- Avoid duplicated addresses in RouterInfo. Check presence of netId and version
- Use TCP/IP sockets for I2CP on Android instead local sockets
- Return uptime as integer in I2PControl
- Reseed servers list/cerificates
- Webconsole's dark style colors
### Fixed
- Attempt to use Yggdrasil on start on Android
- Attempts to send peer tests to itself
- Severe packets drop in SSU
- Crash on tunnel tests
- Loading addressbook subscriptions from config
- Multiple I2CP session to the same destination
- Build on Apple Silicon
## [2.40.0] - 2021-11-29
### Added
- Keep alive parameter for client tunnels
- Support openssl 3.0.0
- Localization to Armenian
- Show git commit info in version
- Windows menu item for opening datadir
- Reseed if too few floodfills
- Don't publish old and replacing tunnel in LeaseSet
- Webconsole light/dark theme depending on system settings (via CSS)
### Changed
- Set gzip compression to false by default
- Build tunnel through ECIES routers only
- Removed ElGamal support for tunnels
- Moved webconsole resources to separate file
- Pick tunnels with compatible transport with another tunnel of floodfill
- Use common cleanup timer for all SSU sessions
- Reduced memory usage
- Reseed servers list
- i18n code called from ClientContext
### Fixed
- Tunnels reload
- Some typos in log messages
- Cleanup relay requests table
- Server tunnel is not published
- Build on GNU/Hurd. Disable pthread_setname_np
- Crash when incorrect sigtype used with blinding
## [2.39.0] - 2021-08-23
### Added
- Short tunnel build messages
- Localization. To: Russian, Ukrainian, Turkmen, Uzbek and Afrikaans
- Custom CSS styles for webconsole
- Avoid slow tunnels with more than 250 ms per hop
- Process DELAY_REQUESTED streaming option
- "certsdir" options for certificates location
- Keep own RouterInfo in NetBb
- Pick ECIES routers only for tunnels on non-x64
- NTP sync through ipv6
- Allow ipv6 addresses for UDP server tunnels
### Changed
- Rekey of all routers to ECIES
- Better distribution for random tunnel's peer selection
- Yggdrasil reseed for v0.4, added two more
- Encryption type 0,4 by default for server tunnels
- Handle i2cp.dontPublishLeaseSet param for all destinations
- reg.i2p for subscriptions
- LeaseSet type 3 by default
- Don't allocate payload buffer for every single ECIESx25519 message
- Prefer public ipv6 instead rfc4941
- Optimal padding for one-time ECIESx25519 message
- Don't send datetime block for one-time ECIESx25519 message with one-time key
- Router with expired introducer is still valid
- Don't disable floodfill if still reachable by ipv6
- Set minimal version for floodfill to 0.9.38
- Eliminate extra lookups for sequential fragments on tunnel endpoint
- Consistent path for explicit peers
- Always create new tunnel from exploratory pool
- Don't try to connect to a router not reachable from us
- Mark additional ipv6 addresses/nets as reserved (#1679)
### Fixed
- Zero-hop tunnels
- Crash upon SAM session termination
- Build with boost < 1.55.0
- Address type for NTCP2 acceptors
- Check of ipv4/ipv6 address
- Request router to send to if not in NetDb
- Count outbound traffic for zero-hop tunnels
- URLdecode domain for registration string generator in webconsole
## [2.38.0] - 2021-05-17
### Added
- Publish ipv6 introducers
- Bind ipv6 or yggdrasil NTCP2 acceptor to specified address
- Support .b32.i2p addresses and hostnames for SAM STREAM CREATE
- ipv6 peer tests
- Publish iexp param for introducers
- Show ipv6 network status on the webconsole
- EdDSA signing keys can also be blinded
- Show router version on the webconsole
### Changed
- Rekey of all routers but floodfills to ECIES
- Increased number of precalculated x25519 keys to 15
- Don't publish LeaseSet without inbound tunnels
- Reseed from compatible address(ipv4 or ipv6)
- Recongnize v4 and v6 SSU addresses without host
- Inbound tunnel gateway must be ipv4 compatible
- Don't select next introducers from existing sessions
- Set X bandwidth for floodfill by default
### Fixed
- Incoming ECIES-x25519 session doesn't send updated LeaseSet
- Unique local address for server tunnels
- Race condition for LeaseSet creation in I2CP
- Relay tag for ipv6 introducer
- Already expired introducers
- Find connected router for first peer in tunnel
- Failed outgoing ECIES-x25519 session's tagset stays forever
- Yggdrasil address disappears if router becomes unreachable through ipv6
- Ignore SSU address/introducers if port is not specified
- Check identity and signature length for SSU SessionConfirmed
## [2.37.0] - 2021-03-15
### Added
- Address registration line for reg.i2p and stats.i2p through the web console
@@ -9,12 +137,12 @@
- Symmetric NAT network status error
- Bind server tunnel connection to specified address
- lookuplocal BOB extended command
- address4 and address6 parameters to bind outgoing connections to
- address4 and address6 parameters to bind outgoing connections to
- Rekey of low-bandwidth routers to ECIES
- Popup notification windows when unable to parse config for Windows
### Changed
- Floodfills with "U" cap are not ignored anymore
- Check transports reachability between tunnel peers and between router and floodfill
- Check transports reachability between tunnel peers and between router and floodfill
- NTCP2 and reseed HTTP proxy support authorization now
- Show actual IP addresses for proxy connections
- Publish and handle SSU addreses without host
@@ -36,22 +164,22 @@
- Dump addressbook in hosts.txt format
- Request RouterInfo through exploratory tunnels if direct connection to fllodfill is not possible
- Threads naming
- Check if public x25519 key is valid
- Check if public x25519 key is valid
- ECIES-X25519-AEAD-Ratchet for shared local destination
- LeaseSet creation timeout for I2CP session
- Resend RouterInfo after some interval for longer NTCP2 sessions
- Select reachable router of inbound tunnel gateway
- Reseed if no compatible routers in netdb
- Reseed if no compatible routers in netdb
- Refresh on swipe in Android webconsole
### Changed
- reg.i2p for default addressbook instead inr.i2p
- ECIES-x25519 (crypto type 4) for new routers
- Try to connect to all compatible addresses from peer's RouterInfo
- Replace LeaseSet completely if store type changes
- Replace LeaseSet completely if store type changes
- Try ECIES-X25519-AEAD-Ratchet tag before ElGamal
- Don't detach ECIES-X25519-AEAD-Ratchet session from destination immediately
- Viewport and styles on error in HTTP proxy
- Don't create notification when Windows taskbar restarted
- Don't create notification when Windows taskbar restarted
- Cumulative SSU ACK bitfields
- limit tunnel length to 8 hops
- Limit tunnels quantity to 16
@@ -84,7 +212,7 @@
- Transient signature length, if different from identity
- Terminate I2CP session if destroyed
- RouterInfo publishing confirmation
- Check if ECIES-X25519-AEAD-Ratchet session expired before generating more tags
- Check if ECIES-X25519-AEAD-Ratchet session expired before generating more tags
- Correct block size for delivery type local for ECIES-X25519-AEAD-Ratchet
## [2.34.0] - 2020-10-27
@@ -95,7 +223,7 @@
- Single thread for I2CP
- Shared transient destination between proxies
- Database lookups from ECIES destinations with ratchets response
- Handle WebDAV HTTP methods
- Handle WebDAV HTTP methods
- Don't try to connect or build tunnels if offline
- Validate IP when trying connect to remote peer
- Handle ICMP responses and WinAPI errors for SSU
@@ -112,7 +240,7 @@
- Random crashes on I2CP session disconnect
- Stream through racthets hangs if first SYN was not acked
- Check "Last-Modified" instead "If-Modified-Since" for addressbook reponse
- Trim behind ECIESx25519 tags
- Trim behind ECIESx25519 tags
- Few bugs with Android main activity
- QT visual and layout issues
@@ -123,11 +251,11 @@
- Multiple encryption keys through I2CP
- Pre-calculated x25519 ephemeral keys
- Change datagram routing path if nothing comes back in 10 seconds
- Shared routing path for datagram session
- Shared routing path for datagram session
### Changed
- UDP tunnels send mix of repliable and raw datagrams in bulk
- Encrypt SSU packet again upon resend
- Start new tunnel message if remaining buffer is too small
- Start new tunnel message if remaining buffer is too small
- Use LeaseSet2 for ECIES-X25519-AEAD-Ratchet automatically
- Save new ECIES-X25519-AEAD-Ratchet session with NSR tagset
- Generate random padding lengths for ECIES-X25519-AEAD-Ratchet in bulk
@@ -135,11 +263,11 @@
- Reseed servers list
### Fixed
- Don't connect through terminated SAM destination
- Differentiate UDP server sessions by port
- Differentiate UDP server sessions by port
- ECIES-X25519-AEAD-Ratchet through I2CP
- Don't save invalid address to AddressBook
- ECDSA signatures names in SAM
- AppArmor profile
- AppArmor profile
## [2.32.1] - 2020-06-02
### Added

115
Makefile
View File

@@ -1,22 +1,50 @@
.DEFAULT_GOAL := all
SYS := $(shell $(CXX) -dumpmachine)
SHLIB := libi2pd.so
ifneq (, $(findstring darwin, $(SYS)))
SHARED_SUFFIX = dylib
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
SHARED_SUFFIX = dll
else
SHARED_SUFFIX = so
endif
SHLIB := libi2pd.$(SHARED_SUFFIX)
ARLIB := libi2pd.a
SHLIB_CLIENT := libi2pdclient.so
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
ARLIB_LANG := libi2pdlang.a
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
ARLIB_CLIENT := libi2pdclient.a
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
ARLIB_WRAP := libi2pdwrapper.a
I2PD := i2pd
LIB_SRC_DIR := libi2pd
LIB_CLIENT_SRC_DIR := libi2pd_client
WRAP_SRC_DIR := libi2pd_wrapper
LANG_SRC_DIR := i18n
DAEMON_SRC_DIR := daemon
# import source files lists
include filelist.mk
USE_AESNI := yes
USE_STATIC := no
USE_MESHNET := no
USE_UPNP := no
DEBUG := yes
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
USE_UPNP := $(or $(USE_UPNP),no)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string
USE_GIT_VERSION := $(or $(USE_GIT_VERSION),no)
# for MacOS only, waiting for "1", not "yes"
HOMEBREW := $(or $(HOMEBREW),0)
# Client protocols
USE_I2PC := $(or $(USE_I2PC),yes)
USE_I2CP := $(or $(USE_I2CP),yes)
USE_SAM := $(or $(USE_SAM),yes)
USE_BOB := $(or $(USE_BOB),yes)
ifeq ($(DEBUG),yes)
CXX_DEBUG = -g
@@ -25,6 +53,19 @@ else
LD_DEBUG = -s
endif
ifeq ($(USE_I2PC),yes)
NEEDED_CXXFLAGS += -DWITH_I2PC
endif
ifeq ($(USE_I2CP),yes)
NEEDED_CXXFLAGS += -DWITH_I2CP
endif
ifeq ($(USE_SAM),yes)
NEEDED_CXXFLAGS += -DWITH_SAM
endif
ifeq ($(USE_BOB),yes)
NEEDED_CXXFLAGS += -DWITH_BOB
endif
ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
ifeq ($(HOMEBREW),1)
@@ -39,35 +80,42 @@ 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/Win32App.cpp Win32/Win32NetState.cpp
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
include Makefile.mingw
else # not supported
$(error Not supported platform)
endif
ifeq ($(USE_MESHNET),yes)
NEEDED_CXXFLAGS += -DMESHNET
ifeq ($(USE_GIT_VERSION),yes)
GIT_VERSION := $(shell git describe --tags)
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
endif
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(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/$(LANG_SRC_DIR)
@mkdir -p obj/$(DAEMON_SRC_DIR)
@mkdir -p obj/$(WRAP_SRC_DIR)
@mkdir -p obj/Win32
api: mk_obj_dir $(SHLIB) $(ARLIB)
client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT)
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
api: $(SHLIB) $(ARLIB)
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
lang: $(SHLIB_LANG) $(ARLIB_LANG)
api_client: api client lang
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
## 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.
@@ -76,23 +124,33 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
## -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.
obj/%.o: %.cpp
obj/%.o: %.cpp | mk_obj_dir
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
# '-' is 'ignore if missing' on first run
-include $(DEPS)
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
$(SHLIB): $(LIB_OBJS)
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG)
endif
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
endif
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS)
$(SHLIB_LANG): $(LANG_OBJS)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
$(ARLIB): $(LIB_OBJS)
@@ -101,12 +159,18 @@ $(ARLIB): $(LIB_OBJS)
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
$(AR) -r $@ $^
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
$(AR) -r $@ $^
$(ARLIB_LANG): $(LANG_OBJS)
$(AR) -r $@ $^
clean:
$(RM) -r obj
$(RM) -r docs/generated
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP)
strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
strip $^
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
@@ -130,6 +194,7 @@ doxygen:
.PHONY: api
.PHONY: api_client
.PHONY: client
.PHONY: lang
.PHONY: mk_obj_dir
.PHONY: install
.PHONY: strip

View File

@@ -39,13 +39,14 @@ ifeq ($(USE_AESNI),yes)
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 -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${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
@gzip -kf 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/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
@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

@@ -62,3 +62,16 @@ ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64
NEEDED_CXXFLAGS += -D__AES__ -maes
endif
endif
install: all
install -d ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/usr ${PREFIX}/usr/share ${PREFIX}/usr/share/doc/i2pd ${PREFIX}/usr/share/i2pd ${PREFIX}/usr/share/man ${PREFIX}/usr/share/man/man1 ${PREFIX}/var/lib ${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}/usr/share/i2pd/
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/usr/share/doc/i2pd
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/usr/share/man/man1
@ln -sf ${PREFIX}/usr/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
@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

@@ -3,9 +3,9 @@ USE_WIN32_APP := yes
WINDRES = windres
CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse
CXXFLAGS := $(CXX_DEBUG) -DWIN32_LEAN_AND_MEAN -fPIC -msse
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc
LDFLAGS := ${LD_DEBUG} -static
# detect proper flag for c++11 support by compilers
CXXVER := $(shell $(CXX) -dumpversion)
@@ -61,5 +61,5 @@ ifeq ($(USE_ASLR),yes)
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols
endif
obj/%.o : %.rc
obj/%.o : %.rc | mk_obj_dir
$(WINDRES) -i $< -o $@

View File

@@ -3,6 +3,7 @@
[![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE)
[![Packaging status](https://repology.org/badge/tiny-repos/i2pd.svg)](https://repology.org/project/i2pd/versions)
[![Docker Pulls](https://img.shields.io/docker/pulls/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd)
[![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd)
*note: i2pd for Android can be found in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository and with Qt GUI in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository*
@@ -68,15 +69,15 @@ Build instructions:
**Supported systems:**
* GNU/Linux - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd)
* GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
* 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/)
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
* 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)
* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/)
* Snap
* FreeBSD
* Android
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
* iOS
Using i2pd
@@ -85,6 +86,16 @@ 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).
Localization
------------
You can help us with translation i2pd to your language using Crowdin platform!
Translation project can be found [here](https://crowdin.com/project/i2pd).
New languages can be requested on project's [discussion page](https://crowdin.com/project/i2pd/discussions).
Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd)
Donations
---------
@@ -94,6 +105,7 @@ ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH
License
-------

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -14,6 +14,7 @@
#include "Log.h"
#ifdef _WIN32
#include "Win32Service.h"
#ifdef WIN32_APP
#include <windows.h>
#include "Win32App.h"
@@ -39,6 +40,19 @@ namespace util
if (!Daemon_Singleton::init(argc, argv))
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;
}
return true;
}

View File

@@ -25,7 +25,7 @@ BEGIN
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", CODENAME
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project"
VALUE "LegalCopyright", "Copyright (C) 2013-2022, The PurpleI2P Project"
VALUE "OriginalFilename", "i2pd"
VALUE "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION

View File

@@ -31,6 +31,7 @@
#define ID_RELOAD 2006
#define ID_ACCEPT_TRANSIT 2007
#define ID_DECLINE_TRANSIT 2008
#define ID_DATADIR 2009
#define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1)
@@ -49,7 +50,8 @@ namespace win32
{
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_DATADIR, "Open &datadir");
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())
@@ -131,7 +133,7 @@ namespace win32
transfer >>= 10;
auto mbytes = transfer & 0x03ff;
transfer >>= 10;
auto gbytes = transfer & 0x03ff;
auto gbytes = transfer;
if (gbytes)
s << gbytes << " GB, ";
@@ -142,25 +144,47 @@ namespace win32
s << bytes << " Bytes\n";
}
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
{
switch (status)
{
case eRouterStatusOK: s << "OK"; break;
case eRouterStatusTesting: s << "Test"; break;
case eRouterStatusFirewalled: s << "FW"; break;
case eRouterStatusUnknown: s << "Unk"; break;
case eRouterStatusProxy: s << "Proxy"; break;
case eRouterStatusMesh: s << "Mesh"; break;
case eRouterStatusError:
{
s << "Err";
switch (i2p::context.GetError ())
{
case eRouterErrorClockSkew:
s << " - Clock skew";
break;
case eRouterErrorOffline:
s << " - Offline";
break;
case eRouterErrorSymmetricNAT:
s << " - Symmetric NAT";
break;
default: ;
}
break;
}
default: s << "Unk";
}
}
static void PrintMainWindowText (std::stringstream& s)
{
s << "\n";
s << "Status: ";
switch (i2p::context.GetStatus())
ShowNetworkStatus (s, i2p::context.GetStatus ());
if (i2p::context.SupportsV6 ())
{
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 << " / ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
}
s << "; ";
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
@@ -281,6 +305,12 @@ namespace win32
SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL);
return 0;
}
case ID_DATADIR:
{
std::string datadir(i2p::fs::GetUTF8DataDir());
ShellExecute(NULL, "explore", datadir.c_str(), NULL, NULL, SW_SHOWNORMAL);
return 0;
}
}
break;
}

View File

@@ -32,7 +32,7 @@ void SubscribeToEvents()
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
if (SUCCEEDED(Result)) {
i2p::transport::transports.SetOnline (true);
LogPrint(eLogInfo, "NetState: current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
}
Result = pNetworkListManager->QueryInterface(IID_IConnectionPointContainer, (void **)&pCPContainer);
@@ -79,7 +79,7 @@ void UnSubscribeFromEvents()
}
catch (std::exception& ex)
{
LogPrint (eLogError, "NetState: received exception: ", ex.what ());
LogPrint (eLogError, "NetState: Received exception: ", ex.what ());
}
}

283
Win32/Win32Service.cpp Normal file
View File

@@ -0,0 +1,283 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include "Win32Service.h"
#include <assert.h>
#include <windows.h>
#include "Daemon.h"
#include "Log.h"
I2PService *I2PService::s_service = NULL;
BOOL I2PService::isService()
{
BOOL bIsService = FALSE;
HWINSTA hWinStation = GetProcessWindowStation();
if (hWinStation != NULL)
{
USEROBJECTFLAGS uof = { 0 };
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
{
bIsService = TRUE;
}
}
return bIsService;
}
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);
}
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;
}
}
I2PService::I2PService(PSTR pszServiceName,
BOOL fCanStop,
BOOL fCanShutdown,
BOOL fCanPauseContinue)
{
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;
if (fCanStop)
dwControlsAccepted |= SERVICE_ACCEPT_STOP;
if (fCanShutdown)
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
if (fCanPauseContinue)
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
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
// the stopped signal of the service.
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hStoppedEvent == NULL)
{
throw GetLastError();
}
}
I2PService::~I2PService(void)
{
if (m_hStoppedEvent)
{
CloseHandle(m_hStoppedEvent);
m_hStoppedEvent = NULL;
}
}
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
{
try
{
SetServiceStatus(SERVICE_START_PENDING);
OnStart(dwArgc, pszArgv);
SetServiceStatus(SERVICE_RUNNING);
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Start error: ", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED);
}
}
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
{
LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
Daemon.start();
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
}
void I2PService::WorkerThread()
{
while (!m_fStopping)
{
::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(eLogInfo, "Win32Service: Stop error: ", dwError);
SetServiceStatus(dwOriginalState);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState);
}
}
void I2PService::OnStop()
{
// Log a service stop message to the Application log.
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
Daemon.stop();
m_fStopping = TRUE;
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
{
throw GetLastError();
}
_worker->join();
delete _worker;
}
void I2PService::Pause()
{
try
{
SetServiceStatus(SERVICE_PAUSE_PENDING);
OnPause();
SetServiceStatus(SERVICE_PAUSED);
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
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(eLogError, "Win32Service: Continue error: ", dwError);
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
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(eLogError, "Win32Service: Shutdown error: ", dwError);
}
catch (...)
{
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)) ?
0 : dwCheckPoint++;
::SetServiceStatus(m_statusHandle, &m_status);
}
//*****************************************************************************
void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService)
{
if (schSCManager)
{
CloseServiceHandle(schSCManager);
schSCManager = NULL;
}
if (schService)
{
CloseServiceHandle(schService);
schService = NULL;
}
}

63
Win32/Win32Service.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef WIN_32_SERVICE_H__
#define WIN_32_SERVICE_H__
#include <thread>
#include <windows.h>
#define SERVICE_NAME "i2pdService"
class I2PService
{
public:
I2PService(PSTR pszServiceName,
BOOL fCanStop = TRUE,
BOOL fCanShutdown = TRUE,
BOOL fCanPauseContinue = FALSE);
virtual ~I2PService(void);
static BOOL isService();
static BOOL Run(I2PService &service);
void Stop();
protected:
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
virtual void OnStop();
virtual void OnPause();
virtual void OnContinue();
virtual void OnShutdown();
void SetServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode = NO_ERROR,
DWORD dwWaitHint = 0);
private:
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
void WorkerThread();
void Start(DWORD dwArgc, PSTR *pszArgv);
void Pause();
void Continue();
void Shutdown();
static I2PService* s_service;
PSTR m_name;
SERVICE_STATUS m_status;
SERVICE_STATUS_HANDLE m_statusHandle;
BOOL m_fStopping;
HANDLE m_hStoppedEvent;
std::thread* _worker;
};
#endif // WIN_32_SERVICE_H__

View File

@@ -1,57 +0,0 @@
version: 2.37.0.{build}
pull_requests:
do_not_increment_build_number: true
branches:
only:
- openssl
skip_tags: true
os: Visual Studio 2015
shallow_clone: true
clone_depth: 1
# avoid building 32-bit if 64-bit failed already
matrix:
fast_finish: true
environment:
APPVEYOR_SAVE_CACHE_ON_ERROR: true
MSYS2_PATH_TYPE: inherit
CHERE_INVOKING: enabled_from_arguments
matrix:
- MSYSTEM: MINGW64
- MSYSTEM: MINGW32
cache:
- c:\msys64\var\cache\pacman\pkg\
install:
# install new signing keyring
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
# remove packages which can break build
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc"
# update runtime
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
# Kill bash before next try
- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0
# update packages and install required
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc"
build_script:
- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3"
# prepare archive for uploading
- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt
- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST%
after_build:
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc"
test: off
deploy: off
artifacts:
- path: i2pd-*.zip

3
build/.gitignore vendored
View File

@@ -3,6 +3,7 @@
/i2pd
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
/cmake_install.cmake
/CMakeCache.txt
/CPackConfig.cmake
@@ -11,4 +12,4 @@
/arch.c
# windows build script
i2pd*.zip
build*.log
build*.log

View File

@@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 2.8.12)
# this addresses CMP0059 with CMake > 3.3 for PCH flags
cmake_policy(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.7)
cmake_policy(VERSION 3.7)
project("i2pd")
# for debugging
@@ -18,8 +17,6 @@ option(WITH_LIBRARY "Build library" ON)
option(WITH_BINARY "Build binary" ON)
option(WITH_STATIC "Static build" OFF)
option(WITH_UPNP "Include support for UPnP client" OFF)
option(WITH_PCH "Use precompiled header" OFF)
option(WITH_MESHNET "Build for cjdns test network" OFF)
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
@@ -27,102 +24,59 @@ option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(CMAKE_SOURCE_DIR "..")
#Handle paths nicely
include(GNUInstallDirs)
# architecture
include(TargetArch)
target_architecture(ARCHITECTURE)
set(LIBI2PD_SRC_DIR ../libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
set(LANG_SRC_DIR ../i18n)
set(DAEMON_SRC_DIR ../daemon)
include_directories(${LIBI2PD_SRC_DIR})
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
include_directories(${LANG_SRC_DIR})
include_directories(${DAEMON_SRC_DIR})
set(LIBI2PD_SRC
"${LIBI2PD_SRC_DIR}/api.cpp"
"${LIBI2PD_SRC_DIR}/Base.cpp"
"${LIBI2PD_SRC_DIR}/Blinding.cpp"
"${LIBI2PD_SRC_DIR}/BloomFilter.cpp"
"${LIBI2PD_SRC_DIR}/ChaCha20.cpp"
"${LIBI2PD_SRC_DIR}/Config.cpp"
"${LIBI2PD_SRC_DIR}/CPU.cpp"
"${LIBI2PD_SRC_DIR}/Crypto.cpp"
"${LIBI2PD_SRC_DIR}/CryptoKey.cpp"
"${LIBI2PD_SRC_DIR}/Datagram.cpp"
"${LIBI2PD_SRC_DIR}/Destination.cpp"
"${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp"
"${LIBI2PD_SRC_DIR}/Ed25519.cpp"
"${LIBI2PD_SRC_DIR}/Elligator.cpp"
"${LIBI2PD_SRC_DIR}/Family.cpp"
"${LIBI2PD_SRC_DIR}/FS.cpp"
"${LIBI2PD_SRC_DIR}/Garlic.cpp"
"${LIBI2PD_SRC_DIR}/Gost.cpp"
"${LIBI2PD_SRC_DIR}/Gzip.cpp"
"${LIBI2PD_SRC_DIR}/HTTP.cpp"
"${LIBI2PD_SRC_DIR}/I2NPProtocol.cpp"
"${LIBI2PD_SRC_DIR}/Identity.cpp"
"${LIBI2PD_SRC_DIR}/LeaseSet.cpp"
"${LIBI2PD_SRC_DIR}/Log.cpp"
"${LIBI2PD_SRC_DIR}/NetDb.cpp"
"${LIBI2PD_SRC_DIR}/NetDbRequests.cpp"
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
"${LIBI2PD_SRC_DIR}/Profiling.cpp"
"${LIBI2PD_SRC_DIR}/Reseed.cpp"
"${LIBI2PD_SRC_DIR}/RouterContext.cpp"
"${LIBI2PD_SRC_DIR}/RouterInfo.cpp"
"${LIBI2PD_SRC_DIR}/Signature.cpp"
"${LIBI2PD_SRC_DIR}/SSU.cpp"
"${LIBI2PD_SRC_DIR}/SSUData.cpp"
"${LIBI2PD_SRC_DIR}/SSUSession.cpp"
"${LIBI2PD_SRC_DIR}/Streaming.cpp"
"${LIBI2PD_SRC_DIR}/Timestamp.cpp"
"${LIBI2PD_SRC_DIR}/TransitTunnel.cpp"
"${LIBI2PD_SRC_DIR}/Transports.cpp"
"${LIBI2PD_SRC_DIR}/Tunnel.cpp"
"${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp"
"${LIBI2PD_SRC_DIR}/TunnelGateway.cpp"
"${LIBI2PD_SRC_DIR}/TunnelPool.cpp"
"${LIBI2PD_SRC_DIR}/TunnelConfig.cpp"
"${LIBI2PD_SRC_DIR}/util.cpp"
)
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES PREFIX "")
if(WITH_LIBRARY)
install(TARGETS libi2pd
EXPORT libi2pd
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
# TODO Make libi2pd available to 3rd party projects via CMake as imported target
# FIXME This pulls stdafx
# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
set(CLIENT_SRC
"${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/MatchedDestination.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/I2PTunnel.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/I2PService.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/SAM.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp"
"${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp"
)
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
add_library(libi2pdclient ${CLIENT_SRC})
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
if(WITH_LIBRARY)
install(TARGETS libi2pdclient
EXPORT libi2pdclient
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
endif()
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
add_library(libi2pdlang ${LANG_SRC})
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
if(WITH_LIBRARY)
install(TARGETS libi2pdlang
EXPORT libi2pdlang
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
endif()
@@ -134,14 +88,14 @@ set(DAEMON_SRC
"${DAEMON_SRC_DIR}/UPnP.cpp"
)
if(WITH_MESHNET)
add_definitions(-DMESHNET)
endif()
if(WITH_UPNP)
add_definitions(-DUSE_UPNP)
endif()
if(APPLE)
add_definitions(-DMAC_OSX)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
@@ -243,21 +197,7 @@ else()
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
endif()
if(WITH_PCH)
include_directories(BEFORE ${CMAKE_BINARY_DIR})
add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp")
string(TOUPPER ${CMAKE_BUILD_TYPE} BTU)
get_directory_property(DEFS DEFINITIONS)
string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}")
add_custom_command(TARGET stdafx PRE_BUILD
COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch
)
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
target_link_libraries(libi2pd stdafx)
endif()
target_link_libraries(libi2pdclient libi2pd)
target_link_libraries(libi2pdclient libi2pd libi2pdlang)
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
if(NOT DEFINED Boost_INCLUDE_DIRS)
@@ -269,6 +209,10 @@ if(NOT DEFINED OPENSSL_INCLUDE_DIR)
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
endif()
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
endif()
if(WITH_UPNP)
find_package(MiniUPnPc REQUIRED)
if(NOT MINIUPNPC_FOUND)
@@ -286,15 +230,7 @@ endif()
# load includes
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
# warn if for meshnet
if(WITH_MESHNET)
message(STATUS "Building for testnet")
message(WARNING "This build will NOT work on mainline i2p")
endif()
if(NOT MSYS)
include(CheckAtomic)
endif()
include(CheckAtomic)
# show summary
message(STATUS "---------------------------------------")
@@ -311,15 +247,10 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}")
message(STATUS " BINARY : ${WITH_BINARY}")
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
message(STATUS " UPnP : ${WITH_UPNP}")
message(STATUS " PCH : ${WITH_PCH}")
message(STATUS " MESHNET : ${WITH_MESHNET}")
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
message(STATUS "---------------------------------------")
#Handle paths nicely
include(GNUInstallDirs)
if(WITH_BINARY)
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
@@ -327,10 +258,6 @@ if(WITH_BINARY)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
endif()
if(WITH_PCH)
target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h)
endif()
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now")
endif()
@@ -351,7 +278,7 @@ if(WITH_BINARY)
endif()
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")

View File

@@ -2,26 +2,25 @@
setlocal enableextensions enabledelayedexpansion
title Building i2pd
REM Copyright (c) 2013-2020, The PurpleI2P Project
REM Copyright (c) 2013-2022, The PurpleI2P Project
REM This file is part of Purple i2pd project and licensed under BSD3
REM See full license text in LICENSE file at top of project tree
REM To use that script, you must have installed in your MSYS installation these packages:
REM Base: git make zip
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
REM UCRT64: mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-gcc
REM MINGW32: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
REM setting up variables for MSYS
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)!
set "WD=C:\msys64\usr\bin\"
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)
set MSYS2_PATH_TYPE=inherit
set CHERE_INVOKING=enabled_from_arguments
REM set MSYSTEM=MSYS
set MSYSTEM=MINGW32
set "WD=C:\msys64\usr\bin\"
set "xSH=%WD%bash -lc"
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d contrib/webconsole"
REM detecting number of processors
set /a threads=%NUMBER_OF_PROCESSORS%
@@ -34,38 +33,67 @@ del /S build_*.log >> nul 2>&1
echo Receiving latest commit and cleaning up...
%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1
echo.
REM set to variable current commit hash
FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO (
for /F "usebackq" %%a in (`%xSH% "git describe --tags"`) DO (
set tag=%%a
)
REM set to variable latest released tag
for /F "usebackq" %%b in (`%xSH% "git describe --abbrev=0"`) DO (
set reltag=%%b
)
echo Preparing configuration files and README for packaging...
%xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
REM converting configuration files to DOS format (usable in default notepad)
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" >> build\build.log 2>&1
REM converting configuration files to DOS format (make usable in Windows Notepad)
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
REM Prepare binary signing command if signing key and password provided
if defined SIGNKEY (
if defined SIGNPASS (
echo Signing options found
for %%X in (signtool.exe) do (set xSIGNTOOL=%%~$PATH:X)
if not defined xSIGNTOOL (
if not defined SIGNTOOL (
echo Error: Can't find signtool. Please provide path to binary using SIGNTOOL variable.
exit /b 1
) else (
set "xSIGNTOOL=%SIGNTOOL%"
)
)
set "xSIGNOPTS=sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f ^"%SIGNKEY%^" /p ^"%SIGNPASS%^""
)
)
REM starting building
set MSYSTEM=MINGW32
set bitness=32
call :BUILDING
set MSYSTEM=MINGW64
set MSYSTEM=UCRT64
set bitness=64
call :BUILDING
REM building for WinXP
set "WD=C:\msys64-xp\usr\bin\"
set MSYSTEM=MINGW32
set bitness=32
set "xSH=%WD%bash -lc"
call :BUILDING_XP
REM build for Windows XP
if exist C:\msys64-xp\ ( call :BUILDING_XP )
echo.
REM compile installer
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%tag%.0" build\win_installer.iss >> build\build.log 2>&1
echo Building installer...
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1
REM Sign binary
if defined xSIGNOPTS (
"%xSIGNTOOL%" %xSIGNOPTS% build\setup_i2pd_v%tag%.exe
)
%xSH% "git checkout contrib/*" >> build\build.log 2>&1
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
echo Build complete...
@@ -74,13 +102,42 @@ exit /b 0
:BUILDING
%xSH% "make clean" >> nul
echo Building i2pd %tag% for win%bitness%
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build\build_win%bitness%_%tag%.log 2>&1
echo Building i2pd %tag% for win%bitness%...
REM Build i2pd
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads%" > build\build_win%bitness%_%tag%.log 2>&1
REM Sign binary
if defined xSIGNOPTS (
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
)
REM Copy binary for installer and create distribution archive
%xSH% "cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST%" >> build\build_win%bitness%_%tag%.log 2>&1
REM Clean work directory
%xSH% "make clean" >> build\build_win%bitness%_%tag%.log 2>&1
goto EOF
:BUILDING_XP
%xSH% "make clean" >> nul
echo Building i2pd %tag% for winxp
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1
set MSYSTEM=MINGW32
set bitness=32
set "WD=C:\msys64-xp\usr\bin\"
set "xSH=%WD%bash -lc"
:EOF
%xSH% "make clean" >> nul
echo Building i2pd %tag% for winxp...
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads%" > build\build_winxp_%tag%.log 2>&1
REM Sign binary
if defined xSIGNOPTS (
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
)
REM Copy binary for installer and create distribution archive
%xSH% "cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST%" >> build\build_winxp_%tag%.log 2>&1
REM Clean work directory
%xSH% "make clean" >> build\build_winxp_%tag%.log 2>&1
goto EOF
:EOF

View File

@@ -1,16 +1,30 @@
# Copyright (c) 2017-2022, The PurpleI2P Project
# This file is part of Purple i2pd project and licensed under BSD3
# See full license text in LICENSE file at top of project tree
# Based on the Qt 5 processor detection code, so should be very accurate
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
# https://github.com/qt/qtbase/blob/dev/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7, v8), x86 (32/64), ia64, mips (32/64, mipsel, mips64el) and ppc (32/64)
# Regarding POWER/PowerPC, just as is noted in the Qt source,
# "There are many more known variants/revisions that we do not handle/detect."
set(archdetect_c_code "
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)|| defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
#if defined(__ARM64_ARCH_8__) \\
|| defined(__aarch64__) \\
|| defined(__ARMv8__) \\
|| defined(__ARMv8_A__) \\
|| defined(_M_ARM64) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
#error cmake_ARCH arm64
#if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
|| defined(__ARM_ARCH_7S__) \\
|| defined(_ARM_ARCH_7) \\
|| defined(__CORE_CORTEXA__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
#error cmake_ARCH armv7
#elif defined(__ARM_ARCH_6__) \\
@@ -23,6 +37,7 @@ set(archdetect_c_code "
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
#error cmake_ARCH armv6
#elif defined(__ARM_ARCH_5TEJ__) \\
|| defined(__ARM_ARCH_5TE__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
#error cmake_ARCH armv5
#else
@@ -34,6 +49,18 @@ set(archdetect_c_code "
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
#if defined(__MIPSEL__)
#error cmake_ARCH mips64el
#else
#error cmake_ARCH mips64
#endif
#elif defined(__MIPSEL__)
#error cmake_ARCH mipsel
#else
#error cmake_ARCH mips
#endif
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
@@ -47,7 +74,7 @@ set(archdetect_c_code "
#error cmake_ARCH unknown
")
# Set ppc_support to TRUE before including this file or ppc and ppc64
# Set ppc_support to TRUE before including this file on ppc and ppc64
# will be treated as invalid architectures since they are no longer supported by Apple
function(target_architecture output_var)
@@ -67,12 +94,14 @@ function(target_architecture output_var)
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
elseif("${osx_arch}" STREQUAL "arm64")
set(osx_arch_arm64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
@@ -83,6 +112,10 @@ function(target_architecture output_var)
list(APPEND ARCH ppc)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
@@ -91,8 +124,8 @@ function(target_architecture output_var)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
if(osx_arch_arm64)
list(APPEND ARCH arm64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")

View File

@@ -1,34 +0,0 @@
Howto build & run
==================
**Build**
Assuming you're in the root directory of the anoncoin source code.
$ `cd build/docker`
$ `docker -t meeh/i2pd:latest .`
**Run**
To run either the local build, or if not found - fetched prebuild from hub.docker.io, run the following command.
$ `docker run --name anonnode -v /path/to/i2pd/datadir/on/host:/var/lib/i2pd -p 7070:7070 -p 4444:4444 -p 4447:4447 -p 7656:7656 -p 2827:2827 -p 7654:7654 -p 7650:7650 -d meeh/i2pd`
All the ports ( -p HOSTPORT:DOCKERPORT ) is optional. However the command above enable all features (Webconsole, HTTP Proxy, BOB, SAM, i2cp, etc)
The volume ( -v HOSTDIR:DOCKERDIR ) is also optional, but if you don't use it, your config, routerid and private keys will die along with the container.
**Options**
Options are set via docker environment variables. This can be set at run with -e parameters.
* **ENABLE_IPV6** - Enable IPv6 support. Any value can be used - it triggers as long as it's not empty.
* **LOGLEVEL** - Set the loglevel.
* **ENABLE_AUTH** - Enable auth for the webconsole. Username and password needs to be set manually in i2pd.conf cause security reasons.
**Logging**
Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :)

View File

@@ -1,11 +0,0 @@
FROM ubuntu
RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \
libboost-program-options-dev libboost-date-time-dev \
libssl-dev git build-essential
RUN git clone https://github.com/PurpleI2P/i2pd.git
WORKDIR /i2pd
RUN make
CMD ./i2pd

View File

@@ -1,2 +0,0 @@
i2pd:
build: .

View File

@@ -1,8 +1,5 @@
#define I2Pd_AppName "i2pd"
#define I2Pd_Publisher "PurpleI2P"
; Get application version from compiled binary
; Disabled to use definition from command line
;#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe")
[Setup]
AppName={#I2Pd_AppName}
@@ -27,7 +24,7 @@ ExtraDiskSpaceRequired=15
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
AppVerName={#I2Pd_AppName}
AppCopyright=Copyright (c) 2013-2020, The PurpleI2P Project
AppCopyright=Copyright (c) 2013-2022, The PurpleI2P Project
AppPublisherURL=http://i2pd.website/
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
@@ -47,6 +44,7 @@ Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyif
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
Source: ..\contrib\webconsole\*; DestDir: {userappdata}\i2pd\webconsole; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
[Icons]
Name: {group}\I2Pd; Filename: {app}\i2pd.exe

View File

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

View File

@@ -1,74 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := i2pd
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
LOCAL_STATIC_LIBRARIES := \
boost_system \
boost_date_time \
boost_filesystem \
boost_program_options \
crypto ssl \
miniupnpc
LOCAL_LDLIBS := -lz
LOCAL_SRC_FILES := $(IFADDRS_PATH)/ifaddrs.c \
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
$(DAEMON_SRC_PATH)/UnixDaemon.cpp \
$(DAEMON_SRC_PATH)/Daemon.cpp \
$(DAEMON_SRC_PATH)/UPnP.cpp \
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
$(DAEMON_SRC_PATH)/I2PControl.cpp \
$(DAEMON_SRC_PATH)/i2pd.cpp
include $(BUILD_EXECUTABLE)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
LOCAL_STATIC_LIBRARIES := crypto
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
include $(PREBUILT_STATIC_LIBRARY)

View File

@@ -1,40 +0,0 @@
APP_ABI := all
#APP_ABI += x86
#APP_ABI += x86_64
#APP_ABI += armeabi-v7a
#APP_ABI += arm64-v8a
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
APP_PLATFORM := android-14
NDK_TOOLCHAIN_VERSION := clang
APP_STL := c++_static
# Enable c++17 extensions in source code
APP_CPPFLAGS += -std=c++17 -fvisibility=default -fPIE
APP_CPPFLAGS += -DANDROID_BINARY -DANDROID -D__ANDROID__ -DUSE_UPNP
APP_LDFLAGS += -rdynamic -fPIE -pie
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_CPPFLAGS += -DANDROID_ARM7A
endif
# Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead.
#APP_OPTIM := debug
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own
I2PD_LIBS_PATH = /path/to/libraries
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
# don't change me
I2PD_SRC_PATH = $(PWD)/../..
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon

View File

@@ -1,2 +0,0 @@
archive
i2pd_*_android_binary.zip

View File

@@ -1,48 +0,0 @@
#!/bin/bash
# Copyright (c) 2013-2020, The PurpleI2P Project
#
# This file is part of Purple i2pd project and licensed under BSD3
#
# See full license text in LICENSE file at top of project tree
GITDESC=$(git describe --tags)
declare -A ABILIST=(
["armeabi-v7a"]="armv7l"
["arm64-v8a"]="aarch64"
["x86"]="x86"
["x86_64"]="x86_64"
)
# Remove old files and archives
if [ -d archive ]; then
rm -r archive
fi
if [ -f ../i2pd_*_android_binary.zip ]; then
rm i2pd_*_android_binary.zip
fi
# Prepare files for package
mkdir archive
for ABI in "${!ABILIST[@]}"; do
if [ -f ../android_binary_only/libs/${ABI}/i2pd ]; then
cp ../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
fi
done
cp i2pd archive/i2pd
cp -rH ../android/assets/certificates archive/
cp -rH ../android/assets/tunnels.conf.d archive/
cp -H ../android/assets/i2pd.conf archive/
cp -H ../android/assets/tunnels.conf archive/
# Compress files
cd archive
zip -r6 ../i2pd_${GITDESC}_android_binary.zip .
# Remove temporary folder
cd ..
rm -r archive

View File

@@ -1,33 +0,0 @@
#!/bin/sh
# Copyright (c) 2013-2020, The PurpleI2P Project
#
# This file is part of Purple i2pd project and licensed under BSD3
#
# See full license text in LICENSE file at top of project tree
#
# That script written for use with Termux.
# https://stackoverflow.com/a/246128
SOURCE="${0}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
arch=$(uname -m)
screenfind=$(which screen)
if [ -z $screenfind ]; then
echo "Can't find 'screen' installed. That script needs it!";
exit 1;
fi
if [ -z i2pd-$arch ]; then
echo "Can't find i2pd binary for your archtecture.";
exit 1;
fi
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR

View File

@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICKDCCAc6gAwIBAgIUcPHZXtYSqGNRCD6z8gp79WUFtI0wCgYIKoZIzj0EAwIw
gZMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGlu
MRgwFgYDVQQKDA9TdG9ybXlDbG91ZCBJbmMxIzAhBgNVBAMMGnN0b3JteWNsb3Vk
LmZhbWlseS5pMnAubmV0MSQwIgYJKoZIhvcNAQkBFhVhZG1pbkBzdG9ybXljbG91
ZC5vcmcwHhcNMjIwMzE5MTU1MjU2WhcNMzIwMzE2MTU1MjU2WjCBkzELMAkGA1UE
BhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xGDAWBgNVBAoM
D1N0b3JteUNsb3VkIEluYzEjMCEGA1UEAwwac3Rvcm15Y2xvdWQuZmFtaWx5Lmky
cC5uZXQxJDAiBgkqhkiG9w0BCQEWFWFkbWluQHN0b3JteWNsb3VkLm9yZzBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABFUli0hvJEmowNjJVjbKEIWBJhqe973S4VdL
cJuA5yY3dC4Y998abWEox7/Y1BhnBbpJuiodA341bXKkLMXQy/kwCgYIKoZIzj0E
AwIDSAAwRQIgD12F/TfY3iV1/WDF7BSKgbD5g2MfELUIy1dtUlJQuJUCIQD69mZw
V1Z9j2x0ZsuirS3i6AMfVyTDj0RFS3U1jeHzIQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFyzCCA7OgAwIBAgIRALWNWsnQ0Vmn/99iCNT7cdQwDQYJKoZIhvcNAQELBQAw
cTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGjAYBgNVBAMM
EWVjaGVsb24zQG1haWwuaTJwMB4XDTIxMTEyOTE5MzU1OVoXDTMxMTEyOTE5MzU1
OVowcTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwG
A1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGjAYBgNV
BAMMEWVjaGVsb24zQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEA3pccNiQWJUS1t3QHK7rBCNKAsM2dz4szN3+3SrDy1w+rOrK8Vt5aypPU
QYUQwG+odjEPacuoRtO/W14KJl5yAI3eQS+X/cYDXmxvfm4zx5JRumYptXwJD57G
rlPHnFvk8R+Hvh+/UyqgSAZ9ZaKjEzYK4AtbYEXtopaM4U2VYN8xKjvKyWlhPdxo
kI3//qcTlSqGHHeHrkItLG1LubM1EnPu+9zI2WN2zBBRcm8ZtWqHoqFJ1zgJr/49
nMK8Lnb3I54ctva8x5+gsSk4dbG/mMsOIZekFqYJJs3+u9w5fmOYI7v9GlQr7UhE
G3MwjJ5Cj1LmLVlz/4LApZrDSd2JvwIUdGL3UW8+blaTeCPKIRvmsTeRxo1gORMF
ZH0dg39722lK7ScwOlOUX9ggzRUlYCmvnjQJZGJEUoP68QxjlQfkXZyffmMfvm6K
V6mcZ5aHMGO1lYAl40kWNJ0jGpmxJqTDhNFDEKr0TlRGVxXGWzObEOrcJ8ysRMc1
x6oXQhh79HXZcKwhZaXLx23ZvVoTfhRm4JH0SSP6XqQm35j4NI1SllEsDns29wU3
Re4wOWJCCYlPG3CtY32CinwQRoVgtiJk18W8+Pxw7sBFq8sL5L0Z+5bB6nTkBfV6
7OrZGWL0i344zQE0e3yIsLih+5Wyqw6RSSMysenl3alnUB9EvE0CAwEAAaNeMFww
DgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAP
BgNVHRMBAf8EBTADAQH/MBoGA1UdDgQTBBFlY2hlbG9uM0BtYWlsLmkycDANBgkq
hkiG9w0BAQsFAAOCAgEAaUMnMYtNFBl9dFON6e4EjYo53Wknj61uIVO11dvLqjnh
7X6guPML+GgNZsPQGLu7Bqw4hVgy/cV5AlFc7SXOhzpaYo1ycpjg3Ws1VK2wrk7+
4bvUThNcS1KZVFDdRE62549rYNfYNfPxXvccOTW9meTCC1kLHerh65ySDr9J02O6
o5Mf685PgBasBH6dlosOLTtee2gRLNFcAluQYKerawS1gDys5239UNHPCqTgO+Od
FiKfl48OIOzPGLKEf4lXC+lkwZElewShrHhzd8aGueedTi0UHOtQuY7ocsofqXc8
OnyT/y2X6wn/YkzviKgfxYDSI7FJiUgXCPcT0jUNmuwR168yL5BfzoQmrCvlOOQg
P7ibdBJ6UkL8pRpv/SYpvaX/kf4agYtwh5IL9FzNCwNu54ZC6JilLUhYAU38Eolq
OZ/cGiMoSFQIeBPvB3cdsqEud9W4P+MqN5A76fMzdVV77lGsIS1eCGMceR3CjOiF
6SdAskcBZWhFiRNQweC0iv57/nPCeTCuNAqbZSHd7zC1AKhNmmsKSJUJQCGijcce
P8Gl0AFfZneN2bVEFvJ/zd71pD8ll1Gkju16bfdWn0V4NRaxFiXNr2bL+ah9blud
EXOomE3R6ow1QZk+Gnpy3wh9jfwlrJuFoANvHnv4WREbdjwr//71XjBri5p1wPE=
-----END CERTIFICATE-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIESg3kkzANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQZWNoZWxvbkBtYWls
LmkycDAeFw0xNDA3MzExNjQ3MDJaFw0yNDA3MzAxNjQ3MDJaMHAxCzAJBgNVBAYT
AlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9u
eW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQDDBBlY2hlbG9uQG1h
aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmcEgLwwhzLNe
XLOMSrhwB8hWpOhfjo4s6S/wjBtjjUc8nI3D0hSn3HY26p0rvcvNEWexPUpPULmC
exGkU463nu7PiFONiORI1eJAiUFHibRiaA7Wboyo38pO73KirwjG07Y+Ua0jp+HS
+4FQ/I/9H/bPplReTOU/6hmRbgQ69U8nE68HzZHQxP68yVJ2rPHSXMPhF4R1h0G1
1mCAT+TgTsnwHNGF77XHJnY4/M4e2cgycEZjZow36C3t2mNDVkMgF19QQeb9WmLR
zREn3nq9BJqHpUkn9yWw0kKXTZSds+7UxESfzf3BzK0+hky2fh5H+qbYAo2lz4yj
81MXTAu+4RRkg4DBLlF+2dkclhwQLxxzvkRC6tPkn5i33Yltg7EfzA9IoQ05potJ
I+iOcF+aStfFgFj9u3B5UkcF4P0cH1QD3c6BK4hIezQYqRoPly1gHqg+XdwjG/dr
4as7HA9FTz3p2E8nClpIC1x3hfgwAdfd29aeBxO1WW/z99iMF7TBAF+u5T86XEW1
WpknqCbTli36yJ8a5fPWxZHrryBRJT5yLxejjFeadtutBSwljiVFq+Y38VqwFivq
VLiBt7IxAsZ8iilgfnnnAvBH6chWfSKb4H7kB4TJvDiV96QmmvoEaWYNHZozMhyK
tO3b5w+xqbJXyCLA3Q75jD0km76hjcECAwEAAaMhMB8wHQYDVR0OBBYEFAHQcAam
QRS/EUhuCSr9pB4Ux0rYMA0GCSqGSIb3DQEBDQUAA4ICAQBq1+1QLmgLAjrTg3tb
4XKgAVICQRoBDNUEobQg3pYeUX9eFNya2RxNljuvYpwT80ilGMPOXcjddmr5ngiK
dbGRcuuJk9MPEHtPaPT3+JJlvKQ3B3g2wva2Wz2OAyLZUGQs389K4nTbwh4QF0n2
aHFL8BHiD62hiKnCoNaW4ZovUNNvOxo9lMyAiaFU2gqQNcdad8hP9EAllbvbxDx9
Tjww2UbwQUIHS9rna4Tlu+f0hDXTWIutc2A51W2fJCb7L3+lYO7Wv55ND/WtryLZ
XpMp27+MpuEnN3kQmz/l9R0hIJsWc/x9GQkjm5wEaIZEyTtenqwRKGmVCtAj0Pgv
jn1L3/lWmrNq+OZHb/QeyfKtA3nXfQKVmT98ewQiK/S5i1xIAXCJPytOD887b/o1
cdurTmCiZMwgiQ+HLJqCg3MDa5mvKqRkRdZXfE6aQWEcSbpAhpV15R17q7L+Fg0W
shLSNucxyGNU8PjiC/nOmqfqUiPiMltJjPmscxBLim8foyxjakC4+6N6m+Jzgznj
PocBehFAfKYj66XEwzIBN7Z2uuXoYH9YptkocFjTzvchcryVulDWZ4FWxreUMhpM
4oyjjhSB4tB9clXlwMqg577q3D6Ms0zLTqsztyPN3zr6jGev3jpVq7Q1GOlciHPv
JNJOWTH/Vas1W6XlwGcOOAARTQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFgTCCA2mgAwIBAgIETWAY1DANBgkqhkiG9w0BAQ0FADBxMQswCQYDVQQGEwJY
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEaMBgGA1UEAwwRaGlkdXNlcjBAbWFp
bC5pMnAwHhcNMjExMjEzMTU0MDI3WhcNMzExMjExMTU0MDI3WjBxMQswCQYDVQQG
EwJYWDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5v
bnltb3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEaMBgGA1UEAwwRaGlkdXNlcjBA
bWFpbC5pMnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXnjJ8UQ0f
lHHpfPMiHofBPSuL4sbOJY6fOXwPhSg/h6THh9DS/ZWmJXQ3qRD0glDVtv4/Dr/9
ldGQ5eltF9iCFXCQlMEy2HjQrBKq0nsl7RpYK12cyMaod0kkzCUk9ITLi9CmHM3Z
gQZcmG8TWjFEpDR+idx/QkQt2pcO4vzWlDit3Vh4ivnbX5jGQHbsVjQEMQWxr+pX
dsS+YQpjZ6RBmrooGTPO8QDOOeYLAn0lCjmffc/kzIH9E/p4/O0rOpyhVYbdxUD1
5wkqN9l4yrtxmORG/PudnRQQ0r4TUq8vsxfGY0Euo9IbhgXF2Parel1ZhDxB1WZV
VwWtgLIh9jGA1UMa8SYKnEfp8LWNZ3b3mUUnZb3kMrLk6jGYRWNsHmamhd4mC7AZ
qf/8lOkEIw3bPd3YguCDRVcLui5BwIEZmqXg8uoESxfO/sW3pBrN/8M7MkTex9kN
vjitGDDXvenK27qmNgZxbBlX72yTSfys7XTYTLnxZC8AwdAo2Wz9Z6HhGiPonf2h
vZkc9ZxuE0jFIrsbJra4X7iyjXgi4vV4ARNg/9Ft6F4/OIbECgeDcBQqq4TlT2bZ
EfWVrBbqXoj5vNsLigIkd+AyUNwPYEcB5IFSiiOh98pC7BH3pg0m8U5YBjxe1i+9
EQOOG0Qtx+JigXZHu6bGE0Twy9zy+UzoKQIDAQABoyEwHzAdBgNVHQ4EFgQUGK1b
0DkL6aLalcfBc/Uj/SF08C0wDQYJKoZIhvcNAQENBQADggIBAMpXM82bJDpH1TlH
TvhU3Z7nfZdvEhOQfujaFUYiuNripuEKcFGn948+DvAG0FUN+uNlJoqOVs8D7InD
gWlA9zpqw5Cl5Hij/Wns9QbXuAHJeA23fVUoaM2A6v9ifcIQ1A+rDuRQAo6/64KW
ChTg2e99RBpfGOyqgeh7tLLe0lPPekVpKHFuXabokaKRDuBcVHcUL4tWXe3dcyqa
Ej/PJrrS+nWL0EGZ4q80CEd2LPuDzPxNGCJt/R7ZfadENWajcgcXGceh1QBzozrB
SL/Ya6wF9SrsB7V/r5wX0LM4ZdDaLWbtmUe5Op0h/ZMH25Sa8xAXVz+O9L6sWSoO
FaiYTOvAiyyPz+nsxKa3xYryDHno7eKSt+hGOcaurhxbdZaEFY/CegEc73tCt9xK
e9qF8O/WkDLmixuErw3f5en4IfzGR7p3lJAwW/8WD8C6HS39h/eE7dVZNaWgtQnZ
SgGjgZMTJqTcQ3aZmfuCZefxGFok8w6AIkdbnd1pdMBRjYu8aXgl2hQSB9ZADDE9
R5d3rXi0PkSFLIvsNjVa5KXrZk/tB0Hpfmepq7CufBqjP/LG9TieRoXzLYUKFF74
QRwjP+y7AJ+VDUTpY1NV1P+k+2raubU2bOnLF3zL5DtyoyieGPhyeMMvp0fRIxdg
bSl5VHgPXHNM8mcnndMAuzvl7jEK
-----END CERTIFICATE-----

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIFzTCCA7WgAwIBAgIQeUqFi0fHNQopg6BZlBLhVzANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEbMBkGA1UEAwwS
aTJwLXJlc2VlZEBtazE2LmRlMB4XDTIyMDIwNTE3MzkzM1oXDTMyMDIwNTE3Mzkz
M1owcjELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwG
A1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGzAZBgNV
BAMMEmkycC1yZXNlZWRAbWsxNi5kZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
AgoCggIBAMYxs2D2xpN/8blGawvAlU9DemHIxApOEwaLNfh8aAvqEdB41NTqcx4U
H8VchSormCfkCvezuMHO+K2HX7ihEZ1v6tbr6aX6hY9UZUyDDYsKmJoB1oKEhddv
5UYfcWPE2eSykdFsWgTQD6Z+cRQWHEoCzb7qc+Jrw6KcnHMD0VrmBrEQPzTBxMHW
4HC97PVkSLJTDArnS6ZiX4IbWRPw/mbpJT6EoVZo8J/it0pdn/X4KodEXDcnEMSe
VRulfZH/nSmOOvKhoHPckmgz/u66BlnuSYXEIB0KfDIcAlSYiPDxGnAemTozJYXA
UVMeFMs+YE5wiPgzzu+vpC31xtZLq0gyaCfgEi1P9j2ES/8pH3Gw6W2OH4kBx+jO
TBsfI+ph6qFZ3WWT23MRVyl3ATuI/GHdczTxD9JaOn74lLI+Hnu8wXnyztVWkTMB
4sAnzjdeHkvNDyQ10vSaN0HnGfg6zuAuUSqFQujFF8Vg8ZCcsh8GouWfzYDvi9mj
9pfxx8v6UCC719I4J9CgFjWnn2Hqez3fO8fFulY61VPyCCZp4gKWbI2SIQP/n5gz
ecYJRrJoem+rYfEQ/fwxROsvm3fCO4D6dt7ILRuX286GDIw2qSvP1zZVAioMwSj3
9CAjKLwD/BhTRiMOlpaVv6IWqjtevbiaIKvbHTnoxvkGsDqe3gJhAgMBAAGjXzBd
MA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
DwYDVR0TAQH/BAUwAwEB/zAbBgNVHQ4EFAQSaTJwLXJlc2VlZEBtazE2LmRlMA0G
CSqGSIb3DQEBCwUAA4ICAQAb+x6XpJdjpVYw2bvWIUbatQJwq0YaEW5W61xGLgIG
a37oll3YZbSY9Vk+N1cE0f61L3ya4Ioz6zlH/MO2zUG/dEk8vqdgIPUYJvyF7wwF
w3/G4VMaDKOJx4bAZNmaiRFGYNhCOhCnZx6uZGrLNIJ2Dc+mflrGmGwYphtXVV3e
Iv+ki3gSRgfXuMfKi4B5bLPnz7XDe4TSmwZZSRac4ly4KqmZUyntqbilRxaGTej3
VYJ1tac8yppyk5N3VopMQNmBarNZG16wSOTD7CtKgn382jgRW8cR7BMeqhORivp0
ZnPJFhzh4uthdlPdXXo6lxfvZjfiwlDPytvEu2QBz3urTgopGqRLcTBnLucWg9li
OSy9z7hNEnIN3iIJJAwI1wBdDa7K0h3PFBbIUa7X2ybn81VeNSfO25Lo8YTZEKsc
wcThJrNV6qOQv8rM/7aXugi6+VzPlCR+18iKRbebCnlqGR2dT1zFtj3negtOkrjo
LH4H6VUr3q2Ie56IubS2hUKiUkDm0ckP3Vum35GGntyEAzl6uyog0hJFOJb3aq30
YQLzyVEOz8NnA+32oMRzJJdDxQ7pqG5fgq7EF4d++YSgEfdVXxvfgXQ6m3jAyC7Z
p/gX4rlxNsjeGU3Ds51wkmhH4IB1aSQr52PE6RaBhhh3SmADEv6S/3eGvE4F4MN5
2Q==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIEbNbRPjANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEZMBcGA1UEAwwQb3JpZ25hbEBtYWls
LmkycDAeFw0yMTA3MDYyMjExMDFaFw0zMTA3MDQyMjExMDFaMHAxCzAJBgNVBAYT
AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u
eW1vdXMgTmV0d29yazEMMAoGA1UECwwDSTJQMRkwFwYDVQQDDBBvcmlnbmFsQG1h
aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvNJz2KGuAkHP
tGFobfLvpybtxB50fkcEsTc9opmiy7wBKK9rSI01VS616IhABkWKZVfK2A9NqpGv
v/CyhTKoaeSNeXY7+zORUWgWK/zA9fA4GRZFqlW8j4tbompDwcLYNqRBCsn1C0OY
YA5JhXPBixMcnXl8N8x4sXhQ4l9R3+QrydhUHRvgDc8dOxRyIX7zuQAyf8tmA2Xo
xZLdvDcCJdLBIbFwxhIceIhgcOwaOx7oRkZDZdYcLJd3zjyPbu8JtOM2ZkwH7r+0
ro5PktuDp2LAS6SII5yYNcwcrvPZGPqhLdifIw1BrdTIb/rIkQZ5iXOOdyPmT7e8
IwAJcPFlfvrS4Vbi9oDqyx3aDUBoubgmFnO1TirL56ck83R/ubcKtdnyzAn5dp+f
ZNYW6/foSBpDDOCViylbFAR5H0HJEbBns7PZx6mGEEI4tUAJdNYl7Ly7Df60a9Rz
cD/gz08U9UwFXYKoT6roEjToADGAzb5MI4cVlAb2AmQaMNXNe04HcDL1bU50mkNU
amqPv8nxf72fBQCEmZz2G57T6QiYTtcCwiWS1QdWsuaOtCo9zO0MKcjzSdUxuxEc
dXhjQdNegsgg/Xk7bJ8lKOsACqMpFftdPmuyeZU2t+3RPuBpV/0j2qUfg/y6kb0z
CxAOYmlcL4kqw4VT+5V/EeZLIG0h9I0CAwEAAaMhMB8wHQYDVR0OBBYEFD/wJObg
CCDuhMJCVWTSTj+B3rsUMA0GCSqGSIb3DQEBDQUAA4ICAQC0PjsTSPWlGbLNeeI8
F0B5xAwXYJzZ7/LRxh8u42HDUqVIDjqkuls1l3v9D7htty2Gr3Ws2dcvcOr2KcOy
mEWg+jdP/N3vt9IkZeVS4YQoPgq6orn7lVkk00bcKb24f7ZnoQnnVV0/m42Y5P4j
LLh+8MBxsez9azXyZbDVEkgsMUAkdVO6KNz6scqz7wb8egV2GAMAp7cwChC6lanK
gv9ZyJhG/HdTv6VyuMZhJy6rX4geM97tm1iHu1VLsQcIzBKAdEvWJv8ofMeiyINe
hqAP9NYaeowKi975NOrmf+XZwxd0niApIohV684RCVUfL8H7HSPbdXhBJ/WslyDP
cTGhA2BLqEXZBn/nLQknlnl0SZTQxG2n4fEgD1E5YS/aoBrig/uXtWm2Zdf8U3mM
+bNXhbi9s7LneN2ye8LlNJBSRklNn/bNo8OmzLII1RQwf1+vaHT96lASbTVepMZ/
Y9VcC8fAmho/zfQEKueLEB03K+gr2dGD+1crmMtUBjWJ9vPjtooZArtkDbh+kVYA
cx4N4NXULRwxVWZe5wTQOqcZ3qSS1ClMwaziwychGaj8xRAirHMZnlPOZO1UK4+5
8F4RMJktyZjNgSLP76XPS4rJK5fobuPqFeA4OpDFn/5+/XeQFF6i6wntx1tzztzH
zc+BrVZOdcYPqu9iLXyRQ9JwwA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFxzCCA6+gAwIBAgIQfKAV7rmoWA8jWpLfMtDQqzANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQ
cmFtYmxlckBtYWlsLmkycDAeFw0yMTExMDYwNzEwMzJaFw0zMTExMDYwNzEwMzJa
MHAxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNV
BAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQD
DBByYW1ibGVyQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAz4vQlIdjY56uqkFKWld9Oy3E8+06Ag9fUzBVleS2bdJfaFtmEa8xz6Pep7Bb
zJK0Q9t2CW7/xqIWuspWlYn5EYAS7BFiNOX70KX4PMpltj3C4Dpxpjll9LdydU2k
FquCflXNJESnBDdd0qDRMboMf4c9lTz0mTLwAtzInLwHGDrbxEiQ/YqPgPJreOXQ
anhjkpxJcgpLR+9od8EdLNKbShVWEeSBnYp0FcjnZKOb9KC2gjqP0sWdzlw3i1hh
CB38A7a03Q4yUcmxCw4ktM60d/2jCZ+G7KHwcbkfxDjl85r0UgEzgfF7LuIuxxmA
MNLH1eAACnLTl42O72EHdtD9VWWwZF2NuFgAzT3MEFnMKDk+OqZOeZQOEgkIfrNP
O5XYMYxHSWCf/dmSq36ZJwhC40k2S9ArS8BQNY8NvwZG5CSGDU52FKaHzFn6EwLE
4CpsrptUX2itXLaFUiNMw6I+eSgTO7x+gpahZVqpdRSQXmpE0xA5jP/DwPyt3ZVe
/4q4kn3imcSCxBP5NQHWfVszsruRkh9np4R0xVlT8UCwJmY8Yg8zwJG5UddTAck5
JavDsaXgWMwcZ/qQboZKlH/iAdQnbkte8Yd5GL5nmTeS+vwuluwmA/y9kUzSUhk+
86kA0eRJ1+e2HdA1/UOTRmyIoIeQ5/fhELMXzhksLcpMGTUCAwEAAaNdMFswDgYD
VR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNV
HRMBAf8EBTADAQH/MBkGA1UdDgQSBBByYW1ibGVyQG1haWwuaTJwMA0GCSqGSIb3
DQEBCwUAA4ICAQAxRdSTZGEblnNeVuRoEQq/a/6q4egFaOkzXCPKEnDzB5yvm83g
35ImquGFZkgaoc5qUAHVeBwOQrWgUI4xHPofnbM2VsgEUMz6h3ovobPNkN3+lRT5
30krd0y+A/Q895EHDu0lyf3BHMmtCWiKWQBttuc0dnmoLCRsQxgy+kYJCS/81jCM
4KNnyrtc6a/czqSq758CncjP2nErVucendsguQoA5JUw53YJ4FYHG/f9tYEkhm9C
D6u7L3vTUcMRUrRxSiJyNixH36nEwpM6DNHiPNc+CFKZ/Zx449R1GjcpDhTrXnWP
2H1r3cyKEM8a76VUEs2GQCaaglOR4N1goyqgYEjScf+/4VmARL3VUzfP8Oub70rM
t1fip5QD/4VDQuA/9C9g5Rr2nJ3K2jVnpSSKnBYFYf5z9RZdTOVXjXaEi72lWxpk
mjgK6c5EFOJxYoCaTbKX9Kz9ZIWVOVMrgHWwA/wDW+Qk5zgP9Ysau65xIp9P1RdB
qHgR5BcIrNky9RD8cIzxzMPCSMVgnf0eLFuHmG8uUl/xHHVRprf0pd7DYkQ44HWN
Z/g/gg3DaJdH7vvkShzgjt4iZrmOCHQIKkSGFRYZf0/Mpn6mgK9+grtO9osVgAQr
LBO+5LIxV/S5bcrzWQLOiMABTd2X/0PTOjuXpfinZ3rDSUiNFPq5kLLSlA==
-----END CERTIFICATE-----

View File

@@ -1,31 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFVDCCAzwCCQC2r1XWYtqtAzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJY
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRMwEQYDVQQKDApQdXJwbGUgSTJQ
MQ0wCwYDVQQLDARJMlBEMR8wHQYJKoZIhvcNAQkBFhBvcmlnbmFsQG1haWwuaTJw
MB4XDTE1MDIyMjEzNTgxOFoXDTI1MDIxOTEzNTgxOFowbDELMAkGA1UEBhMCWFgx
CzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEGA1UECgwKUHVycGxlIEkyUDEN
MAsGA1UECwwESTJQRDEfMB0GCSqGSIb3DQEJARYQb3JpZ25hbEBtYWlsLmkycDCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALp3D/gdvFjrMm+IE8tHZCWE
hQ6Pp0CCgCGDBC3WQFLqR98bqVPl4UwRG/MKY/LY7Woai06JNmGcpfw0LMoNnHxT
bvKtDRe/8kQdhdLHhgIkWKSbMvTAl7uUdV6FzsPgDR0x7scoFVWEhkF0wfmzGF2V
yr/WCBQejFPu69z03m5tRQ8Xjp2txWV45RawUmFu50bgbZvLCSLfTkIvxmfJzgPN
pJ3sPa/g7TBZl2uEiAu4uaEKvTuuzStOWCGgFaHYFVlTfFXTvmhFMqHfaidtzrlu
H35WGrmIWTDl6uGPC5QkSppvkj73rDj5aEyPzWMz5DN3YeECoVSchN+OJJCM6m7+
rLFYXghVEp2h+T9O1GBRfcHlQ2E3CrWWvxhmK8dfteJmd501dyNX2paeuIg/aPFO
54/8m2r11uyF29hgY8VWLdXtqvwhKuK36PCzofEwDp9QQX8GRsEV4pZTrn4bDhGo
kb9BF7TZTqtL3uyiRmIyBXrNNiYlA1Xm4fyKRtxl0mrPaUXdgdnCt3KxOAJ8WM2B
7L/kk9U8C/nexHbMxIZfTap49XcUg5dxSO9kOBosIOcCUms8sAzBPDV2tWAByhYF
jI/Tutbd3F0+fvcmTcIFOlGbOxKgO2SfwXjv/44g/3LMK6IAMFB9UOc8KhnnJP0f
uAHvMXn1ahRs4pM1VizLAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAIOxdaXT+wfu
nv/+1hy5T4TlRMNNsuj79ROcy6Mp+JwMG50HjTc0qTlXh8C7nHybDJn4v7DA+Nyn
RxT0J5I+Gqn+Na9TaC9mLeX/lwe8/KomyhBWxjrsyWj1V6v/cLO924S2rtcfzMDm
l3SFh9YHM1KF/R9N1XYBwtMzr3bupWDnE1yycYp1F4sMLr5SMzMQ0svQpQEM2/y5
kly8+eUzryhm+ag9x1686uEG5gxhQ1eHQoZEaClHUOsV+28+d5If7cqcYx9Hf5Tt
CiVjJQzdxBF+6GeiJtKxnLtevqlkbyIJt6Cm9/7YIy/ovRGF2AKSYN6oCwmZQ6i1
8nRnFq5zE7O94m+GXconWZxy0wVqA6472HThMi7S+Tk/eLYen2ilGY+KCb9a0FH5
5MOuWSoJZ8/HfW2VeQmL8EjhWm5F2ybg28wgXK4BOGR3jQi03Fsc+AFidnWxSKo0
aiJoPgOsfyu8/fnCcAi07kSmjzUKIWskApgcpGQLNXHFK9mtg7+VA8esRnfLlKtP
tJf+nNAPY1sqHfGBzh7WWGWal5RGHF5nEm3ta3oiFF5sMKCJ6C87zVwFkEcRytGC
xOGmiG1O1RPrO5NG7rZUaQ4y1OKl2Y1H+nGONzZ3mvoAOvxEq6JtUnU2kZscpPlk
fpeOSDoGBYJGbIpzDreBDhxaZrwGq36k
-----END CERTIFICATE-----

View File

@@ -25,24 +25,25 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
# 1. install deps, clone and build.
# 2. strip binaries.
# 3. Purge all dependencies and other unrelated packages, including build directory.
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl git \
RUN apk update \
&& apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \
&& mkdir -p /tmp/build \
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
&& cd i2pd \
&& if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \
&& make \
&& make USE_UPNP=yes \
&& cp -R contrib/certificates /i2pd_certificates \
&& mkdir -p /usr/local/bin \
&& mv i2pd /usr/local/bin \
&& cd /usr/local/bin \
&& strip i2pd \
&& rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \
miniupnpc-dev boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \
boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \
libtool g++ gcc
# 2. Adding required libraries to run i2pd to ensure it will run.
RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl musl-utils libstdc++
RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh

724
contrib/i18n/English.po Normal file
View File

@@ -0,0 +1,724 @@
# i2pd
# Copyright (C) 2021 PurpleI2P team
# This file is distributed under the same license as the i2pd package.
# R4SAS <r4sas@i2pmail.org>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: i2pd\n"
"Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n"
"POT-Creation-Date: 2021-08-06 17:12\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.0\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-KeywordsList: ;tr\n"
"X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n"
"X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n"
#: daemon/HTTPServer.cpp:177
msgid "day"
msgid_plural "days"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:181
msgid "hour"
msgid_plural "hours"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:185
msgid "minute"
msgid_plural "minutes"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:188
msgid "second"
msgid_plural "seconds"
msgstr[0] ""
msgstr[1] ""
#. tr: Kibibit
#: daemon/HTTPServer.cpp:196 daemon/HTTPServer.cpp:224
msgid "KiB"
msgstr ""
#. tr: Mebibit
#: daemon/HTTPServer.cpp:198
msgid "MiB"
msgstr ""
#. tr: Gibibit
#: daemon/HTTPServer.cpp:200
msgid "GiB"
msgstr ""
#: daemon/HTTPServer.cpp:217
msgid "building"
msgstr ""
#: daemon/HTTPServer.cpp:218
msgid "failed"
msgstr ""
#: daemon/HTTPServer.cpp:219
msgid "expiring"
msgstr ""
#: daemon/HTTPServer.cpp:220
msgid "established"
msgstr ""
#: daemon/HTTPServer.cpp:221
msgid "unknown"
msgstr ""
#: daemon/HTTPServer.cpp:223
msgid "exploratory"
msgstr ""
#: daemon/HTTPServer.cpp:259
msgid "<b>i2pd</b> webconsole"
msgstr ""
#: daemon/HTTPServer.cpp:262
msgid "Main page"
msgstr ""
#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:725
msgid "Router commands"
msgstr ""
#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:448
#: daemon/HTTPServer.cpp:460
msgid "Local Destinations"
msgstr ""
#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:418
#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:510
#: daemon/HTTPServer.cpp:641 daemon/HTTPServer.cpp:684
#: daemon/HTTPServer.cpp:688
msgid "LeaseSets"
msgstr ""
#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:694
msgid "Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:425
#: daemon/HTTPServer.cpp:787 daemon/HTTPServer.cpp:803
msgid "Transit Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:852
msgid "Transports"
msgstr ""
#: daemon/HTTPServer.cpp:271
msgid "I2P tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:273 daemon/HTTPServer.cpp:914
#: daemon/HTTPServer.cpp:924
msgid "SAM sessions"
msgstr ""
#: daemon/HTTPServer.cpp:289 daemon/HTTPServer.cpp:1306
#: daemon/HTTPServer.cpp:1309 daemon/HTTPServer.cpp:1312
#: daemon/HTTPServer.cpp:1326 daemon/HTTPServer.cpp:1371
#: daemon/HTTPServer.cpp:1374 daemon/HTTPServer.cpp:1377
msgid "ERROR"
msgstr ""
#: daemon/HTTPServer.cpp:296
msgid "OK"
msgstr ""
#: daemon/HTTPServer.cpp:297
msgid "Testing"
msgstr ""
#: daemon/HTTPServer.cpp:298
msgid "Firewalled"
msgstr ""
#: daemon/HTTPServer.cpp:299 daemon/HTTPServer.cpp:320
#: daemon/HTTPServer.cpp:406
msgid "Unknown"
msgstr ""
#: daemon/HTTPServer.cpp:300 daemon/HTTPServer.cpp:435
#: daemon/HTTPServer.cpp:436 daemon/HTTPServer.cpp:982
#: daemon/HTTPServer.cpp:991
msgid "Proxy"
msgstr ""
#: daemon/HTTPServer.cpp:301
msgid "Mesh"
msgstr ""
#: daemon/HTTPServer.cpp:304
msgid "Error"
msgstr ""
#: daemon/HTTPServer.cpp:308
msgid "Clock skew"
msgstr ""
#: daemon/HTTPServer.cpp:311
msgid "Offline"
msgstr ""
#: daemon/HTTPServer.cpp:314
msgid "Symmetric NAT"
msgstr ""
#: daemon/HTTPServer.cpp:326
msgid "Uptime"
msgstr ""
#: daemon/HTTPServer.cpp:329
msgid "Network status"
msgstr ""
#: daemon/HTTPServer.cpp:334
msgid "Network status v6"
msgstr ""
#: daemon/HTTPServer.cpp:340 daemon/HTTPServer.cpp:347
msgid "Stopping in"
msgstr ""
#: daemon/HTTPServer.cpp:354
msgid "Family"
msgstr ""
#: daemon/HTTPServer.cpp:355
msgid "Tunnel creation success rate"
msgstr ""
#: daemon/HTTPServer.cpp:356
msgid "Received"
msgstr ""
#. tr: Kibibit/s
#: daemon/HTTPServer.cpp:358 daemon/HTTPServer.cpp:361
#: daemon/HTTPServer.cpp:364
msgid "KiB/s"
msgstr ""
#: daemon/HTTPServer.cpp:359
msgid "Sent"
msgstr ""
#: daemon/HTTPServer.cpp:362
msgid "Transit"
msgstr ""
#: daemon/HTTPServer.cpp:365
msgid "Data path"
msgstr ""
#: daemon/HTTPServer.cpp:368
msgid "Hidden content. Press on text to see."
msgstr ""
#: daemon/HTTPServer.cpp:371
msgid "Router Ident"
msgstr ""
#: daemon/HTTPServer.cpp:373
msgid "Router Family"
msgstr ""
#: daemon/HTTPServer.cpp:374
msgid "Router Caps"
msgstr ""
#: daemon/HTTPServer.cpp:375
msgid "Version"
msgstr ""
#: daemon/HTTPServer.cpp:376
msgid "Our external address"
msgstr ""
#: daemon/HTTPServer.cpp:384
msgid "supported"
msgstr ""
#: daemon/HTTPServer.cpp:416
msgid "Routers"
msgstr ""
#: daemon/HTTPServer.cpp:417
msgid "Floodfills"
msgstr ""
#: daemon/HTTPServer.cpp:424 daemon/HTTPServer.cpp:968
msgid "Client Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:434
msgid "Services"
msgstr ""
#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436
#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438
#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440
msgid "Enabled"
msgstr ""
#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436
#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438
#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440
msgid "Disabled"
msgstr ""
#: daemon/HTTPServer.cpp:483
msgid "Encrypted B33 address"
msgstr ""
#: daemon/HTTPServer.cpp:492
msgid "Address registration line"
msgstr ""
#: daemon/HTTPServer.cpp:497
msgid "Domain"
msgstr ""
#: daemon/HTTPServer.cpp:498
msgid "Generate"
msgstr ""
#: daemon/HTTPServer.cpp:499
msgid ""
"<b>Note:</b> result string can be used only for registering 2LD domains "
"(example.i2p). For registering subdomains please use i2pd-tools."
msgstr ""
#: daemon/HTTPServer.cpp:505
msgid "Address"
msgstr ""
#: daemon/HTTPServer.cpp:505
msgid "Type"
msgstr ""
#: daemon/HTTPServer.cpp:505
msgid "EncType"
msgstr ""
#: daemon/HTTPServer.cpp:515 daemon/HTTPServer.cpp:699
msgid "Inbound tunnels"
msgstr ""
#. tr: Milliseconds
#: daemon/HTTPServer.cpp:520 daemon/HTTPServer.cpp:530
#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:714
msgid "ms"
msgstr ""
#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:709
msgid "Outbound tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:537
msgid "Tags"
msgstr ""
#: daemon/HTTPServer.cpp:537
msgid "Incoming"
msgstr ""
#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:547
msgid "Outgoing"
msgstr ""
#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:561
msgid "Destination"
msgstr ""
#: daemon/HTTPServer.cpp:545
msgid "Amount"
msgstr ""
#: daemon/HTTPServer.cpp:552
msgid "Incoming Tags"
msgstr ""
#: daemon/HTTPServer.cpp:560 daemon/HTTPServer.cpp:563
msgid "Tags sessions"
msgstr ""
#: daemon/HTTPServer.cpp:561
msgid "Status"
msgstr ""
#: daemon/HTTPServer.cpp:570 daemon/HTTPServer.cpp:626
msgid "Local Destination"
msgstr ""
#: daemon/HTTPServer.cpp:580 daemon/HTTPServer.cpp:947
msgid "Streams"
msgstr ""
#: daemon/HTTPServer.cpp:602
msgid "Close stream"
msgstr ""
#: daemon/HTTPServer.cpp:631
msgid "I2CP session not found"
msgstr ""
#: daemon/HTTPServer.cpp:634
msgid "I2CP is not enabled"
msgstr ""
#: daemon/HTTPServer.cpp:660
msgid "Invalid"
msgstr ""
#: daemon/HTTPServer.cpp:663
msgid "Store type"
msgstr ""
#: daemon/HTTPServer.cpp:664
msgid "Expires"
msgstr ""
#: daemon/HTTPServer.cpp:669
msgid "Non Expired Leases"
msgstr ""
#: daemon/HTTPServer.cpp:672
msgid "Gateway"
msgstr ""
#: daemon/HTTPServer.cpp:673
msgid "TunnelID"
msgstr ""
#: daemon/HTTPServer.cpp:674
msgid "EndDate"
msgstr ""
#: daemon/HTTPServer.cpp:684
msgid "not floodfill"
msgstr ""
#: daemon/HTTPServer.cpp:695
msgid "Queue size"
msgstr ""
#: daemon/HTTPServer.cpp:726
msgid "Run peer test"
msgstr ""
#: daemon/HTTPServer.cpp:731
msgid "Decline transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:733
msgid "Accept transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742
msgid "Cancel graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:739 daemon/HTTPServer.cpp:744
msgid "Start graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:747
msgid "Force shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:748
msgid "Reload external CSS styles"
msgstr ""
#: daemon/HTTPServer.cpp:751
msgid ""
"<b>Note:</b> any action done here are not persistent and not changes your "
"config files."
msgstr ""
#: daemon/HTTPServer.cpp:753
msgid "Logging level"
msgstr ""
#: daemon/HTTPServer.cpp:761
msgid "Transit tunnels limit"
msgstr ""
#: daemon/HTTPServer.cpp:766 daemon/HTTPServer.cpp:778
msgid "Change"
msgstr ""
#: daemon/HTTPServer.cpp:770
msgid "Change language"
msgstr ""
#: daemon/HTTPServer.cpp:803
msgid "no transit tunnels currently built"
msgstr ""
#: daemon/HTTPServer.cpp:908 daemon/HTTPServer.cpp:931
msgid "SAM disabled"
msgstr ""
#: daemon/HTTPServer.cpp:924
msgid "no sessions currently running"
msgstr ""
#: daemon/HTTPServer.cpp:937
msgid "SAM session not found"
msgstr ""
#: daemon/HTTPServer.cpp:942
msgid "SAM Session"
msgstr ""
#: daemon/HTTPServer.cpp:999
msgid "Server Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:1015
msgid "Client Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:1029
msgid "Server Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:1227
msgid "Unknown page"
msgstr ""
#: daemon/HTTPServer.cpp:1246
msgid "Invalid token"
msgstr ""
#: daemon/HTTPServer.cpp:1304 daemon/HTTPServer.cpp:1361
#: daemon/HTTPServer.cpp:1401
msgid "SUCCESS"
msgstr ""
#: daemon/HTTPServer.cpp:1304
msgid "Stream closed"
msgstr ""
#: daemon/HTTPServer.cpp:1306
msgid "Stream not found or already was closed"
msgstr ""
#: daemon/HTTPServer.cpp:1309
msgid "Destination not found"
msgstr ""
#: daemon/HTTPServer.cpp:1312
msgid "StreamID can't be null"
msgstr ""
#: daemon/HTTPServer.cpp:1314 daemon/HTTPServer.cpp:1379
msgid "Return to destination page"
msgstr ""
#: daemon/HTTPServer.cpp:1315 daemon/HTTPServer.cpp:1328
#: daemon/HTTPServer.cpp:1403
msgid "You will be redirected in 5 seconds"
msgstr ""
#: daemon/HTTPServer.cpp:1326
msgid "Transit tunnels count must not exceed 65535"
msgstr ""
#: daemon/HTTPServer.cpp:1327 daemon/HTTPServer.cpp:1402
msgid "Back to commands list"
msgstr ""
#: daemon/HTTPServer.cpp:1363
msgid "Register at reg.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1364
msgid "Description"
msgstr ""
#: daemon/HTTPServer.cpp:1364
msgid "A bit information about service on domain"
msgstr ""
#: daemon/HTTPServer.cpp:1365
msgid "Submit"
msgstr ""
#: daemon/HTTPServer.cpp:1371
msgid "Domain can't end with .b32.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1374
msgid "Domain must end with .i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1377
msgid "Such destination is not found"
msgstr ""
#: daemon/HTTPServer.cpp:1397
msgid "Unknown command"
msgstr ""
#: daemon/HTTPServer.cpp:1401
msgid "Command accepted"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:157
msgid "Proxy error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:165
msgid "Proxy info"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:173
msgid "Proxy error: Host not found"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:174
msgid "Remote host not found in router's addressbook"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:175
msgid "You may try to find this host on jump services below"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288
#: libi2pd_client/HTTPProxy.cpp:322 libi2pd_client/HTTPProxy.cpp:365
msgid "Invalid request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:273
msgid "Proxy unable to parse your request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:288
msgid "addresshelper is not supported"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:297 libi2pd_client/HTTPProxy.cpp:306
#: libi2pd_client/HTTPProxy.cpp:385
msgid "Host"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:297
msgid "added to router's addressbook from helper"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:298
msgid "Click here to proceed:"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:308
msgid "Continue"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:299 libi2pd_client/HTTPProxy.cpp:309
msgid "Addresshelper found"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:306
msgid "already in router's addressbook"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:307
msgid "Click here to update record:"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:322
msgid "invalid request uri"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:365
msgid "Can't detect destination host from request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:382 libi2pd_client/HTTPProxy.cpp:386
msgid "Outproxy failure"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:382
msgid "bad outproxy settings"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:385
msgid "not inside I2P network, but outproxy is not enabled"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:474
msgid "unknown outproxy url"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:480
msgid "cannot resolve upstream proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:488
msgid "hostname too long"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:515
msgid "cannot connect to upstream socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:521
msgid "Cannot negotiate with socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:563
msgid "CONNECT error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:563
msgid "Failed to Connect"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:574 libi2pd_client/HTTPProxy.cpp:600
msgid "socks proxy error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:582
msgid "failed to send request to upstream"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:603
msgid "No Reply From socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:610
msgid "cannot connect"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:610
msgid "http out proxy not implemented"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:611
msgid "cannot connect to upstream http proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:644
msgid "Host is down"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:644
msgid ""
"Can't create connection to requested host, it may be down. Please try again "
"later."
msgstr ""

29
contrib/i18n/README.md Normal file
View File

@@ -0,0 +1,29 @@
`xgettext` command for extracting translation
---
```
xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp
```
Regex for transforming gettext translations to our format:
---
```
in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
out: #{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n
```
```
in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
out: {"$1", "$2"},\n
```
```
in: ^#[:.](.*)$\n
out: <to empty line>
```
```
in: \n\n
out: \n
```

View File

@@ -15,11 +15,16 @@
## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d
# tunnelsdir = /var/lib/i2pd/tunnels.d
## Path to certificates used for verifying .su3, families
## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
# certsdir = /var/lib/i2pd/certificates
## Where to write pidfile (default: i2pd.pid, not used in Windows)
# pidfile = /run/i2pd.pid
## Logging configuration section
## By default logs go to stdout with level 'info' and higher
## For Windows OS by default logs go to file with level 'warn' and higher
##
## Logs destination (valid values: stdout, file, syslog)
## * stdout - print log entries to stdout
@@ -34,14 +39,30 @@
## Write full CLF-formatted date and time to log (default: write only time)
# logclftime = true
## Daemon mode. Router will go to background after start
## Daemon mode. Router will go to background after start. Ignored on Windows
# daemon = true
## Specify a family, router belongs to (default - none)
# family =
## External IP address to listen for connections
## Network interface to bind to
## Updates address4/6 options if they are not set
# ifname =
## You can specify different interfaces for IPv4 and IPv6
# ifname4 =
# ifname6 =
## Local address to bind transport sockets to
## Overrides host option if:
## For ipv4: if ipv4 = true and nat = false
## For ipv6: if 'host' is not set or ipv4 = true
# address4 =
# address6 =
## External IPv4 or IPv6 address to listen for connections
## By default i2pd sets IP automatically
## Sets published NTCP2v4/SSUv4 address to 'host' value if nat = true
## Sets published NTCP2v6/SSUv6 address to 'host' value if ipv4 = false
# host = 1.2.3.4
## Port to listen for connections
@@ -54,27 +75,15 @@ ipv4 = true
## Enable communication through ipv6
ipv6 = false
## Network interface to bind to
# ifname =
## You can specify different interfaces for IPv4 and IPv6
# ifname4 =
# ifname6 =
## Enable NTCP transport (default = true)
# ntcp = true
## If you run i2pd behind a proxy server, you can only use NTCP transport with ntcpproxy option
## Should be http://address:port or socks://address:port
# ntcpproxy = http://127.0.0.1:8118
## Enable SSU transport (default = true)
# ssu = true
## Should we assume we are behind NAT? (false only in MeshNet)
# nat = true
## Bandwidth configuration
## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec,
## X - unlimited
## Default is X for floodfill, L for regular node
## Default is L (regular node) and X if floodfill mode enabled. If you want to
## share more bandwidth without floodfill mode, uncomment that line and adjust
## value to your possibilities
# bandwidth = L
## Max % of bandwidth limit for transit. 0-100. 100 by default
# share = 100
@@ -84,6 +93,7 @@ ipv6 = false
# notransit = true
## Router will be floodfill
## Note: that mode uses much more network connections and CPU!
# floodfill = true
[http]
@@ -95,10 +105,14 @@ address = 127.0.0.1
port = 7070
## Path to web console, default "/"
# webroot = /
## Uncomment following lines to enable Web Console authentication
## Uncomment following lines to enable Web Console authentication
# auth = true
# user = i2pd
# pass = changeme
## Select webconsole language
## Currently supported english (default), afrikaans, armenian, german, russian,
## turkmen, ukrainian and uzbek languages
# lang = english
[httpproxy]
## Uncomment and set to 'false' to disable HTTP Proxy
@@ -131,7 +145,7 @@ port = 4447
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
## Uncomment and set to 'true' to enable SAM Bridge
## Comment or set to 'false' to disable SAM Bridge
enabled = true
## Address and port service will listen on
# address = 127.0.0.1
@@ -171,6 +185,13 @@ enabled = true
## Name i2pd appears in UPnP forwardings list (default = I2Pd)
# name = I2Pd
[meshnets]
## Enable connectivity over the Yggdrasil network
# yggdrasil = false
## You can bind address from your Yggdrasil subnet 300::/64
## The address must first be added to the network interface
# yggaddress =
[reseed]
## Options for bootstrapping into I2P network, aka reseeding
## Enable or disable reseed data verification.
@@ -178,6 +199,8 @@ verify = true
## URLs to request reseed data from, separated by comma
## Default: "mainline" I2P Network reseeds
# urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/
## Reseed URLs through the Yggdrasil, separated by comma
# yggurls = http://[324:9de3:fea4:f6ac::ace]:7070/
## Path to local reseed data file (.su3) for manual reseeding
# file = /path/to/i2pseeds.su3
## or HTTPS URL to reseed from
@@ -195,19 +218,15 @@ verify = true
## Default: reg.i2p at "mainline" I2P Network
# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
## Optional subscriptions URLs, separated by comma
# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
[limits]
## Maximum active transit sessions (default:2500)
# transittunnels = 2500
## Limit number of open file descriptors (0 - use system limit)
## Limit number of open file descriptors (0 - use system limit)
# openfiles = 0
## Maximum size of corefile in Kb (0 - use system limit)
## Maximum size of corefile in Kb (0 - use system limit)
# coresize = 0
## Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit)
# ntcpsoft = 0
## Maximum number of ntcp sessions (0 - use system limit)
# ntcphard = 0
[trust]
## Enable explicit trust options. false by default
@@ -215,13 +234,13 @@ verify = true
## Make direct I2P connections only to routers in specified Family.
# family = MyFamily
## Make direct I2P connections only to routers specified here. Comma separated list of base64 identities.
# routers =
# routers =
## Should we hide our router from other routers? false by default
# hidden = true
[exploratory]
## Exploratory tunnels settings with default values
# inbound.length = 2
# inbound.length = 2
# inbound.quantity = 3
# outbound.length = 2
# outbound.quantity = 3
@@ -229,6 +248,8 @@ verify = true
[persist]
## Save peer profiles on disk (default: true)
# profiles = true
## Save full addresses on disk (default: true)
# addressbook = true
[cpuext]
## Use CPU AES-NI instructions set when work with cryptography when available (default: true)

View File

@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git
Version: 2.37.0
Version: 2.41.0
Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd
@@ -32,7 +32,7 @@ Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
C++ implementation of I2P.
%prep
%setup -q
%setup -q -n i2pd-openssl
%build
@@ -56,9 +56,20 @@ cd build
%endif
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
@@ -66,10 +77,16 @@ pushd build
make %{?_smp_mflags}
%if 0%{?fedora} >= 33
%if 0%{?rhel} == 9
popd
%endif
%if 0%{?fedora} >= 33
%if 0%{?fedora} < 37
popd
%endif
%endif
%if 0%{?mageia} > 7
popd
%endif
@@ -77,9 +94,19 @@ popd
%install
pushd build
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
@@ -90,14 +117,14 @@ chrpath -d i2pd
%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1
%{__cp} -r %{_builddir}/i2pd-openssl/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
%{__cp} -r %{_builddir}/i2pd-openssl/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
@@ -137,6 +164,23 @@ getent passwd i2pd >/dev/null || \
%changelog
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
- update to 2.41.0
- fixed build on Fedora Copr over openssl trunk code
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
- update to 2.40.0
* Tue Aug 24 2021 r4sas <r4sas@i2pmail.org> - 2.39.0-2
- changed if statements to cover fedora 35
* Mon Aug 23 2021 orignal <i2porignal@yandex.ru> - 2.39.0
- update to 2.39.0
- fixed build on fedora 36
* Mon May 17 2021 orignal <i2porignal@yandex.ru> - 2.38.0
- update to 2.38.0
* Mon Mar 15 2021 orignal <i2porignal@yandex.ru> - 2.37.0
- update to 2.37.0

View File

@@ -1,5 +1,5 @@
Name: i2pd
Version: 2.37.0
Version: 2.41.0
Release: 1%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd-git
@@ -54,9 +54,19 @@ cd build
%endif
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
@@ -64,10 +74,16 @@ pushd build
make %{?_smp_mflags}
%if 0%{?fedora} >= 33
%if 0%{?rhel} == 9
popd
%endif
%if 0%{?fedora} >= 33
%if 0%{?fedora} < 37
popd
%endif
%endif
%if 0%{?mageia} > 7
popd
%endif
@@ -75,9 +91,19 @@ popd
%install
pushd build
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
%if 0%{?fedora} < 37
pushd redhat-linux-build
%endif
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
@@ -135,6 +161,22 @@ getent passwd i2pd >/dev/null || \
%changelog
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
- update to 2.41.0
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
- update to 2.40.0
* Tue Aug 24 2021 r4sas <r4sas@i2pmail.org> - 2.39.0-2
- changed if statements to cover fedora 35
* Mon Aug 23 2021 orignal <i2porignal@yandex.ru> - 2.39.0
- update to 2.39.0
- fixed build on fedora 36
* Mon May 17 2021 orignal <i2porignal@yandex.ru> - 2.38.0
- update to 2.38.0
* Mon Mar 15 2021 orignal <i2porignal@yandex.ru> - 2.37.0
- update to 2.37.0

View File

@@ -1,16 +1,16 @@
[IRC-IRC2P]
[IRC-ILITA]
type = client
address = 127.0.0.1
port = 6668
destination = irc.postman.i2p
destination = irc.ilita.i2p
destinationport = 6667
keys = irc-keys.dat
#[IRC-ILITA]
#[IRC-IRC2P]
#type = client
#address = 127.0.0.1
#port = 6669
#destination = irc.ilita.i2p
#destination = irc.postman.i2p
#destinationport = 6667
#keys = irc-keys.dat

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*
******************************************************************
*
* This is style sheet for webconsole, with @media selectors for adaptive
* view on desktop and mobile devices, respecting preferred user's color
* scheme used in system/browser.
*
* Minified copy of that style sheet is bundled inside i2pd sources.
*/
:root {
--main-bg-color: #fafafa;
--main-text-color: #103456;
--main-link-color: #894c84;
--main-link-hover-color: #fafafa;
}
@media (prefers-color-scheme: dark) {
:root {
--main-bg-color: #242424;
--main-text-color: #17ab5c;
--main-link-color: #bf64b7;
--main-link-hover-color: #000000;
}
}
body {
font: 100%/1.5em sans-serif;
margin: 0;
padding: 1.5em;
background: var(--main-bg-color);
color: var(--main-text-color);
}
a, .slide label {
text-decoration: none;
color: var(--main-link-color);
}
a:hover, .slide label:hover, button[type=submit]:hover {
color: var(--main-link-hover-color);
background: var(--main-link-color);
}
a.button {
appearance: button;
text-decoration: none;
padding: 0 5px;
border: 1px solid var(--main-link-color);
}
.header {
font-size: 2.5em;
text-align: center;
margin: 1em 0;
color: var(--main-link-color);
}
.wrapper {
margin: 0 auto;
padding: 1em;
max-width: 64em;
}
.menu {
display: block;
float: left;
overflow: hidden;
padding: 4px;
max-width: 12em;
white-space: nowrap;
text-overflow: ellipsis;
}
.listitem {
display: block;
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.tableitem {
font-family: monospace;
font-size: 1.2em;
white-space: nowrap;
}
.content {
float: left;
font-size: 1em;
margin-left: 2em;
padding: 4px;
max-width: 50em;
overflow: auto;
}
.tunnel.established {
color: #56B734;
}
.tunnel.expiring {
color: #D3AE3F;
}
.tunnel.failed {
color: #D33F3F;
}
.tunnel.building {
color: #434343;
}
caption {
font-size: 1.5em;
text-align: center;
color: var(--main-link-color);
}
table {
display: table;
border-collapse: collapse;
text-align: center;
}
table.extaddr {
text-align: left;
}
table.services {
width: 100%;
}
textarea {
background-color: var(--main-bg-color);
color: var(--main-text-color);
word-break: break-all;
}
.streamdest {
width: 120px;
max-width: 240px;
overflow: hidden;
text-overflow: ellipsis;
}
.slide div.slidecontent, .slide [type="checkbox"] {
display: none;
}
.slide [type="checkbox"]:checked ~ div.slidecontent {
display: block;
margin-top: 0;
padding: 0;
}
.disabled {
color: #D33F3F;
}
.enabled {
color: #56B734;
}
button[type=submit] {
background-color: transparent;
color: var(--main-link-color);
text-decoration: none;
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input, select, select option {
background-color: var(--main-bg-color);
color: var(--main-link-color);
padding: 5px;
border: 1px solid var(--main-link-color);
font-size: 14px;
}
input:focus, select:focus, select option:focus {
outline: none;
}
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
@media screen and (max-width: 1150px) { /* adaptive style */
.wrapper {
max-width: 58em;
}
.content {
max-width: 40em;
}
}
@media screen and (max-width: 980px) {
body {
font: 100%/1.2em sans-serif;
padding: 1.2em 0 0 0;
}
.menu {
width: 100%;
max-width: unset;
display: block;
float: none;
position: unset;
font-size: 16px;
text-align: center;
}
.menu a, .commands a {
display: inline-block;
padding: 4px;
}
.content {
float: none;
margin-left: unset;
margin-top: 16px;
max-width: 100%;
width: 100%;
text-align: center;
}
a, .slide label {
display: block;
}
.header {
margin: unset;
font-size: 1.5em;
}
small {
display: block
}
a.button {
appearance: button;
text-decoration: none;
margin-top: 10px;
padding: 6px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
width: -webkit-fill-available;
}
input, select {
width: 35%;
text-align: center;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 18px;
}
table.extaddr {
margin: auto;
text-align: unset;
}
textarea {
width: -webkit-fill-available;
height: auto;
padding: 5px;
border: 2px solid var(--main-link-color);
border-radius: 5px;
font-size: 12px;
}
button[type=submit] {
padding: 5px 15px;
background: transparent;
border: 2px solid var(--main-link-color);
cursor: pointer;
-webkit-border-radius: 5px;
border-radius: 5px;
position: relative;
height: 36px;
display: -webkit-inline-box;
margin-top: 10px;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -26,12 +26,15 @@
#include "Streaming.h"
#include "Destination.h"
#include "HTTPServer.h"
#ifdef WITH_I2PC
#include "I2PControl.h"
#endif
#include "ClientContext.h"
#include "Crypto.h"
#include "UPnP.h"
#include "Timestamp.h"
#include "util.h"
#include "I18N.h"
namespace i2p
{
@@ -44,7 +47,9 @@ namespace util
~Daemon_Singleton_Private() {};
std::unique_ptr<i2p::http::HTTPServer> httpServer;
#ifdef WITH_I2PC
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
#endif
std::unique_ptr<i2p::transport::UPnP> UPnP;
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
};
@@ -63,6 +68,12 @@ namespace util
return service;
}
void Daemon_Singleton::setDataDir(std::string path)
{
if (path != "")
DaemonDataDir = path;
}
bool Daemon_Singleton::init(int argc, char* argv[]) {
return init(argc, argv, nullptr);
}
@@ -72,8 +83,14 @@ namespace util
i2p::config::Init();
i2p::config::ParseCmdline(argc, argv);
std::string config; i2p::config::GetOption("conf", config);
std::string datadir; i2p::config::GetOption("datadir", datadir);
std::string config; i2p::config::GetOption("conf", config);
std::string datadir;
if(DaemonDataDir != "") {
datadir = DaemonDataDir;
} else {
i2p::config::GetOption("datadir", datadir);
}
i2p::fs::DetectDataDir(datadir, IsService());
i2p::fs::Init();
@@ -93,6 +110,11 @@ namespace util
i2p::config::GetOption("daemon", isDaemon);
std::string certsdir; i2p::config::GetOption("certsdir", certsdir);
i2p::fs::SetCertsDir(certsdir);
certsdir = i2p::fs::GetCertsDir();
std::string logs = ""; i2p::config::GetOption("log", logs);
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
@@ -112,25 +134,26 @@ namespace util
i2p::log::Logger().SetLogLevel(loglevel);
if (logstream) {
LogPrint(eLogInfo, "Log: will send messages to std::ostream");
LogPrint(eLogInfo, "Log: Sending messages to std::ostream");
i2p::log::Logger().SendTo (logstream);
} else if (logs == "file") {
if (logfile == "")
logfile = i2p::fs::DataDirPath("i2pd.log");
LogPrint(eLogInfo, "Log: will send messages to ", logfile);
LogPrint(eLogInfo, "Log: Sending messages to ", logfile);
i2p::log::Logger().SendTo (logfile);
#ifndef _WIN32
} else if (logs == "syslog") {
LogPrint(eLogInfo, "Log: will send messages to syslog");
LogPrint(eLogInfo, "Log: Sending messages to syslog");
i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
#endif
} else {
// use stdout -- default
}
LogPrint(eLogNone, "i2pd v", VERSION, " starting");
LogPrint(eLogDebug, "FS: main config file: ", config);
LogPrint(eLogDebug, "FS: data directory: ", datadir);
LogPrint(eLogNone, "i2pd v", VERSION, " (", I2P_VERSION, ") starting...");
LogPrint(eLogDebug, "FS: Main config file: ", config);
LogPrint(eLogDebug, "FS: Data directory: ", datadir);
LogPrint(eLogDebug, "FS: Certificates directory: ", certsdir);
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
@@ -142,23 +165,19 @@ namespace util
i2p::context.SetNetID (netID);
i2p::context.Init ();
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
#ifdef MESHNET
// manual override for meshnet
ipv4 = false;
ipv6 = true;
#endif
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
// ifname -> address
std::string ifname; i2p::config::GetOption("ifname", ifname);
std::string ifname; i2p::config::GetOption("ifname", ifname);
if (ipv4 && i2p::config::IsDefault ("address4"))
{
std::string ifname4; i2p::config::GetOption("ifname4", ifname4);
if (!ifname4.empty ())
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname4, false).to_string ()); // v4
else if (!ifname.empty ())
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4
}
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4
}
if (ipv6 && i2p::config::IsDefault ("address6"))
{
std::string ifname6; i2p::config::GetOption("ifname6", ifname6);
@@ -166,8 +185,8 @@ namespace util
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname6, true).to_string ()); // v6
else if (!ifname.empty ())
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname, true).to_string ()); // v6
}
}
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
boost::asio::ip::address_v6 yggaddr;
if (ygg)
@@ -197,7 +216,7 @@ namespace util
uint16_t port; i2p::config::GetOption("port", port);
if (!i2p::config::IsDefault("port"))
{
LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
LogPrint(eLogInfo, "Daemon: Accepting incoming connections at port ", port);
i2p::context.UpdatePort (port);
}
i2p::context.SetSupportsV6 (ipv6);
@@ -210,15 +229,15 @@ namespace util
{
bool published; i2p::config::GetOption("ntcp2.published", published);
if (published)
{
{
std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
if (!ntcp2proxy.empty ()) published = false;
}
}
if (published)
{
uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
if (!ntcp2port) ntcp2port = port; // use standard port
i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
i2p::context.PublishNTCP2Address (ntcp2port, true, ipv4, ipv6, false); // publish
if (ipv6)
{
std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
@@ -228,16 +247,27 @@ namespace util
}
}
else
i2p::context.PublishNTCP2Address (port, false); // unpublish
i2p::context.PublishNTCP2Address (port, false, ipv4, ipv6, false); // unpublish
}
if (ygg)
{
if (!ntcp2)
i2p::context.PublishNTCP2Address (port, true);
i2p::context.PublishNTCP2Address (port, true, false, false, true);
i2p::context.UpdateNTCP2V6Address (yggaddr);
if (!ipv4 && !ipv6)
i2p::context.SetStatus (eRouterStatusMesh);
}
i2p::context.SetStatus (eRouterStatusMesh);
}
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
if (ssu2)
{
bool published; i2p::config::GetOption("ssu2.published", published);
if (published)
{
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
}
else
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
}
bool transit; i2p::config::GetOption("notransit", transit);
i2p::context.SetAcceptsTunnels (!transit);
@@ -246,7 +276,7 @@ namespace util
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
if (isFloodfill) {
LogPrint(eLogInfo, "Daemon: router will be floodfill");
LogPrint(eLogInfo, "Daemon: Router configured as floodfill");
i2p::context.SetFloodfill (true);
}
else
@@ -261,7 +291,7 @@ namespace util
if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X')
{
i2p::context.SetBandwidth (bandwidth[0]);
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
LogPrint(eLogInfo, "Daemon: Bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
}
else
{
@@ -269,19 +299,19 @@ namespace util
if (value > 0)
{
i2p::context.SetBandwidth (value);
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
LogPrint(eLogInfo, "Daemon: Bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
}
else
{
LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
LogPrint(eLogInfo, "Daemon: Unexpected bandwidth ", bandwidth, ". Set to 'low'");
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
}
}
}
else if (isFloodfill)
{
LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
LogPrint(eLogInfo, "Daemon: Floodfill bandwidth set to 'extra'");
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2);
}
else
{
@@ -295,12 +325,12 @@ namespace util
std::string family; i2p::config::GetOption("family", family);
i2p::context.SetFamily (family);
if (family.length () > 0)
LogPrint(eLogInfo, "Daemon: family set to ", family);
LogPrint(eLogInfo, "Daemon: Router family set to ", family);
bool trust; i2p::config::GetOption("trust.enabled", trust);
if (trust)
{
LogPrint(eLogInfo, "Daemon: explicit trust enabled");
LogPrint(eLogInfo, "Daemon: Explicit trust enabled");
std::string fam; i2p::config::GetOption("trust.family", fam);
std::string routers; i2p::config::GetOption("trust.routers", routers);
bool restricted = false;
@@ -330,27 +360,31 @@ namespace util
pos = comma + 1;
}
while (comma != std::string::npos);
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers");
LogPrint(eLogInfo, "Daemon: Setting restricted routes to use ", idents.size(), " trusted routers");
i2p::transport::transports.RestrictRoutesToRouters(idents);
restricted = idents.size() > 0;
}
if(!restricted)
LogPrint(eLogError, "Daemon: no trusted routers of families specified");
LogPrint(eLogError, "Daemon: No trusted routers of families specified");
}
bool hidden; i2p::config::GetOption("trust.hidden", hidden);
if (hidden)
{
LogPrint(eLogInfo, "Daemon: using hidden mode");
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
i2p::data::netdb.SetHidden(true);
}
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
i2p::i18n::SetLanguage(httpLang);
return true;
}
bool Daemon_Singleton::start()
{
i2p::log::Logger().Start();
LogPrint(eLogInfo, "Daemon: starting NetDB");
LogPrint(eLogInfo, "Daemon: Starting NetDB");
i2p::data::netdb.Start();
bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
@@ -367,19 +401,20 @@ namespace util
}
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
bool ssu; i2p::config::GetOption("ssu", ssu);
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
LogPrint(eLogInfo, "Daemon: starting Transports");
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
LogPrint(eLogInfo, "Daemon: Starting Transports");
if(!ssu) LogPrint(eLogInfo, "Daemon: SSU disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled");
i2p::transport::transports.SetCheckReserved(checkInReserved);
i2p::transport::transports.Start(ntcp2, ssu);
i2p::transport::transports.Start(ntcp2, ssu, ssu2);
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
LogPrint(eLogInfo, "Daemon: Transports started");
else
{
LogPrint(eLogError, "Daemon: failed to start Transports");
LogPrint(eLogError, "Daemon: Failed to start Transports");
/** shut down netdb right away */
i2p::transport::transports.Stop();
i2p::data::netdb.Stop();
@@ -390,7 +425,7 @@ namespace util
if (http) {
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
LogPrint(eLogInfo, "Daemon: Starting Webconsole at ", httpAddr, ":", httpPort);
try
{
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
@@ -398,24 +433,25 @@ namespace util
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ());
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
}
}
LogPrint(eLogInfo, "Daemon: starting Tunnels");
LogPrint(eLogInfo, "Daemon: Starting Tunnels");
i2p::tunnel::tunnels.Start();
LogPrint(eLogInfo, "Daemon: starting Client");
LogPrint(eLogInfo, "Daemon: Starting Client");
i2p::client::context.Start ();
#ifdef WITH_I2PC
// I2P Control Protocol
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
if (i2pcontrol) {
std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort);
LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
LogPrint(eLogInfo, "Daemon: Starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
try
{
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
@@ -423,19 +459,20 @@ namespace util
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ());
LogPrint (eLogError, "Daemon: Failed to start I2PControl: ", ex.what ());
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
}
}
#endif
return true;
}
bool Daemon_Singleton::stop()
{
LogPrint(eLogInfo, "Daemon: shutting down");
LogPrint(eLogInfo, "Daemon: stopping Client");
LogPrint(eLogInfo, "Daemon: Shutting down");
LogPrint(eLogInfo, "Daemon: Stopping Client");
i2p::client::context.Stop();
LogPrint(eLogInfo, "Daemon: stopping Tunnels");
LogPrint(eLogInfo, "Daemon: Stopping Tunnels");
i2p::tunnel::tunnels.Stop();
if (d.UPnP)
@@ -450,21 +487,23 @@ namespace util
d.m_NTPSync = nullptr;
}
LogPrint(eLogInfo, "Daemon: stopping Transports");
LogPrint(eLogInfo, "Daemon: Stopping Transports");
i2p::transport::transports.Stop();
LogPrint(eLogInfo, "Daemon: stopping NetDB");
LogPrint(eLogInfo, "Daemon: Stopping NetDB");
i2p::data::netdb.Stop();
if (d.httpServer) {
LogPrint(eLogInfo, "Daemon: stopping HTTP Server");
LogPrint(eLogInfo, "Daemon: Stopping HTTP Server");
d.httpServer->Stop();
d.httpServer = nullptr;
}
#ifdef WITH_I2PC
if (d.m_I2PControlService)
{
LogPrint(eLogInfo, "Daemon: stopping I2PControl");
LogPrint(eLogInfo, "Daemon: Stopping I2PControl");
d.m_I2PControlService->Stop ();
d.m_I2PControlService = nullptr;
}
#endif
i2p::crypto::TerminateCrypto ();
i2p::log::Logger().Stop();

View File

@@ -20,27 +20,33 @@ namespace util
class Daemon_Singleton_Private;
class Daemon_Singleton
{
public:
public:
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
virtual bool init(int argc, char* argv[]);
virtual bool start();
virtual bool stop();
virtual void run () {};
virtual bool init (int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
virtual bool init (int argc, char* argv[]);
virtual bool start ();
virtual bool stop ();
virtual void run () {};
bool isDaemon;
bool running;
virtual void setDataDir (std::string path);
protected:
bool isDaemon;
bool running;
Daemon_Singleton();
virtual ~Daemon_Singleton();
protected:
bool IsService () const;
Daemon_Singleton ();
virtual ~Daemon_Singleton ();
// d-pointer for httpServer, httpProxy, etc.
class Daemon_Singleton_Private;
Daemon_Singleton_Private &d;
bool IsService () const;
// d-pointer for httpServer, httpProxy, etc.
class Daemon_Singleton_Private;
Daemon_Singleton_Private &d;
private:
std::string DaemonDataDir;
};
#if defined(QT_GUI_LIB) // check if QT

File diff suppressed because it is too large Load Diff

View File

@@ -95,11 +95,15 @@ namespace http
void ShowTunnels (std::stringstream& s);
void ShowTransitTunnels (std::stringstream& s);
void ShowTransports (std::stringstream& s);
void ShowSAMSessions (std::stringstream& s);
void ShowI2PTunnels (std::stringstream& s);
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
void ShowSAMSession (std::stringstream& s, const std::string& id);
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
#ifdef WITH_SAM
void ShowSAMSessions (std::stringstream& s);
void ShowSAMSession (std::stringstream& s, const std::string& id);
#endif
#ifdef WITH_I2CP
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
#endif
} // http
} // i2p

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef HTTP_SERVER_RESOURCES_H__
#define HTTP_SERVER_RESOURCES_H__
namespace i2p
{
namespace http
{
const std::string itoopieFavicon =
"data:image/png;base64,"
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx"
"jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0"
"d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB"
"vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn"
"cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP"
"6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps"
"/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X"
"+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/"
"z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/"
"P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am"
"+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM"
"EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1"
"oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ"
"JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ"
"RU5ErkJggg==";
// bundled style sheet
const std::string internalCSS =
"<style>\r\n"
":root { --main-bg-color: #fafafa; --main-text-color: #103456; --main-link-color: #894c84; --main-link-hover-color: #fafafa; }\r\n"
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n"
"body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n"
"a, .slide label { text-decoration: none; color: var(--main-link-color); }\r\n"
"a:hover, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n"
"a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color); }\r\n"
".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color); }\r\n"
".wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n"
".menu { display: block; float: left; overflow: hidden; padding: 4px; max-width: 12em; white-space: nowrap; text-overflow: ellipsis ;}\r\n"
".listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
".tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
".content { float: left; font-size: 1em; margin-left: 2em; padding: 4px; max-width: 50em; overflow: auto; }\r\n"
".tunnel.established { color: #56B734; }\r\n"
".tunnel.expiring { color: #D3AE3F; }\r\n"
".tunnel.failed { color: #D33F3F; }\r\n"
".tunnel.building { color: #434343; }\r\n"
"caption { font-size: 1.5em; text-align: center; color: var(--main-link-color); }\r\n"
"table { display: table; border-collapse: collapse; text-align: center; }\r\n"
"table.extaddr { text-align: left; }\r\n"
"table.services { width: 100%; }\r\n"
"textarea { background-color: var(--main-bg-color); color: var(--main-text-color); word-break: break-all; }\r\n"
".streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis; }\r\n"
".slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n"
".slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
".disabled { color: #D33F3F; }\r\n"
".enabled { color: #56B734; }\r\n"
"button[type=submit] { background-color: transparent; color: var(--main-link-color); text-decoration: none;\r\n"
" padding: 5px; border: 1px solid var(--main-link-color); font-size: 14px; }\r\n"
"input, select, select option { background-color: var(--main-bg-color); color: var(--main-link-color); padding: 5px;\r\n"
" border: 1px solid var(--main-link-color); font-size: 14px; }\r\n"
"input:focus, select:focus, select option:focus { outline: none; }\r\n"
"input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; }\r\n"
"@media screen and (max-width: 1150px) { /* adaptive style */\r\n"
" .wrapper { max-width: 58em; }\r\n"
" .content { max-width: 40em; }\r\n"
"}\r\n"
"@media screen and (max-width: 980px) { body { font: 100%/1.2em sans-serif; padding: 1.2em 0 0 0; }\r\n"
" .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px; text-align: center; }\r\n"
" .menu a, .commands a { display: inline-block; padding: 4px; }\r\n"
" .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%; text-align: center; }\r\n"
" a, .slide label { display: block; }\r\n"
" .header { margin: unset; font-size: 1.5em; }\r\n"
" small { display: block; }\r\n"
" a.button { appearance: button; text-decoration: none; margin-top: 10px; padding: 6px; border: 2px solid var(--main-link-color);\r\n"
" border-radius: 5px; width: -webkit-fill-available; }\r\n"
" input, select { width: 35%; text-align: center; padding: 5px; border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 18px; }\r\n"
" table.extaddr { margin: auto; text-align: unset; }\r\n"
" textarea { width: -webkit-fill-available; height: auto; padding: 5px; border: 2px solid var(--main-link-color);\r\n"
" border-radius: 5px; font-size: 12px; }\r\n"
" button[type=submit] { padding: 5px 15px; background: transparent; border: 2px solid var(--main-link-color); cursor: pointer;\r\n"
" border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
"}\r\n"
"</style>\r\n";
// for external style sheet
std::string externalCSS;
} // http
} // i2p
#endif /* HTTP_SERVER_RESOURCES_H__ */

View File

@@ -1,7 +1,21 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifdef WITH_I2PC
#include <stdio.h>
#include <sstream>
#include <openssl/x509.h>
#include <openssl/pem.h>
// Use global placeholders from boost introduced when local_time.hpp is loaded
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/lexical_cast.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
@@ -44,10 +58,10 @@ namespace client
if (i2pcp_key.at(0) != '/')
i2pcp_key = i2p::fs::DataDirPath(i2pcp_key);
if (!i2p::fs::Exists (i2pcp_crt) || !i2p::fs::Exists (i2pcp_key)) {
LogPrint (eLogInfo, "I2PControl: creating new certificate for control connection");
LogPrint (eLogInfo, "I2PControl: Creating new certificate for control connection");
CreateCertificate (i2pcp_crt.c_str(), i2pcp_key.c_str());
} else {
LogPrint(eLogDebug, "I2PControl: using cert from ", i2pcp_crt);
LogPrint(eLogDebug, "I2PControl: Using cert from ", i2pcp_crt);
}
m_SSLContext.set_options (boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use);
m_SSLContext.use_certificate_file (i2pcp_crt, boost::asio::ssl::context::pem);
@@ -75,8 +89,7 @@ namespace client
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
&I2PControlService::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
@@ -93,9 +106,15 @@ namespace client
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
#ifdef WITH_SAM
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
#endif
#ifdef WITH_BOB
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
#endif
#ifdef WITH_I2CP
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
#endif
}
I2PControlService::~I2PControlService ()
@@ -138,7 +157,7 @@ namespace client
try {
m_Service.run ();
} catch (std::exception& ex) {
LogPrint (eLogError, "I2PControl: runtime exception: ", ex.what ());
LogPrint (eLogError, "I2PControl: Runtime exception: ", ex.what ());
}
}
}
@@ -156,10 +175,10 @@ namespace client
Accept ();
if (ecode) {
LogPrint (eLogError, "I2PControl: accept error: ", ecode.message ());
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
return;
}
LogPrint (eLogDebug, "I2PControl: new request from ", socket->lowest_layer ().remote_endpoint ());
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
Handshake (socket);
}
@@ -172,7 +191,7 @@ namespace client
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
{
if (ecode) {
LogPrint (eLogError, "I2PControl: handshake error: ", ecode.message ());
LogPrint (eLogError, "I2PControl: Handshake error: ", ecode.message ());
return;
}
//std::this_thread::sleep_for (std::chrono::milliseconds(5));
@@ -198,7 +217,7 @@ namespace client
{
if (ecode)
{
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
LogPrint (eLogError, "I2PControl: Read error: ", ecode.message ());
return;
}
else
@@ -221,7 +240,7 @@ namespace client
}
if (ss.eof ())
{
LogPrint (eLogError, "I2PControl: malformed request, HTTP header expected");
LogPrint (eLogError, "I2PControl: Malformed request, HTTP header expected");
return; // TODO:
}
std::streamoff rem = contentLength + ss.tellg () - bytes_transferred; // more bytes to read
@@ -246,7 +265,7 @@ namespace client
}
else
{
LogPrint (eLogWarning, "I2PControl: unknown method ", method);
LogPrint (eLogWarning, "I2PControl: Unknown method ", method);
response << "{\"id\":null,\"error\":";
response << "{\"code\":-32601,\"message\":\"Method not found\"},";
response << "\"jsonrpc\":\"2.0\"}";
@@ -255,7 +274,7 @@ namespace client
}
catch (std::exception& ex)
{
LogPrint (eLogError, "I2PControl: exception when handle request: ", ex.what ());
LogPrint (eLogError, "I2PControl: Exception when handle request: ", ex.what ());
std::ostringstream response;
response << "{\"id\":null,\"error\":";
response << "{\"code\":-32700,\"message\":\"" << ex.what () << "\"},";
@@ -264,7 +283,7 @@ namespace client
}
catch (...)
{
LogPrint (eLogError, "I2PControl: handle request unknown exception");
LogPrint (eLogError, "I2PControl: Handle request unknown exception");
}
}
}
@@ -274,11 +293,16 @@ namespace client
ss << "\"" << name << "\":" << value;
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes) const
{
ss << "\"" << name << "\":";
if (value.length () > 0)
ss << "\"" << value << "\"";
{
if (quotes)
ss << "\"" << value << "\"";
else
ss << value;
}
else
ss << "null";
}
@@ -325,12 +349,11 @@ namespace client
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf)
{
if (ecode) {
LogPrint (eLogError, "I2PControl: write error: ", ecode.message ());
LogPrint (eLogError, "I2PControl: Write error: ", ecode.message ());
}
}
// handlers
// handlers
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
int api = params.get<int> ("API");
@@ -355,8 +378,7 @@ namespace client
}
// I2PControl
// I2PControl
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto& it: params)
@@ -375,7 +397,7 @@ namespace client
void I2PControlService::PasswordHandler (const std::string& value)
{
LogPrint (eLogWarning, "I2PControl: new password=", value, ", to make it persistent you should update your config!");
LogPrint (eLogWarning, "I2PControl: New password=", value, ", to make it persistent you should update your config!");
m_Password = value;
m_Tokens.clear ();
}
@@ -391,8 +413,8 @@ namespace client
auto it1 = m_RouterInfoHandlers.find (it->first);
if (it1 != m_RouterInfoHandlers.end ())
{
if (!first) results << ",";
else first = false;
if (!first) results << ",";
else first = false;
(this->*(it1->second))(results);
}
else
@@ -402,7 +424,7 @@ namespace client
void I2PControlService::UptimeHandler (std::ostringstream& results)
{
InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000);
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL), false);
}
void I2PControlService::VersionHandler (std::ostringstream& results)
@@ -490,7 +512,7 @@ namespace client
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;
});
}
@@ -504,7 +526,7 @@ namespace client
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;
});
}
@@ -516,7 +538,7 @@ namespace client
i2p::data::netdb.Reseed ();
}
// network setting
// network setting
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
@@ -573,11 +595,11 @@ namespace client
// save cert
if ((f = fopen (crt_path, "wb")) != NULL) {
LogPrint (eLogInfo, "I2PControl: saving new cert to ", crt_path);
LogPrint (eLogInfo, "I2PControl: Saving new cert to ", crt_path);
PEM_write_X509 (f, x509);
fclose (f);
} else {
LogPrint (eLogError, "I2PControl: can't write cert: ", strerror(errno));
LogPrint (eLogError, "I2PControl: Can't write cert: ", strerror(errno));
}
// save key
@@ -586,18 +608,17 @@ namespace client
PEM_write_PrivateKey (f, pkey, NULL, NULL, 0, NULL, NULL);
fclose (f);
} else {
LogPrint (eLogError, "I2PControl: can't write key: ", strerror(errno));
LogPrint (eLogError, "I2PControl: Can't write key: ", strerror(errno));
}
X509_free (x509);
} else {
LogPrint (eLogError, "I2PControl: can't create RSA key for certificate");
LogPrint (eLogError, "I2PControl: Can't create RSA key for certificate");
}
EVP_PKEY_free (pkey);
}
// ClientServicesInfo
// ClientServicesInfo
void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
for (auto it = params.begin (); it != params.end (); it++)
@@ -703,6 +724,7 @@ namespace client
InsertParam (results, "SOCKS", pt);
}
#ifdef WITH_SAM
void I2PControlService::SAMInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
@@ -714,8 +736,8 @@ namespace client
for (auto& it: sam->GetSessions ())
{
boost::property_tree::ptree sam_session, sam_session_sockets;
auto& name = it.second->localDestination->GetNickname ();
auto& ident = it.second->localDestination->GetIdentHash();
auto& name = it.second->GetLocalDestination ()->GetNickname ();
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
@@ -738,7 +760,9 @@ namespace client
InsertParam (results, "SAM", pt);
}
#endif // WITH_SAM
#ifdef WITH_BOB
void I2PControlService::BOBInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
@@ -753,7 +777,9 @@ namespace client
InsertParam (results, "BOB", pt);
}
#endif // WITH_BOB
#ifdef WITH_I2CP
void I2PControlService::I2CPInfoHandler (std::ostringstream& results)
{
boost::property_tree::ptree pt;
@@ -768,5 +794,7 @@ namespace client
InsertParam (results, "I2CP", pt);
}
#endif // WITH_I2CP
}
}
#endif // WITH_I2PC

View File

@@ -1,11 +1,13 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifdef WITH_I2PC
#ifndef I2P_CONTROL_H__
#define I2P_CONTROL_H__
@@ -65,7 +67,7 @@ namespace client
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes = true) const;
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
// methods
@@ -114,9 +116,15 @@ namespace client
void I2PTunnelInfoHandler (std::ostringstream& results);
void HTTPProxyInfoHandler (std::ostringstream& results);
void SOCKSInfoHandler (std::ostringstream& results);
#ifdef WITH_SAM
void SAMInfoHandler (std::ostringstream& results);
#endif
#ifdef WITH_BOB
void BOBInfoHandler (std::ostringstream& results);
#endif
#ifdef WITH_I2CP
void I2CPInfoHandler (std::ostringstream& results);
#endif
private:
@@ -141,3 +149,4 @@ namespace client
}
#endif
#endif // WITH_I2PC

View File

@@ -29,7 +29,7 @@ namespace transport
{
if (m_IsRunning)
{
LogPrint(eLogInfo, "UPnP: stopping");
LogPrint(eLogInfo, "UPnP: Stopping");
m_IsRunning = false;
m_Timer.cancel ();
m_Service.stop ();
@@ -46,7 +46,7 @@ namespace transport
void UPnP::Start()
{
m_IsRunning = true;
LogPrint(eLogInfo, "UPnP: starting");
LogPrint(eLogInfo, "UPnP: Starting");
m_Service.post (std::bind (&UPnP::Discover, this));
std::unique_lock<std::mutex> l(m_StartedMutex);
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
@@ -72,7 +72,7 @@ namespace transport
}
catch (std::exception& ex)
{
LogPrint (eLogError, "UPnP: runtime exception: ", ex.what ());
LogPrint (eLogError, "UPnP: Runtime exception: ", ex.what ());
PortMapping ();
}
}
@@ -106,7 +106,7 @@ namespace transport
if (isError)
{
LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err);
LogPrint (eLogError, "UPnP: Unable to discover Internet Gateway Devices: error ", err);
return;
}
@@ -117,22 +117,22 @@ namespace transport
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
if(err != UPNPCOMMAND_SUCCESS)
{
LogPrint (eLogError, "UPnP: unable to get external address: error ", err);
LogPrint (eLogError, "UPnP: Unable to get external address: error ", err);
return;
}
else
{
LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL);
LogPrint (eLogError, "UPnP: Found Internet Gateway Device ", m_upnpUrls.controlURL);
if (!m_externalIPAddress[0])
{
LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address");
LogPrint (eLogError, "UPnP: Found Internet Gateway Device doesn't know our external address");
return;
}
}
}
else
{
LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err);
LogPrint (eLogError, "UPnP: Unable to find valid Internet Gateway Device: error ", err);
return;
}
@@ -183,7 +183,7 @@ namespace transport
err = CheckMapping (strPort.c_str (), strType.c_str ());
if (err != UPNPCOMMAND_SUCCESS) // if mapping not found
{
LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err);
LogPrint (eLogDebug, "UPnP: Port ", strPort, " is possibly not forwarded: return code ", err);
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL);
@@ -192,18 +192,18 @@ namespace transport
#endif
if (err != UPNPCOMMAND_SUCCESS)
{
LogPrint (eLogError, "UPnP: port forwarding to ", m_NetworkAddr, ":", strPort, " failed: return code ", err);
LogPrint (eLogError, "UPnP: Port forwarding to ", m_NetworkAddr, ":", strPort, " failed: return code ", err);
return;
}
else
{
LogPrint (eLogInfo, "UPnP: port successfully forwarded (", m_externalIPAddress ,":", strPort, " type ", strType, " -> ", m_NetworkAddr ,":", strPort ,")");
LogPrint (eLogInfo, "UPnP: Port successfully forwarded (", m_externalIPAddress ,":", strPort, " type ", strType, " -> ", m_NetworkAddr ,":", strPort ,")");
return;
}
}
else
{
LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device");
LogPrint (eLogDebug, "UPnP: External forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device");
return;
}
}
@@ -225,7 +225,7 @@ namespace transport
}
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
int err = UPNPCOMMAND_SUCCESS;
err = CheckMapping (strPort.c_str (), strType.c_str ());
if (err == UPNPCOMMAND_SUCCESS)
{

View File

@@ -72,7 +72,8 @@ namespace i2p
if (pid < 0) // error
{
LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not fork: ", strerror(errno));
std::cerr << "i2pd: Could not fork: " << strerror(errno) << std::endl;
return false;
}
@@ -81,13 +82,15 @@ namespace i2p
int sid = setsid();
if (sid < 0)
{
LogPrint(eLogError, "Daemon: could not create process group.");
LogPrint(eLogError, "Daemon: Could not create process group.");
std::cerr << "i2pd: Could not create process group." << std::endl;
return false;
}
std::string d = i2p::fs::GetDataDir();
if (chdir(d.c_str()) != 0)
{
LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not chdir: ", strerror(errno));
std::cerr << "i2pd: Could not chdir: " << strerror(errno) << std::endl;
return false;
}
@@ -102,14 +105,14 @@ namespace i2p
uint16_t nfiles; i2p::config::GetOption("limits.openfiles", nfiles);
getrlimit(RLIMIT_NOFILE, &limit);
if (nfiles == 0) {
LogPrint(eLogInfo, "Daemon: using system limit in ", limit.rlim_cur, " max open files");
LogPrint(eLogInfo, "Daemon: Using system limit in ", limit.rlim_cur, " max open files");
} else if (nfiles <= limit.rlim_max) {
limit.rlim_cur = nfiles;
if (setrlimit(RLIMIT_NOFILE, &limit) == 0) {
LogPrint(eLogInfo, "Daemon: set max number of open files to ",
LogPrint(eLogInfo, "Daemon: Set max number of open files to ",
nfiles, " (system limit is ", limit.rlim_max, ")");
} else {
LogPrint(eLogError, "Daemon: can't set max number of open files: ", strerror(errno));
LogPrint(eLogError, "Daemon: Can't set max number of open files: ", strerror(errno));
}
} else {
LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max);
@@ -122,11 +125,11 @@ namespace i2p
if (cfsize <= limit.rlim_max) {
limit.rlim_cur = cfsize;
if (setrlimit(RLIMIT_CORE, &limit) != 0) {
LogPrint(eLogError, "Daemon: can't set max size of coredump: ", strerror(errno));
LogPrint(eLogError, "Daemon: Can't set max size of coredump: ", strerror(errno));
} else if (cfsize == 0) {
LogPrint(eLogInfo, "Daemon: coredumps disabled");
} else {
LogPrint(eLogInfo, "Daemon: set max size of core files to ", cfsize / 1024, "Kb");
LogPrint(eLogInfo, "Daemon: Set max size of core files to ", cfsize / 1024, "Kb");
}
} else {
LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max);
@@ -143,14 +146,16 @@ namespace i2p
pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
if (pidFH < 0)
{
LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not create pid file " << pidfile << ": " << strerror(errno) << std::endl;
return false;
}
#ifndef ANDROID
if (lockf(pidFH, F_TLOCK, 0) != 0)
{
LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl;
return false;
}
#endif
@@ -159,7 +164,8 @@ namespace i2p
ftruncate(pidFH, 0);
if (write(pidFH, pid, strlen(pid)) < 0)
{
LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno));
LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl;
return false;
}
}

24
debian/changelog vendored
View File

@@ -1,3 +1,27 @@
i2pd (2.41.0-1) unstable; urgency=medium
* updated to version 2.41.0/0.9.53
-- r4sas <r4sas@i2pmail.org> Sun, 20 Feb 2022 13:00:00 +0000
i2pd (2.40.0-1) unstable; urgency=medium
* updated to version 2.40.0/0.9.52
-- orignal <orignal@i2pmail.org> Mon, 29 Nov 2021 16:00:00 +0000
i2pd (2.39.0-1) unstable; urgency=medium
* updated to version 2.39.0/0.9.51
-- orignal <orignal@i2pmail.org> Mon, 23 Aug 2021 16:00:00 +0000
i2pd (2.38.0-1) unstable; urgency=medium
* updated to version 2.38.0/0.9.50
-- orignal <orignal@i2pmail.org> Mon, 17 May 2021 16:00:00 +0000
i2pd (2.37.0-1) unstable; urgency=medium
* updated to version 2.37.0

2
debian/compat vendored
View File

@@ -1 +1 @@
10
9

18
debian/control vendored
View File

@@ -3,30 +3,16 @@ Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.6
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: adduser
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: 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.
.
This package contains the full-featured C++ implementation of I2P router.
Package: i2pd-dbg
Architecture: any
Priority: extra
Section: debug
Depends: i2pd (= ${binary:Version}), ${misc:Depends}
Description: i2pd debugging symbols
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.
.
This package contains symbols required for debugging.

29
debian/copyright vendored
View File

@@ -6,13 +6,6 @@ Files: *
Copyright: 2013-2020 PurpleI2P
License: BSD-3-clause
Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl
qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java
Copyright: 2011-2013 BogDan Vatra <bogdan@kde.org>
License: BSD-2-Clause
Files: debian/*
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
2014-2016 hagen <hagen@i2pmail.org>
@@ -49,28 +42,6 @@ License: BSD-3-clause
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

4
debian/docs vendored
View File

@@ -1,5 +1 @@
README.md
contrib/i2pd.conf
contrib/subscriptions.txt
contrib/tunnels.conf
contrib/tunnels.d

2
debian/i2pd.dirs vendored
View File

@@ -1,2 +0,0 @@
etc/i2pd
var/lib/i2pd

2
debian/i2pd.install vendored
View File

@@ -1,5 +1,5 @@
i2pd usr/sbin/
contrib/i2pd.conf etc/i2pd/
contrib/i2pd.conf etc/i2pd/
contrib/tunnels.conf etc/i2pd/
contrib/subscriptions.txt etc/i2pd/
contrib/certificates/ usr/share/i2pd/

View File

@@ -2,16 +2,16 @@ Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2021-01-16
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -15,7 +15,7 @@ include filelist.mk
USE_AESNI := yes
USE_STATIC := no
USE_MESHNET := no
-USE_UPNP := no
+USE_UPNP := yes
DEBUG := yes
@@ -31,7 +31,7 @@ include filelist.mk
ifeq ($(DEBUG),yes)
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
-USE_UPNP := $(or $(USE_UPNP),no)
+USE_UPNP := $(or $(USE_UPNP),yes)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string

3
debian/postinst vendored
View File

@@ -12,7 +12,6 @@ case "$1" in
# Create user and group as a system user.
if getent passwd $I2PDUSER > /dev/null 2>&1; then
groupadd -f $I2PDUSER || true
usermod -s "/bin/false" -e 1 $I2PDUSER > /dev/null || true
else
adduser --system --quiet --group --home $I2PDHOME $I2PDUSER
fi
@@ -23,7 +22,7 @@ case "$1" in
chmod 640 $LOGFILE
chown -f ${I2PDUSER}:adm $LOGFILE
mkdir -p -m0750 $I2PDHOME
chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
chown -f -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
;;
abort-upgrade|abort-remove|abort-deconfigure)
echo "Aborting upgrade"

26
debian/rules vendored
View File

@@ -1,22 +1,18 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow
#DPKG_EXPORT_BUILDFLAGS = 1
#include /usr/share/dpkg/buildflags.mk
#CXXFLAGS+=$(CPPFLAGS)
#PREFIX=/usr
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
include /usr/share/dpkg/architecture.mk
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic -O3
export DEB_LDFLAGS_MAINT_APPEND =
%:
dh $@ --parallel
# dh_apparmor --profile-name=usr.sbin.i2pd -pi2pd
override_dh_strip:
dh_strip --dbg-package=i2pd-dbg
## uncomment this if you have "missing info" problem when building package
#override_dh_shlibdeps:
# dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
override_dh_auto_install:

6
debian/watch vendored
View File

@@ -1,3 +1,3 @@
version=3
opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/i2pd-$1\.tar\.gz/ \
https://github.com/PurpleI2P/i2pd/tags .*/v?(\d\S*)\.tar\.gz
version=4 opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \
https://github.com/PurpleI2P/i2pd/tags \
(?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate

View File

@@ -19,4 +19,8 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
#DAEMON_SRC = \
# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)

81
i18n/Afrikaans.cpp Normal file
View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Afrikaans localization file
namespace i2p
{
namespace i18n
{
namespace afrikaans // language namespace
{
// language name in lowercase
static std::string language = "afrikaans";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"failed", "Het misluk"},
{"unknown", "onbekend"},
{"Tunnels", "Tonnels"},
{"I2P tunnels", "I2P tonnels"},
{"SAM sessions", "SAM sessies"},
{"OK", "LEKKER"},
{"Testing", "Besig om te toets"},
{"Firewalled", "Vuurmuur'd"},
{"Unknown", "Onbekend"},
{"Error", "Fout"},
{"Offline", "Aflyn"},
{"Uptime", "Optyd"},
{"Network status", "Netwerk status"},
{"Network status v6", "Netwerk status v6"},
{"Family", "Familie"},
{"Received", "Ontvang"},
{"Sent", "Gestuur"},
{"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."},
{"Router Ident", "Router Ident"},
{"Router Family", "Router Familie"},
{"Enabled", "Geaktiveer"},
{"Disabled", "Gedeaktiveer"},
{"Change", "Verander"},
{"Change language", "Verander taal"},
{"Description", "Beskrywing"},
{"Submit", "Stuur"},
{"Proxy error", "Proxy-fout"},
{"Host", "Gasheer"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"dag", "dae"}},
{"hours", {"uur", "ure"}},
{"minutes", {"minuut", "minute"}},
{"seconds", {"seconde", "sekondes"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

215
i18n/Armenian.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Armenian localization file
namespace i2p
{
namespace i18n
{
namespace armenian // language namespace
{
// language name in lowercase
static std::string language = "armenian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"KiB", "ԿիԲ"},
{"MiB", "ՄիԲ"},
{"GiB", "ԳիԲ"},
{"building", "կառուցվում է"},
{"failed", "Անհաջող"},
{"expiring", "Լրանում է"},
{"established", "կարգավոյված է"},
{"unknown", "անհայտ"},
{"exploratory", "հետազոտոկան"},
{"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"},
{"Main page", "Գլխավոր էջ"},
{"Router commands", "Երթուղիչի հրահանգներ"},
{"Local Destinations", "Տեղական վերջնակետերը"},
{"LeaseSets", "ԼիզՍեթեր"},
{"Tunnels", "Թունելներ"},
{"Transit Tunnels", "Տարանցիկ թունելներ"},
{"Transports", "Տրանսպորտ"},
{"I2P tunnels", "I2P թունելներ"},
{"SAM sessions", "SAM նստաշրջաններ"},
{"ERROR", "ՍԽԱԼ"},
{"OK", "ԼԱՎ"},
{"Testing", "Փորձարկում"},
{"Firewalled", "Արգելափակված է դրսից"},
{"Unknown", "Անհայտ"},
{"Proxy", "Պրոկսի"},
{"Mesh", "MESH-ցանց"},
{"Error", "Սխալ"},
{"Clock skew", "Ոչ ճշգրիտ ժամանակ"},
{"Offline", "Օֆլայն"},
{"Symmetric NAT", "Սիմետրիկ NAT"},
{"Uptime", "Առկայություն"},
{"Network status", "Ցանցի կարգավիճակ"},
{"Network status v6", "Ցանցի կարգավիճակ v6"},
{"Stopping in", "Դադարում"},
{"Family", "Խմբատեսակ"},
{"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"},
{"Received", "Ստացվել է"},
{"KiB/s", "ԿիԲ/վ"},
{"Sent", "Ուղարկվել է"},
{"Transit", "Տարանցում"},
{"Data path", "Տվյալների ուղին"},
{"Hidden content. Press on text to see.", "Թաքցված բովանդակություն: Տեսնելու համար սեղմեկ տեքստին:"},
{"Router Ident", "Երթուղիչի նույնականացուցիչ"},
{"Router Family", "Երթուղիչի խումբը"},
{"Router Caps", "Երթուղիչի հատկություններ"},
{"Version", "Տարբերակ"},
{"Our external address", "Մեր արտաքին հասցեն"},
{"supported", "համատեղելի է"},
{"Routers", "Երթուղիչներ"},
{"Floodfills", "Floodfills-ներ"},
{"Client Tunnels", "Oգտատիրական թունելներ"},
{"Services", "Ծառայություններ"},
{"Enabled", "Միացված է"},
{"Disabled", "Անջատված է"},
{"Encrypted B33 address", "Գաղտնագրված B33 հասցեներ"},
{"Address registration line", "Հասցեի գրանցման տող"},
{"Domain", "Տիրույթ"},
{"Generate", "Գեներացնել"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը"},
{"Address", "Հասցե"},
{"Type", "Տեսակը"},
{"EncType", "Գաղտնագրի տեսակը"},
{"Inbound tunnels", "Մուտքային թունելներ"},
{"ms", "մլվ"},
{"Outbound tunnels", "Ելքային թունելներ"},
{"Tags", "Թեգեր"},
{"Incoming", "Մուտքային"},
{"Outgoing", "ելքային"},
{"Destination", "Նշանակման վայր"},
{"Amount", "Քանակ"},
{"Incoming Tags", "Մուտքային պիտակներ"},
{"Tags sessions", "Նստաշրջանի պիտակներ"},
{"Status", "Կարգավիճակ"},
{"Local Destination", "Տեղական նշանակման կետ"},
{"Streams", "Հոսքեր"},
{"Close stream", "Փակել հոսքը"},
{"I2CP session not found", "I2CP նստաշրջանը գոյություն չունի"},
{"I2CP is not enabled", "I2CP միացված է"},
{"Invalid", "Անվավեր"},
{"Store type", "Պահեստավորման տեսակը"},
{"Expires", "Սպառվում է"},
{"Non Expired Leases", "Չսպառված Lease-եր"},
{"Gateway", "Դարպաս"},
{"TunnelID", "Թունելի ID"},
{"EndDate", "Ավարտ"},
{"not floodfill", "ոչ floodfill-ներ"},
{"Queue size", "Հերթի չափսը"},
{"Run peer test", "Գործարկել փորձարկումը"},
{"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"},
{"Accept transit tunnels", "Ընդունել տարանցիկ թունելներ"},
{"Cancel graceful shutdown", "Չեղարկել սահուն անջատումը"},
{"Start graceful shutdown", "Սկսել սահուն անջատումը"},
{"Force shutdown", "Հարկադիր անջատում"},
{"Reload external CSS styles", "Վերաբեռնեք CSS ոճաթերթը"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b> Նշում․ </b> այստեղ կատարված ցանկացած գործողություն մշտական ​​չէ և չի փոխում ձեր կազմաձևման ֆայլերը։"},
{"Logging level", "Գրառման աստիճանը"},
{"Transit tunnels limit", "Տարանցիկ թունելների սահմանափակում"},
{"Change", "Փոփոխել"},
{"Change language", "Փոփոխել լեզուն"},
{"no transit tunnels currently built", "ընթացիկ կառուցված տարանցիկ թունելներ գոյություն չունեն"},
{"SAM disabled", "SAM-ն անջատված է"},
{"no sessions currently running", "ներկայումս գործող նստաշրջաններ գոյություն չունեն"},
{"SAM session not found", "SAM նստաշրջան գոյություն չունի"},
{"SAM Session", "SAM նստաշրջան"},
{"Server Tunnels", "Սերվերային թունելներ"},
{"Client Forwards", "Օգտատիրական փոխանցումներ"},
{"Server Forwards", "Սերվերային փոխանցումներ"},
{"Unknown page", "Անհայտ էջ"},
{"Invalid token", "Սխալ տոկեն"},
{"SUCCESS", "ՀԱՋՈՂՎԱԾ"},
{"Stream closed", "Հոսքն անջատված է"},
{"Stream not found or already was closed", "Հոսքը գոյություն չունի կամ արդեն ավարտված է"},
{"Destination not found", "Հասցեի վայրը չի գտնվել"},
{"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"},
{"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"},
{"You will be redirected in 5 seconds", "Դուք կտեղափոխվեք 5 վայրկյանից"},
{"Transit tunnels count must not exceed 65535", "Տարանցիկ թունելների քանակը չպետք է գերազանցի 65535-ը"},
{"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"},
{"Register at reg.i2p", "Գրանցել reg.i2p-ում"},
{"Description", "Նկարագրություն"},
{"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"},
{"Submit", "Ուղարկվել"},
{"Domain can't end with .b32.i2p", "Տիրույթը չպետք է վերջանա .b32.i2p-ով"},
{"Domain must end with .i2p", "Տիրույթը պետք է վերջանա .i2p-ով"},
{"Such destination is not found", "Այդիպսի հասցե գոյություն չունի"},
{"Unknown command", "Անհայտ հրահանգ"},
{"Command accepted", "Հրարահանգն ընդունված է"},
{"Proxy error", "Պրոկսի սխալ"},
{"Proxy info", "Պրոկսի տեղեկություն"},
{"Proxy error: Host not found", "Պրոկսի սխալ՝ նման հոսթ գոյություն չունի"},
{"Remote host not found in router's addressbook", "Դեպի հոսթ կատարված հարցումը գոյություն չունի երթուղիչի հասցեագրքում"},
{"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"},
{"Invalid request", "Սխալ հարցում"},
{"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"},
{"addresshelper is not supported", "addresshelper-ը համատեղելի չէ"},
{"Host", "Հոսթ"},
{"added to router's addressbook from helper", "Ավելացված է երթուղիչի հասցեագրքում helper-ի միջոցով"},
{"Click here to proceed:", "Շարունակելու համար սեղմեք այստեղ"},
{"Continue", "Շարունակել"},
{"Addresshelper found", "addresshelper-ը գնտված է"},
{"already in router's addressbook", "արդեն առկա է երթուղիչի հասցեագրքում"},
{"Click here to update record:", "Սեղմեկ այստեղ որպեսզի թարվացնեք գրառումը"},
{"invalid request uri", "Սխալ ձևավորված URI հարցում"},
{"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"},
{"Outproxy failure", "Սխալ արտաքին պրոքսի"},
{"bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
{"not inside I2P network, but outproxy is not enabled", "Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
{"unknown outproxy url", "արտաքին պրոքսիի անհայտ URL"},
{"cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
{"hostname too long", "Հոսթի անունը չափազանց երկար է"},
{"cannot connect to upstream socks proxy", "չհաջողվեց միանալ վերադաս socks պրոկսիին"},
{"Cannot negotiate with socks proxy", "Չհաջողվեց պայմանավորվել վերադաս socks պրոկսիի հետ"},
{"CONNECT error", "Սխալ CONNECT հարցում"},
{"Failed to Connect", "Միանալ չhաջողվեց"},
{"socks proxy error", "Սխալ SOCKS պրոկսի"},
{"failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
{"No Reply From socks proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
{"cannot connect", "Հնարավոր չե միանալ"},
{"http out proxy not implemented", "Արտաքին http պրոկսին դեռ իրականացված չէ"},
{"cannot connect to upstream http proxy", "Չհաջողվեց միանալ վերադաս http պրոկսի սերվերին"},
{"Host is down", "Հոսթն անհասանելի է"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"օր", "օր"}},
{"hours", {"ժամ", "ժամ"}},
{"minutes", {"րոպե", "րոպե"}},
{"seconds", {"վարկյան", "վարկյան"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

50
i18n/English.cpp Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// English localization file
// This is an example translation file without strings in it.
namespace i2p
{
namespace i18n
{
namespace english // language namespace
{
// language name in lowercase
static std::string language = "english";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

215
i18n/German.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// German localization file
namespace i2p
{
namespace i18n
{
namespace german // language namespace
{
// language name in lowercase
static std::string language = "german";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"building", "In Bau"},
{"failed", "fehlgeschlagen"},
{"expiring", "läuft ab in"},
{"established", "hergestellt"},
{"unknown", "Unbekannt"},
{"exploratory", "erforschende"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> Webkonsole"},
{"Main page", "Startseite"},
{"Router commands", "Router Befehle"},
{"Local Destinations", "Lokale Destination"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Tunnel"},
{"Transit Tunnels", "Transittunnel"},
{"Transports", "Transporte"},
{"I2P tunnels", "I2P Tunnel"},
{"SAM sessions", "SAM Sitzungen"},
{"ERROR", "FEHLER"},
{"OK", "OK"},
{"Testing", "Testen"},
{"Firewalled", "Hinter eine Firewall"},
{"Unknown", "Unbekannt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Error", "Fehler"},
{"Clock skew", "Zeitabweichung"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symmetrisches NAT"},
{"Uptime", "Laufzeit"},
{"Network status", "Netzwerkstatus"},
{"Network status v6", "Netzwerkstatus v6"},
{"Stopping in", "Stoppt in"},
{"Family", "Familie"},
{"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"},
{"Received", "Eingegangen"},
{"KiB/s", "KiB/s"},
{"Sent", "Gesendet"},
{"Transit", "Transit"},
{"Data path", "Datenpfad"},
{"Hidden content. Press on text to see.", "Versteckter Inhalt. Klicke hier, um ihn zu sehen."},
{"Router Ident", "Routeridentität"},
{"Router Family", "Routerfamilie"},
{"Router Caps", "Routerattribute"},
{"Version", "Version"},
{"Our external address", "Unsere externe Adresse"},
{"supported", "unterstützt"},
{"Routers", "Router"},
{"Floodfills", "Floodfills"},
{"Client Tunnels", "Klienttunnel"},
{"Services", "Services"},
{"Enabled", "Aktiviert"},
{"Disabled", "Deaktiviert"},
{"Encrypted B33 address", "Verschlüsselte B33 Adresse"},
{"Address registration line", "Adresseregistrierungszeile"},
{"Domain", "Domain"},
{"Generate", "Generieren"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Hinweis:</b> Der resultierende String kann nur für die Registrierung einer 2LD Domain (beispiel.i2p) benutzt werden. Für die Registrierung von Subdomains kann i2pd-tools verwendet werden."},
{"Address", "Adresse"},
{"Type", "Typ"},
{"EncType", "Verschlüsselungstyp"},
{"Inbound tunnels", "Eingehende Tunnel"},
{"ms", "ms"},
{"Outbound tunnels", "Ausgehende Tunnel"},
{"Tags", "Tags"},
{"Incoming", "Eingehend"},
{"Outgoing", "Ausgehend"},
{"Destination", "Destination"},
{"Amount", "Anzahl"},
{"Incoming Tags", "Eingehende Tags"},
{"Tags sessions", "Tags Sitzungen"},
{"Status", "Status"},
{"Local Destination", "Lokale Destination"},
{"Streams", "Streams"},
{"Close stream", "Stream schließen"},
{"I2CP session not found", "I2CP Sitzung nicht gefunden"},
{"I2CP is not enabled", "I2CP ist nicht aktiviert"},
{"Invalid", "Ungültig"},
{"Store type", "Speichertyp"},
{"Expires", "Ablaufdatum"},
{"Non Expired Leases", "Nicht abgelaufene Leases"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Enddatum"},
{"not floodfill", "kein Floodfill"},
{"Queue size", "Warteschlangengröße"},
{"Run peer test", "Peer-Test ausführen"},
{"Decline transit tunnels", "Transittunnel ablehnen"},
{"Accept transit tunnels", "Transittunnel akzeptieren"},
{"Cancel graceful shutdown", "Beende das kontrollierte herunterfahren"},
{"Start graceful shutdown", "Starte das kontrollierte Herunterfahren"},
{"Force shutdown", "Herunterfahren erzwingen"},
{"Reload external CSS styles", "Lade externe CSS-Styles neu"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Hinweis:</b> Alle hier durchgeführten Aktionen sind nicht dauerhaft und ändern die Konfigurationsdateien nicht."},
{"Logging level", "Protokollierungslevel"},
{"Transit tunnels limit", "Limit für Transittunnel"},
{"Change", "Verändern"},
{"Change language", "Sprache ändern"},
{"no transit tunnels currently built", "derzeit keine Transittunnel aufgebaut"},
{"SAM disabled", "SAM deaktiviert"},
{"no sessions currently running", "Derzeit keine laufenden Sitzungen"},
{"SAM session not found", "SAM Sitzung nicht gefunden"},
{"SAM Session", "SAM Sitzung"},
{"Server Tunnels", "Servertunnel"},
{"Client Forwards", "Klient-Weiterleitungen"},
{"Server Forwards", "Server-Weiterleitungen"},
{"Unknown page", "Unbekannte Seite"},
{"Invalid token", "Ungültiger Token"},
{"SUCCESS", "ERFOLGREICH"},
{"Stream closed", "Stream geschlossen"},
{"Stream not found or already was closed", "Stream nicht gefunden oder bereits geschlossen"},
{"Destination not found", "Destination nicht gefunden"},
{"StreamID can't be null", "StreamID kann nicht null sein"},
{"Return to destination page", "Zurück zur Destination-Seite"},
{"You will be redirected in 5 seconds", "Du wirst in 5 Sekunden weitergeleitet"},
{"Transit tunnels count must not exceed 65535", "Es darf maximal 65535 Transittunnel geben"},
{"Back to commands list", "Zurück zur Kommandoliste"},
{"Register at reg.i2p", "Auf reg.i2p registrieren"},
{"Description", "Beschreibung"},
{"A bit information about service on domain", "Ein bisschen Informationen über den Service auf der Domain"},
{"Submit", "Einreichen"},
{"Domain can't end with .b32.i2p", "Domain kann nicht mit .b32.i2p enden"},
{"Domain must end with .i2p", "Domain muss mit .i2p enden"},
{"Such destination is not found", "Eine solche Destination konnte nicht gefunden werden"},
{"Unknown command", "Unbekannter Befehl"},
{"Command accepted", "Befehl akzeptiert"},
{"Proxy error", "Proxy-Fehler"},
{"Proxy info", "Proxy-Info"},
{"Proxy error: Host not found", "Proxy-Fehler: Host nicht gefunden"},
{"Remote host not found in router's addressbook", "Remote-Host nicht im Router Adressbuch gefunden"},
{"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einen der Jump-Services unten finden"},
{"Invalid request", "Ungültige Anfrage"},
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht interpretieren"},
{"addresshelper is not supported", "addresshelper wird nicht unterstützt"},
{"Host", "Host"},
{"added to router's addressbook from helper", "vom Helfer zum Router Adressbuch hinzugefügt"},
{"Click here to proceed:", "Klicke hier um fortzufahren:"},
{"Continue", "Fortsetzen"},
{"Addresshelper found", "Adresshelfer gefunden"},
{"already in router's addressbook", "bereits im Adressbuch des Routers"},
{"Click here to update record:", "Klicke hier, um den Eintrag zu aktualisieren:"},
{"invalid request uri", "ungültige Anfrage-URI"},
{"Can't detect destination host from request", "Kann Anhand der Anfrage den Destination-Host nicht erkennen"},
{"Outproxy failure", "Outproxy-Fehler"},
{"bad outproxy settings", "ungültige Outproxy-Einstellungen"},
{"not inside I2P network, but outproxy is not enabled", "nicht innerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
{"unknown outproxy url", "unbekannte Outproxy-URL"},
{"cannot resolve upstream proxy", "kann den Upstream-Proxy nicht auflösen"},
{"hostname too long", "Hostname zu lang"},
{"cannot connect to upstream socks proxy", "Kann keine Verbindung zum Upstream-Socks-Proxy herstellen"},
{"Cannot negotiate with socks proxy", "Kann nicht mit Socks-Proxy verhandeln"},
{"CONNECT error", "CONNECT-Fehler"},
{"Failed to Connect", "Verbindung konnte nicht hergestellt werden"},
{"socks proxy error", "Socks-Proxy-Fehler"},
{"failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
{"No Reply From socks proxy", "Keine Antwort vom Socks-Proxy"},
{"cannot connect", "kann nicht verbinden"},
{"http out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
{"cannot connect to upstream http proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
{"Host is down", "Host ist offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbaunen, vielleicht ist es offline. Versuche es später noch einmal."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"Tag", "Tage"}},
{"hours", {"Stunde", "Stunden"}},
{"minutes", {"Minute", "Minuten"}},
{"seconds", {"Sekunde", "Sekunden"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

45
i18n/I18N.h Normal file
View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef __I18N_H__
#define __I18N_H__
#include "ClientContext.h"
namespace i2p
{
namespace i18n
{
inline void SetLanguage(const std::string &lang)
{
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
else
i2p::client::context.SetLanguage (it->second.LocaleFunc());
}
inline std::string translate (const std::string& arg)
{
return i2p::client::context.GetLanguage ()->GetString (arg);
}
inline std::string translate (const std::string& arg, const std::string& arg2, const int& n)
{
return i2p::client::context.GetLanguage ()->GetPlural (arg, arg2, n);
}
} // i18n
} // i2p
template<typename... TArgs>
std::string tr (TArgs&&... args)
{
return i2p::i18n::translate(std::forward<TArgs>(args)...);
}
#endif // __I18N_H__

101
i18n/I18N_langs.h Normal file
View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef __I18N_LANGS_H__
#define __I18N_LANGS_H__
namespace i2p
{
namespace i18n
{
class Locale
{
public:
Locale (
const std::string& language,
const std::map<std::string, std::string>& strings,
const std::map<std::string, std::vector<std::string>>& plurals,
std::function<int(int)> formula
): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
// Get activated language name for webconsole
std::string GetLanguage() const
{
return m_Language;
}
std::string GetString (const std::string& arg) const
{
const auto it = m_Strings.find(arg);
if (it == m_Strings.end())
{
return arg;
}
else
{
return it->second;
}
}
std::string GetPlural (const std::string& arg, const std::string& arg2, const int& n) const
{
const auto it = m_Plurals.find(arg2);
if (it == m_Plurals.end()) // not found, fallback to english
{
return n == 1 ? arg : arg2;
}
else
{
int form = m_Formula(n);
return it->second[form];
}
}
private:
const std::string m_Language;
const std::map<std::string, std::string> m_Strings;
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
struct langData
{
std::string LocaleName; // localized name
std::string ShortCode; // short language code, like "en"
std::function<std::shared_ptr<const i2p::i18n::Locale> (void)> LocaleFunc;
};
// Add localization here with language name as namespace
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
/**
* That map contains international language name lower-case, name in it's language and it's code
*/
static std::map<std::string, langData> languages
{
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} },
};
} // i18n
} // i2p
#endif // __I18N_LANGS_H__

215
i18n/Russian.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Russian localization file
namespace i2p
{
namespace i18n
{
namespace russian // language namespace
{
// language name in lowercase
static std::string language = "russian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2;
}
static std::map<std::string, std::string> strings
{
{"KiB", "КиБ"},
{"MiB", "МиБ"},
{"GiB", "ГиБ"},
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"unknown", "неизвестно"},
{"exploratory", "исследовательский"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
{"Local Destinations", "Локальные назначения"},
{"LeaseSets", "Лизсеты"},
{"Tunnels", "Туннели"},
{"Transit Tunnels", "Транзитные туннели"},
{"Transports", "Транспорты"},
{"I2P tunnels", "I2P туннели"},
{"SAM sessions", "SAM сессии"},
{"ERROR", "ОШИБКА"},
{"OK", "OK"},
{"Testing", "Тестирование"},
{"Firewalled", "Заблокировано извне"},
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
{"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
{"Received", "Получено"},
{"KiB/s", "КиБ/с"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"Data path", "Путь к данным"},
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
{"Router Ident", "Идентификатор роутера"},
{"Router Family", "Семейство роутера"},
{"Router Caps", "Флаги роутера"},
{"Version", "Версия"},
{"Our external address", "Наш внешний адрес"},
{"supported", "поддерживается"},
{"Routers", "Роутеры"},
{"Floodfills", "Флудфилы"},
{"Client Tunnels", "Клиентские туннели"},
{"Services", "Сервисы"},
{"Enabled", "Включено"},
{"Disabled", "Выключено"},
{"Encrypted B33 address", "Шифрованные B33 адреса"},
{"Address registration line", "Строка регистрации адреса"},
{"Domain", "Домен"},
{"Generate", "Сгенерировать"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Примечание:</b> полученная строка может быть использована только для регистрации доменов второго уровня (example.i2p). Для регистрации поддоменов используйте i2pd-tools."},
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Inbound tunnels", "Входящие туннели"},
{"ms", "мс"},
{"Outbound tunnels", "Исходящие туннели"},
{"Tags", "Теги"},
{"Incoming", "Входящие"},
{"Outgoing", "Исходящие"},
{"Destination", "Назначение"},
{"Amount", "Количество"},
{"Incoming Tags", "Входящие теги"},
{"Tags sessions", "Сессии тегов"},
{"Status", "Статус"},
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
{"Invalid", "Некорректный"},
{"Store type", "Тип хранилища"},
{"Expires", "Истекает"},
{"Non Expired Leases", "Не истекшие Lease-ы"},
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
{"not floodfill", "не флудфил"},
{"Queue size", "Размер очереди"},
{"Run peer test", "Запустить тестирование"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
{"Start graceful shutdown", "Запустить плавную остановку"},
{"Force shutdown", "Принудительная остановка"},
{"Reload external CSS styles", "Перезагрузить внешние CSS стили"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
{"Logging level", "Уровень логирования"},
{"Transit tunnels limit", "Лимит транзитных туннелей"},
{"Change", "Изменить"},
{"Change language", "Изменение языка"},
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
{"SAM disabled", "SAM выключен"},
{"no sessions currently running", "нет запущенных сессий"},
{"SAM session not found", "SAM сессия не найдена"},
{"SAM Session", "SAM сессия"},
{"Server Tunnels", "Серверные туннели"},
{"Client Forwards", "Клиентские перенаправления"},
{"Server Forwards", "Серверные перенаправления"},
{"Unknown page", "Неизвестная страница"},
{"Invalid token", "Неверный токен"},
{"SUCCESS", "УСПЕШНО"},
{"Stream closed", "Стрим закрыт"},
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
{"Destination not found", "Точка назначения не найдена"},
{"StreamID can't be null", "StreamID не может быть пустым"},
{"Return to destination page", "Вернуться на страницу точки назначения"},
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
{"Back to commands list", "Вернуться к списку команд"},
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
{"Submit", "Отправить"},
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"Unknown command", "Неизвестная команда"},
{"Command accepted", "Команда принята"},
{"Proxy error", "Ошибка прокси"},
{"Proxy info", "Информация прокси"},
{"Proxy error: Host not found", "Ошибка прокси: Узел не найден"},
{"Remote host not found in router's addressbook", "Запрошенный узел не найден в адресной книге роутера"},
{"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"},
{"Invalid request", "Некорректный запрос"},
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
{"addresshelper is not supported", "addresshelper не поддерживается"},
{"Host", "Узел"},
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
{"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"},
{"Continue", "Продолжить"},
{"Addresshelper found", "Найден addresshelper"},
{"already in router's addressbook", "уже в адресной книге роутера"},
{"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"},
{"invalid request uri", "некорректный URI запроса"},
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
{"Outproxy failure", "Ошибка внешнего прокси"},
{"bad outproxy settings", "некорректные настройки внешнего прокси"},
{"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
{"unknown outproxy url", "неизвестный URL внешнего прокси"},
{"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"},
{"hostname too long", "имя хоста слишком длинное"},
{"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
{"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
{"CONNECT error", "Ошибка CONNECT запроса"},
{"Failed to Connect", "Не удалось подключиться"},
{"socks proxy error", "ошибка SOCKS прокси"},
{"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
{"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
{"cannot connect", "не удалось подключиться"},
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
{"Host is down", "Узел недоступен"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"день", "дня", "дней"}},
{"hours", {"час", "часа", "часов"}},
{"minutes", {"минуту", "минуты", "минут"}},
{"seconds", {"секунду", "секунды", "секунд"}},
{"", {"", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

215
i18n/Turkmen.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Turkmen localization file
namespace i2p
{
namespace i18n
{
namespace turkmen // language namespace
{
// language name in lowercase
static std::string language = "turkmen";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n != 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"building", "bina"},
{"failed", "şowsuz"},
{"expiring", "möhleti gutarýar"},
{"established", "işleýär"},
{"unknown", "näbelli"},
{"exploratory", "gözleg"},
{"<b>i2pd</b> webconsole", "Web konsoly <b>i2pd</b>"},
{"Main page", "Esasy sahypa"},
{"Router commands", "Marşrutizator buýruklary"},
{"Local Destinations", "Ýerli ýerler"},
{"LeaseSets", "Lizset"},
{"Tunnels", "Tuneller"},
{"Transit Tunnels", "Tranzit Tunelleri"},
{"Transports", "Daşamak"},
{"I2P tunnels", "I2P tuneller"},
{"SAM sessions", "SAM Sessiýasy"},
{"ERROR", "Ýalňyşlyk"},
{"OK", "OK"},
{"Testing", "Synag etmek"},
{"Firewalled", "Daşynda petiklendi"},
{"Unknown", "Näbelli"},
{"Proxy", "Proksi"},
{"Mesh", "MESH-tor"},
{"Error", "Ýalňyşlyk"},
{"Clock skew", "Takyk wagt däl"},
{"Offline", "Awtonom"},
{"Symmetric NAT", "Simmetriklik NAT"},
{"Uptime", "Onlaýn onlaýn sözlügi"},
{"Network status", "Tor ýagdaýy"},
{"Network status v6", "Tor ýagdaýy v6"},
{"Stopping in", "Soň duruň"},
{"Family", "Maşgala"},
{"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"},
{"Received", "Alnan"},
{"KiB/s", "KiB/s"},
{"Sent", "Ýerleşdirildi"},
{"Transit", "Tranzit"},
{"Data path", "Maglumat ýoly"},
{"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."},
{"Router Ident", "Marşrutly kesgitleýji"},
{"Router Family", "Marşrutler maşgalasy"},
{"Router Caps", "Baýdaklar marşruteri"},
{"Version", "Wersiýasy"},
{"Our external address", "Daşarky salgymyz"},
{"supported", "goldanýar"},
{"Routers", "Marşrutizatorlar"},
{"Floodfills", "Fludfillar"},
{"Client Tunnels", "Müşderi tunelleri"},
{"Services", "Hyzmatlar"},
{"Enabled", "Goşuldy"},
{"Disabled", "Öçürildi"},
{"Encrypted B33 address", "Şifrlenen B33 salgylar"},
{"Address registration line", "Hasaba alyş salgysy"},
{"Domain", "Domen"},
{"Generate", "Öndürmek"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Bellik:</b> Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner (example.i2p). Subýutmalary hasaba almak üçin i2pd ulanyň-tools."},
{"Address", "Salgysy"},
{"Type", "Görnüş"},
{"EncType", "Şifrlemek görnüşi"},
{"Inbound tunnels", "Gelýän tuneller"},
{"ms", "ms"},
{"Outbound tunnels", "Çykýan tuneller"},
{"Tags", "Bellikler"},
{"Incoming", "Gelýän"},
{"Outgoing", "Çykýan"},
{"Destination", "Maksat"},
{"Amount", "Sany"},
{"Incoming Tags", "Gelýän bellikler"},
{"Tags sessions", "Sapaklar bellikler"},
{"Status", "Ýagdaýy"},
{"Local Destination", "Ýerli maksat"},
{"Streams", "Strimlary"},
{"Close stream", "Yap strim"},
{"I2CP session not found", "I2CP Sessiýa tapylmady"},
{"I2CP is not enabled", "I2CP goşulmaýar"},
{"Invalid", "Nädogry"},
{"Store type", "Ammar görnüşi"},
{"Expires", "Möhleti gutarýar"},
{"Non Expired Leases", "Möhleti gutarmady Lizsetlary"},
{"Gateway", "Derweze"},
{"TunnelID", "Tuneliň ID"},
{"EndDate", "Gutarýar"},
{"not floodfill", "fludfil däl"},
{"Queue size", "Nobatyň ululygy"},
{"Run peer test", "Synag başlaň"},
{"Decline transit tunnels", "Tranzit tunellerini ret ediň"},
{"Accept transit tunnels", "Tranzit tunellerini alyň"},
{"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"},
{"Start graceful shutdown", "Tekiz durmak"},
{"Force shutdown", "Mejbury duralga"},
{"Reload external CSS styles", "Daşarky CSS stillerini täzeden ýükläň"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Bellik:</b> Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär."},
{"Logging level", "Giriş derejesi"},
{"Transit tunnels limit", "Tranzit tunelleriniň çägi"},
{"Change", "Üýtgetmek"},
{"Change language", "Dil üýtgetmek"},
{"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"},
{"SAM disabled", "SAM öçürilen"},
{"no sessions currently running", "başlamagyň sessiýalary ýok"},
{"SAM session not found", "SAM Sessiýa tapylmady"},
{"SAM Session", "SAM Sessiýa"},
{"Server Tunnels", "Serwer tunelleri"},
{"Client Forwards", "Müşderi gönükdirýär"},
{"Server Forwards", "Serweriň täzeden düzlüleri"},
{"Unknown page", "Näbelli sahypa"},
{"Invalid token", "Nädogry token"},
{"SUCCESS", "Üstünlikli"},
{"Stream closed", "Strim ýapyk"},
{"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"},
{"Destination not found", "Niýetlenen ýeri tapylmady"},
{"StreamID can't be null", "StreamID boş bolup bilmez"},
{"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"},
{"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"},
{"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"},
{"Back to commands list", "Topar sanawyna dolan"},
{"Register at reg.i2p", "Reg.i2P-de hasaba duruň"},
{"Description", "Beýany"},
{"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"},
{"Submit", "Iber"},
{"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez"},
{"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"},
{"Such destination is not found", "Bu barmaly ýer tapylmady"},
{"Unknown command", "Näbelli topar"},
{"Command accepted", "Topar kabul edilýär"},
{"Proxy error", "Proksi ýalňyşlygy"},
{"Proxy info", "Proksi maglumat"},
{"Proxy error: Host not found", "Proksi ýalňyşlygy: Host tapylmady"},
{"Remote host not found in router's addressbook", "Uzakdaky öý eýesi marşruteriň salgy kitabynda tapylmady"},
{"You may try to find this host on jump services below", "Aşakdaky böküş hyzmatlarynda bu öý eýesini tapmaga synanyşyp bilersiňiz"},
{"Invalid request", "Nädogry haýyş"},
{"Proxy unable to parse your request", "Proksi haýyşyňyzy derňäp bilmeýär"},
{"addresshelper is not supported", "Salgylandyryjy goldanok"},
{"Host", "Adres"},
{"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"},
{"Click here to proceed:", "Dowam etmek bu ýerde basyň:"},
{"Continue", "Dowam et"},
{"Addresshelper found", "Forgelper tapyldy"},
{"already in router's addressbook", "marşruteriň adres kitaby"},
{"Click here to update record:", "Recordazgyny täzelemek üçin bu ýerde basyň:"},
{"invalid request uri", "nädogry haýyş URI"},
{"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"},
{"Outproxy failure", "Daşarky proksi ýalňyşlyk"},
{"bad outproxy settings", "daşarky daşarky proksi sazlamalary nädogry"},
{"not inside I2P network, but outproxy is not enabled", "I2P torunda däl, ýöne daşarky proksi goşulmaýar"},
{"unknown outproxy url", "näbelli daşarky proksi URL"},
{"cannot resolve upstream proxy", "has ýokary proksi kesgitläp bilmeýär"},
{"hostname too long", "hoster eýesi ady gaty uzyn"},
{"cannot connect to upstream socks proxy", "ýokary jorap SOCKS proksi bilen birigip bolmaýar"},
{"Cannot negotiate with socks proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"},
{"CONNECT error", "Bagyr haýyşy säwligi"},
{"Failed to Connect", "Birikdirip bilmedi"},
{"socks proxy error", "socks proksi ýalňyşlygy"},
{"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"},
{"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"},
{"cannot connect", "birikdirip bilmedi"},
{"http out proxy not implemented", "daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"},
{"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"},
{"Host is down", "Salgy elýeterli däl"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"gün", "gün"}},
{"hours", {"sagat", "sagat"}},
{"minutes", {"minut", "minut"}},
{"seconds", {"sekunt", "sekunt"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

215
i18n/Ukrainian.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Ukrainian localization file
namespace i2p
{
namespace i18n
{
namespace ukrainian // language namespace
{
// language name in lowercase
static std::string language = "ukrainian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
}
static std::map<std::string, std::string> strings
{
{"KiB", "КіБ"},
{"MiB", "МіБ"},
{"GiB", "ГіБ"},
{"building", "будується"},
{"failed", "невдалий"},
{"expiring", "завершується"},
{"established", "працює"},
{"unknown", "невідомо"},
{"exploratory", "дослідницький"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Головна"},
{"Router commands", "Команди маршрутизатора"},
{"Local Destinations", "Локальні Призначення"},
{"LeaseSets", "Лізсети"},
{"Tunnels", "Тунелі"},
{"Transit Tunnels", "Транзитні Тунелі"},
{"Transports", "Транспорти"},
{"I2P tunnels", "I2P тунелі"},
{"SAM sessions", "SAM сесії"},
{"ERROR", "ПОМИЛКА"},
{"OK", "OK"},
{"Testing", "Тестування"},
{"Firewalled", "Заблоковано ззовні"},
{"Unknown", "Невідомо"},
{"Proxy", "Проксі"},
{"Mesh", "MESH-мережа"},
{"Error", "Помилка"},
{"Clock skew", "Неточний час"},
{"Offline", "Офлайн"},
{"Symmetric NAT", "Симетричний NAT"},
{"Uptime", "У мережі"},
{"Network status", "Мережевий статус"},
{"Network status v6", "Мережевий статус v6"},
{"Stopping in", "Зупинка через"},
{"Family", "Сімейство"},
{"Tunnel creation success rate", "Успішно побудованих тунелів"},
{"Received", "Отримано"},
{"KiB/s", "КіБ/с"},
{"Sent", "Відправлено"},
{"Transit", "Транзит"},
{"Data path", "Шлях до даних"},
{"Hidden content. Press on text to see.", "Прихований вміст. Щоб відобразити, натисніть на текст."},
{"Router Ident", "Ідентифікатор маршрутизатора"},
{"Router Family", "Сімейство маршрутизатора"},
{"Router Caps", "Прапорці маршрутизатора"},
{"Version", "Версія"},
{"Our external address", "Наша зовнішня адреса"},
{"supported", "підтримується"},
{"Routers", "Маршрутизатори"},
{"Floodfills", "Флудфіли"},
{"Client Tunnels", "Клієнтські Тунелі"},
{"Services", "Сервіси"},
{"Enabled", "Увімкнуто"},
{"Disabled", "Вимкнуто"},
{"Encrypted B33 address", "Шифровані B33 адреси"},
{"Address registration line", "Рядок реєстрації адреси"},
{"Domain", "Домен"},
{"Generate", "Згенерувати"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Примітка:</b> отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня (example.i2p). Для реєстрації піддоменів використовуйте i2pd-tools."},
{"Address", "Адреса"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Inbound tunnels", "Вхідні тунелі"},
{"ms", "мс"},
{"Outbound tunnels", "Вихідні тунелі"},
{"Tags", "Теги"},
{"Incoming", "Вхідні"},
{"Outgoing", "Вихідні"},
{"Destination", "Призначення"},
{"Amount", "Кількість"},
{"Incoming Tags", "Вхідні Теги"},
{"Tags sessions", "Сесії Тегів"},
{"Status", "Статус"},
{"Local Destination", "Локальні Призначення"},
{"Streams", "Потоки"},
{"Close stream", "Закрити потік"},
{"I2CP session not found", "I2CP сесія не знайдена"},
{"I2CP is not enabled", "I2CP не увікнуто"},
{"Invalid", "Некоректний"},
{"Store type", "Тип сховища"},
{"Expires", "Завершується"},
{"Non Expired Leases", "Не завершені Lease-и"},
{"Gateway", "Шлюз"},
{"TunnelID", "ID тунеля"},
{"EndDate", "Закінчується"},
{"not floodfill", "не флудфіл"},
{"Queue size", "Розмір черги"},
{"Run peer test", "Запустити тестування"},
{"Decline transit tunnels", "Відхиляти транзитні тунелі"},
{"Accept transit tunnels", "Ухвалювати транзитні тунелі"},
{"Cancel graceful shutdown", "Скасувати плавну зупинку"},
{"Start graceful shutdown", "Запустити плавну зупинку"},
{"Force shutdown", "Примусова зупинка"},
{"Reload external CSS styles", "Перезавантажити зовнішні стилі CSS"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Примітка:</b> будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."},
{"Logging level", "Рівень логування"},
{"Transit tunnels limit", "Обмеження транзитних тунелів"},
{"Change", "Змінити"},
{"Change language", "Змінити мову"},
{"no transit tunnels currently built", "немає побудованих транзитних тунелів"},
{"SAM disabled", "SAM вимкнуто"},
{"no sessions currently running", "немає запущених сесій"},
{"SAM session not found", "SAM сесія не знайдена"},
{"SAM Session", "SAM сесія"},
{"Server Tunnels", "Серверні Тунелі"},
{"Client Forwards", "Клієнтські Переспрямування"},
{"Server Forwards", "Серверні Переспрямування"},
{"Unknown page", "Невідома сторінка"},
{"Invalid token", "Невірний токен"},
{"SUCCESS", "УСПІШНО"},
{"Stream closed", "Потік зачинений"},
{"Stream not found or already was closed", "Потік не знайдений або вже зачинений"},
{"Destination not found", "Точка призначення не знайдена"},
{"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"},
{"Return to destination page", "Повернутися на сторінку точки призначення"},
{"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"},
{"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"},
{"Back to commands list", "Повернутися до списку команд"},
{"Register at reg.i2p", "Зареєструвати на reg.i2p"},
{"Description", "Опис"},
{"A bit information about service on domain", "Трохи інформації про сервіс на домені"},
{"Submit", "Надіслати"},
{"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"},
{"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"},
{"Such destination is not found", "Така точка призначення не знайдена"},
{"Unknown command", "Невідома команда"},
{"Command accepted", "Команда прийнята"},
{"Proxy error", "Помилка проксі"},
{"Proxy info", "Інформація проксі"},
{"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"},
{"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі маршрутизатора"},
{"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"},
{"Invalid request", "Некоректний запит"},
{"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"},
{"addresshelper is not supported", "addresshelper не підтримується"},
{"Host", "Адреса"},
{"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"},
{"Click here to proceed:", "Натисніть тут щоб продовжити:"},
{"Continue", "Продовжити"},
{"Addresshelper found", "Знайдено addresshelper"},
{"already in router's addressbook", "вже в адресній книзі маршрутизатора"},
{"Click here to update record:", "Натисніть тут щоб оновити запис:"},
{"invalid request uri", "некоректний URI запиту"},
{"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"},
{"Outproxy failure", "Помилка зовнішнього проксі"},
{"bad outproxy settings", "некоректні налаштування зовнішнього проксі"},
{"not inside I2P network, but outproxy is not enabled", "не в I2P мережі, але зовнішній проксі не включений"},
{"unknown outproxy url", "невідомий URL зовнішнього проксі"},
{"cannot resolve upstream proxy", "не вдається визначити висхідний проксі"},
{"hostname too long", "ім'я вузла надто довге"},
{"cannot connect to upstream socks proxy", "не вдається підключитися до висхідного SOCKS проксі"},
{"Cannot negotiate with socks proxy", "Не вдається домовитися з висхідним SOCKS проксі"},
{"CONNECT error", "Помилка CONNECT запиту"},
{"Failed to Connect", "Не вдалося підключитися"},
{"socks proxy error", "помилка SOCKS проксі"},
{"failed to send request to upstream", "не вдалося відправити запит висхідному проксі"},
{"No Reply From socks proxy", "Немає відповіді від SOCKS проксі сервера"},
{"cannot connect", "не вдалося підключитися"},
{"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"},
{"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"},
{"Host is down", "Вузол недоступний"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"день", "дня", "днів"}},
{"hours", {"годину", "години", "годин"}},
{"minutes", {"хвилину", "хвилини", "хвилин"}},
{"seconds", {"секунду", "секунди", "секунд"}},
{"", {"", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

215
i18n/Uzbek.cpp Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Ukrainian localization file
namespace i2p
{
namespace i18n
{
namespace uzbek // language namespace
{
// language name in lowercase
static std::string language = "uzbek";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return n > 1 ? 1 : 0;
}
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"building", "yaratilmoqda"},
{"failed", "muvaffaqiyatsiz"},
{"expiring", "muddati tugaydi"},
{"established", "aloqa o'rnatildi"},
{"unknown", "noma'lum"},
{"exploratory", "tadqiqiy"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> veb-konsoli"},
{"Main page", "Asosiy sahifa"},
{"Router commands", "Router buyruqlari"},
{"Local Destinations", "Mahalliy joylanishlar"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Tunnellar"},
{"Transit Tunnels", "Tranzit Tunellari"},
{"Transports", "Transportlar"},
{"I2P tunnels", "I2P tunnellari"},
{"SAM sessions", "SAM sessiyalari"},
{"ERROR", "XATO"},
{"OK", "OK"},
{"Testing", "Testlash"},
{"Firewalled", "Xavfsizlik devori bilan himoyalangan"},
{"Unknown", "Notanish"},
{"Proxy", "Proksi"},
{"Mesh", "Mesh To'r"},
{"Error", "Xato"},
{"Clock skew", "Aniq vaqt emas"},
{"Offline", "Oflayn"},
{"Symmetric NAT", "Simmetrik NAT"},
{"Uptime", "Ish vaqti"},
{"Network status", "Tarmoq holati"},
{"Network status v6", "Tarmoq holati v6"},
{"Stopping in", "Ichida to'xtatish"},
{"Family", "Oila"},
{"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"},
{"Received", "Qabul qilindi"},
{"KiB/s", "KiB/s"},
{"Sent", "Yuborilgan"},
{"Transit", "Tranzit"},
{"Data path", "Ma'lumotlar joylanishi"},
{"Hidden content. Press on text to see.", "Yashirin tarkib. Ko'rish uchun matn ustida bosing."},
{"Router Ident", "Router identifikatori"},
{"Router Family", "Router oilasi"},
{"Router Caps", "Router Bayroqlari"},
{"Version", "Versiya"},
{"Our external address", "Bizning tashqi manzilimiz"},
{"supported", "qo'llab-quvvatlanadi"},
{"Routers", "Routerlar"},
{"Floodfills", "Floodfills"},
{"Client Tunnels", "Mijoz Tunellari"},
{"Services", "Xizmatlar"},
{"Enabled", "Yoqilgan"},
{"Disabled", "O'chirilgan"},
{"Encrypted B33 address", "Shifrlangan B33 manzil"},
{"Address registration line", "Manzilni ro'yxatga olish liniyasi"},
{"Domain", "Domen"},
{"Generate", "Yaratish"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Eslatma:</b> natija satridan faqat 2LD domenlarini ro'yxatdan o'tkazish uchun foydalanish mumkin (example.i2p). Subdomenlarni ro'yxatdan o'tkazish uchun 'i2pd-tools'dan foydalaning."},
{"Address", "Manzil"},
{"Type", "Turi"},
{"EncType", "ShifrlashTuri"},
{"Inbound tunnels", "Kirish tunnellari"},
{"ms", "ms"},
{"Outbound tunnels", "Chiquvchi tunnellar"},
{"Tags", "Teglar"},
{"Incoming", "Kiruvchi"},
{"Outgoing", "Chiquvchi"},
{"Destination", "Manzilgoh"},
{"Amount", "Soni"},
{"Incoming Tags", "Kiruvchi teglar"},
{"Tags sessions", "Teglar sessiyalari"},
{"Status", "Holat"},
{"Local Destination", "Mahalliy joylanish"},
{"Streams", "Strim"},
{"Close stream", "Strimni o'chirish"},
{"I2CP session not found", "I2CP sessiyasi topilmadi"},
{"I2CP is not enabled", "I2CP yoqilmagan"},
{"Invalid", "Noto'g'ri"},
{"Store type", "Saqlash turi"},
{"Expires", "Muddati tugaydi"},
{"Non Expired Leases", "Muddati O'tmagan Leases"},
{"Gateway", "Kirish yo'li"},
{"TunnelID", "TunnelID"},
{"EndDate", "Tugash Sanasi"},
{"not floodfill", "floodfill emas"},
{"Queue size", "Navbat hajmi"},
{"Run peer test", "Sinovni boshlang"},
{"Decline transit tunnels", "Tranzit tunnellarini rad etish"},
{"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"},
{"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qilish"},
{"Start graceful shutdown", "Yumshoq to'xtashni boshlash"},
{"Force shutdown", "Majburiy to'xtatish"},
{"Reload external CSS styles", "Tashqi CSS uslublarini qayta yuklang"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Eslatma:</b> shu yerda qilingan har qanday harakat doimiy emas va konfiguratsiya fayllarini o'zgartirmaydi."},
{"Logging level", "Jurnal darajasi"},
{"Transit tunnels limit", "Tranzit tunellarning chegarasi"},
{"Change", "O'zgartirish"},
{"Change language", "Tilni o'zgartirish"},
{"no transit tunnels currently built", "qurilgan tranzit tunnellari yo'q"},
{"SAM disabled", "SAM o'chirilgan"},
{"no sessions currently running", "hech qanday ishlaydigan sessiyalar yo'q"},
{"SAM session not found", "SAM sessiyasi topilmadi"},
{"SAM Session", "SAM sessiyasi"},
{"Server Tunnels", "Server Tunellari"},
{"Client Forwards", "Mijozlarni Yo'naltirish"},
{"Server Forwards", "Serverni Yo'naltirish"},
{"Unknown page", "Noma'lum sahifa"},
{"Invalid token", "Notogri belgi"},
{"SUCCESS", "Muvaffaqiyat"},
{"Stream closed", "Strim yopiq"},
{"Stream not found or already was closed", "Strim topilmadi yoki allaqachon yopilgan"},
{"Destination not found", "Yo'nalish topilmadi"},
{"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"},
{"Return to destination page", "Manzilgoh sahifasiga qaytish"},
{"You will be redirected in 5 seconds", "Siz 5 soniya ichida qayta yo'naltirilasiz"},
{"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"},
{"Back to commands list", "Buyruqlar ro'yxatiga qaytish"},
{"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"},
{"Description", "Tavsif"},
{"A bit information about service on domain", "Domen xizmatlari haqida bir oz ma'lumot"},
{"Submit", "Yuborish"},
{"Domain can't end with .b32.i2p", "Domen .b32.i2p bilan tugashi mumkin emas"},
{"Domain must end with .i2p", "Domen .i2p bilan tugashi kerak"},
{"Such destination is not found", "Bunday yo'nalish topilmadi"},
{"Unknown command", "Noma'lum buyruq"},
{"Command accepted", "Buyruq qabul qilindi"},
{"Proxy error", "Proksi xatosi"},
{"Proxy info", "Proksi ma'lumotlari"},
{"Proxy error: Host not found", "Proksi xatosi: Xost topilmadi"},
{"Remote host not found in router's addressbook", "Masofaviy xost yo'riqnoma manzillar kitobida topilmadi"},
{"You may try to find this host on jump services below", "Siz xost quyida o'tish xizmatlari orqali topishga harakat qilishingiz mumkin"},
{"Invalid request", "Notogri sorov"},
{"Proxy unable to parse your request", "Proksi sizning so'rovingizni aniqlab ololmayapti"},
{"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"},
{"Host", "Xost"},
{"added to router's addressbook from helper", "'helper'dan routerning 'addressbook'ga qo'shildi"},
{"Click here to proceed:", "Davom etish uchun shu yerni bosing:"},
{"Continue", "Davom etish"},
{"Addresshelper found", "Addresshelper topildi"},
{"already in router's addressbook", "allaqachon 'addressbook'da yozilgan"},
{"Click here to update record:", "Yozuvni yangilash uchun shu yerni bosing:"},
{"invalid request uri", "noto'g'ri URI so'rovi"},
{"Can't detect destination host from request", "Sorov orqali manzil xostini aniqlab bo'lmayapti"},
{"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"},
{"bad outproxy settings", "noto'g'ri tashqi proksi-server sozlamalari"},
{"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"},
{"unknown outproxy url", "noma'lum outproxy url"},
{"cannot resolve upstream proxy", "yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"},
{"hostname too long", "xost nomi juda uzun"},
{"cannot connect to upstream socks proxy", "yuqori 'socks proxy'ga ulanib bo'lmayapti"},
{"Cannot negotiate with socks proxy", "'Socks proxy' bilan muzokara olib bo'lmaydi"},
{"CONNECT error", "CONNECT xatosi"},
{"Failed to Connect", "Ulanib bo'lmayapti"},
{"socks proxy error", "'socks proxy' xatosi"},
{"failed to send request to upstream", "yuqori http proksi-serveriga so'rovni uborib bo'lmadi"},
{"No Reply From socks proxy", "'Socks proxy'dan javob yo'q"},
{"cannot connect", "ulanib bo'lmaydi"},
{"http out proxy not implemented", "tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"},
{"cannot connect to upstream http proxy", "yuqori http 'proxy-server'iga ulanib bo'lmayapti"},
{"Host is down", "Xost ishlamayapti"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Talab qilingan xost bilan aloqa o'rnatilmadi, u ishlamay qolishi mumkin. Iltimos keyinroq qayta urinib ko'ring."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"kun", "kun"}},
{"hours", {"soat", "soat"}},
{"minutes", {"daqiqa", "daqiqa"}},
{"seconds", {"soniya", "soniya"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -185,10 +185,7 @@ namespace data
if (InCount && !m)
outCount = 3 * n;
else
{
outCount = 0;
return 0;
}
ps = (unsigned char *)(InBuffer + InCount - 1);
while ( *ps-- == P64 )
@@ -196,7 +193,7 @@ namespace data
ps = (unsigned char *)InBuffer;
if (outCount > len)
return -1;
return 0;
pd = OutBuffer;
auto endOfOutBuffer = OutBuffer + outCount;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -122,7 +122,7 @@ namespace data
break;
}
default:
LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA");
LogPrint (eLogError, "Blinding: Signature type ", (int)sigType, " is not ECDSA");
}
if (group)
{
@@ -146,7 +146,10 @@ namespace data
m_PublicKey.resize (len);
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
m_SigType = identity->GetSigningKeyType ();
m_BlindedSigType = m_SigType;
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
else
m_BlindedSigType = m_SigType;
}
BlindedPublicKey::BlindedPublicKey (const std::string& b33):
@@ -156,7 +159,7 @@ namespace data
size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40);
if (l < 32)
{
LogPrint (eLogError, "Blinding: malformed b33 ", b33);
LogPrint (eLogError, "Blinding: Malformed b33 ", b33);
return;
}
uint32_t checksum = crc32 (0, addr + 3, l - 3);
@@ -186,10 +189,10 @@ namespace data
memcpy (m_PublicKey.data (), addr + offset, len);
}
else
LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType);
LogPrint (eLogError, "Blinding: Public key in b33 address is too short for signature type ", (int)m_SigType);
}
else
LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33");
LogPrint (eLogError, "Blinding: Unknown signature type ", (int)m_SigType, " in b33");
}
std::string BlindedPublicKey::ToB33 () const
@@ -256,7 +259,7 @@ namespace data
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
break;
default:
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType);
LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType);
}
return publicKeyLength;
}
@@ -277,8 +280,16 @@ namespace data
i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub);
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
break;
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{
uint8_t exp[64];
i2p::crypto::Ed25519::ExpandPrivateKey (priv, exp);
i2p::crypto::GetEd25519 ()->BlindPrivateKey (exp, seed, blindedPriv, blindedPub);
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
break;
}
default:
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType);
LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType);
}
return publicKeyLength;
}
@@ -316,7 +327,7 @@ namespace data
SHA256_Final ((uint8_t *)hash, &ctx);
}
else
LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported");
LogPrint (eLogError, "Blinding: Blinded key type ", (int)m_BlindedSigType, " is not supported");
return hash;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -37,6 +37,7 @@ namespace config {
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
("certsdir", value<std::string>()->default_value(""), "Path to certificates used for verifying .su3, families (default: ~/.i2pd/certificates or /var/lib/i2pd/certificates")
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
@@ -60,7 +61,7 @@ namespace config {
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
("notransit", bool_switch()->default_value(false), "Router will not accept transit tunnels at startup (default: disabled)")
("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
("bandwidth", value<std::string>()->default_value(""), "Transit traffic bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
("ntcp", bool_switch()->default_value(false), "Ignored. Always false")
("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)")
@@ -93,6 +94,7 @@ namespace config {
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
("http.lang", value<std::string>()->default_value("english"), "WebUI language (default: english )")
;
options_description httpproxy("HTTP Proxy options");
@@ -107,12 +109,15 @@ namespace config {
("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity")
("httpproxy.inbound.lengthVariance", value<std::string>()->default_value("0"), "HTTP proxy inbound tunnels length variance")
("httpproxy.outbound.lengthVariance", value<std::string>()->default_value("0"), "HTTP proxy outbound tunnels length variance")
("httpproxy.latency.min", value<std::string>()->default_value("0"), "HTTP proxy min latency for tunnels")
("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
("httpproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
("httpproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
("httpproxy.i2cp.leaseSetPrivKey", value<std::string>()->default_value(""), "LeaseSet private key")
;
options_description socksproxy("SOCKS Proxy options");
@@ -127,6 +132,8 @@ namespace config {
("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")
("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity")
("socksproxy.inbound.lengthVariance", value<std::string>()->default_value("0"), "SOCKS proxy inbound tunnels length variance")
("socksproxy.outbound.lengthVariance", value<std::string>()->default_value("0"), "SOCKS proxy outbound tunnels length variance")
("socksproxy.latency.min", value<std::string>()->default_value("0"), "SOCKS proxy min latency for tunnels")
("socksproxy.latency.max", value<std::string>()->default_value("0"), "SOCKS proxy max latency for tunnels")
("socksproxy.outproxy.enabled", value<bool>()->default_value(false), "Enable or disable SOCKS outproxy")
@@ -134,6 +141,7 @@ namespace config {
("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
("socksproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
("socksproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
("socksproxy.i2cp.leaseSetPrivKey", value<std::string>()->default_value(""), "LeaseSet private key")
;
options_description sam("SAM bridge options");
@@ -199,17 +207,24 @@ namespace config {
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
("reseed.urls", value<std::string>()->default_value(
"https://reseed.i2p-projekt.de/,"
"https://reseed2.i2p.net/,"
"https://reseed.diva.exchange/,"
"https://reseed-fr.i2pd.xyz/,"
"https://reseed.memcpy.io/,"
"https://reseed.onion.im/,"
"https://i2pseed.creativecowpat.net:8443/,"
"https://reseed.i2pgit.org/,"
"https://i2p.novg.net/"
"https://i2p.novg.net/,"
"https://banana.incognet.io/,"
"https://reseed-pl.i2pd.xyz/,"
"https://www2.mk16.de/"
), "Reseed URLs, separated by comma")
("reseed.yggurls", value<std::string>()->default_value(
"http://[324:9de3:fea4:f6ac::ace]:7070/"
"http://[324:71e:281a:9ed3::ace]:7070/,"
"http://[301:65b9:c7cd:9a36::1]:18801/,"
"http://[320:8936:ec1a:31f1::216]/,"
"http://[306:3834:97b9:a00a::1]/,"
"http://[316:f9e0:f22e:a74f::216]/"
), "Reseed URLs through the Yggdrasil, separated by comma")
;
@@ -218,7 +233,9 @@ namespace config {
("addressbook.defaulturl", value<std::string>()->default_value(
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
), "AddressBook subscription URL for initial setup")
("addressbook.subscriptions", value<std::string>()->default_value(""), "AddressBook subscriptions URLs, separated by comma")
("addressbook.subscriptions", value<std::string>()->default_value(
"http://reg.i2p/hosts.txt"
), "AddressBook subscriptions URLs, separated by comma")
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
options_description trust("Trust options");
@@ -254,6 +271,13 @@ namespace config {
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
;
options_description ssu2("SSU2 Options");
ntcp2.add_options()
("ssu2.enabled", value<bool>()->default_value(false), "Enable SSU2 (default: disabled)")
("ssu2.published", value<bool>()->default_value(false), "Publish SSU2 (default: disabled)")
("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
;
options_description nettime("Time sync options");
nettime.add_options()
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
@@ -262,8 +286,9 @@ namespace config {
"1.pool.ntp.org,"
"2.pool.ntp.org,"
"3.pool.ntp.org"
), "Comma separated list of NTCP servers")
), "Comma separated list of NTP servers")
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
("nettime.frompeers", value<bool>()->default_value(true), "Sync clock from transport peers (default: enabled)")
;
options_description persist("Network information persisting options");
@@ -281,7 +306,7 @@ namespace config {
options_description meshnets("Meshnet transports options");
meshnets.add_options()
("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)")
("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)")
("meshnets.yggaddress", value<std::string>()->default_value(""), "Yggdrasil address to publish")
;
@@ -303,6 +328,7 @@ namespace config {
.add(websocket) // deprecated
.add(exploratory)
.add(ntcp2)
.add(ssu2)
.add(nettime)
.add(persist)
.add(cpuext)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -389,7 +389,7 @@ namespace crypto
{
size_t len = 32;
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
}
}
#else
memcpy (m_PrivateKey, priv, 32);
if (calculatePublic)
@@ -398,8 +398,9 @@ namespace crypto
}
// ElGamal
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted)
{
BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx);
// everything, but a, because a might come from table
BIGNUM * k = BN_CTX_get (ctx);
@@ -435,37 +436,32 @@ namespace crypto
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);
}
encrypted[0] = 0;
bn2buf (a, encrypted + 1, 256);
encrypted[257] = 0;
bn2buf (b, encrypted + 258, 256);
BN_free (a);
BN_CTX_end (ctx);
BN_CTX_free (ctx);
}
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
uint8_t * data, BN_CTX * ctx, bool zeroPadding)
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data)
{
BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx);
BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx);
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);
BN_bin2bn (encrypted + 1, 256, a);
BN_bin2bn (encrypted + 258, 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_CTX_end (ctx);
BN_CTX_free (ctx);
uint8_t hash[32];
SHA256 (m + 33, 222, hash);
if (memcmp (m + 1, hash, 32))
@@ -499,8 +495,9 @@ namespace crypto
}
// ECIES
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted)
{
BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx);
BIGNUM * q = BN_CTX_get (ctx);
EC_GROUP_get_order(curve, q, ctx);
@@ -512,19 +509,10 @@ namespace crypto
EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx);
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
if (zeroPadding)
{
encrypted[0] = 0;
bn2buf (x, encrypted + 1, len);
bn2buf (y, encrypted + 1 + len, len);
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
}
else
{
bn2buf (x, encrypted, len);
bn2buf (y, encrypted + len, len);
RAND_bytes (encrypted + 2*len, 256 - 2*len);
}
encrypted[0] = 0;
bn2buf (x, encrypted + 1, len);
bn2buf (y, encrypted + 1 + len, len);
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
// encryption key and iv
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
@@ -541,36 +529,25 @@ namespace crypto
CBCEncryption encryption;
encryption.SetKey (shared);
encryption.SetIV (iv);
if (zeroPadding)
{
encrypted[257] = 0;
encryption.Encrypt (m, 256, encrypted + 258);
}
else
encryption.Encrypt (m, 256, encrypted + 256);
encrypted[257] = 0;
encryption.Encrypt (m, 256, encrypted + 258);
EC_POINT_free (p);
BN_CTX_end (ctx);
BN_CTX_free (ctx);
}
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data)
{
bool ret = true;
BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx);
BIGNUM * q = BN_CTX_get (ctx);
EC_GROUP_get_order(curve, q, ctx);
int len = BN_num_bytes (q);
// point for shared secret
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
if (zeroPadding)
{
BN_bin2bn (encrypted + 1, len, x);
BN_bin2bn (encrypted + 1 + len, len, y);
}
else
{
BN_bin2bn (encrypted, len, x);
BN_bin2bn (encrypted + len, len, y);
}
BN_bin2bn (encrypted + 1, len, x);
BN_bin2bn (encrypted + 1 + len, len, y);
auto p = EC_POINT_new (curve);
if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr))
{
@@ -587,10 +564,7 @@ namespace crypto
CBCDecryption decryption;
decryption.SetKey (shared);
decryption.SetIV (iv);
if (zeroPadding)
decryption.Decrypt (encrypted + 258, 256, m);
else
decryption.Decrypt (encrypted + 256, 256, m);
decryption.Decrypt (encrypted + 258, 256, m);
// verify and copy
uint8_t hash[32];
SHA256 (m + 33, 222, hash);
@@ -610,6 +584,7 @@ namespace crypto
EC_POINT_free (p);
BN_CTX_end (ctx);
BN_CTX_free (ctx);
return ret;
}
@@ -1302,7 +1277,7 @@ namespace crypto
EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len);
}
if (info.length () > 0)
EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ());
EVP_PKEY_CTX_add1_hkdf_info (pctx, (const uint8_t *)info.c_str (), info.length ());
EVP_PKEY_derive (pctx, out, &outLen);
EVP_PKEY_CTX_free (pctx);
#else
@@ -1320,7 +1295,7 @@ namespace crypto
}
// Noise
void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len)
{
SHA256_CTX ctx;
@@ -1330,13 +1305,23 @@ namespace crypto
SHA256_Final (m_H, &ctx);
}
void NoiseSymmetricState::MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs)
{
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
for (const auto& it: bufs)
SHA256_Update (&ctx, it.first, it.second);
SHA256_Final (m_H, &ctx);
}
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
{
HKDF (m_CK, sharedSecret, 32, "", m_CK);
// new ck is m_CK[0:31], key is m_CK[32:63]
}
static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck,
static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck,
const uint8_t * hh, const uint8_t * pub)
{
// pub is Bob's public static key, hh = SHA256(h)
@@ -1346,22 +1331,22 @@ namespace crypto
SHA256_Update (&ctx, hh, 32);
SHA256_Update (&ctx, pub, 32);
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
}
}
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
{
static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
static const uint8_t hh[32] =
{
0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1,
0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1,
0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54
}; // hh = SHA256(protocol_name || 0)
InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0
}
}
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
{
static const uint8_t protocolNameHash[] =
static const uint8_t protocolNameHash[32] =
{
0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed,
0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71
@@ -1371,9 +1356,24 @@ namespace crypto
0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5,
0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e
}; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub);
}
InitNoiseState (state, protocolNameHash, hh, pub);
}
void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub)
{
static const uint8_t protocolNameHash[32] =
{
0xb1, 0x37, 0x22, 0x81, 0x74, 0x23, 0xa8, 0xfd, 0xf4, 0x2d, 0xf2, 0xe6, 0x0e, 0xd1, 0xed, 0xf4,
0x1b, 0x93, 0x07, 0x1d, 0xb1, 0xec, 0x24, 0xa3, 0x67, 0xf7, 0x84, 0xec, 0x27, 0x0d, 0x81, 0x32
}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
static const uint8_t hh[32] =
{
0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
}; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub);
}
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
{
static const uint8_t protocolNameHash[32] =
@@ -1386,9 +1386,9 @@ namespace crypto
0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32,
0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c
}; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub);
}
InitNoiseState (state, protocolNameHash, hh, pub);
}
// init and terminate
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -39,7 +39,9 @@
# define OPENSSL_HKDF 1
# define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1
# define OPENSSL_SIPHASH 1
# if (OPENSSL_VERSION_NUMBER < 0x030000000) // 3.0.0, regression in SipHash
# define OPENSSL_SIPHASH 1
# endif
# endif
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
@@ -93,7 +95,7 @@ namespace crypto
bool IsElligatorIneligible () const { return m_IsElligatorIneligible; }
void SetElligatorIneligible () { m_IsElligatorIneligible = true; }
private:
uint8_t m_PublicKey[32];
@@ -104,17 +106,17 @@ namespace crypto
BN_CTX * m_Ctx;
uint8_t m_PrivateKey[32];
#endif
bool m_IsElligatorIneligible = false; // true if definitly ineligible
bool m_IsElligatorIneligible = false; // true if definitely ineligible
};
// ElGamal
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false);
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub);
// ECIES
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
// HMAC
@@ -315,13 +317,15 @@ namespace crypto
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
void MixHash (const uint8_t * buf, size_t len);
void MixKey (const uint8_t * sharedSecret);
void MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs);
void MixKey (const uint8_t * sharedSecret);
};
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router)
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2)
void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (SSU2)
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets)
// init and terminate
void InitCrypto (bool precomputation, bool aesni, bool avx, bool force);
void TerminateCrypto ();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -20,10 +20,9 @@ namespace crypto
memcpy (m_PublicKey, pub, 256);
}
void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
{
if (!ctx) return;
ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding);
ElGamalEncrypt (m_PublicKey, data, encrypted);
}
ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
@@ -31,10 +30,9 @@ namespace crypto
memcpy (m_PrivateKey, priv, 256);
}
bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
{
if (!ctx) return false;
return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding);
return ElGamalDecrypt (m_PrivateKey, encrypted, data);
}
ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
@@ -54,10 +52,10 @@ namespace crypto
if (m_PublicKey) EC_POINT_free (m_PublicKey);
}
void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
{
if (m_Curve && m_PublicKey)
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding);
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted);
}
ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
@@ -72,10 +70,10 @@ namespace crypto
if (m_PrivateKey) BN_free (m_PrivateKey);
}
bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
{
if (m_Curve && m_PrivateKey)
return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding);
return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data);
return false;
}
@@ -114,10 +112,10 @@ namespace crypto
if (m_PublicKey) EC_POINT_free (m_PublicKey);
}
void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
{
if (m_PublicKey)
ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding);
ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted);
}
ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv)
@@ -130,10 +128,10 @@ namespace crypto
if (m_PrivateKey) BN_free (m_PrivateKey);
}
bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
{
if (m_PrivateKey)
return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding);
return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data);
return false;
}
@@ -161,7 +159,7 @@ namespace crypto
memcpy (m_PublicKey, pub, 32);
}
void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool)
void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub)
{
memcpy (pub, m_PublicKey, 32);
}
@@ -171,7 +169,7 @@ namespace crypto
m_StaticKeys.SetPrivateKey (priv, calculatePublic);
}
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding)
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret)
{
return m_StaticKeys.Agree (epub, sharedSecret);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -21,7 +21,7 @@ namespace crypto
public:
virtual ~CryptoKeyEncryptor () {};
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; // 222 bytes data, 512/514 bytes encrypted
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) = 0;
};
class CryptoKeyDecryptor
@@ -29,7 +29,7 @@ namespace crypto
public:
virtual ~CryptoKeyDecryptor () {};
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data) = 0;
virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2
};
@@ -39,7 +39,7 @@ namespace crypto
public:
ElGamalEncryptor (const uint8_t * pub);
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
void Encrypt (const uint8_t * data, uint8_t * encrypted) override; // 222 bytes data, 514 bytes encrypted
private:
@@ -51,8 +51,8 @@ namespace crypto
public:
ElGamalDecryptor (const uint8_t * priv);
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
size_t GetPublicKeyLen () const { return 256; };
bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; // 514 bytes encrypted, 222 bytes data
size_t GetPublicKeyLen () const override { return 256; };
private:
@@ -67,7 +67,7 @@ namespace crypto
ECIESP256Encryptor (const uint8_t * pub);
~ECIESP256Encryptor ();
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
void Encrypt (const uint8_t * data, uint8_t * encrypted) override;
private:
@@ -82,8 +82,8 @@ namespace crypto
ECIESP256Decryptor (const uint8_t * priv);
~ECIESP256Decryptor ();
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
size_t GetPublicKeyLen () const { return 64; };
bool Decrypt (const uint8_t * encrypted, uint8_t * data) override;
size_t GetPublicKeyLen () const override { return 64; };
private:
@@ -101,7 +101,7 @@ namespace crypto
ECIESGOSTR3410Encryptor (const uint8_t * pub);
~ECIESGOSTR3410Encryptor ();
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
void Encrypt (const uint8_t * data, uint8_t * encrypted) override;
private:
@@ -115,8 +115,8 @@ namespace crypto
ECIESGOSTR3410Decryptor (const uint8_t * priv);
~ECIESGOSTR3410Decryptor ();
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
size_t GetPublicKeyLen () const { return 64; };
bool Decrypt (const uint8_t * encrypted, uint8_t * data) override;
size_t GetPublicKeyLen () const override { return 64; };
private:
@@ -133,7 +133,7 @@ namespace crypto
ECIESX25519AEADRatchetEncryptor (const uint8_t * pub);
~ECIESX25519AEADRatchetEncryptor () {};
void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool);
void Encrypt (const uint8_t *, uint8_t * pub) override;
// copies m_PublicKey to pub
private:
@@ -147,9 +147,9 @@ namespace crypto
ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false);
~ECIESX25519AEADRatchetDecryptor () {};
bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding);
bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret) override;
// agree with static and return in sharedSecret (32 bytes)
size_t GetPublicKeyLen () const { return 32; };
size_t GetPublicKeyLen () const override { return 32; };
const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); };
private:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -21,6 +21,9 @@ namespace datagram
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip):
m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip)
{
if (m_Gzip)
m_Deflator.reset (new i2p::data::GzipDeflator);
auto identityLen = m_Owner->GetIdentity ()->GetFullLen ();
m_From.resize (identityLen);
m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen);
@@ -152,11 +155,16 @@ namespace datagram
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
{
size_t size;
auto msg = m_I2NPMsgsPool.AcquireShared ();
uint8_t * buf = msg->GetPayload ();
buf += 4; // reserve for length
size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) :
i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len);
if (m_Gzip && m_Deflator)
size = m_Deflator->Deflate (payloads, buf, msg->maxLen - msg->len);
else
size = i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len);
if (size)
{
htobe32buf (msg->GetPayload (), size); // length
@@ -295,7 +303,7 @@ namespace datagram
}
}
if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ())
if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ())
{
bool found = false;
for (auto& it: m_PendingRoutingSessions)
@@ -363,8 +371,6 @@ namespace datagram
{
// no current path, make one
path = std::make_shared<i2p::garlic::GarlicRoutingPath>();
path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel();
if (!path->outboundTunnel) return nullptr;
if (m_RemoteLeaseSet)
{
@@ -378,6 +384,11 @@ namespace datagram
}
else
return nullptr;
auto leaseRouter = i2p::data::netdb.FindRouter (path->remoteLease->tunnelGateway);
path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(nullptr,
leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports);
if (!path->outboundTunnel) return nullptr;
}
else
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -117,12 +117,12 @@ namespace datagram
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
// TODO: implement calls from other thread from SAM
std::shared_ptr<DatagramSession> GetSession(const i2p::data::IdentHash & ident);
void SendDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
void SendRawDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
void FlushSendQueue (std::shared_ptr<DatagramSession> session);
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false);
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
@@ -164,7 +164,7 @@ namespace datagram
std::map<uint16_t, Receiver> m_ReceiversByPorts;
i2p::data::GzipInflator m_Inflator;
i2p::data::GzipDeflator m_Deflator;
std::unique_ptr<i2p::data::GzipDeflator> m_Deflator;
std::vector<uint8_t> m_From, m_Signature;
i2p::util::MemoryPool<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> > m_I2NPMsgsPool;
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -35,6 +35,8 @@ namespace client
int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY;
int outLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
int inVar = DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE;
int outVar = DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE;
int numTags = DEFAULT_TAGS_TO_SEND;
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
try
@@ -53,10 +55,16 @@ namespace client
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY);
if (it != params->end ())
outQty = std::stoi(it->second);
it = params->find (I2CP_PARAM_INBOUND_TUNNELS_LENGTH_VARIANCE);
if (it != params->end ())
inVar = std::stoi(it->second);
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_LENGTH_VARIANCE);
if (it != params->end ())
outVar = std::stoi(it->second);
it = params->find (I2CP_PARAM_TAGS_TO_SEND);
if (it != params->end ())
numTags = std::stoi(it->second);
LogPrint (eLogInfo, "Destination: parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags");
LogPrint (eLogInfo, "Destination: Parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags");
it = params->find (I2CP_PARAM_RATCHET_INBOUND_TAGS);
if (it != params->end ())
SetNumRatchetInboundTags (std::stoi(it->second));
@@ -82,6 +90,14 @@ namespace client
if (it != params->end ()) m_Nickname = it->second;
// otherwise we set default nickname in Start when we know local address
}
it = params->find (I2CP_PARAM_DONT_PUBLISH_LEASESET);
if (it != params->end ())
{
// oveeride isPublic
bool dontpublish = false;
i2p::config::GetOption (it->second, dontpublish);
m_IsPublic = !dontpublish;
}
it = params->find (I2CP_PARAM_LEASESET_TYPE);
if (it != params->end ())
m_LeaseSetType = std::stoi(it->second);
@@ -104,7 +120,7 @@ namespace client
m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>());
if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32)
{
LogPrint(eLogError, "Destination: invalid value i2cp.leaseSetPrivKey ", it->second);
LogPrint(eLogError, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second);
m_LeaseSetPrivKey.reset (nullptr);
}
}
@@ -112,10 +128,10 @@ namespace client
}
catch (std::exception & ex)
{
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
}
SetNumTags (numTags);
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty);
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty, inVar, outVar);
if (explicitPeers)
m_Pool->SetExplicitPeers (explicitPeers);
if(params)
@@ -128,7 +144,7 @@ namespace client
auto minlatency = std::stoi(itr->second);
if ( minlatency > 0 && maxlatency > 0 ) {
// set tunnel pool latency
LogPrint(eLogInfo, "Destination: requiring tunnel latency [", minlatency, "ms, ", maxlatency, "ms]");
LogPrint(eLogInfo, "Destination: Requiring tunnel latency [", minlatency, "ms, ", maxlatency, "ms]");
m_Pool->RequireLatency(minlatency, maxlatency);
}
}
@@ -243,7 +259,7 @@ namespace client
}
else
{
LogPrint (eLogWarning, "Destination: remote LeaseSet expired");
LogPrint (eLogWarning, "Destination: Remote LeaseSet expired");
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
m_RemoteLeaseSets.erase (ident);
return nullptr;
@@ -300,7 +316,11 @@ namespace client
{
int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels
if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum
CreateNewLeaseSet (m_Pool->GetInboundTunnels (numTunnels));
auto tunnels = m_Pool->GetInboundTunnels (numTunnels);
if (!tunnels.empty ())
CreateNewLeaseSet (tunnels);
else
LogPrint (eLogInfo, "Destination: No inbound tunnels for LeaseSet");
}
bool LeaseSetDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
@@ -319,6 +339,22 @@ namespace client
return true;
}
void LeaseSetDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
{
struct
{
uint8_t k[32];
uint64_t t;
} data;
memcpy (data.k, key, 32);
data.t = tag;
auto s = shared_from_this ();
m_Service.post ([s,data](void)
{
s->AddECIESx25519Key (data.k, data.t);
});
}
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
@@ -333,10 +369,11 @@ namespace client
void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len)
{
I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]);
LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE);
uint32_t msgID = bufbe32toh (buf + I2NP_HEADER_MSGID_OFFSET);
LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID);
}
bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len)
bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID)
{
switch (typeID)
{
@@ -353,6 +390,9 @@ namespace client
case eI2NPDatabaseSearchReply:
HandleDatabaseSearchReplyMessage (payload, len);
break;
case eI2NPShortTunnelBuildReply: // might come as garlic encrypted
i2p::HandleI2NPMessage (CreateI2NPMessage (typeID, payload, len, msgID));
break;
default:
LogPrint (eLogWarning, "Destination: Unexpected I2NP message type ", typeID);
return false;
@@ -379,14 +419,14 @@ namespace client
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
auto it = m_RemoteLeaseSets.find (key);
if (it != m_RemoteLeaseSets.end () &&
if (it != m_RemoteLeaseSets.end () &&
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
{
leaseSet = it->second;
if (leaseSet->IsNewer (buf + offset, len - offset))
{
leaseSet->Update (buf + offset, len - offset);
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ())
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
else
{
@@ -405,7 +445,7 @@ namespace client
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset); // LeaseSet
else
leaseSet = std::make_shared<i2p::data::LeaseSet2> (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ())
{
if (leaseSet->GetIdentHash () != GetIdentHash ())
{
@@ -471,7 +511,7 @@ namespace client
i2p::data::IdentHash peerHash (buf + 33 + i*32);
if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash))
{
LogPrint (eLogInfo, "Destination: Found new floodfill, request it");
LogPrint (eLogInfo, "Destination: Found new floodfill, request it");
i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory
}
}
@@ -539,16 +579,9 @@ namespace client
shared_from_this (), std::placeholders::_1));
return;
}
auto outbound = m_Pool->GetNextOutboundTunnel ();
if (!outbound)
if (!m_Pool->GetInboundTunnels ().size () || !m_Pool->GetOutboundTunnels ().size ())
{
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
return;
}
auto inbound = m_Pool->GetNextInboundTunnel ();
if (!inbound)
{
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
LogPrint (eLogError, "Destination: Can't publish LeaseSet. Destination is not ready");
return;
}
auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
@@ -557,7 +590,34 @@ namespace client
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
m_ExcludedFloodfills.clear ();
return;
}
}
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!outbound || !inbound)
{
LogPrint (eLogInfo, "Destination: No compatible tunnels with ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another floodfill");
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
if (floodfill)
{
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
if (outbound)
{
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!inbound)
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
}
else
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
}
else
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
if (!floodfill || !outbound || !inbound)
{
m_ExcludedFloodfills.clear ();
return;
}
}
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
@@ -602,7 +662,7 @@ namespace client
auto ls = GetLeaseSetMt ();
if (!ls)
{
LogPrint (eLogWarning, "Destination: couldn't verify LeaseSet for ", GetIdentHash().ToBase32());
LogPrint (eLogWarning, "Destination: Couldn't verify LeaseSet for ", GetIdentHash().ToBase32());
return;
}
auto s = shared_from_this ();
@@ -614,7 +674,7 @@ namespace client
if (*ls == *leaseSet)
{
// we got latest LeasetSet
LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", s->GetIdentHash().ToBase32());
LogPrint (eLogDebug, "Destination: Published LeaseSet verified for ", s->GetIdentHash().ToBase32());
s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL));
s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1));
return;
@@ -623,7 +683,7 @@ namespace client
LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", s->GetIdentHash().ToBase32());
}
else
LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", s->GetIdentHash().ToBase32());
LogPrint (eLogWarning, "Destination: Couldn't find published LeaseSet for ", s->GetIdentHash().ToBase32());
// we have to publish again
s->Publish ();
});
@@ -735,10 +795,10 @@ namespace client
std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request)
{
if (!request->replyTunnel || !request->replyTunnel->IsEstablished ())
request->replyTunnel = m_Pool->GetNextInboundTunnel ();
request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true));
if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found");
if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ())
request->outboundTunnel = m_Pool->GetNextOutboundTunnel ();
request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false));
if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found");
if (request->replyTunnel && request->outboundTunnel)
@@ -751,11 +811,11 @@ namespace client
uint8_t replyKey[32], replyTag[32];
RAND_bytes (replyKey, 32); // random session key
RAND_bytes (replyTag, isECIES ? 8 : 32); // random session tag
if (isECIES)
if (isECIES)
AddECIESx25519Key (replyKey, replyTag);
else
else
AddSessionKey (replyKey, replyTag);
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
request->outboundTunnel->SendTunnelDataMsg (
{
@@ -850,8 +910,8 @@ namespace client
ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys,
bool isPublic, const std::map<std::string, std::string> * params):
LeaseSetDestination (service, isPublic, params),
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
LeaseSetDestination (service, isPublic, params),
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS),
m_DatagramDestination (nullptr), m_RefCounter (0),
m_ReadyChecker(service)
@@ -900,11 +960,11 @@ namespace client
encryptionKey->GenerateKeys ();
encryptionKey->CreateDecryptor ();
if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
{
{
m_ECIESx25519EncryptionKey.reset (encryptionKey);
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2
}
SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2
}
else
m_StandardEncryptionKey.reset (encryptionKey);
}
@@ -923,7 +983,7 @@ namespace client
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
if (it != params->end ())
i2p::config::GetOption (it->second, m_IsStreamingAnswerPings);
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
{
// authentication for encrypted LeaseSet
@@ -950,7 +1010,7 @@ namespace client
}
catch (std::exception & ex)
{
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
}
}
@@ -1026,7 +1086,7 @@ namespace client
LogPrint (eLogError, "Destination: Missing raw datagram destination");
break;
default:
LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]);
LogPrint (eLogError, "Destination: Data: Unexpected protocol ", buf[9]);
}
}
@@ -1034,7 +1094,7 @@ namespace client
{
if (!streamRequestComplete)
{
LogPrint (eLogError, "Destination: request callback is not specified in CreateStream");
LogPrint (eLogError, "Destination: Request callback is not specified in CreateStream");
return;
}
auto leaseSet = FindLeaseSet (dest);
@@ -1058,7 +1118,7 @@ namespace client
{
if (!streamRequestComplete)
{
LogPrint (eLogError, "Destination: request callback is not specified in CreateStream");
LogPrint (eLogError, "Destination: Request callback is not specified in CreateStream");
return;
}
auto s = GetSharedFromThis ();
@@ -1080,6 +1140,35 @@ namespace client
return nullptr;
}
void ClientDestination::SendPing (const i2p::data::IdentHash& to)
{
if (m_StreamingDestination)
{
auto leaseSet = FindLeaseSet (to);
if (leaseSet)
m_StreamingDestination->SendPing (leaseSet);
else
{
auto s = m_StreamingDestination;
RequestDestination (to,
[s](std::shared_ptr<const i2p::data::LeaseSet> ls)
{
if (ls) s->SendPing (ls);
});
}
}
}
void ClientDestination::SendPing (std::shared_ptr<const i2p::data::BlindedPublicKey> to)
{
auto s = m_StreamingDestination;
RequestDestinationWithEncryptedLeaseSet (to,
[s](std::shared_ptr<const i2p::data::LeaseSet> ls)
{
if (ls) s->SendPing (ls);
});
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::GetStreamingDestination (int port) const
{
if (port)
@@ -1127,6 +1216,21 @@ namespace client
return dest;
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::RemoveStreamingDestination (int port)
{
if (port)
{
auto it = m_StreamingDestinationsByPorts.find (port);
if (it != m_StreamingDestinationsByPorts.end ())
{
auto ret = it->second;
m_StreamingDestinationsByPorts.erase (it);
return ret;
}
}
return nullptr;
}
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
{
if (m_DatagramDestination == nullptr)
@@ -1176,7 +1280,7 @@ namespace client
LogPrint(eLogError, "Destinations: Can't save keys to ", path);
}
void ClientDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels)
void ClientDestination::CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels)
{
std::shared_ptr<i2p::data::LocalLeaseSet> leaseSet;
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
@@ -1214,15 +1318,15 @@ namespace client
if (m_DatagramDestination) m_DatagramDestination->CleanUp ();
}
bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const
bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const
{
if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor)
return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true);
return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data);
if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor)
return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true);
return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data);
else
LogPrint (eLogError, "Destinations: decryptor is not set");
LogPrint (eLogError, "Destinations: Decryptor is not set");
return false;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -53,6 +53,10 @@ namespace client
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_INBOUND_TUNNELS_LENGTH_VARIANCE[] = "inbound.lengthVariance";
const int DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE = 0;
const char I2CP_PARAM_OUTBOUND_TUNNELS_LENGTH_VARIANCE[] = "outbound.lengthVariance";
const int DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE = 0;
const char I2CP_PARAM_EXPLICIT_PEERS[] = "explicitPeers";
const int STREAM_REQUEST_TIMEOUT = 60; //in seconds
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
@@ -61,8 +65,9 @@ namespace client
const char I2CP_PARAM_RATCHET_OUTBOUND_TAGS[] = "crypto.ratchet.outboundTags"; // not used yet
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname";
const char I2CP_PARAM_DONT_PUBLISH_LEASESET[] = "i2cp.dontPublishLeaseSet";
const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType";
const int DEFAULT_LEASESET_TYPE = 1;
const int DEFAULT_LEASESET_TYPE = 3;
const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType";
const char I2CP_PARAM_LEASESET_PRIV_KEY[] = "i2cp.leaseSetPrivKey"; // PSK decryption key, base64
const char I2CP_PARAM_LEASESET_AUTH_TYPE[] = "i2cp.leaseSetAuthType";
@@ -79,7 +84,7 @@ namespace client
const char I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY[] = "i2p.streaming.initialAckDelay";
const int DEFAULT_INITIAL_ACK_DELAY = 200; // milliseconds
const char I2CP_PARAM_STREAMING_ANSWER_PINGS[] = "i2p.streaming.answerPings";
const int DEFAULT_ANSWER_PINGS = true;
const int DEFAULT_ANSWER_PINGS = true;
typedef std::function<void (std::shared_ptr<i2p::stream::Stream> stream)> StreamRequestComplete;
@@ -133,17 +138,19 @@ namespace client
// override GarlicDestination
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag);
void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag);
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
void SetLeaseSetUpdated ();
bool IsPublic () const { return m_IsPublic; };
void SetPublic (bool pub) { m_IsPublic = pub; };
protected:
// implements GarlicDestination
void HandleI2NPMessage (const uint8_t * buf, size_t len);
bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len);
bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID);
void SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet);
int GetLeaseSetType () const { return m_LeaseSetType; };
@@ -152,7 +159,7 @@ namespace client
virtual void CleanupDestination () {}; // additional clean up in derived classes
// I2CP
virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0;
virtual void CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels) = 0;
virtual void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) = 0;
private:
@@ -236,23 +243,26 @@ namespace client
// streaming
std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (int port, bool gzip = true); // additional
std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (int port = 0) const;
std::shared_ptr<i2p::stream::StreamingDestination> RemoveStreamingDestination (int port);
// following methods operate with default streaming destination
void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0);
void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port = 0);
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
void SendPing (const i2p::data::IdentHash& to);
void SendPing (std::shared_ptr<const i2p::data::BlindedPublicKey> to);
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
void StopAcceptingStreams ();
bool IsAcceptingStreams () const;
void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor);
int GetStreamingAckDelay () const { return m_StreamingAckDelay; }
bool IsStreamingAnswerPings () const { return m_IsStreamingAnswerPings; }
// datagram
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true);
// implements LocalDestination
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const;
bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const;
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const;
@@ -262,7 +272,7 @@ namespace client
void CleanupDestination ();
// I2CP
void HandleDataMessage (const uint8_t * buf, size_t len);
void CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels);
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels);
private:
@@ -309,5 +319,4 @@ namespace client
}
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,16 +31,16 @@ namespace garlic
uint8_t keydata[64];
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf);
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_SessionTagKeyData);
// [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32);
memcpy (m_SymmKeyCK, (const uint8_t *)m_SessionTagKeyData + 32, 32);
m_NextSymmKeyIndex = 0;
}
void RatchetTagSet::NextSessionTagRatchet ()
{
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64)
memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32);
i2p::crypto::HKDF (m_SessionTagKeyData, nullptr, 0, "STInitialization", m_SessionTagKeyData); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64)
memcpy (m_SessTagConstant, (const uint8_t *)m_SessionTagKeyData + 32, 32); // SESSTAG_CONSTANT = keydata[32:63]
m_NextIndex = 0;
}
@@ -52,8 +52,8 @@ namespace garlic
LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty");
return 0;
}
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
return m_KeyData.GetTag ();
i2p::crypto::HKDF (m_SessionTagKeyData, m_SessTagConstant, 32, "SessionTagKeyGen", m_SessionTagKeyData); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
return m_SessionTagKeyData.GetLL ()[4]; // tag = keydata[32:39]
}
void RatchetTagSet::GetSymmKey (int index, uint8_t * key)
@@ -90,24 +90,24 @@ namespace garlic
}
void RatchetTagSet::DeleteSymmKey (int index)
{
{
m_ItermediateSymmKeys.erase (index);
}
void ReceiveRatchetTagSet::Expire ()
{
if (!m_ExpirationTimestamp)
m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT;
}
bool ReceiveRatchetTagSet::IsExpired (uint64_t ts) const
{
return m_ExpirationTimestamp && ts > m_ExpirationTimestamp;
}
bool ReceiveRatchetTagSet::IsIndexExpired (int index) const
{
return index < m_TrimBehindIndex;
bool ReceiveRatchetTagSet::IsExpired (uint64_t ts) const
{
return m_ExpirationTimestamp && ts > m_ExpirationTimestamp;
}
bool ReceiveRatchetTagSet::IsIndexExpired (int index) const
{
return index < m_TrimBehindIndex;
}
bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index)
@@ -115,54 +115,55 @@ namespace garlic
auto session = GetSession ();
if (!session) return false;
return session->HandleNextMessage (buf, len, shared_from_this (), index);
}
DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key):
ReceiveRatchetTagSet (nullptr), m_Destination (destination)
{
memcpy (m_Key, key, 32);
Expire ();
}
bool DatabaseLookupTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index)
SymmetricKeyTagSet::SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key):
ReceiveRatchetTagSet (nullptr), m_Destination (destination)
{
memcpy (m_Key, key, 32);
Expire ();
}
bool SymmetricKeyTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index)
{
if (len < 24) return false;
uint8_t nonce[12];
memset (nonce, 0, 12); // n = 0
size_t offset = 8; // first 8 bytes is reply tag used as AD
size_t offset = 8; // first 8 bytes is reply tag used as AD
len -= 16; // poly1305
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len - offset, buf, 8, m_Key, nonce, buf + offset, len - offset, false)) // decrypt
{
LogPrint (eLogWarning, "Garlic: Lookup reply AEAD decryption failed");
LogPrint (eLogWarning, "Garlic: Symmetric key tagset AEAD decryption failed");
return false;
}
// we assume 1 I2NP block with delivery type local
if (offset + 3 > len)
{
LogPrint (eLogWarning, "Garlic: Lookup reply is too short ", len);
if (offset + 3 > len)
{
LogPrint (eLogWarning, "Garlic: Symmetric key tagset is too short ", len);
return false;
}
}
if (buf[offset] != eECIESx25519BlkGalicClove)
{
LogPrint (eLogWarning, "Garlic: Lookup reply unexpected block ", (int)buf[offset]);
LogPrint (eLogWarning, "Garlic: Symmetric key tagset unexpected block ", (int)buf[offset]);
return false;
}
}
offset++;
auto size = bufbe16toh (buf + offset);
offset += 2;
if (offset + size > len)
if (offset + size > len)
{
LogPrint (eLogWarning, "Garlic: Lookup reply block is too long ", size);
LogPrint (eLogWarning, "Garlic: Symmetric key tagset block is too long ", size);
return false;
}
}
if (m_Destination)
m_Destination->HandleECIESx25519GarlicClove (buf + offset, size);
m_Destination->HandleECIESx25519GarlicClove (buf + offset, size);
return true;
}
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet):
GarlicRoutingSession (owner, attachLeaseSet)
}
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS):
GarlicRoutingSession (owner, true)
{
if (!attachLeaseSetNS) SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0;
}
@@ -180,11 +181,11 @@ namespace garlic
{
bool ineligible = false;
while (!ineligible)
{
{
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
ineligible = m_EphemeralKeys->IsElligatorIneligible ();
if (!ineligible) // we haven't tried it yet
{
{
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf))
return true; // success
// otherwise return back
@@ -193,9 +194,9 @@ namespace garlic
}
else
i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys);
}
}
// we still didn't find elligator eligible pair
for (int i = 0; i < 10; i++)
for (int i = 0; i < 25; i++)
{
// create new
m_EphemeralKeys = std::make_shared<i2p::crypto::X25519Keys>();
@@ -207,7 +208,7 @@ namespace garlic
// let NTCP2 use it
m_EphemeralKeys->SetElligatorIneligible ();
i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys);
}
}
}
LogPrint (eLogError, "Garlic: Can't generate elligator eligible x25519 keys");
return false;
@@ -228,7 +229,7 @@ namespace garlic
// we are Bob
// KDF1
i2p::crypto::InitNoiseIKState (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk
if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk))
{
LogPrint (eLogError, "Garlic: Can't decode elligator");
@@ -238,11 +239,11 @@ namespace garlic
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
uint8_t sharedSecret[32];
if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
{
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
return false;
}
}
MixKey (sharedSecret);
// decrypt flags/static
@@ -262,11 +263,11 @@ namespace garlic
{
// static key, fs is apk
memcpy (m_RemoteStaticKey, fs, 32);
if (!GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk)
if (!GetOwner ()->Decrypt (fs, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk)
{
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
return false;
}
}
MixKey (sharedSecret);
}
else // all zeros flags
@@ -279,13 +280,13 @@ namespace garlic
LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed");
return false;
}
m_State = eSessionStateNewSessionReceived;
if (isStatic)
{
if (isStatic)
{
MixHash (buf, len); // h = SHA256(h || ciphertext)
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
}
}
HandlePayload (payload.data (), len - 16, nullptr, 0);
return true;
@@ -313,7 +314,7 @@ namespace garlic
GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size);
break;
case eECIESx25519BlkNextKey:
LogPrint (eLogDebug, "Garlic: next key");
LogPrint (eLogDebug, "Garlic: Next key");
if (receiveTagset)
HandleNextKey (buf + offset, size, receiveTagset);
else
@@ -321,7 +322,7 @@ namespace garlic
break;
case eECIESx25519BlkAck:
{
LogPrint (eLogDebug, "Garlic: ack");
LogPrint (eLogDebug, "Garlic: Ack");
int numAcks = size >> 2; // /4
auto offset1 = offset;
for (auto i = 0; i < numAcks; i++)
@@ -333,24 +334,24 @@ namespace garlic
}
case eECIESx25519BlkAckRequest:
{
LogPrint (eLogDebug, "Garlic: ack request");
LogPrint (eLogDebug, "Garlic: Ack request");
m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index});
break;
}
case eECIESx25519BlkTermination:
LogPrint (eLogDebug, "Garlic: termination");
LogPrint (eLogDebug, "Garlic: Termination");
if (GetOwner ())
GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey);
if (receiveTagset) receiveTagset->Expire ();
break;
case eECIESx25519BlkDateTime:
LogPrint (eLogDebug, "Garlic: datetime");
LogPrint (eLogDebug, "Garlic: Datetime");
break;
case eECIESx25519BlkOptions:
LogPrint (eLogDebug, "Garlic: options");
LogPrint (eLogDebug, "Garlic: Options");
break;
case eECIESx25519BlkPadding:
LogPrint (eLogDebug, "Garlic: padding");
LogPrint (eLogDebug, "Garlic: Padding");
break;
default:
LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk);
@@ -380,7 +381,7 @@ namespace garlic
newTagset->NextSessionTagRatchet ();
m_SendTagset = newTagset;
m_SendForwardKey = false;
LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created");
LogPrint (eLogDebug, "Garlic: Next send tagset ", newTagset->GetTagSetID (), " created");
}
else
LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID);
@@ -423,7 +424,7 @@ namespace garlic
GenerateMoreReceiveTags (newTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ?
GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MAX_NUM_GENERATED_TAGS);
receiveTagset->Expire ();
LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created");
LogPrint (eLogDebug, "Garlic: Next receive tagset ", tagsetID, " created");
}
}
@@ -445,7 +446,7 @@ namespace garlic
m_NextSendRatchet->key = i2p::transport::transports.GetNextX25519KeysPair ();
m_SendForwardKey = true;
LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
LogPrint (eLogDebug, "Garlic: New send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
}
bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic)
@@ -467,7 +468,7 @@ namespace garlic
{
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
return false;
}
}
MixKey (sharedSecret);
// encrypt flags/static key section
uint8_t nonce[12];
@@ -477,7 +478,7 @@ namespace garlic
fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
else
{
memset (out + offset, 0, 32); // all zeros flags section
memset (out + offset, 0, 32); // all zeros flags section
fs = out + offset;
}
if (!i2p::crypto::AEADChaCha20Poly1305 (fs, 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
@@ -485,14 +486,14 @@ namespace garlic
LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed ");
return false;
}
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
offset += 48;
// KDF2
if (isStatic)
{
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk)
MixKey (sharedSecret);
{
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk)
MixKey (sharedSecret);
}
else
CreateNonce (1, nonce);
@@ -502,50 +503,22 @@ namespace garlic
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
return false;
}
m_State = eSessionStateNewSessionSent;
if (isStatic)
{
{
MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext)
if (GetOwner ())
{
auto tagsetNsr = std::make_shared<ReceiveRatchetTagSet>(shared_from_this (), true);
InitNewSessionTagset (tagsetNsr);
tagsetNsr->Expire (); // let non-replied session expire
GenerateMoreReceiveTags (tagsetNsr, ECIESX25519_NSR_NUM_GENERATED_TAGS);
}
}
}
return true;
}
bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
{
// we are Alice, router's bpk is m_RemoteStaticKey
i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey);
size_t offset = 0;
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32);
MixHash (out + offset, 32); // h = SHA256(h || aepk)
offset += 32;
uint8_t sharedSecret[32];
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk)
{
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
return false;
}
MixKey (sharedSecret);
uint8_t nonce[12];
CreateNonce (0, nonce);
// encrypt payload
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt
{
LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed");
return false;
}
m_State = eSessionStateNewSessionSent;
return true;
}
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
{
// we are Bob
@@ -561,7 +534,7 @@ namespace garlic
LogPrint (eLogError, "Garlic: Can't encode elligator");
return false;
}
memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR
memcpy (m_NSREncodedKey, out + offset, 32); // for possible next NSR
memcpy (m_NSRH, m_H, 32);
offset += 32;
// KDF for Reply Key Section
@@ -572,13 +545,13 @@ namespace garlic
{
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
return false;
}
}
MixKey (sharedSecret);
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk)
{
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
return false;
}
}
MixKey (sharedSecret);
uint8_t nonce[12];
CreateNonce (0, nonce);
@@ -611,10 +584,10 @@ namespace garlic
}
m_State = eSessionStateNewSessionReplySent;
m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch ();
return true;
}
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
{
// we are Bob and sent NSR already
@@ -645,7 +618,7 @@ namespace garlic
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
{
// we are Alice
LogPrint (eLogDebug, "Garlic: reply received");
LogPrint (eLogDebug, "Garlic: Reply received");
const uint8_t * tag = buf;
buf += 8; len -= 8; // tag
uint8_t bepk[32]; // Bob's ephemeral key
@@ -664,9 +637,9 @@ namespace garlic
{
LogPrint (eLogWarning, "Garlic: Incorrect Bob ephemeral key");
return false;
}
}
MixKey (sharedSecret);
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
GetOwner ()->Decrypt (bepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
MixKey (sharedSecret);
uint8_t nonce[12];
@@ -727,11 +700,11 @@ namespace garlic
uint64_t tag = m_SendTagset->GetNextSessionTag ();
if (!tag)
{
LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for send tagset");
LogPrint (eLogError, "Garlic: Can't create new ECIES-X25519-AEAD-Ratchet tag for send tagset");
if (GetOwner ())
GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey);
return false;
}
}
memcpy (out, &tag, 8);
// ad = The session tag, 8 bytes
// ciphertext = ENCRYPT(k, n, payload, ad)
@@ -763,7 +736,7 @@ namespace garlic
}
HandlePayload (payload, len - 16, receiveTagset, index);
if (GetOwner ())
{
{
int moreTags = 0;
if (GetOwner ()->GetNumRatchetInboundTags () > 0) // override in settings?
{
@@ -772,17 +745,17 @@ namespace garlic
index -= GetOwner ()->GetNumRatchetInboundTags (); // trim behind
}
else
{
{
moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4
if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS;
moreTags -= (receiveTagset->GetNextIndex () - index);
index -= ECIESX25519_MAX_NUM_GENERATED_TAGS; // trim behind
}
}
if (moreTags > 0)
GenerateMoreReceiveTags (receiveTagset, moreTags);
if (index > 0)
receiveTagset->SetTrimBehind (index);
}
}
return true;
}
@@ -801,30 +774,30 @@ namespace garlic
#endif
case eSessionStateEstablished:
if (receiveTagset->IsNS ())
{
// our of sequence NSR
LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index);
{
// our of sequence NSR
LogPrint (eLogDebug, "Garlic: Check for out of order NSR with index ", index);
if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2)
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS);
return HandleNewOutgoingSessionReply (buf, len);
}
}
else
return HandleExistingSessionMessage (buf, len, receiveTagset, index);
case eSessionStateNew:
return HandleNewIncomingSession (buf, len);
case eSessionStateNewSessionSent:
receiveTagset->Expire (); // NSR tagset
return HandleNewOutgoingSessionReply (buf, len);
default:
return false;
}
return true;
}
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
{
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
size_t len = payload.size ();
uint8_t * payload = GetOwner ()->GetPayloadBuffer ();
if (!payload) return nullptr;
size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload);
if (!len) return nullptr;
auto m = NewI2NPMessage (len + 100); // 96 + 4
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
@@ -833,35 +806,30 @@ namespace garlic
switch (m_State)
{
case eSessionStateEstablished:
if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
if (!NewExistingSessionMessage (payload, len, buf, m->maxLen))
return nullptr;
len += 24;
break;
case eSessionStateNew:
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen))
return nullptr;
len += 96;
break;
case eSessionStateNewSessionReceived:
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
if (!NewSessionReplyMessage (payload, len, buf, m->maxLen))
return nullptr;
len += 72;
break;
case eSessionStateNewSessionReplySent:
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen))
return nullptr;
len += 72;
break;
case eSessionStateOneTime:
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen, false))
if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false))
return nullptr;
len += 96;
break;
case eSessionStateForRouter:
if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen))
return nullptr;
len += 48;
break;
break;
default:
return nullptr;
}
@@ -872,22 +840,22 @@ namespace garlic
return m;
}
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter)
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg)
{
m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime;
m_State = eSessionStateOneTime;
return WrapSingleMessage (msg);
}
std::vector<uint8_t> ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first)
}
size_t ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first, uint8_t * payload)
{
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
size_t payloadLen = 0;
if (first) payloadLen += 7;// datatime
if (msg)
{
{
payloadLen += msg->GetPayloadLength () + 13;
if (m_Destination) payloadLen += 32;
}
}
if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)
{
// resubmit non-confirmed LeaseSet
@@ -928,9 +896,9 @@ namespace garlic
paddingSize = m_PaddingSizes[m_NextPaddingSize++] & 0x0F; // 0 - 15
if (m_NextPaddingSize >= 32)
{
RAND_bytes (m_PaddingSizes, 32);
RAND_bytes (m_PaddingSizes, 32);
m_NextPaddingSize = 0;
}
}
if (delta > 3)
{
delta -= 3;
@@ -940,89 +908,93 @@ namespace garlic
payloadLen += paddingSize + 3;
}
}
std::vector<uint8_t> v(payloadLen);
if (payloadLen)
{
{
if (payloadLen > I2NP_MAX_MESSAGE_SIZE)
{
LogPrint (eLogError, "Garlic: Payload length ", payloadLen, " is too long");
return 0;
}
m_LastSentTimestamp = ts;
size_t offset = 0;
// DateTime
if (first)
{
v[offset] = eECIESx25519BlkDateTime; offset++;
htobe16buf (v.data () + offset, 4); offset += 2;
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
payload[offset] = eECIESx25519BlkDateTime; offset++;
htobe16buf (payload + offset, 4); offset += 2;
htobe32buf (payload + offset, ts/1000); offset += 4; // in seconds
}
// LeaseSet
if (leaseSet)
{
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
offset += CreateLeaseSetClove (leaseSet, ts, payload + offset, payloadLen - offset);
if (!first)
{
// ack request
v[offset] = eECIESx25519BlkAckRequest; offset++;
htobe16buf (v.data () + offset, 1); offset += 2;
v[offset] = 0; offset++; // flags
payload[offset] = eECIESx25519BlkAckRequest; offset++;
htobe16buf (payload + offset, 1); offset += 2;
payload[offset] = 0; offset++; // flags
}
}
// msg
if (msg)
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset);
offset += CreateGarlicClove (msg, payload + offset, payloadLen - offset);
// ack
if (m_AckRequests.size () > 0)
{
v[offset] = eECIESx25519BlkAck; offset++;
htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2;
payload[offset] = eECIESx25519BlkAck; offset++;
htobe16buf (payload + offset, m_AckRequests.size () * 4); offset += 2;
for (auto& it: m_AckRequests)
{
htobe16buf (v.data () + offset, it.first); offset += 2;
htobe16buf (v.data () + offset, it.second); offset += 2;
htobe16buf (payload + offset, it.first); offset += 2;
htobe16buf (payload + offset, it.second); offset += 2;
}
m_AckRequests.clear ();
}
// next keys
if (m_SendReverseKey)
{
v[offset] = eECIESx25519BlkNextKey; offset++;
htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2;
v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG;
payload[offset] = eECIESx25519BlkNextKey; offset++;
htobe16buf (payload + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2;
payload[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG;
int keyID = m_NextReceiveRatchet->keyID - 1;
if (m_NextReceiveRatchet->newKey)
{
v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG;
payload[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG;
keyID++;
}
offset++; // flag
htobe16buf (v.data () + offset, keyID); offset += 2; // keyid
htobe16buf (payload + offset, keyID); offset += 2; // keyid
if (m_NextReceiveRatchet->newKey)
{
memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32);
memcpy (payload + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32);
offset += 32; // public key
}
m_SendReverseKey = false;
}
if (m_SendForwardKey)
{
v[offset] = eECIESx25519BlkNextKey; offset++;
htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2;
v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG;
if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only
payload[offset] = eECIESx25519BlkNextKey; offset++;
htobe16buf (payload + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2;
payload[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG;
if (!m_NextSendRatchet->keyID) payload[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only
offset++; // flag
htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid
htobe16buf (payload + offset, m_NextSendRatchet->keyID); offset += 2; // keyid
if (m_NextSendRatchet->newKey)
{
memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32);
memcpy (payload + offset, m_NextSendRatchet->key->GetPublicKey (), 32);
offset += 32; // public key
}
}
// padding
if (paddingSize)
{
v[offset] = eECIESx25519BlkPadding; offset++;
htobe16buf (v.data () + offset, paddingSize); offset += 2;
memset (v.data () + offset, 0, paddingSize); offset += paddingSize;
payload[offset] = eECIESx25519BlkPadding; offset++;
htobe16buf (payload + offset, paddingSize); offset += 2;
memset (payload + offset, 0, paddingSize); offset += paddingSize;
}
}
return v;
}
return payloadLen;
}
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len)
@@ -1078,17 +1050,17 @@ namespace garlic
void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr<ReceiveRatchetTagSet> receiveTagset, int numTags)
{
if (GetOwner ())
{
{
for (int i = 0; i < numTags; i++)
{
{
auto tag = GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset);
if (!tag)
{
LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for receive tagset");
LogPrint (eLogError, "Garlic: Can't create new ECIES-X25519-AEAD-Ratchet tag for receive tagset");
break;
}
}
}
}
}
}
}
bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts)
@@ -1101,68 +1073,138 @@ namespace garlic
RouterIncomingRatchetSession::RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState):
ECIESX25519AEADRatchetSession (&i2p::context, false)
{
SetLeaseSetUpdateStatus (eLeaseSetDoNotSend);
SetNoiseState (initState);
}
}
bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len)
{
if (!GetOwner ()) return false;
i2p::crypto::NoiseSymmetricState state (GetNoiseState ());
m_CurrentNoiseState = GetNoiseState ();
// we are Bob
state.MixHash (buf, 32);
m_CurrentNoiseState.MixHash (buf, 32);
uint8_t sharedSecret[32];
if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
if (!GetOwner ()->Decrypt (buf, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
{
LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key");
return false;
}
state.MixKey (sharedSecret);
buf += 32; len -= 32;
}
m_CurrentNoiseState.MixKey (sharedSecret);
buf += 32; len -= 32;
uint8_t nonce[12];
CreateNonce (0, nonce);
std::vector<uint8_t> payload (len - 16);
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, state.m_H, 32, state.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
std::vector<uint8_t> payload (len - 16);
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_CurrentNoiseState.m_H, 32,
m_CurrentNoiseState.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
{
LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed");
return false;
}
HandlePayload (payload.data (), len - 16, nullptr, 0);
return true;
}
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
}
static size_t CreateGarlicPayload (std::shared_ptr<const I2NPMessage> msg, uint8_t * payload,
bool datetime, size_t optimalSize)
{
size_t len = 0;
if (datetime)
{
// DateTime
payload[0] = eECIESx25519BlkDateTime;
htobe16buf (payload + 1, 4);
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
len = 7;
}
// I2NP
payload += len;
uint16_t cloveSize = msg->GetPayloadLength () + 10;
payload[0] = eECIESx25519BlkGalicClove; // clove type
htobe16buf (payload + 1, cloveSize); // size
payload += 3;
payload[0] = 0; // flag and delivery instructions
payload[1] = msg->GetTypeID (); // I2NP msg type
htobe32buf (payload + 2, msg->GetMsgID ()); // msgID
htobe32buf (payload + 6, msg->GetExpiration () / 1000); // expiration in seconds
memcpy (payload + 10, msg->GetPayload (), msg->GetPayloadLength ());
len += cloveSize + 3;
payload += cloveSize;
// padding
int delta = (int)optimalSize - (int)len;
if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size
{
uint8_t paddingSize = rand () & 0x0F; // 0 - 15
if (delta > 3)
{
delta -= 3;
if (paddingSize > delta) paddingSize %= delta;
}
payload[0] = eECIESx25519BlkPadding;
htobe16buf (payload + 1, paddingSize);
if (paddingSize) memset (payload + 3, 0, paddingSize);
len += paddingSize + 3;
}
return len;
}
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
{
auto m = NewI2NPMessage ();
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
uint8_t nonce[12];
memset (nonce, 0, 12); // n = 0
size_t offset = 0;
memcpy (buf + offset, &tag, 8); offset += 8;
auto payload = buf + offset;
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
size_t len = cloveSize + 3;
payload[0] = eECIESx25519BlkGalicClove; // clove type
htobe16buf (payload + 1, cloveSize); // size
payload += 3;
*payload = 0; payload++; // flag and delivery instructions
*payload = msg->GetTypeID (); // I2NP msg type
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt
size_t len = CreateGarlicPayload (msg, payload, false, 956); // 1003 - 8 tag - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 3 local tunnel delivery
uint8_t nonce[12];
memset (nonce, 0, 12); // n = 0
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt
{
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
return nullptr;
}
offset += len + 16;
htobe32buf (m->GetPayload (), offset);
m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
return m;
}
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<const I2NPMessage> msg, const uint8_t * routerPublicKey)
{
// Noise_N, we are Alice, routerPublicKey is Bob's
i2p::crypto::NoiseSymmetricState noiseState;
i2p::crypto::InitNoiseNState (noiseState, routerPublicKey);
auto m = NewI2NPMessage ();
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
size_t offset = 0;
auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32);
noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk)
offset += 32;
uint8_t sharedSecret[32];
if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk)
{
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
return nullptr;
}
noiseState.MixKey (sharedSecret);
auto payload = buf + offset;
size_t len = CreateGarlicPayload (msg, payload, true, 900); // 1003 - 32 eph key - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 35 router tunnel delivery
uint8_t nonce[12];
memset (nonce, 0, 12);
// encrypt payload
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt
{
LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed");
return nullptr;
}
offset += len + 16;
htobe32buf (m->GetPayload (), offset);
m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
return m;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -27,7 +27,7 @@ namespace garlic
{
const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second since session creation we can restart session after
const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of seconds we receive nothing and should restart if we can
const int ECIESX25519_SEND_INACTIVITY_TIMEOUT = 5000; // number of milliseconds we can send empty(pyaload only) packet after
const int ECIESX25519_SEND_INACTIVITY_TIMEOUT = 5000; // number of milliseconds we can send empty(pyaload only) packet after
const int ECIESX25519_SEND_EXPIRATION_TIMEOUT = 480; // in seconds
const int ECIESX25519_RECEIVE_EXPIRATION_TIMEOUT = 600; // in seconds
const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180
@@ -45,7 +45,7 @@ namespace garlic
RatchetTagSet () {};
virtual ~RatchetTagSet () {};
void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
void NextSessionTagRatchet ();
uint64_t GetNextSessionTag ();
@@ -56,23 +56,14 @@ namespace garlic
int GetTagSetID () const { return m_TagSetID; };
void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; };
private:
union
{
uint64_t ll[8];
uint8_t buf[64];
const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31]
const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63]
uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39]
} m_KeyData;
i2p::data::Tag<64> m_SessionTagKeyData;
uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32];
int m_NextIndex, m_NextSymmKeyIndex;
std::unordered_map<int, i2p::data::Tag<32> > m_ItermediateSymmKeys;
int m_TagSetID = 0;
};
@@ -82,42 +73,43 @@ namespace garlic
{
public:
ReceiveRatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session, bool isNS = false):
ReceiveRatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session, bool isNS = false):
m_Session (session), m_IsNS (isNS) {};
bool IsNS () const { return m_IsNS; };
std::shared_ptr<ECIESX25519AEADRatchetSession> GetSession () { return m_Session; };
void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; };
void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; };
int GetTrimBehind () const { return m_TrimBehindIndex; };
void Expire ();
bool IsExpired (uint64_t ts) const;
bool IsExpired (uint64_t ts) const;
virtual bool IsIndexExpired (int index) const;
virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index);
private:
int m_TrimBehindIndex = 0;
std::shared_ptr<ECIESX25519AEADRatchetSession> m_Session;
bool m_IsNS;
uint64_t m_ExpirationTimestamp = 0;
};
};
class DatabaseLookupTagSet: public ReceiveRatchetTagSet
class SymmetricKeyTagSet: public ReceiveRatchetTagSet
{
public:
DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key);
SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key);
bool IsIndexExpired (int index) const { return false; };
bool HandleNextMessage (uint8_t * buf, size_t len, int index);
private:
GarlicDestination * m_Destination;
uint8_t m_Key[32];
};
};
enum ECIESx25519BlockType
{
eECIESx25519BlkDateTime = 0,
@@ -135,7 +127,7 @@ namespace garlic
const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02;
const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04;
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession,
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession,
private i2p::crypto::NoiseSymmetricState,
public std::enable_shared_from_this<ECIESX25519AEADRatchetSession>
{
@@ -146,8 +138,7 @@ namespace garlic
eSessionStateNewSessionSent,
eSessionStateNewSessionReplySent,
eSessionStateEstablished,
eSessionStateOneTime,
eSessionStateForRouter
eSessionStateOneTime
};
struct DHRatchet
@@ -160,16 +151,16 @@ namespace garlic
public:
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet);
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS);
~ECIESX25519AEADRatchetSession ();
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<ReceiveRatchetTagSet> receiveTagset, int index = 0);
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter = false);
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg);
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
void Terminate () { m_IsTerminated = true; }
void SetDestination (const i2p::data::IdentHash& dest) // TODO:
{
@@ -179,19 +170,19 @@ namespace garlic
bool CheckExpired (uint64_t ts); // true is expired
bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; }
bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); }
bool IsRatchets () const { return true; };
bool IsReadyToSend () const { return m_State != eSessionStateNewSessionSent; };
bool IsTerminated () const { return m_IsTerminated; }
uint64_t GetLastActivityTimestamp () const { return m_LastActivityTimestamp; };
protected:
protected:
i2p::crypto::NoiseSymmetricState& GetNoiseState () { return *this; };
void SetNoiseState (const i2p::crypto::NoiseSymmetricState& state) { GetNoiseState () = state; };
void CreateNonce (uint64_t seqn, uint8_t * nonce);
void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<ReceiveRatchetTagSet>& receiveTagset, int index);
private:
bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes
@@ -206,9 +197,8 @@ namespace garlic
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first);
size_t CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first, uint8_t * payload);
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len);
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
@@ -230,7 +220,7 @@ namespace garlic
bool m_SendReverseKey = false, m_SendForwardKey = false, m_IsTerminated = false;
std::unique_ptr<DHRatchet> m_NextReceiveRatchet, m_NextSendRatchet;
uint8_t m_PaddingSizes[32], m_NextPaddingSize;
public:
// for HTTP only
@@ -248,10 +238,17 @@ namespace garlic
RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState);
bool HandleNextMessage (const uint8_t * buf, size_t len);
};
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
private:
i2p::crypto::NoiseSymmetricState m_CurrentNoiseState;
};
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<const I2NPMessage> msg, const uint8_t * routerPublicKey);
}
}
#endif

View File

@@ -12,6 +12,7 @@
#ifdef _WIN32
#include <shlobj.h>
#include <windows.h>
#include <codecvt>
#endif
#include "Base.h"
@@ -23,6 +24,7 @@ namespace i2p {
namespace fs {
std::string appName = "i2pd";
std::string dataDir = "";
std::string certsDir = "";
#ifdef _WIN32
std::string dirSep = "\\";
#else
@@ -41,16 +43,32 @@ namespace fs {
return dataDir;
}
const std::string & GetCertsDir () {
return certsDir;
}
const std::string GetUTF8DataDir () {
#ifdef _WIN32
boost::filesystem::wpath path (dataDir);
auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) ); // convert path to UTF-8
auto dataDirUTF8 = path.string();
boost::filesystem::path::imbue(loc); // Return locale settings back
return dataDirUTF8;
#else
return dataDir; // linux, osx, android uses UTF-8 by default
#endif
}
void DetectDataDir(const std::string & cmdline_param, bool isService) {
if (cmdline_param != "") {
dataDir = cmdline_param;
return;
}
#ifdef _WIN32
char localAppData[MAX_PATH];
wchar_t localAppData[MAX_PATH];
// check executable directory first
if(!GetModuleFileName(NULL, localAppData, MAX_PATH))
if(!GetModuleFileNameW(NULL, localAppData, MAX_PATH))
{
#ifdef WIN32_APP
MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
@@ -61,14 +79,15 @@ namespace fs {
}
else
{
auto execPath = boost::filesystem::path(localAppData).parent_path();
auto execPath = boost::filesystem::wpath(localAppData).parent_path();
// if config file exists in .exe's folder use it
if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
dataDir = execPath.string ();
else // otherwise %appdata%
{
if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
dataDir = execPath.string ();
} else // otherwise %appdata%
{
if(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
{
#ifdef WIN32_APP
MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
@@ -78,7 +97,9 @@ namespace fs {
exit(1);
}
else
dataDir = std::string(localAppData) + "\\" + appName;
{
dataDir = boost::filesystem::wpath(localAppData).string() + "\\" + appName;
}
}
}
return;
@@ -110,6 +131,21 @@ namespace fs {
#endif
}
void SetCertsDir(const std::string & cmdline_certsdir) {
if (cmdline_certsdir != "")
{
if (cmdline_certsdir[cmdline_certsdir.length()-1] == '/')
certsDir = cmdline_certsdir.substr(0, cmdline_certsdir.size()-1); // strip trailing slash
else
certsDir = cmdline_certsdir;
}
else
{
certsDir = i2p::fs::DataDirPath("certificates");
}
return;
}
bool Init() {
if (!boost::filesystem::exists(dataDir))
boost::filesystem::create_directory(dataDir);

View File

@@ -75,6 +75,12 @@ namespace fs {
/** @brief Returns datadir path */
const std::string & GetDataDir();
/** @brief Returns certsdir path */
const std::string & GetCertsDir();
/** @brief Returns datadir path in UTF-8 encoding */
const std::string GetUTF8DataDir();
/**
* @brief Set datadir either from cmdline option or using autodetection
* @param cmdline_param Value of cmdline parameter --datadir=<something>
@@ -87,7 +93,20 @@ namespace fs {
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
*/
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
/**
* @brief Set certsdir either from cmdline option or using autodetection
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
*
* Examples of autodetected paths:
*
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\certificates
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\certificates
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
*/
void SetCertsDir(const std::string & cmdline_certsdir);
/**
* @brief Create subdirectories inside datadir

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -13,6 +13,7 @@
#include "FS.h"
#include "Log.h"
#include "Family.h"
#include "Config.h"
namespace i2p
{
@@ -87,7 +88,7 @@ namespace data
}
EVP_PKEY_free (pkey);
if (verifier && cn)
m_SigningKeys[cn] = verifier;
m_SigningKeys.emplace (cn, std::make_pair(verifier, m_SigningKeys.size () + 1));
}
SSL_free (ssl);
}
@@ -98,7 +99,8 @@ namespace data
void Families::LoadCertificates ()
{
std::string certDir = i2p::fs::DataDirPath("certificates", "family");
std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "family";
std::vector<std::string> files;
int numCertificates = 0;
@@ -119,7 +121,7 @@ namespace data
}
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
const char * signature, const char * key)
const char * signature, const char * key) const
{
uint8_t buf[100], signatureBuf[64];
size_t len = family.length (), signatureLen = strlen (signature);
@@ -135,11 +137,19 @@ namespace data
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
auto it = m_SigningKeys.find (family);
if (it != m_SigningKeys.end ())
return it->second->Verify (buf, len, signatureBuf);
return it->second.first->Verify (buf, len, signatureBuf);
// TODO: process key
return true;
}
FamilyID Families::GetFamilyID (const std::string& family) const
{
auto it = m_SigningKeys.find (family);
if (it != m_SigningKeys.end ())
return it->second.second;
return 0;
}
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
{
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2022, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -19,6 +19,7 @@ namespace i2p
{
namespace data
{
typedef int FamilyID;
class Families
{
public:
@@ -27,7 +28,8 @@ namespace data
~Families ();
void LoadCertificates ();
bool VerifyFamily (const std::string& family, const IdentHash& ident,
const char * signature, const char * key = nullptr);
const char * signature, const char * key = nullptr) const;
FamilyID GetFamilyID (const std::string& family) const;
private:
@@ -35,7 +37,7 @@ namespace data
private:
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
std::map<std::string, std::pair<std::shared_ptr<i2p::crypto::Verifier>, FamilyID> > m_SigningKeys; // family -> (verifier, id)
};
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);

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