Compare commits

..

592 Commits

Author SHA1 Message Date
r4sas
1b5f67e185 [FS] misc: bump year
Signed-off-by: r4sas <r4sas@i2pmail.org>
2024-04-06 20:38:58 +00:00
r4sas
89064b6fb4 2.51.0
Signed-off-by: r4sas <r4sas@i2pmail.org>
2024-04-06 20:03:16 +00:00
orignal
c49dd712de 2.51.0 2024-04-06 08:53:54 -04:00
orignal
4f1cb74f75 request choking delay if too many NACKs. Drop window size to 1 if choking delay received 2024-04-02 18:49:16 -04:00
orignal
75df8d3c7b drop ack Through to last packet if Number of NACKs exceeds 255 2024-04-02 11:30:38 -04:00
orignal
85be76b01a check if LeaseSet was submitted recently. Fixed typo 2024-04-01 08:41:58 -04:00
orignal
835c480269 Merge pull request #2047 from Vort/ssu2_lag
select maximum SSU2 queue size depending on RTT value
2024-03-28 13:43:29 -04:00
Vort
ac9d92c681 select maximum SSU2 queue size depending on RTT value 2024-03-26 10:18:56 +02:00
r4sas
a30d1972e5 [win] update status code
Signed-off-by: r4sas <r4sas@i2pmail.org>
2024-03-22 23:18:51 +03:00
orignal
0c2330bf14 Merge pull request #2045 from Vort/rtt_sample
streaming improvements
2024-03-19 13:52:38 -04:00
Vort
a703d31893 don't double initial RTO 2024-03-19 10:48:42 +02:00
Vort
4f8f3a386f restart stream resend timer after updating initial RTO 2024-03-19 09:21:57 +02:00
Vort
83f0b9c041 extract single RTT sample from stream ACK 2024-03-19 09:21:43 +02:00
Vort
cf77be0eeb add lower limit for stream RTO 2024-03-19 06:37:21 +02:00
orignal
b2aa34baa6 use C++17 for newer versions of clang for BSD 2024-03-17 11:49:14 -04:00
orignal
4def0b6ea5 use C++17 for newer versions of clang for BSD 2024-03-17 11:46:02 -04:00
orignal
25592a00b6 use C++17 for newer versions of clang for BSD 2024-03-17 11:42:44 -04:00
orignal
edaf162f9c Merge pull request #2044 from Vort/stream_resend_rtt
exclude resent stream packets from RTT calculations
2024-03-16 15:12:24 -04:00
Vort
e7ff15c573 exclude resent stream packets from RTT calculations 2024-03-16 20:55:49 +02:00
orignal
161ff3579b don't delete new session with same router hash from sessions-by-hash table 2024-03-15 20:12:47 -04:00
orignal
f2085ecc8d fixed warning 2024-03-15 19:17:25 -04:00
orignal
0c5dee69ba Merge pull request #2043 from Vort/rtt_tune
tune RTT calculations
2024-03-15 14:50:56 -04:00
Vort
d74033dd2b tune RTT calculations 2024-03-15 09:06:33 +02:00
orignal
5412e29ff5 Merge pull request #2042 from Vort/ssu2_spikes
lower SSU2 resend traffic spikes
2024-03-14 15:50:17 -04:00
Vort
0236769134 lower SSU2 resend traffic spikes 2024-03-14 19:41:16 +02:00
orignal
530a078535 don't request temination if session was not established 2024-03-13 13:56:10 -04:00
orignal
fbca27fe73 Merge pull request #2041 from Vort/i2np_typo
fix typo in message expiration check
2024-03-13 12:26:48 -04:00
Vort
08cc256c54 fix typo in message expiration check 2024-03-13 16:41:01 +02:00
orignal
6432963294 Merge pull request #2037 from vovasty/fs_ios_simulator_fix
fix HashedStorage::Init exceptions in ios simulator.
2024-03-11 14:55:16 -04:00
Vlad Solomenchuk
59beb5e4e4 fix TARGET_OS_SIMULATOR check 2024-03-11 11:29:41 -07:00
orignal
217aa0c882 fixed #2038. don't add comma for missing param 2024-03-11 11:11:38 -04:00
orignal
e889dc1508 Merge pull request #2039 from Vort/ssu2_expiration
add expiration for messages in SSU2 send queue
2024-03-11 07:59:59 -04:00
Vort
2d06c0cbe6 add expiration for messages in SSU2 send queue 2024-03-09 19:09:05 +02:00
Vlad Solomenchuk
51446f0324 fix FS::HashedStorage::Init exceptions in ios simulator. 2024-03-08 10:23:51 -08:00
orignal
66d0b7aec4 correct publication verification for encrypted LeaseSet 2024-03-07 10:25:10 -05:00
orignal
92b49fb969 clear excluded floodfills after successive publishing 2024-03-06 21:01:17 -05:00
orignal
17dd5c1285 publish encrypted leaset on floodfill closest to store hash 2024-03-06 18:36:01 -05:00
orignal
ce97ec1534 Merge pull request #2036 from Vort/stream_ewma2
changes in stream RTT estimation and window size drop percent
2024-03-06 08:13:19 -05:00
Vort
3ceb64db2e 1. Use EWMA for stream RTT estimation;
2. Drop window size by 10% instead of 50% in case of resend.

Change is based on code by onon.
2024-03-06 15:06:04 +02:00
orignal
bb702700f7 don't check session for single tag 2024-03-06 07:17:59 -05:00
orignal
ff3fec9a00 remove tag immediately after use 2024-03-05 10:30:01 -05:00
orignal
3873e60cbb try to send database store reply directly to IBGW 2024-03-04 14:30:49 -05:00
orignal
2dbf094433 try to send lookup reply directly to IBGW 2024-03-04 13:34:57 -05:00
orignal
e85e96bc35 Merge pull request #2035 from Vort/high_latency_fix
fix high latency threshold
2024-03-04 06:56:38 -05:00
Vort
98543af92b fix high latency threshold 2024-03-04 13:41:50 +02:00
orignal
af0d853ccd some cleanup 2024-03-03 10:28:25 -05:00
orignal
20a5e19ea1 don't request banned router 2024-03-03 09:56:11 -05:00
orignal
f1058410fb don't request banned router 2024-03-03 07:42:39 -05:00
orignal
6ba42a0912 check if established peer test session has the same address type 2024-03-02 18:17:56 -05:00
orignal
1292ec67c0 check if remote router supports peer test 2024-03-02 18:02:55 -05:00
orignal
2f2f14e3a7 try publishing again after 5 seconds if no tunnels in the pool 2024-03-02 11:26:41 -05:00
orignal
edd9dd2c39 try to publish again after 5 seconds if destination is not ready 2024-03-02 10:57:01 -05:00
orignal
f8722f17c6 pick peer test session only if Charlie's address supports peer testing 2024-03-01 21:59:52 -05:00
orignal
38cc01e13d check own peer test cap for peer test msg 2 2024-03-01 14:33:11 -05:00
orignal
6ca266ff3b reject peer test msg 2 if peer testing is not supported 2024-03-01 14:03:13 -05:00
orignal
b9773c88e4 don't set test failed state to expiring tunnels 2024-03-01 12:45:21 -05:00
orignal
3311fe62bb fixed potential race condition with tunnel tests 2024-03-01 08:03:40 -05:00
orignal
a284c85153 Merge pull request #2033 from Vort/ssu2_dynamic_buffer
derive SSU2 socket buffer size from bandwidth limit
2024-02-29 09:32:50 -05:00
Vort
e5f75eb61c log would_block error at info level 2024-02-29 16:12:51 +02:00
Vort
89f9bec49a derive SSU2 socket buffer size from bandwidth limit 2024-02-29 16:02:43 +02:00
orignal
dbc3952654 Merge pull request #2031 from Vort/buf_size_log
write SSU2 socket buffer sizes to log
2024-02-29 07:28:14 -05:00
Vort
f3c052ed0c write SSU2 socket buffer sizes to log 2024-02-29 10:27:52 +02:00
orignal
692f495adc Merge pull request #2030 from Vort/non_block
enable non-blocking mode for UDP sockets
2024-02-28 11:58:19 -05:00
Vort
aa1de7fe94 enable non-blocking mode for UDP sockets 2024-02-28 18:55:28 +02:00
orignal
ca45fe73e9 never delete conneted router from netdb 2024-02-27 16:10:17 -05:00
orignal
a8af683643 renamed steady to monotonic 2024-02-27 12:33:07 -05:00
orignal
b86c83a068 encrypt tunnel tests for ElGamal-only destinations 2024-02-27 11:47:32 -05:00
orignal
6656ef3c8d correct clock for non-encrypted tunnel tests 2024-02-27 09:02:26 -05:00
orignal
6898d04a1d send tunnel test mesaage only if encrypted 2024-02-27 08:30:31 -05:00
orignal
3215125950 Merge pull request #2029 from Vort/tunnel_test_msg
add tunnel test message
2024-02-27 08:03:27 -05:00
Vort
3d03732555 add tunnel test message 2024-02-27 11:08:14 +02:00
Vort
d6d440ba8a allow 0ms latency for tunnel 2024-02-26 05:57:28 +02:00
orignal
821a76a7c5 flush IBGW if tunnel build request OBEP is on the same router 2024-02-25 09:15:08 -05:00
r4sas
34154596f2 [gha] build only when related to app and runner itself files are changed, disable temporary msvc
Signed-off-by: r4sas <r4sas@i2pmail.org>
2024-02-24 23:35:56 +00:00
orignal
a1dce017f4 allow tunnel endpoint to send tunnel build reply to itself 2024-02-24 11:40:43 -05:00
orignal
78af34237e reduce session termination timeout 2024-02-23 19:22:49 -05:00
orignal
8874ea8033 fixed typo 2024-02-23 18:06:31 -05:00
orignal
6bd1ee36f7 fixed typo 2024-02-23 16:09:32 -05:00
orignal
f07c4bd1dd drop transit tunnel if next ident is ours 2024-02-23 15:24:52 -05:00
orignal
8524a67895 fail last tunnel if tunnel quantity is 1 2024-02-23 12:32:21 -05:00
orignal
43d880752e Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2024-02-23 11:37:52 -05:00
orignal
d4246edb82 don't fail last tunnel 2024-02-23 11:37:09 -05:00
orignal
ee8449fa05 Merge pull request #2024 from Vort/congestion_zero_check
add zero check to congestion level calculations
2024-02-22 14:54:47 -05:00
Vort
5415598f60 add zero check to congestion level calculations 2024-02-22 21:50:05 +02:00
orignal
7d73c304b5 Extend transit tunnels limit to 4 bytes. Bump default value to 10K 2024-02-22 14:22:11 -05:00
orignal
d25206abce encrypted tunnel test messages 2024-02-21 19:46:29 -05:00
r4sas
5d7c6fb0b3 [gha] msvc: copy openssl libraries to fix build
Signed-off-by: r4sas <r4sas@i2pmail.org>
2024-02-21 22:31:20 +03:00
orignal
36a060d50f Consider 'M' routers as low bandwidth 2024-02-21 12:37:33 -05:00
orignal
577ed56af0 store HTTP and SOCKS proxy as pointer to I2PService 2024-02-20 18:51:37 -05:00
orignal
695dc96a83 common ServiceAcceptor for all stream protocols 2024-02-20 18:32:51 -05:00
orignal
e5251bf3c3 Merge pull request #2022 from Vort/bw_time_jumps3
skip bandwidth updates in case of time going backwards
2024-02-20 17:44:42 -05:00
R4SAS
2692aef53d [gha] update windows msvc action 2024-02-21 01:36:32 +03:00
Vort
d524105727 skip bandwidth updates in case of time going backwards 2024-02-20 23:27:31 +02:00
orignal
26463c50fc Merge pull request #2020 from Vort/select_next_hop2
make more attempts to select not bad hop
2024-02-20 12:22:36 -05:00
Vort
b092e712ec make more attempts to select not bad hop 2024-02-20 19:05:19 +02:00
orignal
cb8fbb0135 Merge pull request #2018 from Vort/congestion_consts
add constants for congestion levels
2024-02-20 07:30:16 -05:00
Vort
19e23b34da add constants for congestion levels 2024-02-20 10:30:05 +02:00
orignal
a4a3f8e96b support upstream proxy through local sockets 2024-02-19 22:04:43 -05:00
orignal
f2b720617c Merge pull request #2016 from Vort/medium_congestion2
implement medium congestion indication
2024-02-19 19:13:12 -05:00
Vort
d677d67676 implement medium congestion indication 2024-02-19 21:36:38 +02:00
orignal
7e3157b162 don't process packet in terminated stream 2024-02-18 21:28:06 -05:00
orignal
2b6a95cbee don't check session for symmetric key tagset. re-create tags hash if too many used tags 2024-02-16 21:30:40 -05:00
orignal
900153765a move router's tags cleanup to router's thread 2024-02-16 18:56:04 -05:00
orignal
441e847de8 don't try to decrypt dulpicate message 2024-02-16 14:49:12 -05:00
orignal
6439e227f6 consider test failed state as established. Delete failed tunnels sooner 2024-02-15 19:29:33 -05:00
orignal
def404b61a skip failed and expiring tunnels for peer tests 2024-02-14 22:19:07 -05:00
orignal
d8be5b8ce1 fixed warning 2024-02-14 21:58:03 -05:00
orignal
dddbca6ffb common rng for random shuffle 2024-02-14 21:35:41 -05:00
orignal
56619caa71 random shuffle of tunnels for peer test pairs 2024-02-14 20:16:36 -05:00
orignal
0e502c49b5 show correct tunnel status. restore tunnel if delivery status or data for inbound tunnel received 2024-02-14 18:53:28 -05:00
orignal
710b27688b generic SocketsPipe for different socket types 2024-02-14 15:35:47 -05:00
orignal
a9ad6fc31e renamed TCPIPPipe to SocketsPipe 2024-02-13 18:52:18 -05:00
orignal
967627e58a read correct reply length and handle reply codes 2024-02-12 21:55:30 -05:00
orignal
7691a5b4a9 use common SOCK5 code for reseed 2024-02-12 13:22:26 -05:00
orignal
d9b6262a6e removed unused field 2024-02-12 12:10:29 -05:00
orignal
075f80aea2 use SOCK5 proxy for upstream 2024-02-11 15:33:37 -05:00
orignal
b07530a8a1 don't print error message if operation cancelled 2024-02-11 11:44:15 -05:00
orignal
0ae7931a6f replaced SOCKS4 outproxy by SOCKS5 2024-02-11 11:23:37 -05:00
orignal
158160f5c0 common code for SOCKS5 proxy connectivity 2024-02-10 20:03:36 -05:00
orignal
4cb2ad48be Merge pull request #2014 from Vort/log_fixes
Logging fixes
2024-02-10 10:22:52 -05:00
Vort
adba3987f8 logging fixes 2024-02-10 17:10:21 +02:00
orignal
36dbc15bca keep SSU2 socket open even if failed to bind 2024-02-09 18:08:51 -05:00
orignal
d96803a290 always request through tunnels in case of restricted routes 2024-02-09 15:24:48 -05:00
orignal
592d6ae4f4 check log level before calculating base32 or base64 of ident 2024-02-08 21:56:25 -05:00
orignal
7dd9a7a0af added CheckLogLevel 2024-02-08 21:45:57 -05:00
orignal
1b23aa2d7b increase request timeout 2024-02-08 21:44:12 -05:00
orignal
f980277552 don't flood failed router 2024-02-08 19:55:54 -05:00
orignal
586695673b correct log message for next netdb request 2024-02-08 18:48:10 -05:00
orignal
c158bbe90a send frame when it exceeds 16K 2024-02-07 19:43:29 -05:00
orignal
c01fd3299f handle drop of destination publish msg 2024-02-06 18:51:59 -05:00
orignal
f64b136f5a remove prestium reseeds 2024-02-06 13:37:08 -05:00
orignal
37e67cbcaa Merge pull request #2013 from WaxySteelWorm/openssl
reseed.stormycloud.org reseed added
2024-02-06 13:07:04 -05:00
orignal
be815804e6 expire transit tunnel is not sent further 2024-02-05 15:44:17 -05:00
orignal
ce35637866 handle drop of tunnel build message 2024-02-04 15:45:22 -05:00
StormyCloudInc
de2b0f6e09 Update Config.cpp 2024-02-03 10:24:11 -06:00
StormyCloudInc
7b776666a3 Add files via upload 2024-02-03 10:21:19 -06:00
orignal
47578b69c6 handle drop of tunnel test message 2024-02-01 19:38:12 -05:00
orignal
8f28cee32f drop earlier if delayed queue is semi-full 2024-02-01 18:55:10 -05:00
orignal
96cf6ca531 drop earlier if outgoing queue is semi-full 2024-02-01 18:14:45 -05:00
orignal
83cb3a1820 reduce router unreachable interval 2024-01-31 15:41:21 -05:00
orignal
ffdd5935e9 Handle drop of own RouterInfo publishing message 2024-01-31 11:46:01 -05:00
orignal
2e9f2d4a3b Drop for LeaseSet request 2024-01-30 21:52:18 -05:00
orignal
0ca782ed71 drop unsent messages if session disconnects 2024-01-30 18:02:14 -05:00
orignal
e40b656ecf Drop for tunnel and encrypted messages 2024-01-30 15:41:57 -05:00
orignal
85f5f5b91e fixed potential deadlock 2024-01-30 10:04:19 -05:00
orignal
f008478505 handle I2NP messages drops 2024-01-29 19:54:43 -05:00
orignal
d926a31064 fixed warning 2024-01-29 18:01:41 -05:00
orignal
822cb35efe limit send Ack timeout by Ack delay interval 2024-01-28 18:12:40 -05:00
orignal
faaa8115d9 Merge pull request #2011 from Vort/net_status
log changes of network status
2024-01-28 09:16:20 -05:00
Vort
81015a5228 log changes of network status 2024-01-28 16:13:23 +02:00
orignal
a3246cd9dc doen't send Ack packet too often if missing packets 2024-01-27 17:57:50 -05:00
orignal
530c353b00 don't send Ack with NACK immediately but after 2 milliseconds 2024-01-27 12:17:59 -05:00
orignal
75c2cb751f lock mutex before deleting RouterInfo's buffer 2024-01-25 18:51:46 -05:00
orignal
67c4d4bcaa fixed VS build error 2024-01-25 09:09:44 -05:00
orignal
25e82105b2 Merge pull request #2010 from wekoq/udp-tunnels-dest
Add support for multiple udp server tunnels on one destionation
2024-01-24 21:05:42 -05:00
weko
4b167fdbaf Update copyright year 2024-01-25 01:57:24 +00:00
weko
5b93558bd0 Add support for multiple udp server tunnels on one destionation 2024-01-25 01:05:58 +00:00
orignal
70639f1139 don't adjust clock if offsets came from same router 2024-01-24 19:05:38 -05:00
orignal
c5a1806528 fixed possible deadlock 2024-01-24 13:58:42 -05:00
orignal
a2249f0a82 identify server tunnel session but from ant to ports 2024-01-24 13:52:13 -05:00
orignal
9f217f8a11 don't send expired I2NP messages 2024-01-21 18:59:04 -05:00
orignal
5e19e361e7 check max frame sizebefore sending 2024-01-20 17:33:28 -05:00
orignal
0b47f65b06 don't remove another NTCP2 session with same address 2024-01-19 18:29:17 -05:00
orignal
140146e433 limit mininal received packet size to 40 bytes 2024-01-19 14:09:48 -05:00
R4SAS
b4484c8e8f [gha] msvc: switch back to boost 1.81.0 2024-01-19 21:54:10 +03:00
orignal
1e5604ed43 check if peer is connected before trying to connect 2024-01-18 19:18:51 -05:00
orignal
39e378a03d check received data size 2024-01-17 18:15:49 -05:00
orignal
7cfcb12c7b don't create peer for unreachable router 2024-01-16 14:33:36 -05:00
orignal
49f4dc53ad try next floodfill for router request on demand 2024-01-15 19:32:17 -05:00
orignal
4afdca090d support multiple RouterInfo request callbacks 2024-01-14 18:54:21 -05:00
orignal
d8f6c4a93d correct encryption and path for follow on lookup request 2024-01-14 17:16:31 -05:00
orignal
d724948d03 Merge pull request #2007 from Vort/reservedrange2
handle 'reservedrange' param properly
2024-01-12 10:25:26 -05:00
Vort
34d75b08dd handle 'reservedrange' param properly 2024-01-12 17:17:16 +02:00
orignal
ca9782dd0d handle 'reservedrange' param properly 2024-01-11 15:39:42 -05:00
orignal
2ad26dd4c9 fixed race condition in ECIESx25519 tags table 2024-01-11 14:09:08 -05:00
orignal
828facab57 Merge pull request #2003 from rex4539/typos
Fix typos
2024-01-11 13:14:20 -05:00
orignal
cd087568b5 reply with CANT_REACH_PEER if connect to outselves 2024-01-09 21:02:11 -05:00
R4SAS
dfe8b25e5e [gha] MSVC: remove deletion of installation files 2024-01-08 17:05:36 +03:00
R4SAS
1e9bcd6b8b [gha] MSVC: Switch to direct Boost and OpenSSL installation 2024-01-08 16:36:14 +03:00
orignal
8bc58daa5a fixed #2004. Check supported crypto 2024-01-07 18:42:34 -05:00
orignal
3b97feb89f 2.50.2 2024-01-06 15:07:51 -05:00
orignal
a8135b8d18 2.50.2 2024-01-06 14:51:42 -05:00
orignal
5cf1961fa4 drop updated routers from future 2024-01-06 11:31:01 -05:00
Dimitris Apostolou
577c71b930 Fix typos 2024-01-04 21:35:25 +02:00
orignal
c5cab05a6b reset peding time offset if correct time was received 2024-01-02 19:42:49 -05:00
orignal
b855c71891 don't adjust clock if time offsets are too different 2023-12-31 14:39:59 -05:00
orignal
21f41a2b2a correct time offset direction 2023-12-31 10:14:24 -05:00
orignal
8319dd6b25 drop exploratory and leaseset lookups for non-floodfill router 2023-12-30 19:49:16 -05:00
orignal
d4c47d90cb adjust time offset after second time discrepancy 2023-12-30 17:16:28 -05:00
orignal
302af823a3 fixed race condition with openssl 3.2.0 2023-12-30 15:55:53 -05:00
r4sas
69ee6112b3 [changelog] fix version
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-23 19:53:39 +00:00
r4sas
816a58f292 2.50.1
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-23 18:13:31 +00:00
orignal
43e130ee34 reinitialize context before each Sign/Verify call to make it working with openssl 3.2 2023-12-19 19:29:08 -05:00
orignal
8ffc1486a4 test-eddsa added 2023-12-18 09:32:12 -05:00
orignal
0e98dd5c70 use fallback EdDSA implementation with openssl 3.2.0 due to regression in EVP_DigestSign (#23075) 2023-12-18 07:40:40 -05:00
r4sas
beffdb9fe1 [apparmor] add profile for docker container
Author: corona@mail.i2p

Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-18 10:06:49 +00:00
r4sas
05eda2bc9e [gha] build docker containers only on specific paths changes
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-18 09:55:10 +00:00
r4sas
c3429bb1a9 [gha] return freebsd build back
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-18 09:38:08 +00:00
r4sas
53c6b10177 [make] get the mistakenly deleted pthread back
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-17 19:41:28 +00:00
r4sas
c2d7133174 [make] fix windows msys2 build
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-12-17 19:30:55 +00:00
orignal
9b82265cd8 2.50.0 2023-12-17 11:07:10 -05:00
orignal
c802c2deb0 update yggdrasil ressed address 2023-12-05 15:48:26 -05:00
orignal
c215f2e8d1 check router for null pointer 2023-11-23 13:06:50 -05:00
orignal
d327533b56 close unclaimed acceptors after 3 seconds 2023-11-17 18:50:52 -05:00
orignal
94255ebaf4 STREAM ACCEPT queue 2023-11-17 13:44:30 -05:00
orignal
21259204b1 eliminate send buffer mutex completely 2023-11-14 09:39:36 -05:00
orignal
8d6eb5b6b2 don't lock mutex in AsyncSend 2023-11-13 19:12:07 -05:00
orignal
9632e7ba03 exclude NAT64 ipv6 addresses 2023-11-12 18:32:57 -05:00
Dimitris Apostolou
1a02819187 Remove deprecated bind_at_load from macOS 2023-11-12 10:30:30 +00:00
Fabrice Fontaine
6b33250c59 build/CMakeLists.txt: enable C language
Detection of libatomic is broken since version 2.47.0 and
b7f0d87daf
because C language is not enabled anymore:

-- Looking for __atomic_fetch_add_4 in atomic
-- Looking for __atomic_fetch_add_4 in atomic - not found
CMake Error at cmake_modules/CheckAtomic.cmake:59 (message):
  Host compiler appears to require libatomic, but cannot find it.
Call Stack (most recent call first):
  CMakeLists.txt:54 (include)

Indeed if C language is not enabled, the test will be run with the C++
compiler resulting in the following error:

Building CXX object CMakeFiles/cmTC_03d01.dir/CheckFunctionExists.cxx.o
        /home/fabrice/buildroot/output/host/bin/x86_64-linux-g++ --sysroot=/home/fabrice/buildroot/output/host/x86_64-buildroot-linux-gnu/sysroot   -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O1 -g0 -D_FORTIFY_SOURCE=2 -DCHECK_FUNCTION_EXISTS=__atomic_fetch_add_4  -DNDEBUG -o CMakeFiles/cmTC_03d01.dir/CheckFunctionExists.cxx.o -c /home/fabrice/buildroot/output/build/i2pd-2.49.0/build/CMakeFiles/CMakeScratch/TryCompile-NApnv9/CheckFunctionExists.cxx
        <command-line>: error: new declaration ‘char __atomic_fetch_add_4()’ ambiguates built-in declaration ‘unsigned int __atomic_fetch_add_4(volatile void*, unsigned int, int)’ [-fpermissive]

whereas with a C compiler, we'll get:

Building C object CMakeFiles/cmTC_7e47b.dir/CheckFunctionExists.c.o
        /home/fabrice/buildroot/output/host/bin/x86_64-linux-gcc --sysroot=/home/fabrice/buildroot/output/host/x86_64-buildroot-linux-gnu/sysroot   -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O1 -g0 -D_FORTIFY_SOURCE=2 -DCHECK_FUNCTION_EXISTS=__atomic_fetch_add_4  -DNDEBUG -o CMakeFiles/cmTC_7e47b.dir/CheckFunctionExists.c.o -c /home/fabrice/buildroot/output/build/i2pd-2.49.0/build/CMakeFiles/CMakeScratch/TryCompile-e0zFMG/CheckFunctionExists.c
        <command-line>: warning: conflicting types for built-in function ‘__atomic_fetch_add_4’; expected ‘unsigned int(volatile void *, unsigned int,  int)’ [-Wbuiltin-declaration-mismatch]

Fix #1908

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2023-11-12 10:29:24 +00:00
orignal
083034fa35 send peer tests with random delays 2023-11-09 21:56:32 -05:00
R4SAS
0021501d75 [gha] disable FreeBSD build
Additional info: https://github.com/vmactions/freebsd-vm/issues/74
2023-10-31 22:39:51 +03:00
R4SAS
379be2a29e [gha] Update FreeBSD build action 2023-10-31 22:33:12 +03:00
orignal
a3f62e1d71 check actual distance with router to reduce expiration time 2023-10-31 13:20:04 -04:00
orignal
a6ee1e648e recognize trailing padding as part of base64 address 2023-10-31 09:10:56 -04:00
orignal
575268d360 reduce expiration time for low bandwidth and far routers 2023-10-30 20:02:48 -04:00
orignal
69b0bef206 fixed possible invalid pointer when send error response 2023-10-30 10:09:47 -04:00
orignal
e1b4feb618 correct base64 check 2023-10-30 08:10:17 -04:00
orignal
3286bdb4a7 verify jump link for valid characters 2023-10-29 22:11:38 -04:00
orignal
c8ae15041f Merge pull request #1980 from freeacetone/openssl
Yggdrasil reseed address replaced by address for 4.X+ version
2023-10-29 07:44:51 -04:00
acetone
e090b9052a Yggdrasil reseed address replaced by address for 4.X+ version 2023-10-29 11:57:14 +03:00
Dex
0ef9c08326 fix manpage typo for ipv4 flag 2023-10-28 16:25:51 +00:00
orignal
d04b19d77c don't recalculate badwidth if clock was adjusted too much 2023-10-18 18:09:41 -04:00
orignal
04adc14b76 ls@mail.i2p yggdrasil reseed added 2023-10-16 18:46:59 -04:00
orignal
0dee0609ea Merge pull request #1972 from Vort/nominmax
Fix MSVC compilation for std::max
2023-10-15 11:31:56 -04:00
Vort
0a519d8072 Fix MSVC compilation for std::max 2023-10-15 18:08:15 +03:00
orignal
0cc91dd2d2 don't pick too active peer 2023-10-15 08:31:55 -04:00
orignal
606e35eec1 reseed.us.prestium.org reseed added 2023-10-10 12:59:40 -04:00
orignal
e926b0392f reseed.is.prestium.org reseed added 2023-10-07 14:22:53 -04:00
orignal
9980bfa0e7 Update README.md 2023-09-30 14:10:45 -04:00
orignal
efdbe26755 try peer test again if Unknown 2023-09-28 18:40:51 -04:00
orignal
bb3ae8f5e4 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2023-09-28 16:06:33 -04:00
orignal
1e6edf06a2 send already accepting error response 2023-09-28 16:05:13 -04:00
hfsfox
0cf656cd76 Add Haiku OS support (#1970) 2023-09-28 22:30:38 +03:00
r4sas
fb420bb563 [cpu] more builtin version check changes
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-18 18:12:26 +00:00
r4sas
3da5061426 [cpu] Increase GCC version for use of builtin CPU extensions checker
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-18 17:11:45 +00:00
orignal
dd32f1ed6d Merge pull request #1968 from PurpleI2P/cpu
[cpu] use short defines instead of long checks
2023-09-17 14:38:16 -04:00
r4sas
1857f14be8 [cpu] use short defines instead of long checks
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-17 18:33:42 +00:00
r4sas
9c25a88707 [i18n] update translations
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-17 16:21:36 +00:00
r4sas
c599d65307 [i18n] update translations
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-17 15:59:11 +00:00
r4sas
4d573f6655 2.49.0
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-17 15:38:13 +00:00
orignal
3a4238729a 2.49.0 2023-09-17 10:41:31 -04:00
orignal
df6bb6d9b8 2.49.0 2023-09-17 10:19:57 -04:00
orignal
918aa556ef fixed non-x86 build 2023-09-15 11:37:45 -04:00
r4sas
1e7feae0df [rpm] remove BuildRequires tabulation
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-10 13:08:00 +03:00
r4sas
70829ee79e [rpm] add Fedora ELN support
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-10 13:02:52 +03:00
r4sas
4ed19c05f6 [cpu] split AES detect for GNU C < 5
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-07 21:20:52 +00:00
r4sas
4a5e16b994 [cpu] tests with preprocessor
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-07 16:56:53 +00:00
r4sas
c53ad2012c [cpu] use cpuid on gcc < 5
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-09-06 23:30:16 +03:00
R4SAS
7b6aa41ca8 CPU: remove AVX code, switch to __builtin for AES detection (#1959)
* [cpu] remove avx detect and code blocks, try to switch to __builtin
* [cpu] use __builtin_* only on x86 systems
* [cpu] perform check in separate function
* [cpu] set AES definition on MSVC
* update x86 and aes support checks at compile time
* [cmake] update comment about AES on MSVC
2023-08-31 19:52:51 +03:00
జిందం వాఐి
32c5ff23a6 Differentiate cryptocurrency & its associated address (#1951) 2023-08-31 19:51:21 +03:00
orignal
c112276eea memory poll for RouterProfile 2023-08-26 10:57:05 -04:00
Chad Fraleigh
662a59d0fd Eliminate additional undefined behavior of bit shifting signed int. 2023-08-16 19:49:18 +00:00
orignal
72919ec076 Merge pull request #1960 from chadf/chacha20-buf-outlen
Fixed buf offset EVP_EncryptFinal_ex() to include outlen.
2023-08-15 17:56:45 -04:00
Chad Fraleigh
627b8dca83 Fixed buf offset EVP_EncryptFinal_ex() to include outlen. 2023-08-13 17:08:14 -07:00
orignal
7bcc905f05 exclude SSU1 introducers 2023-08-07 21:28:13 -04:00
orignal
8447822c35 don't publish intrducers with zero tag 2023-08-05 15:25:16 -04:00
orignal
411063e3b5 Merge pull request #1958 from Vort/session_log
improve transport session logging
2023-08-05 13:55:03 -04:00
Vort
9bac680f2a improve transport session logging 2023-08-05 18:25:01 +03:00
orignal
38795a41cb don't publish introducers with zero iTag 2023-08-05 08:55:06 -04:00
orignal
e170c39dfc Merge pull request #1957 from Vort/peer_test
Separate test status from network status
2023-08-04 08:21:54 -04:00
Vort
68f4961f1a separate test status from network status 2023-07-30 15:44:16 +03:00
orignal
ae5239de43 remove introducer from RouterInfo after 60 minutes 2023-07-23 07:42:36 -04:00
orignal
2064504cce fixed send keepalive for existing session 2023-07-23 07:17:10 -04:00
orignal
4aa631c33f clear implied list if no more introducers found 2023-07-22 16:51:19 -04:00
orignal
d6834d6a9a keep non-published, but not-expired introducers in the introducers list 2023-07-22 15:03:03 -04:00
orignal
413e25f20e don't pick too old session for introducer 2023-07-22 10:13:05 -04:00
orignal
b8e19bf5f1 reduced peer test interval and added peer test interval variance 2023-07-22 08:50:49 -04:00
orignal
c7efd465fa padding for path response 2023-07-21 18:25:28 -04:00
orignal
6e9a3422e9 correct min size for keepalive 2023-07-21 07:59:09 -04:00
orignal
d3cd8517b7 Merge pull request #1952 from Vort/explicit0hops
allow 0 hops with explicitPeers
2023-07-19 10:43:03 -04:00
Vort
f13cc0b862 allow 0 hops with explicitPeers 2023-07-19 16:43:40 +03:00
orignal
0754255c1f drop incoming session from too old or from future routers 2023-07-17 21:08:26 -04:00
orignal
902899ae24 don't pick completely unreachable peers 2023-07-17 19:49:42 -04:00
orignal
c620fc1232 clear unreachable flag upon succesive connect 2023-07-17 18:44:51 -04:00
orignal
e7157cf15e don't create paired inbound tunnel if length is different 2023-07-17 17:57:30 -04:00
r4sas
940a97db11 [gha] fix msvc build
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-07-16 14:02:53 +03:00
orignal
8e63f8f333 consider all addresses non published for U and H routers 2023-07-15 17:11:56 -04:00
orignal
5e97b54d1b Merge pull request #1950 from Vort/term_fix
fix termination block processing and size check
2023-07-15 13:53:17 -04:00
Vort
ea7cf1cf69 fix termination block processing and size check 2023-07-15 18:44:37 +03:00
orignal
17c4038c60 select router with ipv4 for endpoint 2023-07-11 13:16:35 -04:00
orignal
5022a9c610 Merge pull request #1948 from chadf/fuzzing-5
Use offset from Identity::signingKey instead of Identity::certificate for key.
2023-07-10 08:06:47 -04:00
orignal
ca8ec6286a Merge pull request #1947 from chadf/fuzzing-4
Eliminate undefined behavior of bit shifting signed int.
2023-07-10 08:03:10 -04:00
orignal
5142459e12 Merge pull request #1945 from chadf/fuzzing-2
Fixed division by zero due to thread race condition.
2023-07-10 08:01:46 -04:00
orignal
8590dbd3d3 Merge pull request #1946 from chadf/fuzzing-3
Fixed crash when Base64ToByteStream() is only given '=' characters.
2023-07-10 08:00:30 -04:00
Chad Fraleigh
c4be5f7fdb Use offset from Identity::signingKey instead of Identity::certificate for key. 2023-07-09 18:45:30 -07:00
Chad Fraleigh
47dc5591b9 Eliminate undefined behavior of bit shifting signed int. 2023-07-09 15:09:17 -07:00
Chad Fraleigh
2bb48b4546 Fixed crash when Base64ToByteStream() is only given '=' characters. 2023-07-09 13:12:22 -07:00
Chad Fraleigh
638e9b4d7f Fixed division by zero due to thread race condition. 2023-07-08 17:07:04 -07:00
orignal
b8f998f76a don't delete BOBDestination if used by another BOBSession 2023-07-06 13:08:39 -04:00
orignal
5f43026986 check if local destination is not null 2023-07-06 12:30:33 -04:00
orignal
13f263b791 correct transport comptibility for OBEP in second attempt 2023-06-30 11:54:55 -04:00
orignal
07c529173e send current version of the subnegotiation in user/password response 2023-06-17 10:08:04 -04:00
orignal
fee940238a handle SOCK5 authrosation with empty user/password 2023-06-17 07:52:06 -04:00
R4SAS
ca02b5d860 debian: add compat patches for previous releases
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-06-12 14:45:34 +00:00
r4sas
fba23a4528 i18n: update translations
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-12 16:33:21 +03:00
r4sas
a0795d8534 set server tunnel inport in ClientContext from port (#1936)
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-12 05:12:07 +03:00
r4sas
03cc6e0524 use uint16_t for ports
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-12 05:10:32 +03:00
r4sas
3af1f4bc76 Use of 'server' type tunnel port as inport (#1936)
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-12 00:32:44 +03:00
orignal
52b2d6c393 2.48.0 2023-06-11 15:44:16 -04:00
orignal
bb52056aec correct index for connected transport 2023-06-11 06:48:47 -04:00
r4sas
75aa9f2c0c i18n: update translation file
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-10 04:30:48 +03:00
r4sas
4e426727e9 Webconsole: fix output on i2p tunnels, add b32 on dest page
Fixes:
* adding of "Client Destinations" section header when there is no such tunnels
* Print error when destination is not found instead of empty page

Adds:
* Print b32 on destination page

Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-10 04:12:38 +03:00
r4sas
09f233dbfb NetDB: ignore LeaseSet store request if not floodfill
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-06-06 01:00:07 +03:00
r4sas
dfe5df29e1 suppress build warnings on windows
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-30 21:05:15 +03:00
AsciiMoth
d5ee1f602f Update dates in license (#1934)
Update copyright timestamp in LICENSE file from 2020 to actual 2023
2023-05-30 17:27:40 +03:00
orignal
86173400d5 don't drop profile of real router too early 2023-05-29 08:49:45 -04:00
r4sas
ae439b5385 SSU2: check if socket is opened before sending data, handle network_reset error
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-27 01:00:19 +03:00
r4sas
dc6a42c26f [contrib] update example config file comments, remove ssu option
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-23 00:44:48 +03:00
r4sas
fdf38f45d9 more debug messages at destinations stop
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-23 00:44:47 +03:00
r4sas
a2726cf206 [cmake] print commit-based version if option is used
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-23 00:44:46 +03:00
r4sas
e56d243c3f [win32] suppress fallthrough warning
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-05-23 00:44:42 +03:00
orignal
e95fb3ab89 allow user/password authentication 2023-05-22 08:58:04 -04:00
orignal
c984f89dfb don't handle unecnrypted DatabaseSearchReply msg if came throug client tunnel 2023-05-21 18:43:58 -04:00
orignal
5a09c11e90 Merge pull request #1927 from wekoq/refactor_TBM_handling
refactor TBM hadling
2023-05-08 12:48:45 -04:00
weko
d44be2fd73 fix typo 2023-05-08 15:33:40 +00:00
weko
a158647153 refactor TBM hadling 2023-05-08 14:52:48 +00:00
orignal
623c3f4605 check for max number of records in tunnel build and tunnel build reply messages 2023-05-06 18:07:21 -04:00
orignal
8a52295882 make router real upon successive outgoing NTCP2 session. Eliminate static keys table 2023-05-06 16:43:09 -04:00
orignal
f2bc2598dc Merge pull request #1925 from wekoq/openssl
Do not save useless peer profiles
2023-05-06 06:34:59 -04:00
weko
1d8a91c5cc redo no save useless profiles 2023-05-06 08:04:27 +00:00
orignal
3bc56ba423 store 'connected' in 'usage' section 2023-05-06 08:04:27 +00:00
orignal
e068a3cf22 store 'connected' in 'usage' section 2023-05-05 19:58:58 -04:00
weko
2e2cbe7803 save profile if has connected 2023-05-05 22:46:48 +00:00
weko
1c1452e06b Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2023-05-05 22:42:46 +00:00
orignal
c757b6d020 reset floodfill cap for unknown floodfills 2023-05-05 18:22:11 -04:00
weko
8fcab7b0c1 fix incorrect merge conflict resolve 2023-05-05 21:55:31 +00:00
weko
7646147ed2 save only non-default peer profile 2023-05-05 21:44:54 +00:00
orignal
b6de474fda don't include unconfirmed floodfill to the list if we have enough floodfills already 2023-05-05 16:14:54 -04:00
orignal
2f74e670a5 invalidate routers with incorrect family signature 2023-05-04 15:32:19 -04:00
orignal
c1168c2aa0 don't catch RouterInfo at OBEP 2023-05-04 09:39:37 -04:00
orignal
1bd6390f78 check if s is x25519 public key 2023-05-04 08:20:38 -04:00
orignal
a9e9e14c42 Merge pull request #1921 from contextswap/openssl
limit aes-ni assembly to x86
2023-05-03 12:21:00 -04:00
orignal
19471dbb90 Merge pull request #1922 from SidorKozlov/zombie-config
Configurable minimum successful tunnels
2023-05-03 11:43:19 -04:00
SidorKozlov
3b13a3f2a1 Configurable minimum successful tunnels 2023-05-03 16:13:03 +02:00
orignal
4ce2ef1d83 make router unreachable if AEAD fails in SessionCreated 2023-05-03 07:43:28 -04:00
contextswap
12d0abda55 [
Signed-off-by: contextswap <ctxswp@proton.me>
2023-05-03 19:10:16 +09:00
contextswap
7418f11651 limit aesni inline asm to x86
Signed-off-by: contextswap <ctxswp@proton.me>
2023-05-03 19:04:16 +09:00
orignal
fb83ca42f4 Merge pull request #1919 from wekoq/openssl
Recognize invalid static key
2023-05-01 16:17:00 -04:00
weko
dab34e9051 get indent hash directly 2023-05-01 20:08:08 +00:00
weko
ec2297ed9d Recognize invalid static key 2023-05-01 19:28:32 +00:00
orignal
7c535159bc static keys table 2023-04-30 20:05:35 -04:00
orignal
2af4a2b58d override reply token only if non-zero 2023-04-28 08:01:02 -04:00
orignal
ead6a6dca3 correct parsing of caught RouterInfo at IBGW and OBEP 2023-04-27 21:37:30 -04:00
orignal
0ce15ffc91 check for incomplete HTTP header 2023-04-26 21:34:22 -04:00
orignal
76adac31c3 enrcrypt lookup if being sent through a tunnel 2023-04-24 19:25:26 -04:00
r4sas
edfcd23b01 [webconsole] added a button to prematurely release a leaseset
Signed-off-by: r4sas <r4sas@i2pmail.org>
2023-04-24 14:01:21 +03:00
orignal
f21e1c75d5 check tagset for null 2023-04-23 15:31:24 -04:00
orignal
786c27c8ec publish encrypted RouterInfo 2023-04-21 22:27:55 -04:00
orignal
c34df2090c don't reply to DatabaseStore messages extracted from transit 2023-04-21 21:31:14 -04:00
orignal
5769a41208 use unordered_map for LeaseSets 2023-04-21 14:54:54 -04:00
orignal
dc265367dc drop unexpected I2NP messages 2023-04-20 14:23:41 -04:00
orignal
c22fc75370 set router properties from incoming connections 2023-04-19 19:48:09 -04:00
orignal
6206616347 don't set unreachable twice 2023-04-18 20:21:22 -04:00
orignal
7a12b5ca4b handle incomplete HTTP header lines 2023-04-18 19:25:15 -04:00
orignal
b77ae08388 exclude previously non-reachable transports 2023-04-18 14:35:13 -04:00
orignal
527ee3b3c5 check if ident is unrechable only once 2023-04-16 08:18:41 -04:00
orignal
cd5bfaabb5 mark and check unreachable ident hashes 2023-04-15 22:16:31 -04:00
orignal
e20acb93cf don't lookup streaming destination for each message 2023-04-12 15:28:15 -04:00
orignal
132557f941 don't return default destination if port is specified explicitly 2023-04-12 13:33:20 -04:00
orignal
b8d21a1282 create non-default port destination explicitly 2023-04-12 07:46:50 -04:00
orignal
4ebc7c970a bypass medium congestion(D) routers for client tunnels 2023-04-10 23:04:38 -04:00
orignal
572694b141 check routers' congestion before recreating a tunnel 2023-04-09 21:32:44 -04:00
orignal
c1f19cb258 fixed typo 2023-04-06 16:19:56 -04:00
orignal
caff003a85 check for published ipv4 addresses for floodfills and IBGW 2023-04-06 16:03:15 -04:00
orignal
d580c0155a fixed typo 2023-04-05 21:49:49 -04:00
orignal
9475a22728 update introducers. cleanup unreachable routers 2023-04-05 21:30:36 -04:00
orignal
e3fb9d8483 fixed warning 2023-04-04 13:57:46 -04:00
orignal
220ef283de rename SendTunnelDataMsg to SendTunnelDataMsgTo for router tunnel delivery types 2023-04-04 13:48:00 -04:00
orignal
8178df752b fixed warning 2023-04-04 13:42:54 -04:00
orignal
922e5915b1 rename SendTunnelDataMsg to SendTunnelDataMsgs for multiple messages 2023-04-04 13:19:08 -04:00
orignal
dc6499aa98 fixed warnings 2023-04-03 22:50:31 -04:00
orignal
0c8a80b6f8 fixed warnings 2023-04-03 21:35:10 -04:00
orignal
7c2da75197 don't recreate existing streaming destination 2023-04-03 19:05:35 -04:00
orignal
b8032e7fbf publish congestion cap G 2023-04-02 11:27:51 -04:00
orignal
b42be2b391 Merge pull request #1910 from wekoq/critical_log_level
Add critical log level
2023-03-31 08:42:20 -04:00
weko
a3bdc4ddc1 change some log levels back 2023-03-31 12:40:38 +00:00
weko
2abc997af8 change some log levels back 2023-03-31 12:29:13 +00:00
weko
710a35993d change some log level to error back 2023-03-31 12:16:32 +00:00
weko
e36d5634e7 fix log level show in webconsole 2023-03-31 11:40:07 +00:00
weko
354a04f0f6 Up level for some logs to critical 2023-03-31 11:29:04 +00:00
weko
a80aeb6715 add critical log level 2023-03-30 21:31:12 +00:00
orignal
cd1af85e39 bypass slow transport sessions 2023-03-29 15:54:53 -04:00
orignal
60e648bf9a set cap 6 for unspecified ipv6 address 2023-03-29 13:40:12 -04:00
orignal
c45e31b1b2 validate new router 2023-03-28 22:00:17 -04:00
orignal
6d204b4d7b shorter streaming I2NP data messages 2023-03-26 22:12:43 -04:00
ralsei
71bad23906 add dinit service
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-26 23:18:49 +03:00
Dimitris Apostolou
d91d734b5c Fix typos 2023-03-26 01:48:22 +00:00
orignal
5fee6df87a handle reset in reposnse to SYN 2023-03-23 19:52:39 -04:00
orignal
644d65054d create smaller I2NP packets 2023-03-21 21:25:00 -04:00
orignal
f41563a700 check packet number for SessionConfirmed 2023-03-19 17:42:53 -04:00
orignal
32b54fa1f8 handle i2p.streaming.answerPings properly 2023-03-19 15:47:50 -04:00
orignal
084663d6ea mediam size I2NP messages 2023-03-18 15:32:05 -04:00
orignal
55b2f2c625 memory pool for IdentityEx 2023-03-16 21:32:53 -04:00
orignal
5ad9c8e740 create I2NP tunnel message for first fragment 2023-03-13 19:19:57 -04:00
R4SAS
e96f0bfb14 [msvc] fix warnings, revert cmake boost libs linking list
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-13 18:34:45 +00:00
R4SAS
8677cd54bd [cmake] win32: do not use static boost libs without WITH_STATIC
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-12 21:41:20 +00:00
R4SAS
b97ef1af49 2.47.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-11 21:54:32 +00:00
R4SAS
227697c388 [i18n] update translations
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-11 21:53:11 +00:00
orignal
a6bd8275ca 2.47.0 2023-03-11 10:35:55 -05:00
orignal
6f01ebc0a5 check target destination 2023-03-11 08:44:07 -05:00
orignal
98f06e3ba1 Merge pull request #1889 from polistern/feat/sam-udp-port
Added SAM UDP port parameter
2023-03-10 11:11:27 -05:00
R4SAS
b6d1d8117b [GHA] Windows MSVC workflow (#1904) 2023-03-10 04:32:07 +03:00
R4SAS
7b35c793f3 [reseed] support domains in yggdrasil reseeder, fix IPv6 URL host parsing
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-10 01:19:09 +00:00
R4SAS
58ef08310d [reseed] skip records in reserved IP ranges, check Yggdrasil avalability if domain resolves in ygg address
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-09 18:50:28 +03:00
orignal
ec5c13a95e add back i2p.novg.net with new certificate 2023-03-08 18:38:49 -05:00
orignal
0a564d153a reseed update 2023-03-08 18:23:32 -05:00
R4SAS
0a8da6bc2f [cmake] msvc build revision
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-03-08 14:41:29 +03:00
orignal
46e4f4aea5 update RouterInfo if congestion cap changed 2023-03-07 13:09:07 -05:00
orignal
6d7f20961f Merge pull request #1902 from Vort/pool_leak
Prevent leaking of ExploratoryPool
2023-03-07 10:06:45 -05:00
Vort
4b7fcdc719 Prevent leaking of ExploratoryPool 2023-03-07 12:06:50 +02:00
orignal
716926f0d7 publish high congestion cap 2023-03-06 19:48:04 -05:00
orignal
24a14e3440 moved max num transit tunnels to Tunnels 2023-03-05 20:08:15 -05:00
Vort
5470a3a453 Eliminate memory leak in Win32NetState 2023-03-05 21:14:43 +00:00
Sergey Fedorov
c02c9c3c24 Makefile.osx: do not use Intel flags on PPC 2023-03-05 21:13:43 +00:00
orignal
3154eda6a6 fixed typos 2023-03-04 15:46:44 -05:00
orignal
d50cf0ad83 recognize congestion caps 2023-03-03 20:21:56 -05:00
orignal
d6ed9152ee Merge pull request #1898 from Vort/reseed_fixes
Reseed fixes
2023-03-03 14:41:04 -05:00
Vort
a4759694c8 Prevent out of bounds array access 2023-03-03 21:28:22 +02:00
Vort
6610af08c2 Correct processing of reseed.floodfill option 2023-03-03 21:26:38 +02:00
orignal
4db643aa8e limited number of acked packets to 511 2023-03-02 16:18:25 -05:00
orignal
75c9f596b2 Merge pull request #1894 from Vort/remove_reseed
Remove unreachable reseed
2023-03-02 14:31:40 -05:00
Vort
064c013a72 Remove unreachable reseed 2023-03-02 21:25:29 +02:00
orignal
75ab385ab7 Merge pull request #1893 from Vort/warning_fixes
Fix several warnings
2023-03-02 07:11:27 -05:00
Vort
9e0389df1b Fix several warnings 2023-03-02 12:22:24 +02:00
orignal
1b921a2eac removed some SSU1 code 2023-03-01 22:05:24 -05:00
orignal
f2729b3efe Merge pull request #1892 from Vort/msvc_compat
Improve MSVC 2015 compatibility
2023-03-01 15:56:16 -05:00
Vort
231c02c058 Make Win32NetState compatible with MSVC 2023-03-01 22:41:31 +02:00
Vort
a199084c99 Add MSVC support to CMake build 2023-03-01 08:52:40 +02:00
Vort
64f0a545fd Improve MSVC 2015 compatibility 2023-02-28 19:41:17 +02:00
Vort
34617bcb44 Code style unification across file 2023-02-27 20:00:43 +00:00
Vort
5f8820d9d6 Silence several compiler warnings 2023-02-27 20:00:43 +00:00
Vort
10dfe39f5f Fix architecture detection in cmake build (#1890) 2023-02-27 15:32:42 +03:00
R4SAS
b7f0d87daf GHA and Cmake changes (#1888)
Done with Vort's (https://github.com/Vort) cooperation

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-26 23:38:23 +03:00
polistern
3ff1adf597 feat: Added SAM UDP port parameter. 2023-02-26 16:51:56 +00:00
orignal
93d89a1fe0 fixed typo 2023-02-26 09:07:53 -05:00
orignal
3c9a574e90 create io_service after daemonization 2023-02-26 08:46:01 -05:00
orignal
de82b3ae19 don't publish non-reachable router 2023-02-25 17:19:14 -05:00
orignal
4b421d3feb publish own RouterInfo in router's thread 2023-02-24 18:33:33 -05:00
orignal
f84d88ac63 publish own RouterInfo in router's thread 2023-02-24 18:28:30 -05:00
orignal
2e62f9532f separate thread for processing router's messages 2023-02-23 13:58:06 -05:00
R4SAS
5657079355 [gha] update deb build action
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-23 14:35:38 +00:00
R4SAS
bd63383d7f [gha] update deb build action
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-23 14:31:50 +00:00
R4SAS
db0f2fab11 [gha] update deb build action
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-23 14:24:15 +00:00
R4SAS
f33b0cad2e [gha] update deb build action
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-23 14:13:59 +00:00
R4SAS
e3fbc246f4 [gha] try to fix deb build
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-23 00:26:41 +03:00
orignal
d602ea1061 Merge pull request #1883 from Vort/null_fix
Remove extra null characters from webconsole output
2023-02-22 16:11:32 -05:00
orignal
d40cd00cdb use DHT table for floodfills 2023-02-22 15:58:20 -05:00
orignal
692600dfac Merge pull request #1885 from Vort/null_check
Check for null pointer before dereferencing it
2023-02-22 12:46:08 -05:00
Vort
95cc544c92 Check for null pointer before dereferencing it 2023-02-22 19:39:32 +02:00
orignal
8544283110 don't expire connected routers 2023-02-21 21:33:30 -05:00
orignal
abf687ff09 store RouterInfo in DHT 2023-02-21 19:08:12 -05:00
Vort
be2629aa5a Remove extra null characters from webconsole output 2023-02-21 11:14:53 +02:00
R4SAS
ebee6c5f13 2.46.1-1
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-21 05:53:51 +03:00
orignal
3adff82d4a don't handle ack request for router 2023-02-20 14:55:59 -05:00
R4SAS
200ad5524d 2.46.1
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-20 02:57:56 +00:00
R4SAS
82ac0aa492 2.46.1
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-20 05:50:14 +03:00
orignal
b8a99878b6 don't create profile for every new non-floodfill 2023-02-19 10:30:07 -05:00
orignal
eaca435a5b find multiple closest hashes 2023-02-18 19:45:31 -05:00
orignal
ce05cce331 validate LeaseSet if signature verification was not requested 2023-02-18 08:54:36 -05:00
orignal
e190dab7d6 fixed crash when shows leasesets 2023-02-17 21:13:50 -05:00
orignal
289c308600 set proper caps if host is unspecified 2023-02-17 20:08:05 -05:00
orignal
bff12b06f4 fixed race condition 2023-02-17 10:34:14 -05:00
orignal
b8590075e6 initial commit for Kademlia DHT 2023-02-16 22:14:02 -05:00
R4SAS
1da9e2e1c0 2.46.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-15 21:59:06 +00:00
R4SAS
a1fb97cfad [i18n] update and add Polish, Portuguese, Turkish
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-16 00:42:31 +03:00
R4SAS
e53fe2d988 2.46.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-15 21:27:01 +00:00
orignal
182a721674 2.46.0 2023-02-15 14:47:02 -05:00
barracuda156
00c75a7afa CMakeLists.txt: update comment re Boost and atomics on PPC 2023-02-15 18:16:03 +00:00
barracuda156
385e592045 TargetArch.cmake: fix info re OSX arch support, update copyright year 2023-02-15 18:16:03 +00:00
R4SAS
359781c698 [webconsole] streams table little fix
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-15 17:56:44 +00:00
R4SAS
c6c7191682 [debian] exclude parallel flag, remove conffiles
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-15 20:55:38 +03:00
orignal
fa286a6fb3 faster GetBit 2023-02-14 19:49:29 -05:00
orignal
02a36a9fa8 don't populate buffer of unreachable router 2023-02-14 15:44:35 -05:00
R4SAS
77142e59ee [http] fix query detection, addresshelper processing, update tests
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-14 18:51:14 +00:00
orignal
4156900fb5 Merge pull request #1879 from wekoq/no_reversed_ports
Don't use reversed port for choise random port. (by whothefuckami)
2023-02-14 13:06:31 -05:00
weko
76d39cc7c9 changed to tabs, move tor port to function 2023-02-14 20:46:24 +03:00
weko
9e0c5d67c7 Don't use reversed port for choise random port. (by whothefuckami) 2023-02-14 20:46:24 +03:00
orignal
03111ad0df don't save profiles under mutex 2023-02-14 09:50:32 -05:00
orignal
abb81c353d fixed race condition 2023-02-14 09:33:10 -05:00
orignal
1ad38c0b95 fixed typo 2023-02-13 19:37:11 -05:00
orignal
532a29b0c4 don't reply with unreachable router 2023-02-13 19:18:02 -05:00
orignal
4f3a416e37 send DateTime together with RouterInfo 2023-02-13 15:44:20 -05:00
orignal
4d0ad47491 GetBit for IdentHash 2023-02-13 13:45:06 -05:00
orignal
7b632bd03d set minimal floodfill version to 0.9.51 2023-02-13 13:25:02 -05:00
orignal
c2faa5c614 don't try to save RouterInfo if no buffer 2023-02-12 19:10:22 -05:00
orignal
d15581d95e delete invalid router after update 2023-02-12 18:02:16 -05:00
orignal
7bde4de1f5 don't try to save unreachable routers 2023-02-12 15:28:06 -05:00
orignal
88f19f551d don't save RouterInfo buffer if invalid 2023-02-12 09:21:59 -05:00
orignal
d79bdc9f66 send datetime block after approximately every 250 packets 2023-02-11 20:11:34 -05:00
orignal
48a3c767e5 in-meory storage for router profiles 2023-02-11 16:22:02 -05:00
R4SAS
86fc12e395 [style] clean code
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-11 09:41:51 +03:00
R4SAS
3c65012a63 [ssu2] close socket if it was opened on OpenSocket
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-02-11 06:29:37 +00:00
orignal
97b7ea0da5 create separate new ipv4 and ipv6 published addresses 2023-02-10 22:04:42 -05:00
orignal
1c4cc02c23 drop garlic message in garlic clove 2023-02-10 18:21:12 -05:00
orignal
ac94341203 disconnect established session if clock skew detected 2023-02-10 11:48:11 -05:00
orignal
234540f9e7 Merge pull request #1873 from Vort/ntp_desc
Fix description for nettime.enabled option
2023-02-10 10:12:11 -05:00
Vort
cb44a35fde Fix description for nettime.enabled option 2023-02-10 16:58:42 +02:00
orignal
6ac849fe37 Merge pull request #1872 from Vort/log_fix
Fix debug log output
2023-02-09 19:34:25 -05:00
Vort
0829b186b7 Fix debug log output 2023-02-10 01:57:43 +02:00
orignal
993900aa77 terminate sessions if clock was adjusted backwards too much 2023-02-09 18:49:35 -05:00
orignal
aac9a8d18f check if clock was adjusted backwards 2023-02-09 18:32:18 -05:00
orignal
2baaa8bb8f fixed typo 2023-02-07 18:01:24 -05:00
orignal
f29ef2c057 don't compare first byte for yggdrasil addresses 2023-02-07 15:28:33 -05:00
orignal
d1c98c58b9 update status before deleting session 2023-02-06 19:31:31 -05:00
orignal
4930157e93 don't innsert back unreachable router 2023-02-06 16:18:16 -05:00
orignal
d30d1e8a7d don't set unrechable for routers without published addresses 2023-02-06 14:18:15 -05:00
orignal
80a55c5b75 store unrechable in profile 2023-02-06 13:19:41 -05:00
orignal
3c02cade58 compare only first 8 bytes for temporary addreses 2023-02-05 19:19:20 -05:00
orignal
21123e2afa compare published address and actual endpoint 2023-02-05 18:26:09 -05:00
orignal
f1415c2234 compare published address and actual endpoint 2023-02-05 15:42:46 -05:00
orignal
212a1156a1 filter our addresses with invalid hosts 2023-02-05 11:00:00 -05:00
orignal
54fb234424 limit number of acked packets to 510 2023-02-03 19:17:46 -05:00
orignal
5a6b50ae51 fixed typo 2023-02-03 17:32:43 -05:00
orignal
21542e8150 select first hop from high bandwidth peer for client tunnels 2023-02-03 15:59:56 -05:00
orignal
544fcd147f Merge pull request #1867 from Vort/sort_transports
Sort transports by IP:port pairs
2023-02-02 19:20:11 -05:00
Vort
9bc3b11b96 Sort transports by IP:port pairs 2023-02-03 01:36:16 +02:00
orignal
02e7f6b0c3 cleanup out of sequence packet nums in one call 2023-02-02 13:52:48 -05:00
orignal
f7101cc260 fixed warning 2023-02-01 21:28:05 -05:00
orignal
e9f0ed6473 cleanup out-of-sequnce list more aggressivly 2023-02-01 19:05:04 -05:00
orignal
4960587f46 cleanup out-of-sequnce list more aggressivly 2023-02-01 18:37:31 -05:00
orignal
bf8eecf407 more attempts to find good peer 2023-02-01 16:04:09 -05:00
orignal
09a1a78bd6 Merge pull request #1865 from wekoq/openssl
Add parameter for show TCSR with old algorithm and it's realization
2023-02-01 11:42:27 -05:00
weko
7df2ed6114 rename and refactor 2023-02-01 19:14:56 +03:00
weko
22b1066b0a Add parameter for show TCSR with old algorithm and it's realization 2023-02-01 14:06:28 +03:00
orignal
89695a7040 Merge pull request #1864 from Vort/ipv6_brackets
enclose IPv6 address in square brackets
2023-01-31 18:21:05 -05:00
Vort
2ed281472f enclose IPv6 address in square brackets 2023-02-01 01:13:46 +02:00
orignal
fafdb0c590 drop too long or too short LeaseSet 2023-01-30 15:06:40 -05:00
R4SAS
2a6883e305 [debian] add missing space in changelog (closes #1863) 2023-01-30 20:57:08 +03:00
R4SAS
3cee8bfcb2 Update tests and corresponding makefiles (#1862) 2023-01-30 04:17:49 +03:00
orignal
86dbfdb536 mutex for encrypted LeaseSet update 2023-01-29 09:19:12 -05:00
orignal
70fec2bc99 don't publish localhost addresses in RouterInfo 2023-01-28 22:33:44 -05:00
orignal
8a106eb09e fixed test-http-req 2023-01-28 17:18:54 -05:00
R4SAS
f9331897b8 [gha] fix docker manifest merging
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-27 21:11:26 +00:00
R4SAS
126ca0209b [gha] update docker build workflow
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-27 20:11:05 +00:00
orignal
ad5540c9f3 delete address if corresponding transport is disabled 2023-01-26 11:32:59 -05:00
orignal
e91d0bbec8 delete address if corresponding transport is disabled 2023-01-26 11:21:08 -05:00
orignal
8ee461f60a enable all ipv4 adresses even if one is already enabled 2023-01-25 18:11:26 -05:00
orignal
4de6201b84 update RouuterInfo if NTCP2 or SSU2 keys were recreated 2023-01-25 13:23:46 -05:00
orignal
273aa31b1e try another floodfill if it's incompatible with tunnels 2023-01-25 12:43:46 -05:00
R4SAS
b31f52e332 [http] keep query even if it was empty (closes #1844)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-25 08:54:45 +00:00
orignal
4fae7b8d65 don't update local RouterInfo addresses in Load but in InitTransports only 2023-01-24 18:20:16 -05:00
orignal
5479ddd03c publish NTCP2 addreses by index 2023-01-24 14:07:22 -05:00
orignal
1f23584c24 update all SSU2 addresses 2023-01-23 21:24:01 -05:00
orignal
067fb45a25 exclude router from tunnel build for 2.5 minutes if doesn't reply too often 2023-01-21 19:40:43 -05:00
R4SAS
ac287a896c [websonsole] use a function to format the amount of tunnel traffic
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-20 23:03:00 +00:00
R4SAS
8baf62eb2c [websonsole] fix int concatenation with char strings
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-21 01:55:43 +03:00
R4SAS
e1ec79daf2 [webconsole] format transit tunnels with table
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-21 00:51:07 +03:00
orignal
d4426118c5 exclude router from tunnel build for 2.5 minutes if declined 2023-01-20 15:34:40 -05:00
orignal
64fe56aa07 Merge pull request #1854 from Vort/server_forwards_style
use correct style for Server Forwards section
2023-01-20 11:58:10 -05:00
Vort
47eb49c34e use correct style for Server Forwards section 2023-01-20 18:52:56 +02:00
orignal
cd6d86c8c3 make sure that async CreateStream complete 2023-01-19 13:40:12 -05:00
R4SAS
84d4e074ce add loglevel checker, fix fields passing to translated string formatter
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-19 08:33:03 +03:00
R4SAS
a0e71c4173 [i18n] update strings and translation file
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-19 07:46:54 +03:00
R4SAS
533c8a8a55 [i18n] set decimal point based on language
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-19 06:40:32 +03:00
R4SAS
a57ae4dc56 [i18n] add sweedish translation
Translation author: corona@mail.i2p

Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-19 05:53:29 +03:00
R4SAS
88dfe3ca4e [i18n] fix build on macos
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-18 18:56:21 +03:00
R4SAS
d68c7f8ea7 [i18n] fix build on macos
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-18 08:19:45 +03:00
R4SAS
e8ace998ba [i18n] add support of string formatting
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-18 07:21:44 +03:00
orignal
e8be39af17 memrory pool for SSU2IncompleteMessage 2023-01-17 21:32:36 -05:00
orignal
7196db09d6 Merge pull request #1852 from freeacetone/openssl
HTTPProxy message stream correcting and comments
2023-01-17 07:48:05 -05:00
acetone
b290ee1aa0 Cfg example: verbose comments for Web Console auth and addresshelper for public proxy 2023-01-17 09:00:11 +03:00
acetone
d105ab11af Joining two strings to one and correct comments 2023-01-17 08:45:18 +03:00
orignal
bc888167a7 use linked list for out of sequence fragments 2023-01-16 21:40:23 -05:00
R4SAS
6ca6591c43 [make] set PREFIX from DESTDIR if it present
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-17 01:30:31 +03:00
orignal
36cb707e47 Merge pull request #1849 from freeacetone/openssl
Addresshelper updating: referer check
2023-01-16 08:33:07 -05:00
acetone
013d5ff74f Addresshelper request validation by Refer-header 2023-01-16 16:16:16 +03:00
acetone
9af5a90757 Copyright year updated 2023-01-16 13:57:15 +03:00
acetone
d8b6f5438c log typo 2023-01-16 13:56:36 +03:00
acetone
10030a4e0d Addresshelper updating: referer check 2023-01-16 13:31:13 +03:00
orignal
993dc72ce6 use separate pointer to second fragment of incomplete message 2023-01-15 22:50:54 -05:00
orignal
324ace103b memoery pool for fragments 2023-01-14 17:05:09 -05:00
orignal
d530269e4f try to insert received msgid instead lookup 2023-01-13 19:23:26 -05:00
orignal
7146a4dbae check if session socket was closed before tunnels were built 2023-01-12 15:41:57 -05:00
R4SAS
f79900653b Update README.md 2023-01-12 15:49:02 +03:00
orignal
f172f44f32 Merge pull request #1833 from TomasGlgg/feature
Использование скользящего среднего для рассчета tunnel creation success rate
2023-01-11 15:36:37 -05:00
orignal
f34abe60fa 2.45.1 2023-01-11 13:52:20 -05:00
orignal
a3c305032a don't set Firewalled upon SessionCreated if ports mismatch 2023-01-08 08:25:23 -05:00
orignal
2921eaa055 differentiate symmetric and full cone NAT 2023-01-07 12:11:51 -05:00
orignal
1cc68ea402 differentiate symmetric and full cone NAT 2023-01-07 12:06:26 -05:00
orignal
c18e8f6c78 drop too long LeaseSet without processing 2023-01-07 10:54:49 -05:00
orignal
e59ca8420e temporary change back to C++17 2023-01-06 18:20:26 -05:00
orignal
a6f9a56e40 support C++20 2023-01-06 14:08:39 -05:00
R4SAS
4011502f5f [docker] put config in correct place
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-06 03:59:03 +03:00
orignal
acd6af709e don't use netdb memory pool for local RouterInfo 2023-01-05 18:16:36 -05:00
orignal
55704ece3a drop duplicated I2NP messages 2023-01-05 15:33:41 -05:00
orignal
0d3ede56cb reject duplicated trnsit tunnel 2023-01-05 11:59:47 -05:00
R4SAS
06fae976b3 [style] update editorconfig
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-04 17:10:06 +03:00
orignal
e95035c143 Merge pull request #1835 from kleenexi2p/openssl
Fix segfault when UPnP is enabled
2023-01-04 08:45:17 -05:00
kleenex
55be5c74f0 Fix segfault when UPnP is enabled
Added null check.

Signed-off-by: kleenex <kleenex@i2pmail.org>
2023-01-04 22:41:54 +09:00
R4SAS
a1c16e129d [rpm] fix date
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-04 16:28:42 +03:00
Tomas Globis
66f82cb43f Use moving average to calculate tunnel creation success rate 2023-01-03 03:07:07 +03:00
189 changed files with 9886 additions and 4855 deletions

View File

@@ -13,6 +13,11 @@ insert_final_newline = true
indent_style = tab
indent_size = 4
[*.cmd]
indent_style = space
indent_size = 2
end_of_line = crlf
[*.{h,cpp}]
indent_style = tab
indent_size = 4
@@ -25,3 +30,10 @@ indent_size = 4
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[*.patch]
trim_trailing_whitespace = false

View File

@@ -1,32 +1,57 @@
name: Build Debian packages
on: [push, pull_request]
on:
push:
branches:
- '*'
paths:
- .github/workflows/build-deb.yml
- contrib/**
- daemon/**
- debian/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Makefile
- Makefile.linux
tags:
- '*'
pull_request:
branches:
- '*'
jobs:
build:
name: ${{ matrix.dist }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dist: ['buster', 'bullseye', 'bookworm']
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "trunk build"
- uses: jtdor/build-deb-action@v1
- name: Build package
uses: jtdor/build-deb-action@v1
with:
docker-image: debian:${{ matrix.dist }}-slim
buildpackage-opts: --build=binary --no-sign
- uses: actions/upload-artifact@v3
before-build-hook: debchange --controlmaint --local "+${{ github.sha }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build"
extra-build-deps: devscripts git
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: i2pd_${{ matrix.dist }}
path: debian/artifacts/i2pd_*.deb
- uses: actions/upload-artifact@v3
- name: Upload debugging symbols
uses: actions/upload-artifact@v3
with:
name: i2pd-dbgsym_${{ matrix.dist }}
path: debian/artifacts/i2pd-dbgsym_*.deb

View File

@@ -1,16 +1,37 @@
name: Build on FreeBSD
on: [push, pull_request]
on:
push:
branches:
- '*'
paths:
- .github/workflows/build-freebsd.yml
- build/CMakeLists.txt
- build/cmake_modules/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Makefile
- Makefile.homebrew
tags:
- '*'
pull_request:
branches:
- '*'
jobs:
build:
runs-on: macos-12
runs-on: ubuntu-latest
name: with UPnP
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0.3.0
uses: vmactions/freebsd-vm@v1
with:
usesh: true
mem: 2048
@@ -21,8 +42,9 @@ jobs:
cd build
cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
gmake -j2
- name: Upload artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: i2pd-freebsd
path: build/i2pd
path: build/i2pd

View File

@@ -1,21 +1,42 @@
name: Build on OSX
on: [push, pull_request]
on:
push:
branches:
- '*'
paths:
- .github/workflows/build-osx.yml
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Makefile
- Makefile.homebrew
tags:
- '*'
pull_request:
branches:
- '*'
jobs:
build:
name: With USE_UPNP=${{ matrix.with_upnp }}
runs-on: macOS-latest
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: install packages
run: |
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
brew update
brew install boost miniupnpc openssl@1.1
- name: build application
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3

View File

@@ -0,0 +1,80 @@
name: Build on Windows with MSVC
on:
push:
branches:
- '*'
paths:
- .github/workflows/build-windows-msvc.yml
- build/CMakeLists.txt
- build/cmake_modules/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Win32/**
tags:
- '*'
pull_request:
branches:
- '*'
jobs:
build:
name: Build
runs-on: windows-latest
env:
boost_path: ${{ github.workspace }}\boost_1_83_0
openssl_path: ${{ github.workspace }}\openssl_3_2_1
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build and install zlib
run: |
powershell -Command "(Invoke-WebRequest -Uri https://raw.githubusercontent.com/r4sas/zlib.install/master/install.bat -OutFile install_zlib.bat)"
powershell -Command "(Get-Content install_zlib.bat) | Set-Content install_zlib.bat" # fixing line endings
set BUILD_TYPE=Debug
./install_zlib.bat
set BUILD_TYPE=Release
./install_zlib.bat
del install_zlib.bat
- name: Install Boost
run: |
powershell -Command "(Start-BitsTransfer -Source https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe/download -Destination boost_1_83_0-msvc-14.3-64.exe)"
./boost_1_83_0-msvc-14.3-64.exe /DIR="${{env.boost_path}}" /VERYSILENT /SUPPRESSMSGBOXES /SP-
- name: Install OpenSSL
run: |
powershell -Command "(Start-BitsTransfer -Source https://slproweb.com/download/Win64OpenSSL-3_2_1.exe -Destination Win64OpenSSL-3_2_1.exe)"
./Win64OpenSSL-3_2_1.exe /DIR="${{env.openssl_path}}" /TASKS="copytobin" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
- name: Make copy of the OpenSSL libraries for CMake
run: |
dir ${{ github.workspace }}
dir ${{env.openssl_path}}\lib\VC
dir ${{env.openssl_path}}\lib\VC\x64\
dir ${{env.openssl_path}}\lib\VC\x64\MTd\
xcopy /s /y "${{env.openssl_path}}\lib\VC\x64\MTd" "${{env.openssl_path}}\lib"
- name: Configure
working-directory: build
run: cmake -DBoost_ROOT="${{env.boost_path}}" -DOPENSSL_ROOT_DIR="${{env.openssl_path}}" -DWITH_STATIC=ON .
- name: Build
working-directory: build
run: cmake --build . --config Debug -- -m
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: i2pd-msvc
path: build/Debug/i2pd.*

View File

@@ -1,6 +1,25 @@
name: Build on Windows
on: [push, pull_request]
on:
push:
branches:
- '*'
paths:
- .github/workflows/build-windows.yml
- build/CMakeLists.txt
- build/cmake_modules/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Win32/**
- Makefile
- Makefile.mingw
tags:
- '*'
pull_request:
branches:
- '*'
defaults:
run:
@@ -8,44 +27,106 @@ defaults:
jobs:
build:
name: Building using ${{ matrix.arch }} toolchain
name: ${{ matrix.arch }}
runs-on: windows-latest
strategy:
fail-fast: true
fail-fast: false
matrix:
include: [
{ 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 }
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
]
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
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
install: base-devel git mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
update: true
- name: Install additional clang packages
if: ${{ matrix.msystem == 'CLANG64' }}
run: pacman --noconfirm -S mingw-w64-${{ matrix.arch }}-gcc-compat
- 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 -j3
- name: Upload artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: i2pd-${{ matrix.arch_short }}.exe
path: i2pd.exe
build-xp:
name: Building for Windows XP
build-cmake:
name: CMake ${{ matrix.arch }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include: [
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
]
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
install: base-devel git mingw-w64-${{ matrix.arch }}-cmake mingw-w64-${{ matrix.arch }}-ninja mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
update: true
- name: Build application
run: |
cd build
cmake -DWITH_GIT_VERSION=ON -DWITH_STATIC=ON -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
cmake --build . -- -j3
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: i2pd-cmake-${{ matrix.arch_short }}.exe
path: build/i2pd.exe
build-xp:
name: XP
runs-on: windows-latest
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- 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
@@ -64,12 +145,14 @@ jobs:
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
uses: actions/upload-artifact@v3
with:
name: i2pd-xp.exe
path: i2pd.exe

View File

@@ -1,38 +1,65 @@
name: Build on Ubuntu
on: [push, pull_request]
on:
push:
branches:
- '*'
paths:
- .github/workflows/build.yml
- build/CMakeLists.txt
- build/cmake_modules/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Makefile
- Makefile.linux
tags:
- '*'
pull_request:
branches:
- '*'
jobs:
build-make:
name: Make with USE_UPNP=${{ matrix.with_upnp }}
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
sudo apt-get install build-essential libboost-all-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
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
with_upnp: ['ON', 'OFF']
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- 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
sudo apt-get install build-essential cmake libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: |
cd build

View File

@@ -5,11 +5,22 @@ on:
branches:
- openssl
- docker
paths:
- .github/workflows/docker.yml
- contrib/docker/**
- contrib/certificates/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Makefile
- Makefile.linux
tags:
- '*'
jobs:
build:
name: Building container for ${{ matrix.platform }}
runs-on: ubuntu-latest
permissions:
packages: write
@@ -25,41 +36,44 @@ jobs:
]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build container for ${{ matrix.archname }}
uses: docker/build-push-action@v3
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: ${{ matrix.platform }}
push: true
tags: |
purplei2p/i2pd:latest-${{ matrix.archname }}
ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
- name: Build container for ${{ matrix.archname }}
uses: docker/build-push-action@v3
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: ${{ matrix.platform }}
push: true
tags: |
purplei2p/i2pd:latest-${{ matrix.archname }}
ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
provenance: false
push:
name: Pushing merged manifest
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
@@ -67,74 +81,60 @@ jobs:
needs: build
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push latest manifest image to Docker Hub
uses: Noelware/docker-manifest-action@master
with:
base-image: purplei2p/i2pd:latest
extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push latest manifest image to Docker Hub
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: purplei2p/i2pd:latest
images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push latest manifest image to GHCR
uses: Noelware/docker-manifest-action@master
with:
base-image: ghcr.io/purplei2p/i2pd:latest
extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Create and push latest manifest image to GHCR
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: ghcr.io/purplei2p/i2pd:latest
images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Store release version to env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Store release version to env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Create and push release manifest image to Docker Hub
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
base-image: purplei2p/i2pd:latest-release
extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push release manifest to Docker Hub
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push release manifest image to GHCR
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
base-image: ghcr.io/purplei2p/i2pd:latest-release
extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Create and push versioned manifest image to Docker Hub
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
base-image: purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
push: true
- name: Create and push versioned manifest image to GHCR
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
base-image: ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true
- name: Create and push release manifest to GHCR
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: Noelware/docker-manifest-action@master
with:
inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
push: true

205
ChangeLog
View File

@@ -1,6 +1,211 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
## [2.51.0] - 2024-04-06
### Added
- Non-blocking mode for UDP sockets
- Set SSU2 socket buffer size based on bandwidth limit
- Encrypted tunnel tests
- Support for multiple UDP server tunnels on one destination
- Publish medium congestion indication
- Local domain sockets for SOCKS proxy upstream
- Tunnel status "declined" in web console
- SAM error reply "Incompatible crypto" if remote destination has incompatible crypto
- Reduce amount of traffic by handling local message drops
- Keep SSU2 socket open even if it fails to bind
- Lower SSU2 resend traffic spikes
- Expiration for messages in SSU2 send queue
- Use EWMA for stream RTT estimation
- Request choking delay if too many NACKs in stream
- Allow 0ms latency for tunnel
- Randomize tunnels selection for tests
### Changed
- Upstream SOCKS proxy from SOCKS4 to SOCKS5
- Transit tunnels limit to 4 bytes. Default value to 10K
- Reply CANT_REACH_PEER if connect to ourselves in SAM
- Don't send already expired I2NP messages
- Use monotonic timer to measure tunnel test latency
- Standard NTCP2 frame doesn't exceed 16K
- Always send request through tunnels in case of restricted routes
- Don't delete connected routers from NetDb
- Send lookup reply directly to reply tunnel gateway if possible
- Reduce unreachable router ban interval to 8 minutes
- Don't request banned routers / don't try to connect to unreachable router
- Consider 'M' routers as low bandwidth
- Limit minimal received SSU2 packet size to 40 bytes
- Bob picks peer test session only if Charlie's address supports peer testing
- Reject peer test msg 2 if peer testing is not supported
- Don't request termination if SSU2 session was not established
- Set maximum SSU2 queue size depending on RTT value
- New streaming RTT calculation algorithm
- Don't double initial RTO for streams when changing tunnels
- Restore failed tunnel if test or data for inbound tunnel received
- Don't fail last remaining tunnel in pool
- Publish LeasetSet again if local destination was not ready or no tunnels
- Make more attempts to pick high bandwidth hop for client tunnel
- Reduced SSU2 session termination timeout to 165 seconds
- Reseeds list
### Fixed
- ECIESx25519 symmetric key tagset early expiration
- Encrypted LeaseSet lookup
- Outbound tunnel build fails if it's endpoint is the same as reply tunnel gateway
- I2PControl RouterManager returns invalid JSON when unknown params are passed
- Mix of data between different UDP sessions on the same server
- TARGET_OS_SIMULATOR check
- Handling of "reservedrange" param
- New NTCP2 session gets teminated upon termination of old one
- New SSU2 session gets teminated upon termination of old one
- Peer test to non-supporting router
- Streaming ackThrough off 1 if number of NACKs exceeds 255
- Race condition in ECIESx25519 tags table
- Good tunnel becomes failed
- Crash when packet comes to terminated stream
- Stream hangs during LeaseSet update
## [2.50.2] - 2024-01-06
###Fixed
- Crash with OpenSSL 3.2.0
- False positive clock skew detection
## [2.50.1] - 2023-12-23
###Fixed
- Support for new EdDSA usage behavior in OpenSSL 3.2.0
## [2.50.0] - 2023-12-18
### Added
- Support of concurrent ACCEPTs on SAM 3.1
- Haiku OS support
- Low bandwidth and far routers can expire before 1 hour
### Changed
- Don't pick too active peer for first hop
- Try peer test again if status is Unknown
- Send peer tests with random delay
- Reseeds list
### Fixed
- XSS vulnerability in addresshelper
- Publishing NAT64 ipv6 addresses
- Deadlock in AsyncSend callback
## [2.49.0] - 2023-09-18
### Added
- Handle SOCK5 authorization with empty user/password
- Drop incoming transport sessions from too old or from future routers
- Memory pool for router profiles
- Allow 0 hops in explicitPeers
### Changed
- Separate network and testing status
- Remove AVX code
- Improve NTCP2 transport session logging
- Select router with ipv4 for tunnel endpoint
- Consider all addresses non-published for U and H routers even if they have host/port
- Don't pick completely unreachable routers for tunnels
- Exclude SSU1 introducers from SSU2 addresses
- Don't create paired inbound tunnel if length is different
- Remove introducer from RouterInfo after 60 minutes
- Reduce SSU2 keep alive interval and add keep alive interval variance
- Don't pick too old sessions for introducer
### Fixed
- Version of the subnegotiation in user/password SOCKS5 response
- Send keepalive for existing session with introducer
- Buffer offset for EVP_EncryptFinal_ex() to include outlen
- Termination block size processing for transport sessions
- Crash if deleted BOB destination was shared between few BOB sessions
- Introducers with zero tag
- Padding for SSU2 path response
## [2.48.0] - 2023-06-12
### Added
- Allow user/password authentication method for SOCK5 proxy
- Publish reject all congestion cap 'G' if transit is not accepted
- 'critical' log level
- Print b32 on webconsole destination page
- Webconsole button to drop a remote LeaseSet
- limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup
- Recognize real routers if successfully connected or responded to tunnel build request
### Changed
- Bypass slow transport sessions for first hop selection
- Limit AESNI inline asm to x86/x64
- Create smaller I2NP packets if possible
- Make router unreachable if AEAD tag verification fails in SessionCreated
- Don't include a router to floodfills list until it's confirmed as real
- Drop LeaseSet store request if not floodfill
- Bypass medium congestion('D') routers for client tunnels
- Publish encrypted RouterInfo through tunnels
- Check if s is valid x25519 public key
- Check if socket is open before sending data in SSU2
### Fixed
- Webconsole empty page if destination is not found
- i2p.streaming.answerPings param
- Reload tunnels
- Address caps for unspecified ipv6 address
- Incomplete HTTP headers in I2P tunnels
- SSU2 socket network exceptions on Windows
- Use of 'server' type tunnel port as inport (#1936)
## [2.47.0] - 2023-03-11
### Added
- Congestion caps
- SAM UDP port parameter
- Support domain addresses for yggdrasil reseeds
### Changed
- DHT for floodfills instead plain list
- Process router's messages in separate thread
- Don't publish non-reachable router
- Send and check target destination in first streaming SYN packet
- Reseeds list
### Fixed
- Memory leak in windows network state detection
- Reseed attempts from invalid address
## [2.46.1] - 2023-02-20
### Fixed
- Race condition while getting router's peer profile
- Creation of new router.info
- Displaying LeaseSets in the webconsole
- Crash when processing ACK request
## [2.46.0] - 2023-02-15
### Added
- Limit number of acked SSU2 packets to 511
- Localization to Swedish, Portuguese, Turkish, Polish
- Periodically send Datetime block in NTCP2 and SSU2
- Don't select random port from reserved
- In memory table for peer profiles
- Store if router was unreachable in it's peer profile
- Show IPv6 addresses in square brackets in webconsole
- Check referer when processing Addresshelper
### Changed
- Algorithm for tunnel creation success rate calculation
- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint
- Exclude actually unreachable router from netdb for 2 hours
- Select first hop from high bandwidth peers for client tunnels
- Drop too long or too short LeaseSet
- Delete router from netdb if became invalid after update
- Terminate existing session if clock skew detected
- Close previous UDP socket if open before reopening
- Minimal version for floodfill is 0.9.51
- Sort transports by endpoints in webconsole
### Fixed
- Deadlock during processing I2NP block with Garlic in ECIES encrypted message to router
- Race condition with encrypted LeaseSets
- HTTP query detection
- Connection attempts to IPs from invalid ranges
- Publish "0.0.0.0" in RouterInfo
- Crash upon receiving PeerTest 7
- Tunnels for closed SAM session socket
- Missing NTCP2 address in RouterInfo if enabled back
## [2.45.1] - 2023-01-11
### Added
- Full Cone NAT status error
### Changed
- Drop duplicated I2NP messages in SSU2
- Set rejection code 30 if tunnel with id already exists
- Network status is always OK if peer test msg 5 received
### Fixed
- UPnP crash if SSU2 or NTCP2 is disabled
- Crash on termination for some platforms
## [2.45.0] - 2023-01-03
### Added
- Test for Symmetric NAT with peer test msgs 6 and 7

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2020, The PurpleI2P Project
Copyright (c) 2013-2023, The PurpleI2P Project
All rights reserved.

View File

@@ -47,6 +47,10 @@ else
LD_DEBUG = -s
endif
ifneq (, $(DESTDIR))
PREFIX = $(DESTDIR)
endif
ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
ifeq ($(HOMEBREW),1)
@@ -63,17 +67,22 @@ else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.bsd
else ifneq (, $(findstring haiku, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.haiku
else # not supported
$(error Not supported platform)
endif
INCFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
DEFINES += -DOPENSSL_SUPPRESS_DEPRECATED
NEEDED_CXXFLAGS += -MMD -MP
ifeq ($(USE_GIT_VERSION),yes)
GIT_VERSION := $(shell git describe --tags)
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
DEFINES += -DGITVER=$(GIT_VERSION)
endif
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) -DOPENSSL_SUPPRESS_DEPRECATED
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))
@@ -106,17 +115,17 @@ wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
## custom FLAGS to work at build-time.
obj/%.o: %.cpp | mk_obj_dir
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(DEFINES) $(INCFLAGS) -c -o $@ $<
# '-' is 'ignore if missing' on first run
-include $(DEPS)
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
$(CXX) $(DEFINES) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
$(SHLIB): $(LIB_OBJS)
ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG)
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG)

View File

@@ -6,7 +6,13 @@ CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misl
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
## custom FLAGS to work at build-time.
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
CXXVER := $(shell $(CXX) -dumpversion)
ifeq (${CXXVER}, "4.2.1") # older clang always returned 4.2.1
NEEDED_CXXFLAGS = -std=c++11
else # newer versions support C++17
NEEDED_CXXFLAGS = -std=c++17
endif
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
INCFLAGS = -I/usr/include/ -I/usr/local/include/
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread

10
Makefile.haiku Normal file
View File

@@ -0,0 +1,10 @@
CXX = g++
CXXFLAGS := -Wall -std=c++11
INCFLAGS = -I/system/develop/headers
DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE
LDLIBS = -lbe -lbsd -lnetwork -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
ifeq ($(USE_UPNP),yes)
DEFINES += -DUSE_UPNP
LDLIBS += -lminiupnpc
endif

View File

@@ -20,7 +20,11 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10+
# NEEDED_CXXFLAGS += -std=c++20
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
else # not supported
@@ -54,12 +58,13 @@ endif
# UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes)
NEEDED_CXXFLAGS += -DUSE_UPNP
DEFINES += -DUSE_UPNP
endif
ifeq ($(USE_AESNI),yes)
ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that
NEEDED_CXXFLAGS += -D__AES__ -maes
NEEDED_CXXFLAGS += -maes
DEFINES += -D__AES__
endif
endif

View File

@@ -4,49 +4,50 @@ USE_WIN32_APP := yes
WINDRES = windres
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
LDFLAGS := ${LD_DEBUG} -static
INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32
LDFLAGS := ${LD_DEBUG} -static -fPIC -msse
NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN
# Boost libraries suffix
BOOST_SUFFIX = -mt
NEEDED_CXXFLAGS += -std=c++17
DEFINES += -DWIN32_LEAN_AND_MEAN
# UPNP Support
ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB
LDLIBS = -lminiupnpc
endif
LDLIBS += \
-lboost_system$(BOOST_SUFFIX) \
-lboost_date_time$(BOOST_SUFFIX) \
-lboost_filesystem$(BOOST_SUFFIX) \
-lboost_program_options$(BOOST_SUFFIX) \
-lssl \
-lcrypto \
-lz \
$(MINGW_PREFIX)/lib/libboost_system-mt.a \
$(MINGW_PREFIX)/lib/libboost_date_time-mt.a \
$(MINGW_PREFIX)/lib/libboost_filesystem-mt.a \
$(MINGW_PREFIX)/lib/libboost_program_options-mt.a \
$(MINGW_PREFIX)/lib/libssl.a \
$(MINGW_PREFIX)/lib/libcrypto.a \
$(MINGW_PREFIX)/lib/libz.a \
-lwsock32 \
-lws2_32 \
-lgdi32 \
-liphlpapi \
-lcrypt32 \
-lgdi32 \
-lole32 \
-luuid \
-lpthread
ifeq ($(USE_WIN32_APP), yes)
NEEDED_CXXFLAGS += -DWIN32_APP
DEFINES += -DWIN32_APP
LDFLAGS += -mwindows
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
ifeq ($(USE_WINXP_FLAGS), yes)
NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
endif
ifeq ($(USE_AESNI),yes)
NEEDED_CXXFLAGS += -D__AES__ -maes
NEEDED_CXXFLAGS += -maes
LDFLAGS += -maes
DEFINES += -D__AES__
endif
ifeq ($(USE_ASLR),yes)
@@ -54,4 +55,4 @@ ifeq ($(USE_ASLR),yes)
endif
obj/%.o : %.rc | mk_obj_dir
$(WINDRES) -i $< -o $@
$(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@

View File

@@ -1,10 +1,10 @@
CXX = clang++
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11
INCFLAGS = -I/usr/local/include
DEFINES := -DMAC_OSX
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDFLAGS += -Wl,-dead_strip
LDFLAGS += -Wl,-dead_strip_dylibs
LDFLAGS += -Wl,-bind_at_load
ifeq ($(USE_STATIC),yes)
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
@@ -14,7 +14,7 @@ endif
ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
DEFINES += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a
else
@@ -22,8 +22,12 @@ ifeq ($(USE_UPNP),yes)
endif
endif
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -D__AES__ -maes
else
CXXFLAGS += -msse
OSARCH = $(shell uname -p)
ifneq ($(OSARCH),powerpc)
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -D__AES__ -maes
else
CXXFLAGS += -msse
endif
endif

View File

@@ -69,12 +69,12 @@ Build instructions:
**Supported systems:**
* 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.
* GNU/Linux (Debian, Ubuntu, etc) - [![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, etc.
* 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)
* Mac OS - [![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 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)
@@ -99,13 +99,23 @@ Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](http
Donations
---------
BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH
**E-Mail**: ```i2porignal at yandex.com```
**BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f```
**LTC**: ```LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59```
**ETH**: ```0x9e5bac70d20d1079ceaa111127f4fb3bccce379d```
**GST**: ```GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG```
**DASH**: ```Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF```
**ZEC**: ```t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ```
**ANC**: ```AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z```
**XMR**: ```497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH```
License
-------

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -29,7 +29,7 @@ namespace util
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
//setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
i2p::log::SetThrowFunction ([](const std::string& s)
@@ -47,7 +47,7 @@ namespace util
I2PService service((PSTR)SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
LogPrint(eLogCritical, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
return false;
}
return false;
@@ -61,10 +61,10 @@ namespace util
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
//setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
#ifdef WIN32_APP
if (!i2p::win32::StartWin32App ()) return false;
if (!i2p::win32::StartWin32App (isDaemon)) return false;
#endif
bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile)

View File

@@ -1,36 +1,36 @@
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
MAINICON ICON "mask.ico"
#endif // English (United States) resources
#ifndef APSTUDIO_INVOKED
#include "Resource.rc2"
#endif // not APSTUDIO_INVOKED
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
MAINICON ICON "mask.ico"
#endif // English (United States) resources
#ifndef APSTUDIO_INVOKED
#include "Resource.rc2"
#endif // not APSTUDIO_INVOKED

View File

@@ -2,7 +2,7 @@
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
#include "../libi2pd/version.h"
#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
@@ -25,7 +25,7 @@ BEGIN
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", CODENAME
VALUE "LegalCopyright", "Copyright (C) 2013-2022, The PurpleI2P Project"
VALUE "LegalCopyright", "Copyright (C) 2013-2023, The PurpleI2P Project"
VALUE "OriginalFilename", "i2pd"
VALUE "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -45,6 +45,7 @@ namespace i2p
namespace win32
{
DWORD g_GracefulShutdownEndtime = 0;
bool g_isWinService;
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{
@@ -144,30 +145,37 @@ namespace win32
s << bytes << " Bytes\n";
}
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing, RouterError error)
{
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;
default: s << "Unk";
};
if (i2p::context.GetError () != eRouterErrorNone)
if (testing)
s << " (Test)";
if (error != eRouterErrorNone)
{
switch (i2p::context.GetError ())
switch (error)
{
case eRouterErrorClockSkew:
s << " - Clock skew";
s << " - " << tr("Clock skew");
break;
case eRouterErrorOffline:
s << " - Offline";
s << " - " << tr("Offline");
break;
case eRouterErrorSymmetricNAT:
s << " - Symmetric NAT";
s << " - " << tr("Symmetric NAT");
break;
case eRouterErrorFullConeNAT:
s << " - " << tr("Full cone NAT");
break;
case eRouterErrorNoDescriptors:
s << " - " << tr("No Descriptors");
break;
default: ;
}
@@ -178,11 +186,11 @@ namespace win32
{
s << "\n";
s << "Status: ";
ShowNetworkStatus (s, i2p::context.GetStatus ());
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting(), i2p::context.GetError ());
if (i2p::context.SupportsV6 ())
{
s << " / ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6(), i2p::context.GetErrorV6 ());
}
s << "; ";
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
@@ -347,6 +355,9 @@ namespace win32
}
}
}
#if (__cplusplus >= 201703L) // C++ 17 or higher
[[fallthrough]];
#endif
}
case WM_TRAYICON:
{
@@ -416,8 +427,9 @@ namespace win32
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
bool StartWin32App ()
bool StartWin32App (bool isWinService)
{
g_isWinService = isWinService;
if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")))
{
MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK);
@@ -446,7 +458,9 @@ namespace win32
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;
}
SubscribeToEvents();
// COM requires message loop to work, which is not implemented in service mode
if (!g_isWinService)
SubscribeToEvents();
return true;
}
@@ -466,7 +480,8 @@ namespace win32
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0);
// UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app
else if(!g_isWinService)
UnSubscribeFromEvents();
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
}

View File

@@ -17,7 +17,7 @@ namespace win32
{
extern DWORD g_GracefulShutdownEndtime;
bool StartWin32App ();
bool StartWin32App (bool isWinService);
void StopWin32App ();
int RunWin32App ();
bool GracefulShutdown ();

View File

@@ -15,6 +15,7 @@ IUnknown *pUnknown = nullptr;
INetworkListManager *pNetworkListManager = nullptr;
IConnectionPointContainer *pCPContainer = nullptr;
IConnectionPoint *pConnectPoint = nullptr;
CNetworkListManagerEvent *pNetEvent = nullptr;
DWORD Cookie = 0;
void SubscribeToEvents()
@@ -29,7 +30,11 @@ void SubscribeToEvents()
if (SUCCEEDED(Result))
{
VARIANT_BOOL IsConnect = VARIANT_FALSE;
#if defined(_MSC_VER)
Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
#else
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
#endif
if (SUCCEEDED(Result)) {
i2p::transport::transports.SetOnline (true);
LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
@@ -41,8 +46,8 @@ void SubscribeToEvents()
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
if(SUCCEEDED(Result))
{
CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
pNetEvent = new CNetworkListManagerEvent;
Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie);
if (SUCCEEDED(Result))
LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages");
else
@@ -59,6 +64,7 @@ void SubscribeToEvents()
void UnSubscribeFromEvents()
{
LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
try
{
if (pConnectPoint) {
@@ -66,6 +72,9 @@ void UnSubscribeFromEvents()
pConnectPoint->Release();
}
if (pNetEvent)
pNetEvent->Release();
if (pCPContainer)
pCPContainer->Release();

View File

@@ -19,21 +19,18 @@ class CNetworkListManagerEvent : public INetworkListManagerEvents
{
public:
CNetworkListManagerEvent() : m_ref(1) { }
~CNetworkListManagerEvent() { }
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
{
HRESULT Result = S_OK;
if (IsEqualIID(riid, IID_IUnknown)) {
*ppvObject = (IUnknown *)this;
} else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) {
*ppvObject = (INetworkListManagerEvents *)this;
} else {
Result = E_NOINTERFACE;
return E_NOINTERFACE;
}
AddRef();
return Result;
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()

View File

@@ -21,7 +21,7 @@ BOOL I2PService::isService()
HWINSTA hWinStation = GetProcessWindowStation();
if (hWinStation != NULL)
{
USEROBJECTFLAGS uof = { 0 };
USEROBJECTFLAGS uof = { FALSE, FALSE, 0 };
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
{
bIsService = TRUE;
@@ -119,12 +119,12 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Start error: ", dwError);
LogPrint(eLogCritical, "Win32Service: Start error: ", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED);
}
}
@@ -162,7 +162,7 @@ void I2PService::Stop()
}
catch (...)
{
LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogCritical, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState);
}
}
@@ -191,12 +191,12 @@ void I2PService::Pause()
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError);
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogCritical, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_RUNNING);
}
}
@@ -215,12 +215,12 @@ void I2PService::Continue()
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Continue error: ", dwError);
LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError);
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogCritical, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_PAUSED);
}
}
@@ -238,11 +238,11 @@ void I2PService::Shutdown()
}
catch (DWORD dwError)
{
LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError);
LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError);
}
catch (...)
{
LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

14
build/.gitignore vendored
View File

@@ -1,6 +1,13 @@
# Various generated files
/CMakeFiles/
/Testing/
/tests/
/.ninja_*
/arch.c
/build.ninja
/i2pd
/i2pd.exe
/i2pd.exe.debug
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
@@ -8,8 +15,13 @@
/CMakeCache.txt
/CPackConfig.cmake
/CPackSourceConfig.cmake
/CTestTestfile.cmake
/install_manifest.txt
/arch.c
/Makefile
# windows build script
i2pd*.zip
build*.log
# MVS project files
*.vcxproj
*.vcxproj.filters
*.sln

View File

@@ -1,14 +1,32 @@
cmake_minimum_required(VERSION 3.7)
cmake_policy(VERSION 3.7)
project("i2pd")
if(${CMAKE_VERSION} VERSION_LESS 3.22)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.22)
endif()
# for debugging
#set(CMAKE_VERBOSE_MAKEFILE on)
# Win32 build with cmake is not supported
if(WIN32 OR MSVC OR MSYS OR MINGW)
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
endif()
# paths
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client)
set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n)
set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon)
include(Version)
set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION)
project(
i2pd
VERSION ${PROJECT_VERSION}
HOMEPAGE_URL "https://i2pd.website/"
LANGUAGES C CXX
)
# configurable options
option(WITH_AESNI "Use AES-NI instructions set" ON)
@@ -26,27 +44,22 @@ IF(BUILD_TESTING)
enable_testing()
ENDIF()
# paths
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
# Handle paths nicely
include(GNUInstallDirs)
# architecture
# 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(CheckAtomic)
if(WITH_STATIC)
if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
include_directories(${LIBI2PD_SRC_DIR})
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
include_directories(${LANG_SRC_DIR})
include_directories(${DAEMON_SRC_DIR})
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES PREFIX "")
@@ -57,11 +70,9 @@ if(WITH_LIBRARY)
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()
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
add_library(libi2pdclient ${CLIENT_SRC})
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
@@ -74,6 +85,7 @@ if(WITH_LIBRARY)
COMPONENT Libraries)
endif()
include_directories(${LANG_SRC_DIR})
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
add_library(libi2pdlang ${LANG_SRC})
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
@@ -86,6 +98,8 @@ if(WITH_LIBRARY)
COMPONENT Libraries)
endif()
include_directories(${DAEMON_SRC_DIR})
set(DAEMON_SRC
"${DAEMON_SRC_DIR}/Daemon.cpp"
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
@@ -95,6 +109,22 @@ set(DAEMON_SRC
"${DAEMON_SRC_DIR}/UPnP.cpp"
)
if(WIN32)
set(WIN32_SRC_DIR ${CMAKE_SOURCE_DIR}/Win32)
include_directories(${WIN32_SRC_DIR})
list(APPEND DAEMON_SRC
"${WIN32_SRC_DIR}/DaemonWin32.cpp"
"${WIN32_SRC_DIR}/Win32App.cpp"
"${WIN32_SRC_DIR}/Win32Service.cpp"
"${WIN32_SRC_DIR}/Win32NetState.cpp"
)
file(GLOB WIN32_RC ${WIN32_SRC_DIR}/*.rc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN -DNOMINMAX")
endif()
if(WITH_UPNP)
add_definitions(-DUSE_UPNP)
endif()
@@ -102,30 +132,44 @@ endif()
if(WITH_GIT_VERSION)
include(GetGitRevisionDescription)
git_describe(GIT_VERSION)
add_definitions(-DGITVER="${GIT_VERSION}")
add_definitions(-DGITVER=${GIT_VERSION})
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.
# Multiple definitions of __stack_chk_fail(libssp & libc)
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
if(HAIKU)
add_definitions(-D_DEFAULT_SOURCE -D_GNU_SOURCE)
endif()
# check for c++17 & c++11 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
if(CXX17_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(CXX11_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if(MSVC)
add_definitions(-DWINVER=0x0600)
add_definitions(-D_WIN32_WINNT=0x0600)
else()
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
# Multiple definitions of __stack_chk_fail(libssp & libc)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s")
endif()
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
# check for c++17 & c++11 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
if(CXX17_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(CXX11_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -157,8 +201,11 @@ endif()
# Note: AES-NI and AVX is available on x86-based CPU's.
# Here also ARM64 implementation, but currently we don't support it.
# MSVC is not supported due to different ASM processing, so we hope OpenSSL has its own checks to run optimized code.
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
add_definitions(-D__AES__)
endif()
@@ -178,6 +225,7 @@ endif()
# Use std::atomic instead of GCC builtins on macOS PowerPC:
# For more information refer to: https://github.com/PurpleI2P/i2pd/issues/1726#issuecomment-1306335111
# This has been fixed in Boost 1.81, nevertheless we retain the setting for the sake of compatibility.
if(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
add_definitions(-DBOOST_SP_USE_STD_ATOMIC)
endif()
@@ -187,10 +235,36 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
if(WITH_STATIC)
if(NOT MSVC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
if(MSVC)
set(Boost_USE_STATIC_RUNTIME ON)
else()
set(Boost_USE_STATIC_RUNTIME OFF)
endif()
if(MSVC)
set(OPENSSL_MSVC_STATIC_RT ON)
endif()
set(OPENSSL_USE_STATIC_LIBS ON)
set(ZLIB_USE_STATIC_LIBS ON)
if(MSVC)
set(ZLIB_NAMES zlibstatic zlibstat)
else()
set(ZLIB_NAMES libz zlibstatic zlibstat zlib z)
endif()
if(WITH_UPNP)
set(MINIUPNPC_USE_STATIC_LIBS ON)
add_definitions(-DMINIUPNP_STATICLIB)
endif()
set(BUILD_SHARED_LIBS OFF)
if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
# set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
@@ -200,17 +274,23 @@ else()
# TODO: Consider separate compilation for LIBI2PD_SRC for library.
# No need in -fPIC overhead for binary if not interested in library
# HINT: revert c266cff CMakeLists.txt: compilation speed up
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
if(WIN32)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
endif()
endif()
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
if(NOT DEFINED Boost_INCLUDE_DIRS)
find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic)
if(NOT DEFINED Boost_FOUND)
message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!")
endif()
find_package(OpenSSL REQUIRED)
if(NOT DEFINED OPENSSL_INCLUDE_DIR)
if(NOT DEFINED OPENSSL_FOUND)
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
endif()
@@ -235,8 +315,6 @@ endif()
# load includes
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
include(CheckAtomic)
# show summary
message(STATUS "---------------------------------------")
message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
@@ -252,16 +330,34 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}")
message(STATUS " BINARY : ${WITH_BINARY}")
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
message(STATUS " UPnP : ${WITH_UPNP}")
if(WITH_GIT_VERSION)
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION} (${GIT_VERSION})")
else()
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}")
endif()
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
message(STATUS "---------------------------------------")
if(WITH_BINARY)
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
if(WIN32)
add_executable("${PROJECT_NAME}" WIN32 ${DAEMON_SRC} ${WIN32_RC})
else()
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
endif()
if(WIN32)
list(APPEND MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi")
# OpenSSL may require Crypt32 library on MSVC build, which is not added by CMake lesser than 3.21
if(MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.21)
list(APPEND MINGW_EXTRA "crypt32")
endif()
endif()
if(WITH_STATIC)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
if(NOT MSVC)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
endif()
endif()
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -274,11 +370,18 @@ if(WITH_BINARY)
list(REMOVE_AT Boost_LIBRARIES -1)
endif()
# synchronization library is incompatible with Windows 7
if(WIN32)
get_target_property(BOOSTFSLIBS Boost::filesystem INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM BOOSTFSLIBS synchronization)
set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}")
endif()
if(WITH_STATIC)
set(DL_LIB ${CMAKE_DL_LIBS})
endif()
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${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

@@ -1,4 +1,4 @@
# Copyright (c) 2017-2022, The PurpleI2P Project
# Copyright (c) 2017-2023, 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
@@ -18,7 +18,7 @@ set(archdetect_c_code "
|| defined(_M_ARM64) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
#error cmake_ARCH arm64
#if defined(__ARM_ARCH_7__) \\
#elif defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
@@ -83,13 +83,13 @@ function(target_architecture output_var)
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# the OS X SDK version 10.7 or later - you'll need 10.4/10.5/10.6 for that, so we
# disable it by default. Also, ppc64 is not supported in 10.6.
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise; 10.6 also supports ppc.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
@@ -133,11 +133,11 @@ function(target_architecture output_var)
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# This compiles a small C program which is a series of ifdefs that selects
# a particular #error preprocessor directive whose message string contains
# the target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of
# the #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(

View File

@@ -0,0 +1,16 @@
# read version
function(set_version version_file output_var)
file(READ "${version_file}" version_data)
string(REGEX MATCH "I2PD_VERSION_MAJOR ([0-9]*)" _ ${version_data})
set(version_major ${CMAKE_MATCH_1})
string(REGEX MATCH "I2PD_VERSION_MINOR ([0-9]*)" _ ${version_data})
set(version_minor ${CMAKE_MATCH_1})
string(REGEX MATCH "I2PD_VERSION_MICRO ([0-9]*)" _ ${version_data})
set(version_micro ${CMAKE_MATCH_1})
set(${output_var} "${version_major}.${version_minor}.${version_micro}" PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,42 @@
# _________________________________________
# / Copy this file to the right location \
# | then load with: |
# | |
# | apparmor_parser -r -W |
# | /etc/apparmor.d/docker-i2pd |
# | |
# | docker run --security-opt |
# | "apparmor=docker-i2pd" ... |
# | purplei2p/i2pd |
# | |
# \ And "aa-status" to verify it's loaded. /
# -----------------------------------------
# \ ^__^
# \ (oo)\_______
# (__)\ )\/\
# ||----w |
# || ||
#include <tunables/global>
profile docker-i2pd flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
#include <abstractions/openssl>
#include <abstractions/nameservice>
/bin/busybox ix,
/usr/local/bin/i2pd ix,
/entrypoint.sh ixr,
/i2pd_certificates/** r,
/home/i2pd/data/** rw,
/home/i2pd/data/i2pd.pid k,
deny /home/i2pd/data/i2pd.conf w,
deny /home/i2pd/data/tunnels.conf w,
deny /home/i2pd/data/tunnels.d/** w,
deny /home/i2pd/data/certificates/** w,
deny /home/i2pd/data/i2pd.log r,
}

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF1zCCA7+gAwIBAgIRAMDqFR09Xuj8ZUu+oetSvAEwDQYJKoZIhvcNAQELBQAw
dTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxHjAcBgNVBAMM
FWFkbWluQHN0b3JteWNsb3VkLm9yZzAeFw0yNDAxMjUxNDE1MzBaFw0zNDAxMjUx
NDE1MzBaMHUxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx
HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR4w
HAYDVQQDDBVhZG1pbkBzdG9ybXljbG91ZC5vcmcwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQDbGX+GikPzQXr9zvkrhfO9g0l49KHLNQhUKYqd6T+PfnGo
Fm0d3ZZVVQZ045vWgroOXDGGZZWxUIlb2inRaR2DF1TxN3pPYt59RgY9ZQ9+TL7o
isY91krCRygY8EcAmHIjlfZQ9dBVcL7CfyT0MYZA5Efee9+NDHSewTfQP9T2faIE
83Fcyd93a2mIHYjKUbJnojng/wgsy8srbsEuuTok4MIQmDj+B5nz+za2FgI0/ydh
srlMt4aGJF4/DIem9z9d0zBCOkwrmtFIzjNF1mOSA8ES4m5YnKA/y9rZlRidLPGu
prbXhPVnqHeOnHMz2QCw1wbVo504kl0bMqyEz2tVWsO9ep7iZoQs2xkFAEaegYNT
QLUpwVGlyuq3wXXwopFRffOSimGSazICwWI6j+K0pOtgefNJaWrqKYvtkj1SbK2L
LBNUIENz6VnB7KPRckuX6zxC8PpOiBK9BcftfO+xAz/wC6qq3riBPw30KKSym0nC
Zp5KciDn4Phtw9PGq8Bkl8SyWl0jtFnfTB1tzJkisf2qKcNHaFTEe2JW763YLbh/
AU+8X8evFu40qLgvOgKoyy5DLy6i8zetX+3t9K0Fxt9+Vzzq6lm5V/RS8iIPPn+M
q1/3Z5kD0KQBG9h/Gl8BH+lB71ZxPAOZ3SMu8DJZcxBLVmDWqQPCr5CKnoz0swID
AQABo2IwYDAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG
AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHgYDVR0OBBcEFWFkbWluQHN0b3JteWNs
b3VkLm9yZzANBgkqhkiG9w0BAQsFAAOCAgEARWOJ69vTHMneSXYscha+4Ytjg0RM
faewJNEGj8qy/Qvh9si2bWYNPRK6BlbHFS7pRYBLAnhaeLBGVv1CCR6GUMMe74zQ
UuMeAoWU6qMDmB3GfYoZJh8sIxpwHqyJeTdeccRbZ4sX4F6u3IHPXYiU/AgbYqH7
pYXQg2lCjXZYaDFAlEf5SlYUDOhhXe5kR8Edhlrsu32/JzA1DQK0JjxKCBp+DQmA
ltdOpQtAg03fHP4ssdj7VvjIDl28iIlATwBvHrdNm7T0tYWn6TWhvxbRqvfTxfaH
MvxnPdIJwNP4/9TyQkwjwHb1h+ucho3CnxI/AxspdOvT1ElMhP6Ce6rcS9pk11Rl
x0ChsqpWwDg7KYpg0qZFSKCTBp4zBq9xoMJ6BQcgMfyl736WbsCzFTEyfifp8beg
NxUa/Qk7w7cuSPGyMIKNOmOR7FLlFbtocy8sXVsUQdqnp/edelufdNe39U9uNtY6
yoXI9//Tc6NgOwy2Oyia0slZ5qHRkB7e4USXMRzJ3p4q9eCVKjAJs81Utp7O2U+9
vhbhwWP8CAnNTT1E5WS6EKtfrdqF7wjkV+noPGLDGmrXi01J1fSMAjMfVO+7/LOL
UN+G4ybKWnEhhOO27yidN8Xx6UrCS23DBlPPQAeA74dTsTExiOxf1o1EXzcQiMyO
LAj3/Ojbi1xkWhI=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQIHQPtSoFU+cUpYD8PZaWZjANBgkqhkiG9w0BAQsFADB2
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEfMB0GA1UEAwwW
YXJuYXZiaGF0dDI4OEBtYWlsLmkycDAeFw0yMzAxMjUxODUzNDFaFw0zMzAxMjUx
ODUzNDFaMHYxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx
HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR8w
HQYDVQQDDBZhcm5hdmJoYXR0Mjg4QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAtwG73sC0jYd3fgEzZh0SveAdUd5yD35nINJRrdPSrSwY
n3i1qGe3fNLj877PvUDU+qiHH0fFZfyFkXTaq3TUp1u4YkmvaoPHy6FZlojB08lK
FBm+iJ1hifQ7MFmvIKUGv+cjlN6xSoQ0U6B2QOy6iZnBgFZ/7jbRY4iZOIj7VJtY
aodeHfy0bWe447VJovbkUi7NJPFZQS65LMcAIWcWTxrC0Gj8SmdxL3a5+hxpmmg0
+KCQvWQDdxAQjsc16sgUCdUc6cWYO4yw9H6fgdq9GJX+LnXR9OB58GsAjjlLlFoI
CZxdARDpoqcIj6AoKIanALf8yfbIyrqqJE47cuaqV9bht5MWKnXbwHplEkT4ZNkh
PnRDia7B5HY3uwbt39CBm264PEWXvWG2sozTWKQqBjmMN2cj/NFDUEqKv6BggMY1
HcqxWFKRcgKCtRvrmTmfp5l0/ou+OtUaFUg0a6Qhtb93Hj10vK6wZzidBqj0ggzB
eJDI95b89u8JgzRoOBriuMKTc91WTkOvBLkB3dgUbUpx2p8KHjvf/pppBH9u0oxp
qJFFK840DbnJydEvjKezeVe5Ax6YRSRxyEdKzRoWdvKVxb3qBBKMdCKTYEPxHPBu
JMEQVUCXJMti++1KEiQGhcfWvLyT7OewbcIZNk9XWNrxlKcGrTp9AOwaaNC5m1kC
AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr
BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB8GA1UdDgQYBBZhcm5hdmJoYXR0Mjg4
QG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAHiK0ld/1PF9DIhutD660/bzBg
mF2Z76hcBqDZ8tnQai/u/RXYrH9wso9BYyrVsvk3fr6tpGT49Ian0MVpPOxMoTU2
oBEmQlYrfclQLFsOLmA0y2r1ggXzIrt69jB710Vhwdnz09oOE8rS4E2T5oDD8Wvy
Kony+AarRceqtkOlzyquc42KjzdrbHsosF7G2iGhNI6t+T3BfWJ+Q+d5sj3OIh6e
gSfvHL44E4vZt6dtofRN3MAZ60kNLF5YWyaUo3Snv9Lso1IwIz3AVr5ehv+8sFL/
KxaXdkZ5Yn2YUX7p1t4VQd+eXVPYjf1befg4PvrwSkylu3Jpee3fllZSKXeSVx9x
jpJiq5vIakqk22pnWb1Vn7xzSW1vtEG7QLjobOr1WrcGiwdv+HKiWcXJXDzKoWXs
h3VEfr51Kap8cIJv+D6lJIG9IcIhiQ6CXWBmtjWJvbdVwFBy1/3Fhaou9liHi+gK
4Yh5a5OGCzc7xjtpGaTmoLEz7NzDNOdd/r840qRDOh70izzmFZd5Gwq4hoVcPJcS
EAySwtgqK0/4d0zDd2Wg9ASJV9DnDf8QuSmHZgZ9Efs47XcWz9TvkWUS1E66AJsN
mmI1NDQ3mv3dv5+WPq+dqqYFsnx3xWL1g5Z3buk0opeuXMzoHwM7UfN8h7Q1M5+t
+XBgkaYA4iEwYKqlCQ==
-----END CERTIFICATE-----

View File

@@ -1,33 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt
MIIFvjCCA6agAwIBAgIQBnsUOmOu2oZZIwHBmQc1BDANBgkqhkiG9w0BAQsFADBt
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN
aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x
aWdvckBub3ZnLm5ldDAeFw0yMzAxMjgxNDM4MzFaFw0zMzAxMjgxNDM4MzFaMG0x
CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT
FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4
cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF
x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h
vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm
w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw
MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy
Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy
f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b
mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d
Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP
0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq
jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLkf
bM3uiYfp9m0vgdoftyXtk2/9bHf3u5iaM0WfoJIsw1iizo/mxJl+Iy7SxLC16nV0
v5FpncVv+Z8x9dgoAYVuLq9zKfsAbpj6kuxAqw6vJMlD1TiIL3nSODV9BJLk47X5
tmvoOSj9BgvemYThTE3nj+DbuJRW5q90KyBV/LdLrQJX3k5R3FFL5tTad2LKFNZ4
vEOcYwwx6mvrkJ2lly6bAQUCtfc648Jyq+NO3Rba1fmn7gcP9zXXc5KYsj/ovyY2
OaocSF5wMhzBuPxO+M2HqbYLMAkc6/GesGds8Rm8wofuhJoI5YtqJuLKZm6nQXSc
fx6PKgbKcTIUWNFMsxyfghz9hpbg0rkvC7PtfAjtV0yaDtUum1eZeNEx1HbRWN2n
TQNCVuv0yaKC41qxqzhEybkdjL9JlgUh7VuskaCelB0lz+kgYjGu8ezOa0ua2iKq
4FC/1MbPulxN8NOt4pmbGqqoxmCdShp38wdnOBM3DsAS9f0JaQZd4CDyY4DCSfVn
xPdWk31+VXVt3Ixh1EUqZWYTRSsZApkCyYzkiZ/qPGG6FR9Hq2SuhC5o4P44k7eo
6wwBWD8a5RjsZhvr05E5yBrKXh/PjLwmtG73QC+ouR54/5xtedvdTwNS94FnNctX
FT6QGZnRwCkhPaRe1oQMzP+88pGoCfO33GBAuwUCAwEAAaNaMFgwDgYDVR0PAQH/
BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E
BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC
AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk
5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o
3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS
AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal
zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs
0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ
cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4
4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6
GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW
dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5
qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w==
AQCteAb5/bqhHr/i5CJbDzlofprXFC826c19GxQ/9Hw0kA52l0J9Q8Vz8Vy7VQyP
QNa8MCv6FeNy8a/wXp6cafyFsBtvehVQO8lFlpCgMEl2Bma43+GaCwkrM6bFNXeW
iQ9h4e1KjsUZ8cQDNEcamiJ80+xbMhBrj5bAZwKmZs8MoGEMyXKEZmcmwA+/fy1c
cx4izsOsmRXmEHXsvB9ydJHZZeKW8+r0DAtgPslwXuXHG6MuBQo7dKCqn+iMxHXV
Jxriq3yvNffdGx4maSLJrjQ1ealt/UMzql7huVSItnVFWoYf7GAELXNJ/PmqVyaK
q11LQ8W/Aud6s/bblaJrFJnK8PbPpaw4RvHoWVLYaZYmQnV2msWs5EuESBlEADbv
UklQXLMc2f9HKWPA5678nvYPrmu8IL5pMkAxgGRqmd+7vCz4lU9M5z3HObU+WRBt
qEMYyXywV8o3tbmnlDS5S5Xxf+tLZn1cxz3ZrmcHPHDbLBNdvszF3CTJH/R2sQvD
bizvYJM+p5F+GWM5mt6w0HrOut5MRlpOws/NRrkbijuVA/A45nzTtKplIFYE3qe8
q5SAbwYLc8cJcZCN3PxtWwbEv81V33abMt5QcjnWGLH5t2+1Z2KLCgKLSCQTxM8s
zBPHtUe8qtSQaElnNLILYbtJ1w67dPnGYTphHihC+CXjBg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFdTCCA12gAwIBAgIEQ5vCxzANBgkqhkiG9w0BAQ0FADBrMQswCQYDVQQGEwJY
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEUMBIGA1UEAwwLbHNAbWFpbC5pMnAw
HhcNMjMxMDE2MjAwNTA5WhcNMzMxMDEzMjAwNTA5WjBrMQswCQYDVQQGEwJYWDEL
MAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnltb3Vz
IE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEUMBIGA1UEAwwLbHNAbWFpbC5pMnAwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDPcbKRtf4PzrDa0iRit0XrwnmA
2c1fJhkBipdPor7gMOAlkR82H1lkZSizR7kTZnr7vYqjDrOQr7bl5Dy3qo8/YCbZ
jsnUCTIIgIJQUxUlR40RjaSXphqzUEiXKHR6b0RahhFisQ3hlbbgzSch5YgSLKws
hOLi+eDSXw+HlwHlWFlT1XOKxSTJ/F3Bv40gxqZVC2pbxiPOeRZHQ6Ojw75lxTSF
gww2WzgztiWt4X9BO1yepnVqhAVRPmTfGUMfKzq9jkMzZKeQFV4uZSP9nCqzEpYd
WNDUfpTWiAQ9F+BwFXGusXXA3tGVwS7s6IEoiJFM5fsoJYfRoWGh3/1eirhBXW7U
M6oubMSTADyrvfjLfJBMmMnc2hNblRlKr0ZKUjMfv8cnyT4kQxlXLAHHXY2P89TM
TEVODkU48gnv6tC4t1JCb1/Da+3yVMjNX6rCzQfUwnLFrWthrwiI0NivAKFtiZjq
w1/ZQcYke2YyeqcfXMn+NTUA22Sm2mJoMo7jUf+rbM9Pi27/DncJgRGj5qwY0D3S
gc7829EjuZNPttGBmae1EmO7WQMB32cqdmItnV2FXpMhnn9h0u5H52kYqwn+mdtc
dTJRcbfKG1RTr3UjFISaTwL8qigMIkVXIzcpnr/R/sSeEs8xCqfsJ6rb4dCyFx+M
hqQcOCL5tumyd4W/LQIDAQABoyEwHzAdBgNVHQ4EFgQUgfaOG5HCnlW82wZ5BahL
GRO06igwDQYJKoZIhvcNAQENBQADggIBAKdVpqS9qF7gGotgXaVA1iP5YNsWlTvG
daGqeA/87//U21W6gpq82FhzsmsvUtXZfIeVIlDPI7WNDzS+A3K/KKrwM7dLgSie
r9eMl3D8WYPU95QF4mAlRyl7PCCsYoVjyvfro0iq3/iudIA5476rjfLdTXRi5hAT
qemPj0S+6sRjKEldRtGXrQATFlvLIWVYpgHijdDDx5M2hAz2y0mFxlDZTlA4BhL4
DwtGlVKmbc2x5MvIQM4UhbQqkxYS4gXnzf5Qx9QIytHfTr/hmbrkhKR1GCO31BSk
x9LhZxdI8LlwKSo6YgwXEB9E0M/tplaK9iZJFv4HPYLZrVJpb4IklMumyLMrgW5P
fR0dgKn+R9lk0emJ1Cu+qyyzf1vsLycYBwaEztINn4VK+/HfDFpnVCvJOyNuDmj5
KBLIoGdGoVfylmnc+e8zAXe+DY41fgniHMISOO78P8Bx9vTB+rhqnOUr9MzlUxPB
sKGjbXy2YynEqiGb+9g344v/+ukTSDenqTPHVzJ5uOi0iedy+3ASzUNN6GJocovP
167VOhwaETM0FwiKe0VdZRLLbbZ79CtJC0tmgcgPQPRa9Ldr6KN7u1J3D6lUp6zl
byPom10ueKONRb36t7ai79l2SEUZRSMkx6AXIU0JJ1SMtQtav7b5LkpYJfdL7+vO
dDx2/Za0VmdD
-----END CERTIFICATE-----

View File

@@ -1,2 +1,5 @@
This forder contain systemd unit files.
To use systemd daemon control, place files from this directory to debian folder before building package.
This forder contain files required for building debian packages.
The trunk repository is contains the packaging files for the latest stable version of Debian (if we not forgot to update them).
Files in subdirectories contains fixes to make possible to build package on specific versions of Debian/Ubuntu. They are used when building the release package.

View File

@@ -0,0 +1 @@
11

View File

@@ -0,0 +1,18 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 11~), 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: 4.2.0
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: ${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.

View File

@@ -0,0 +1 @@
9

View File

@@ -0,0 +1,18 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), 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.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: ${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.

View File

@@ -0,0 +1,17 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
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

View File

@@ -0,0 +1,19 @@
Description: Disable LogsDirectory and LogsDirectoryMode options in service
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2023-05-17
--- a/contrib/i2pd.service
+++ b/contrib/i2pd.service
@@ -8,8 +8,8 @@ User=i2pd
Group=i2pd
RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -0,0 +1,2 @@
01-upnp.patch
02-service.patch

18
contrib/debian/trusty/rules Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/make -f
#export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS=hardening=+all
include /usr/share/dpkg/architecture.mk
ifeq ($(DEB_HOST_ARCH),i386)
export DEB_BUILD_OPTIONS=parallel=1
endif
export DEB_CXXFLAGS_MAINT_APPEND=-Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND=
%:
dh $@ --parallel
override_dh_auto_install:

View File

@@ -0,0 +1 @@
9

View File

@@ -0,0 +1,18 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), 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.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: ${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.

View File

@@ -0,0 +1,17 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
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

View File

@@ -0,0 +1,19 @@
Description: Disable LogsDirectory and LogsDirectoryMode options in service
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2023-05-17
--- a/contrib/i2pd.service
+++ b/contrib/i2pd.service
@@ -8,8 +8,8 @@ User=i2pd
Group=i2pd
RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -0,0 +1,2 @@
01-upnp.patch
02-service.patch

13
contrib/debian/xenial/rules Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/make -f
#export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
include /usr/share/dpkg/architecture.mk
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND =
%:
dh $@ --parallel
override_dh_auto_install:

8
contrib/dinit/i2pd Normal file
View File

@@ -0,0 +1,8 @@
type = bgprocess
run-as = i2pd
command = /usr/bin/i2pd --conf=/var/lib/i2pd/i2pd.conf --pidfile=/var/lib/i2pd/i2pd.pid --daemon --service
smooth-recovery = true
depends-on = ntpd
# uncomment if you want to use i2pd with yggdrasil
# depends-on = yggdrasil
pid-file = /var/lib/i2pd/i2pd.pid

View File

@@ -60,8 +60,8 @@ RUN apk update \
RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++
# 3. Copy preconfigured config file and entrypoint
COPY i2pd-docker.conf "$I2PD_HOME/i2pd.conf"
RUN chown i2pd:nobody "$I2PD_HOME/i2pd.conf"
COPY i2pd-docker.conf "$DATA_DIR/i2pd.conf"
RUN chown i2pd:nobody "$DATA_DIR/i2pd.conf"
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -19,7 +19,7 @@
## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
# certsdir = /var/lib/i2pd/certificates
## Where to write pidfile (default: i2pd.pid, not used in Windows)
## Where to write pidfile (default: /run/i2pd.pid, not used in Windows)
# pidfile = /run/i2pd.pid
## Logging configuration section
@@ -31,15 +31,16 @@
## * file - log entries to a file
## * syslog - use syslog, see man 3 syslog
# log = file
## Path to logfile (default - autodetect)
## Path to logfile (default: autodetect)
# logfile = /var/log/i2pd/i2pd.log
## Log messages above this level (debug, info, *warn, error, none)
## Log messages above this level (debug, info, *warn, error, critical, none)
## If you set it to none, logging will be disabled
# loglevel = warn
## Write full CLF-formatted date and time to log (default: write only time)
# logclftime = true
## Daemon mode. Router will go to background after start. Ignored on Windows
## (default: true)
# daemon = true
## Specify a family, router belongs to (default - none)
@@ -70,90 +71,97 @@
## don't just uncomment this
# port = 4567
## Enable communication through ipv4
## Enable communication through ipv4 (default: true)
ipv4 = true
## Enable communication through ipv6
## Enable communication through ipv6 (default: false)
ipv6 = false
## Enable SSU transport
ssu = false
## Bandwidth configuration
## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec,
## L limit bandwidth to 32 KB/sec, O - to 256 KB/sec, P - to 2048 KB/sec,
## X - unlimited
## 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
## 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. Value can be set to
## integer in kilobytes, it will apply that limit and flag will be used
## from next upper limit (example: if you set 4096 flag will be X, but real
## limit will be 4096 KB/s). Same can be done when floodfill mode is used,
## but keep in mind that low values may be negatively evaluated by Java
## router algorithms.
# bandwidth = L
## Max % of bandwidth limit for transit. 0-100. 100 by default
## Max % of bandwidth limit for transit. 0-100 (default: 100)
# share = 100
## Router will not accept transit tunnels, disabling transit traffic completely
## (default = false)
## (default: false)
# notransit = true
## Router will be floodfill
## Router will be floodfill (default: false)
## Note: that mode uses much more network connections and CPU!
# floodfill = true
[ntcp2]
## Enable NTCP2 transport (default = true)
## Enable NTCP2 transport (default: true)
# enabled = true
## Publish address in RouterInfo (default = true)
## Publish address in RouterInfo (default: true)
# published = true
## Port for incoming connections (default is global port option value)
# port = 4567
[ssu2]
## Enable SSU2 transport
## Enable SSU2 transport (default: true)
# enabled = true
## Publish address in RouterInfo
## Publish address in RouterInfo (default: true)
# published = true
## Port for incoming connections (default is global port option value or port + 1 if SSU is enabled)
## Port for incoming connections (default is global port option value)
# port = 4567
[http]
## Web Console settings
## Uncomment and set to 'false' to disable Web Console
## Enable the Web Console (default: true)
# enabled = true
## Address and port service will listen on
address = 127.0.0.1
port = 7070
## Path to web console, default "/"
## Address and port service will listen on (default: 127.0.0.1:7070)
# address = 127.0.0.1
# port = 7070
## Path to web console (default: /)
# webroot = /
## Uncomment following lines to enable Web Console authentication
## Enable Web Console authentication (default: false)
## You should not use Web Console via public networks without additional encryption.
## HTTP authentication is not encryption layer!
# auth = true
# user = i2pd
# pass = changeme
## Select webconsole language
## Currently supported english (default), afrikaans, armenian, chinese, czech, french,
## german, italian, russian, spanish, turkmen, ukrainian and uzbek languages
## german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian
## and uzbek languages
# lang = english
[httpproxy]
## Uncomment and set to 'false' to disable HTTP Proxy
## Enable the HTTP proxy (default: true)
# enabled = true
## Address and port service will listen on
address = 127.0.0.1
port = 4444
## Optional keys file for proxy local destination
## Address and port service will listen on (default: 127.0.0.1:4444)
# address = 127.0.0.1
# port = 4444
## Optional keys file for proxy local destination (default: http-proxy-keys.dat)
# keys = http-proxy-keys.dat
## Enable address helper for adding .i2p domains with "jump URLs" (default: true)
## You should disable this feature if your i2pd HTTP Proxy is public,
## because anyone could spoof the short domain via addresshelper and forward other users to phishing links
# addresshelper = true
## Address of a proxy server inside I2P, which is used to visit regular Internet
# outproxy = http://false.i2p
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
[socksproxy]
## Uncomment and set to 'false' to disable SOCKS Proxy
## Enable the SOCKS proxy (default: true)
# enabled = true
## Address and port service will listen on
address = 127.0.0.1
port = 4447
## Optional keys file for proxy local destination
## Address and port service will listen on (default: 127.0.0.1:4447)
# address = 127.0.0.1
# port = 4447
## Optional keys file for proxy local destination (default: socks-proxy-keys.dat)
# keys = socks-proxy-keys.dat
## Socks outproxy. Example below is set to use Tor for all connections except i2p
## Uncomment and set to 'true' to enable using of SOCKS outproxy
## Enable using of SOCKS outproxy (works only with SOCKS4, default: false)
# outproxy.enabled = false
## Address and port of outproxy
# outproxy = 127.0.0.1
@@ -161,33 +169,34 @@ port = 4447
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
## Comment or set to 'false' to disable SAM Bridge
enabled = true
## Address and port service will listen on
## Enable the SAM bridge (default: true)
# enabled = false
## Address and ports service will listen on (default: 127.0.0.1:7656, udp: 7655)
# address = 127.0.0.1
# port = 7656
# portudp = 7655
[bob]
## Uncomment and set to 'true' to enable BOB command channel
## Enable the BOB command channel (default: false)
# enabled = false
## Address and port service will listen on
## Address and port service will listen on (default: 127.0.0.1:2827)
# address = 127.0.0.1
# port = 2827
[i2cp]
## Uncomment and set to 'true' to enable I2CP protocol
## Enable the I2CP protocol (default: false)
# enabled = false
## Address and port service will listen on
## Address and port service will listen on (default: 127.0.0.1:7654)
# address = 127.0.0.1
# port = 7654
[i2pcontrol]
## Uncomment and set to 'true' to enable I2PControl protocol
## Enable the I2PControl protocol (default: false)
# enabled = false
## Address and port service will listen on
## Address and port service will listen on (default: 127.0.0.1:7650)
# address = 127.0.0.1
# port = 7650
## Authentication password. "itoopie" by default
## Authentication password (default: itoopie)
# password = itoopie
[precomputation]
@@ -198,11 +207,11 @@ enabled = true
[upnp]
## Enable or disable UPnP: automatic port forwarding (enabled by default in WINDOWS, ANDROID)
# enabled = false
## Name i2pd appears in UPnP forwardings list (default = I2Pd)
## Name i2pd appears in UPnP forwardings list (default: I2Pd)
# name = I2Pd
[meshnets]
## Enable connectivity over the Yggdrasil network
## Enable connectivity over the Yggdrasil network (default: false)
# yggdrasil = false
## You can bind address from your Yggdrasil subnet 300::/64
## The address must first be added to the network interface
@@ -210,13 +219,13 @@ enabled = true
[reseed]
## Options for bootstrapping into I2P network, aka reseeding
## Enable or disable reseed data verification.
## Enable reseed data verification (default: true)
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/
# yggurls = http://[324:71e:281a:9ed3::ace]:7070/
## Path to local reseed data file (.su3) for manual reseeding
# file = /path/to/i2pseeds.su3
## or HTTPS URL to reseed from
@@ -226,7 +235,7 @@ verify = true
## If you run i2pd behind a proxy server, set proxy server for reseeding here
## Should be http://address:port or socks://address:port
# proxy = http://127.0.0.1:8118
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
## Minimum number of known routers, below which i2pd triggers reseeding (default: 25)
# threshold = 25
[addressbook]
@@ -246,13 +255,13 @@ verify = true
# coresize = 0
[trust]
## Enable explicit trust options. false by default
## Enable explicit trust options. (default: false)
# enabled = 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 =
## Should we hide our router from other routers? false by default
## Should we hide our router from other routers? (default: false)
# hidden = true
[exploratory]
@@ -271,8 +280,6 @@ verify = true
[cpuext]
## Use CPU AES-NI instructions set when work with cryptography when available (default: true)
# aesni = true
## Use CPU AVX instructions set when work with cryptography when available (default: true)
# avx = true
## Force usage of CPU instructions set, even if they not found
## Force usage of CPU instructions set, even if they not found (default: false)
## DO NOT TOUCH that option if you really don't know what are you doing!
# force = false

View File

@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git
Version: 2.45.0
Version: 2.51.0
Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd
@@ -28,9 +28,11 @@ Requires: logrotate
Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description
C++ implementation of I2P.
%prep
%setup -q -n i2pd-openssl
@@ -38,72 +40,56 @@ C++ implementation of I2P.
%build
cd build
%if 0%{?rhel} == 7
%cmake3 \
%cmake3 \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF
%else
%cmake \
%cmake \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
%if 0%{?fedora} > 29
%if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \
.
%else
%else
-DBUILD_SHARED_LIBS:BOOL=OFF
%endif
%endif
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
pushd redhat-linux-build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} > 7
pushd build
%if 0%{?mageia} > 7
pushd build
%endif
%endif
make %{?_smp_mflags}
%if 0%{?rhel} == 9
popd
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%endif
%if 0%{?fedora} >= 33
popd
%endif
%if 0%{?mageia} > 7
popd
%endif
%install
pushd build
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
pushd redhat-linux-build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia}
pushd build
%if 0%{?mageia}
pushd build
%endif
%endif
chrpath -d i2pd
@@ -158,7 +144,37 @@ getent passwd i2pd >/dev/null || \
%changelog
* Mon Tue 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
* Sat Apr 06 2024 orignal <orignal@i2pmail.org> - 2.51.0
- update to 2.51.0
* Sat Jan 06 2024 orignal <orignal@i2pmail.org> - 2.50.2
- update to 2.50.2
* Sat Dec 23 2023 r4sas <r4sas@i2pmail.org> - 2.50.1
- update to 2.50.1
* Mon Dec 18 2023 orignal <orignal@i2pmail.org> - 2.50.0
- update to 2.50.0
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0

View File

@@ -1,5 +1,5 @@
Name: i2pd
Version: 2.45.0
Version: 2.51.0
Release: 1%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd-git
@@ -26,9 +26,11 @@ Requires: logrotate
Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description
C++ implementation of I2P.
%prep
%setup -q
@@ -36,71 +38,56 @@ C++ implementation of I2P.
%build
cd build
%if 0%{?rhel} == 7
%cmake3 \
%cmake3 \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF
%else
%cmake \
%cmake \
-DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \
-DWITH_HARDENING=ON \
%if 0%{?fedora} > 29
%if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \
.
%else
%else
-DBUILD_SHARED_LIBS:BOOL=OFF
%endif
%endif
%endif
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
pushd redhat-linux-build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} > 7
pushd build
%if 0%{?mageia} > 7
pushd build
%endif
%endif
make %{?_smp_mflags}
%if 0%{?rhel} == 9
popd
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%endif
%if 0%{?fedora} >= 33
popd
%endif
%if 0%{?mageia} > 7
popd
%endif
%install
pushd build
%if 0%{?rhel} == 9
pushd redhat-linux-build
%endif
%if 0%{?fedora} >= 35
pushd redhat-linux-build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia}
pushd build
%if 0%{?mageia}
pushd build
%endif
%endif
chrpath -d i2pd
@@ -155,6 +142,36 @@ getent passwd i2pd >/dev/null || \
%changelog
* Sat Apr 06 2024 orignal <orignal@i2pmail.org> - 2.51.0
- update to 2.51.0
* Sat Jan 06 2024 orignal <orignal@i2pmail.org> - 2.50.2
- update to 2.50.2
* Sat Dec 23 2023 r4sas <r4sas@i2pmail.org> - 2.50.1
- update to 2.50.1
* Mon Dec 18 2023 orignal <orignal@i2pmail.org> - 2.50.0
- update to 2.50.0
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0

View File

@@ -1,293 +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;
}
}
/*
* Copyright (c) 2021-2023, 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, a.button.selected, .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-2023, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -150,17 +150,20 @@ namespace util
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
bool avx; i2p::config::GetOption("cpuext.avx", avx);
bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
bool ssu; i2p::config::GetOption("ssu", ssu);
if (!ssu && i2p::config::IsDefault ("precomputation.elgamal"))
precomputation = false; // we don't elgamal table if no ssu, unless it's specified explicitly
i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
i2p::crypto::InitCrypto (precomputation, aesni, forceCpuExt);
i2p::transport::InitAddressFromIface (); // get address4/6 from interfaces
int netID; i2p::config::GetOption("netid", netID);
i2p::context.SetNetID (netID);
bool checkReserved; i2p::config::GetOption("reservedrange", checkReserved);
i2p::transport::transports.SetCheckReserved(checkReserved);
i2p::context.Init ();
i2p::transport::InitTransports ();
@@ -176,10 +179,10 @@ namespace util
bool transit; i2p::config::GetOption("notransit", transit);
i2p::context.SetAcceptsTunnels (!transit);
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
uint32_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels"))
transitTunnels *= 2; // double default number of transit tunnels for floodfill
SetMaxNumTransitTunnels (transitTunnels);
i2p::tunnel::tunnels.SetMaxNumTransitTunnels (transitTunnels);
/* this section also honors 'floodfill' flag, if set above */
std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
@@ -269,7 +272,7 @@ namespace util
if (hidden)
{
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
i2p::data::netdb.SetHidden(true);
i2p::context.SetHidden(true);
}
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
@@ -299,18 +302,16 @@ namespace util
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
LogPrint(eLogInfo, "Daemon: Starting Transports");
if(!ssu2) LogPrint(eLogInfo, "Daemon: SSU2 disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled");
i2p::transport::transports.SetCheckReserved(checkInReserved);
i2p::transport::transports.Start(ntcp2, ssu2);
if (i2p::transport::transports.IsBoundSSU2() || i2p::transport::transports.IsBoundNTCP2())
LogPrint(eLogInfo, "Daemon: Transports started");
else
{
LogPrint(eLogError, "Daemon: Failed to start Transports");
LogPrint(eLogCritical, "Daemon: Failed to start Transports");
/** shut down netdb right away */
i2p::transport::transports.Stop();
i2p::data::netdb.Stop();
@@ -329,15 +330,17 @@ namespace util
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ());
LogPrint (eLogCritical, "Daemon: Failed to start Webconsole: ", ex.what ());
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
}
}
LogPrint(eLogInfo, "Daemon: Starting Tunnels");
i2p::tunnel::tunnels.Start();
LogPrint(eLogInfo, "Daemon: Starting Router context");
i2p::context.Start();
LogPrint(eLogInfo, "Daemon: Starting Client");
i2p::client::context.Start ();
@@ -354,7 +357,7 @@ namespace util
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Daemon: Failed to start I2PControl: ", ex.what ());
LogPrint (eLogCritical, "Daemon: Failed to start I2PControl: ", ex.what ());
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
}
}
@@ -366,6 +369,8 @@ namespace util
LogPrint(eLogInfo, "Daemon: Shutting down");
LogPrint(eLogInfo, "Daemon: Stopping Client");
i2p::client::context.Stop();
LogPrint(eLogInfo, "Daemon: Stopping Router context");
i2p::context.Stop();
LogPrint(eLogInfo, "Daemon: Stopping Tunnels");
i2p::tunnel::tunnels.Stop();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2023, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -87,6 +87,7 @@ namespace http {
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css";
const char HTTP_COMMAND_EXPIRELEASE[] = "expirelease";
static std::string ConvertTime (uint64_t time)
{
@@ -103,18 +104,18 @@ namespace http {
int num;
if ((num = seconds / 86400) > 0) {
s << num << " " << tr("day", "days", num) << ", ";
s << ntr("%d day", "%d days", num, num) << ", ";
seconds -= num * 86400;
}
if ((num = seconds / 3600) > 0) {
s << num << " " << tr("hour", "hours", num) << ", ";
s << ntr("%d hour", "%d hours", num, num) << ", ";
seconds -= num * 3600;
}
if ((num = seconds / 60) > 0) {
s << num << " " << tr("minute", "minutes", num) << ", ";
s << ntr("%d minute", "%d minutes", num, num) << ", ";
seconds -= num * 60;
}
s << seconds << " " << tr("second", "seconds", seconds);
s << ntr("%d second", "%d seconds", seconds, seconds);
}
static void ShowTraffic (std::stringstream& s, uint64_t bytes)
@@ -122,40 +123,37 @@ namespace http {
s << std::fixed << std::setprecision(2);
auto numKBytes = (double) bytes / 1024;
if (numKBytes < 1024)
s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB");
s << tr(/* tr: Kibibyte */ "%.2f KiB", numKBytes);
else if (numKBytes < 1024 * 1024)
s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB");
s << tr(/* tr: Mebibyte */ "%.2f MiB", numKBytes / 1024);
else
s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB");
s << tr(/* tr: Gibibyte */ "%.2f GiB", numKBytes / 1024 / 1024);
}
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
{
std::string state, stateText;
switch (eState) {
switch (eState)
{
case i2p::tunnel::eTunnelStateBuildReplyReceived :
case i2p::tunnel::eTunnelStatePending : state = "building"; break;
case i2p::tunnel::eTunnelStateBuildFailed :
case i2p::tunnel::eTunnelStateTestFailed :
case i2p::tunnel::eTunnelStateBuildFailed : state = "failed"; stateText = "declined"; break;
case i2p::tunnel::eTunnelStateTestFailed : state = "failed"; stateText = "test failed"; break;
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
case i2p::tunnel::eTunnelStateEstablished : state = "established"; break;
default: state = "unknown"; break;
}
if (state == "building") stateText = tr("building");
else if (state == "failed") stateText = tr("failed");
else if (state == "expiring") stateText = tr("expiring");
else if (state == "established") stateText = tr("established");
else stateText = tr("unknown");
if (stateText.empty ()) stateText = tr(state);
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
s << " " << (int) (bytes / 1024) << "&nbsp;" << tr(/* tr: Kibibit */ "KiB") << "\r\n";
ShowTraffic(s, bytes);
s << "\r\n";
}
static void SetLogLevel (const std::string& level)
{
if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug")
if (level == "none" || level == "critical" || level == "error" || level == "warn" || level == "info" || level == "debug")
i2p::log::Logger().SetLogLevel(level);
else {
LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted");
@@ -198,7 +196,7 @@ namespace http {
if (i2p::context.AcceptsTunnels () || i2p::tunnel::tunnels.CountTransitTunnels())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit Tunnels") << "</a><br>\r\n";
s <<
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr("Transports") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
if (i2p::client::context.GetSAMBridge ())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
@@ -220,18 +218,19 @@ namespace http {
s << "<b>" << tr("ERROR") << ":</b>&nbsp;" << string << "<br>\r\n";
}
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, RouterError error)
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing, RouterError error)
{
switch (status)
{
case eRouterStatusOK: s << tr("OK"); break;
case eRouterStatusTesting: s << tr("Testing"); break;
case eRouterStatusFirewalled: s << tr("Firewalled"); break;
case eRouterStatusUnknown: s << tr("Unknown"); break;
case eRouterStatusProxy: s << tr("Proxy"); break;
case eRouterStatusMesh: s << tr("Mesh"); break;
default: s << tr("Unknown");
}
if (testing)
s << " (" << tr("Testing") << ")";
if (error != eRouterErrorNone)
{
switch (error)
@@ -245,6 +244,9 @@ namespace http {
case eRouterErrorSymmetricNAT:
s << " - " << tr("Symmetric NAT");
break;
case eRouterErrorFullConeNAT:
s << " - " << tr("Full cone NAT");
break;
case eRouterErrorNoDescriptors:
s << " - " << tr("No Descriptors");
break;
@@ -259,12 +261,12 @@ namespace http {
ShowUptime(s, i2p::context.GetUptime ());
s << "<br>\r\n";
s << "<b>" << tr("Network status") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetError ());
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting(), i2p::context.GetError ());
s << "<br>\r\n";
if (i2p::context.SupportsV6 ())
{
s << "<b>" << tr("Network status v6") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetErrorV6 ());
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6(), i2p::context.GetErrorV6 ());
s << "<br>\r\n";
}
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
@@ -285,15 +287,20 @@ namespace http {
if (family.length () > 0)
s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n";
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
bool isTotalTCSR;
i2p::config::GetOption("http.showTotalTCSR", isTotalTCSR);
if (isTotalTCSR) {
s << "<b>" << tr("Total tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTotalTunnelCreationSuccessRate() << "%<br/>\r\n";
}
s << "<b>" << tr("Received") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
s << " (" << (double) i2p::transport::transports.GetInBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Sent") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
s << " (" << (double) i2p::transport::transports.GetOutBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Transit") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
s << "<div class='slide'>";
if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
@@ -325,17 +332,18 @@ namespace http {
default:
s << tr("Unknown");
}
if (address->IsV6 ())
bool v6 = address->IsV6 ();
if (v6)
{
if (address->IsV4 ()) s << "v4";
s << "v6";
}
s << "</td>\r\n";
if (address->published)
s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n";
s << "<td>" << (v6 ? "[" : "") << address->host.to_string() << (v6 ? "]:" : ":") << address->port << "</td>\r\n";
else
{
s << "<td>" << tr("supported");
s << "<td>" << tr(/* tr: Shown when router doesn't publish itself and have "Firewalled" state */ "supported");
if (address->port)
s << " :" << address->port;
s << "</td>\r\n";
@@ -411,8 +419,12 @@ namespace http {
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
{
s << "<b>Base32:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"1\">";
s << dest->GetIdentHash ().ToBase32 () << "</textarea><br>\r\n<br>\r\n";
s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"8\">";
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
if (dest->IsEncryptedLeaseSet ())
{
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
@@ -424,12 +436,11 @@ namespace http {
if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ())
{
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
auto base32 = dest->GetIdentHash ().ToBase32 ();
s << "<div class='slide'><label for='slide-regaddr'><b>" << tr("Address registration line") << "</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
"<form method=\"get\" action=\"" << webroot << "\">\r\n"
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
" <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
" <input type=\"hidden\" name=\"b32\" value=\"" << dest->GetIdentHash ().ToBase32 () << "\">\r\n"
" <b>" << tr("Domain") << ":</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
" <button type=\"submit\">" << tr("Generate") << "</button>\r\n"
"</form>\r\n<small>" << tr("<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
@@ -438,9 +449,23 @@ namespace http {
if (dest->GetNumRemoteLeaseSets())
{
s << "<div class='slide'><label for='slide-lease'><b>" << tr("LeaseSets") << ":</b> <i>" << dest->GetNumRemoteLeaseSets ()
<< "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n<table><thead><th>"<< tr("Address") << "</th><th>" << tr("Type") << "</th><th>" << tr("EncType") << "</th></thead><tbody class=\"tableitem\">";
<< "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n"
<< "<table><thead>"
<< "<th>" << tr("Address") << "</th>"
<< "<th style=\"width:5px;\">&nbsp;</th>" // LeaseSet expiration button column
<< "<th>" << tr("Type") << "</th>"
<< "<th>" << tr("EncType") << "</th>"
<< "</thead><tbody class=\"tableitem\">";
for(auto& it: dest->GetLeaseSets ())
s << "<tr><td>" << it.first.ToBase32 () << "</td><td>" << (int)it.second->GetStoreType () << "</td><td>" << (int)it.second->GetEncryptionType () <<"</td></tr>\r\n";
{
s << "<tr>"
<< "<td>" << it.first.ToBase32 () << "</td>"
<< "<td><a class=\"button\" href=\"/?cmd=" << HTTP_COMMAND_EXPIRELEASE<< "&b32=" << dest->GetIdentHash ().ToBase32 ()
<< "&lease=" << it.first.ToBase32 () << "&token=" << token << "\" title=\"" << tr("Expire LeaseSet") << "\"> &#10008; </a></td>"
<< "<td>" << (int)it.second->GetStoreType () << "</td>"
<< "<td>" << (int)it.second->GetEncryptionType () <<"</td>"
<< "</tr>\r\n";
}
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
} else
s << "<b>" << tr("LeaseSets") << ":</b> <i>0</i><br>\r\n<br>\r\n";
@@ -463,7 +488,7 @@ namespace http {
}
s << "&#8658; " << it->GetTunnelID () << ":me";
if (it->LatencyIsKnown())
s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )";
s << " ( " << tr(/* tr: Milliseconds */ "%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
s << "</div>\r\n";
}
@@ -483,22 +508,26 @@ namespace http {
);
}
if (it->LatencyIsKnown())
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
s << "</div>\r\n";
}
}
s << "<br>\r\n";
s << "<b>" << tr("Tags") << "</b><br>\r\n" << tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
s << "<b>" << tr("Tags") << "</b><br>\r\n"
<< tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
if (!dest->GetSessions ().empty ()) {
std::stringstream tmp_s; uint32_t out_tags = 0;
for (const auto& it: dest->GetSessions ()) {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
out_tags += it.second->GetNumOutgoingTags ();
}
s << "<div class='slide'><label for='slide-tags'>" << tr("Outgoing") << ": <i>" << out_tags << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-tags\" />\r\n"
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Amount") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
s << "<div class='slide'><label for='slide-tags'>" << tr("Outgoing") << ": <i>" << out_tags << "</i></label>\r\n"
<< "<input type=\"checkbox\" id=\"slide-tags\" />\r\n"
<< "<div class=\"slidecontent\">\r\n"
<< "<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Amount") << "</th></thead>\r\n"
<< "<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
} else
s << tr("Outgoing") << ": <i>0</i><br>\r\n";
s << "<br>\r\n";
@@ -513,8 +542,11 @@ namespace http {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
ecies_sessions++;
}
s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("Tags sessions") << ": <i>" << ecies_sessions << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-ecies-sessions\" />\r\n"
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Status") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("Tags sessions") << ": <i>" << ecies_sessions << "</i></label>\r\n"
<< "<input type=\"checkbox\" id=\"slide-ecies-sessions\" />\r\n"
<< "<div class=\"slidecontent\">\r\n<table>\r\n"
<< "<thead><th>" << tr("Destination") << "</th><th>" << tr("Status") << "</th></thead>\r\n"
<< "<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
} else
s << tr("Tags sessions") << ": <i>0</i><br>\r\n";
s << "<br>\r\n";
@@ -537,7 +569,7 @@ namespace http {
<< tr("Streams")
<< "</caption>\r\n<thead>\r\n<tr>"
<< "<th style=\"width:25px;\">StreamID</th>"
<< "<th style=\"width:5px;\" \\>" // Stream closing button column
<< "<th style=\"width:5px;\">&nbsp;</th>" // Stream closing button column
<< "<th class=\"streamdest\">Destination</th>"
<< "<th>Sent</th>"
<< "<th>Received</th>"
@@ -574,6 +606,8 @@ namespace http {
}
s << "</tbody>\r\n</table>";
}
else
ShowError(s, tr("Such destination is not found"));
}
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
@@ -608,7 +642,10 @@ namespace http {
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET)
ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
else
ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
{
ls.reset (new i2p::data::LeaseSet2 (storeType));
ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false);
}
if (!ls) return;
s << "<div class=\"leaseset listitem";
if (ls->IsExpired())
@@ -639,7 +676,7 @@ namespace http {
}
else if (!i2p::context.IsFloodfill ())
{
s << "<b>" << tr("LeaseSets") << ":</b> " << tr("not floodfill") << ".<br>\r\n";
s << "<b>" << tr("LeaseSets") << ":</b> " << tr(/* Message on LeaseSets page */ "floodfill mode is disabled") << ".<br>\r\n";
}
else
{
@@ -668,7 +705,7 @@ namespace http {
}
s << "&#8658; " << it->GetTunnelID () << ":me";
if (it->LatencyIsKnown())
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
s << "</div>\r\n";
}
@@ -688,7 +725,7 @@ namespace http {
);
}
if (it->LatencyIsKnown())
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
s << "</div>\r\n";
}
@@ -726,19 +763,21 @@ namespace http {
s << "<br>\r\n<small>" << tr("<b>Note:</b> any action done here are not persistent and not changes your config files.") << "</small>\r\n<br>\r\n";
auto loglevel = i2p::log::Logger().GetLogLevel();
s << "<b>" << tr("Logging level") << "</b><br>\r\n";
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n";
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n";
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\"> info </a> \r\n";
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
s << " <a class=\"button" << (loglevel == eLogNone ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogCritical ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=critical&token=" << token << "\"> critical </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogError ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogWarning ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogInfo ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\"> info </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogDebug ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
uint16_t maxTunnels = GetMaxNumTransitTunnels ();
uint32_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels ();
s << "<b>" << tr("Transit tunnels limit") << "</b><br>\r\n";
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_LIMITTRANSIT << "\">\r\n";
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
s << " <input type=\"number\" min=\"0\" max=\"" << TRANSIT_TUNNELS_LIMIT <<"\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
s << "</form>\r\n<br>\r\n";
@@ -768,60 +807,71 @@ namespace http {
{
if (i2p::tunnel::tunnels.CountTransitTunnels())
{
s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n";
s << "<table><thead><th>&#8658;</th><th>ID</th><th>&#8658;</th><th>" << tr("Amount") << "</th></thead><tbody class=\"tableitem\">";
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
{
s << "<div class=\"listitem\">\r\n";
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
s << it->GetTunnelID () << " &#8658; ";
s << "<tr><td></td><td>" << it->GetTunnelID () << "</td><td>&#8658;</td><td>";
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
s << " &#8658; " << it->GetTunnelID ();
s << "<tr><td>&#8658;</td><td>" << it->GetTunnelID () << "</td><td></td><td>";
else
s << " &#8658; " << it->GetTunnelID () << " &#8658; ";
s << " " << it->GetNumTransmittedBytes () << "</div>\r\n";
s << "<tr><td>&#8658;</td><td>" << it->GetTunnelID () << "</td><td>&#8658;</td><td>";
ShowTraffic(s, it->GetNumTransmittedBytes ());
s << "</td></tr>\r\n";
}
s << "</div>\r\n";
s << "</tbody></table>\r\n";
}
else
{
s << "<b>" << tr("Transit Tunnels") << ":</b> " << tr("no transit tunnels currently built") << ".<br>\r\n";
s << "<b>" << tr("Transit Tunnels") << ":</b> " << tr(/* Message on transit tunnels page */ "no transit tunnels currently built") << ".<br>\r\n";
}
}
template<typename Sessions>
static void ShowTransportSessions (std::stringstream& s, const Sessions& sessions, const std::string name)
{
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
for (const auto& it: sessions )
auto comp = [](typename Sessions::mapped_type a, typename Sessions::mapped_type b)
{ return a->GetRemoteEndpoint() < b->GetRemoteEndpoint(); };
std::set<typename Sessions::mapped_type, decltype(comp)> sortedSessions(comp);
for (const auto& it : sessions)
{
auto endpoint = it.second->GetRemoteEndpoint ();
if (it.second && it.second->IsEstablished () && endpoint.address ().is_v4 ())
auto ret = sortedSessions.insert(it.second);
if (!ret.second)
LogPrint(eLogError, "HTTPServer: Duplicate remote endpoint detected: ", (*ret.first)->GetRemoteEndpoint());
}
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
for (const auto& it: sortedSessions)
{
auto endpoint = it->GetRemoteEndpoint ();
if (it && it->IsEstablished () && endpoint.address ().is_v4 ())
{
tmp_s << "<div class=\"listitem\">\r\n";
if (it.second->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
if (it->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": "
<< endpoint.address ().to_string () << ":" << endpoint.port ();
if (!it.second->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
if (it.second->GetRelayTag ())
tmp_s << " [itag:" << it.second->GetRelayTag () << "]";
if (it.second->GetSendQueueSize () > 0)
tmp_s << " [queue:" << it.second->GetSendQueueSize () << "]";
if (!it->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]";
if (it->GetRelayTag ())
tmp_s << " [itag:" << it->GetRelayTag () << "]";
if (it->GetSendQueueSize () > 0)
tmp_s << " [queue:" << it->GetSendQueueSize () << "]";
if (it->IsSlow ()) tmp_s << " [slow]";
tmp_s << "</div>\r\n" << std::endl;
cnt++;
}
if (it.second && it.second->IsEstablished () && endpoint.address ().is_v6 ())
if (it && it->IsEstablished () && endpoint.address ().is_v6 ())
{
tmp_s6 << "<div class=\"listitem\">\r\n";
if (it.second->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
if (it->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": "
<< "[" << endpoint.address ().to_string () << "]:" << endpoint.port ();
if (!it.second->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
if (it.second->GetRelayTag ())
tmp_s6 << " [itag:" << it.second->GetRelayTag () << "]";
if (it.second->GetSendQueueSize () > 0)
tmp_s6 << " [queue:" << it.second->GetSendQueueSize () << "]";
if (!it->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]";
if (it->GetRelayTag ())
tmp_s6 << " [itag:" << it->GetRelayTag () << "]";
if (it->GetSendQueueSize () > 0)
tmp_s6 << " [queue:" << it->GetSendQueueSize () << "]";
tmp_s6 << "</div>\r\n" << std::endl;
cnt6++;
}
@@ -881,7 +931,7 @@ namespace http {
s << "</div>\r\n";
}
else
s << "<b>" << tr("SAM sessions") << ":</b> " << tr("no sessions currently running") << ".<br>\r\n";
s << "<b>" << tr("SAM sessions") << ":</b> " << tr(/* Message on SAM sessions page */ "no sessions currently running") << ".<br>\r\n";
}
void ShowSAMSession (std::stringstream& s, const std::string& id)
@@ -925,34 +975,42 @@ namespace http {
void ShowI2PTunnels (std::stringstream& s)
{
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto& it: i2p::client::context.GetClientTunnels ())
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << it.second->GetName () << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
auto& clientTunnels = i2p::client::context.GetClientTunnels ();
auto httpProxy = i2p::client::context.GetHttpProxy ();
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "HTTP " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (socksProxy)
if (!clientTunnels.empty () || httpProxy || socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "SOCKS " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
if (!clientTunnels.empty ())
{
for (auto& it: clientTunnels)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << it.second->GetName () << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
}
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "HTTP " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "SOCKS " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
s << "</div>\r\n";
}
s << "</div>\r\n";
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
if (!serverTunnels.empty ()) {
@@ -990,7 +1048,7 @@ namespace http {
for (auto& it: serverForwards)
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << it.second->GetName () << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
@@ -1200,7 +1258,7 @@ namespace http {
url.parse_query(params);
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
std::string redirect = "5; url=" + webroot + "?page=commands";
std::string redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=commands";
std::string token = params["token"];
if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ())
@@ -1274,20 +1332,50 @@ namespace http {
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("StreamID can't be null") << "<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>";
redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32;
res.add_header("Refresh", redirect.c_str());
return;
}
else if (cmd == HTTP_COMMAND_EXPIRELEASE)
{
std::string b32 = params["b32"];
std::string lease = params["lease"];
i2p::data::IdentHash ident, leaseident;
ident.FromBase32 (b32);
leaseident.FromBase32 (lease);
auto dest = i2p::client::context.FindLocalDestination (ident);
if (dest)
{
auto leaseset = dest->FindLeaseSet (leaseident);
if (leaseset)
{
leaseset->ExpireLease ();
s << "<b>" << tr("SUCCESS") << "</b>:&nbsp;" << tr("LeaseSet expiration time updated") << "<br>\r\n<br>\r\n";
}
else
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("LeaseSet is not found or already expired") << "<br>\r\n<br>\r\n";
}
else
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Destination not found") << "<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>";
redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32;
res.add_header("Refresh", redirect.c_str());
return;
}
else if (cmd == HTTP_COMMAND_LIMITTRANSIT)
{
uint32_t limit = std::stoul(params["limit"], nullptr);
if (limit > 0 && limit <= 65535)
SetMaxNumTransitTunnels (limit);
if (limit > 0 && limit <= TRANSIT_TUNNELS_LIMIT)
i2p::tunnel::tunnels.SetMaxNumTransitTunnels (limit);
else {
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Transit tunnels count must not exceed 65535") << "\r\n<br>\r\n<br>\r\n";
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\r\n<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n";
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>";
res.add_header("Refresh", redirect.c_str());
return;
}
@@ -1362,7 +1450,7 @@ namespace http {
s << "<b>" << tr("SUCCESS") << "</b>:&nbsp;" << tr("Command accepted") << "<br><br>\r\n";
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>";
res.add_header("Refresh", redirect.c_str());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -24,6 +24,8 @@ namespace http
{
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds
const int COMMAND_REDIRECT_TIMEOUT = 5; // in seconds
const int TRANSIT_TUNNELS_LIMIT = 1000000;
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -38,7 +38,7 @@ namespace http
"@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:hover, a.button.selected, .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"

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -338,10 +338,11 @@ namespace client
{
for (auto it = params.begin (); it != params.end (); it++)
{
if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
auto it1 = m_RouterManagerHandlers.find (it->first);
if (it1 != m_RouterManagerHandlers.end ()) {
if (it1 != m_RouterManagerHandlers.end ())
{
if (it != params.begin ()) results << ",";
(this->*(it1->second))(results);
} else
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);

View File

@@ -163,7 +163,7 @@ namespace transport
if (!a) return;
for (const auto& address : *a)
{
if (!address->host.is_v6 () && address->port)
if (address && !address->host.is_v6 () && address->port)
TryPortMapping (address);
}
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
@@ -215,7 +215,7 @@ namespace transport
if (!a) return;
for (const auto& address : *a)
{
if (!address->host.is_v6 () && address->port)
if (address && !address->host.is_v6 () && address->port)
CloseMapping (address);
}
}

View File

@@ -173,7 +173,7 @@ namespace i2p
ftruncate(pidFH, 0);
if (write(pidFH, pid, strlen(pid)) < 0)
{
LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
LogPrint(eLogCritical, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl;
return false;
}

66
debian/changelog vendored
View File

@@ -1,3 +1,69 @@
i2pd (2.51.0-1) unstable; urgency=medium
* updated to version 2.51.0/0.9.62
-- orignal <orignal@i2pmail.org> Sat, 06 Apr 2024 16:00:00 +0000
i2pd (2.50.2-1) unstable; urgency=medium
* updated to version 2.50.2/0.9.61
-- orignal <orignal@i2pmail.org> Sat, 06 Jan 2024 16:00:00 +0000
i2pd (2.50.1-1) unstable; urgency=medium
* updated to version 2.50.1/0.9.61
-- r4sas <r4sas@i2pmail.org> Sat, 23 Dec 2023 18:30:00 +0000
i2pd (2.50.0-1) unstable; urgency=medium
* updated to version 2.50.0/0.9.61
-- orignal <orignal@i2pmail.org> Mon, 18 Dec 2023 16:00:00 +0000
i2pd (2.49.0-1) unstable; urgency=medium
* updated to version 2.49.0/0.9.60
-- orignal <orignal@i2pmail.org> Mon, 18 Sep 2023 16:00:00 +0000
i2pd (2.48.0-1) unstable; urgency=high
* updated to version 2.48.0/0.9.59
-- orignal <orignal@i2pmail.org> Mon, 12 Jun 2023 16:00:00 +0000
i2pd (2.47.0-1) unstable; urgency=high
* updated to version 2.47.0/0.9.58
-- orignal <orignal@i2pmail.org> Sat, 11 Mar 2023 16:00:00 +0000
i2pd (2.46.1-2) unstable; urgency=critical
* re-pushed release due to new critical bug
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 23:40:00 +0000
i2pd (2.46.1-1) unstable; urgency=high
* updated to version 2.46.1/0.9.57
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 02:45:00 +0000
i2pd (2.46.0-1) unstable; urgency=high
* updated to version 2.46.0/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 15 Feb 2023 19:00:00 +0000
i2pd (2.45.1-1) unstable; urgency=medium
* updated to version 2.45.1/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
i2pd (2.45.0-1) unstable; urgency=high
* updated to version 2.45.0/0.9.57

2
debian/conffiles vendored
View File

@@ -1,2 +0,0 @@
/etc/i2pd/i2pd.conf
/etc/i2pd/tunnels.conf

2
debian/i2pd.1 vendored
View File

@@ -64,7 +64,7 @@ The network interface to bind to for IPv4 connections
The network interface to bind to for IPv6 connections
.TP
\fB\-\-ipv4=\fR
Enable communication through ipv6 (\fIenabled\fR by default)
Enable communication through ipv4 (\fIenabled\fR by default)
.TP
\fB\-\-ipv6\fR
Enable communication through ipv6 (\fIdisabled\fR by default)

2
debian/rules vendored
View File

@@ -8,6 +8,6 @@ export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND =
%:
dh $@ --parallel
dh $@
override_dh_auto_install:

View File

@@ -64,10 +64,10 @@ namespace afrikaans // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"dag", "dae"}},
{"hours", {"uur", "ure"}},
{"minutes", {"minuut", "minute"}},
{"seconds", {"seconde", "sekondes"}},
{"%d days", {"%d dag", "%d dae"}},
{"%d hours", {"%d uur", "%d ure"}},
{"%d minutes", {"%d minuut", "%d minute"}},
{"%d seconds", {"%d seconde", "%d sekondes"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@ namespace armenian // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "ԿիԲ"},
{"MiB", "ՄիԲ"},
{"GiB", "ԳիԲ"},
{"%.2f KiB", "%.2f ԿիԲ"},
{"%.2f MiB", "%.2f ՄիԲ"},
{"%.2f GiB", "%.2f ԳիԲ"},
{"building", "կառուցվում է"},
{"failed", "Անհաջող"},
{"expiring", "Լրանում է"},
{"established", "կարգավոյված է"},
{"unknown", "անհայտ"},
{"exploratory", "հետազոտոկան"},
{"Purple I2P Webconsole", "Վեբ-կոնսոլ Purple I2P"},
{"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"},
{"Main page", "Գլխավոր էջ"},
{"Router commands", "Երթուղիչի հրահանգներ"},
@@ -57,10 +58,10 @@ namespace armenian // language namespace
{"Unknown", "Անհայտ"},
{"Proxy", "Պրոկսի"},
{"Mesh", "MESH-ցանց"},
{"Error", "Սխալ"},
{"Clock skew", "Ոչ ճշգրիտ ժամանակ"},
{"Offline", "Օֆլայն"},
{"Symmetric NAT", "Սիմետրիկ NAT"},
{"Full cone NAT", "Full cone NAT"},
{"Uptime", "Առկայություն"},
{"Network status", "Ցանցի կարգավիճակ"},
{"Network status v6", "Ցանցի կարգավիճակ v6"},
@@ -68,7 +69,7 @@ namespace armenian // language namespace
{"Family", "Խմբատեսակ"},
{"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"},
{"Received", "Ստացվել է"},
{"KiB/s", "ԿիԲ/վ"},
{"%.2f KiB/s", "%.2f ԿիԲ/վ"},
{"Sent", "Ուղարկվել է"},
{"Transit", "Տարանցում"},
{"Data path", "Տվյալների ուղին"},
@@ -89,12 +90,12 @@ namespace armenian // language namespace
{"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 գործիքակազմը"},
{"<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", "մլվ"},
{"%dms", "%dմլվ"},
{"Outbound tunnels", "Ելքային թունելներ"},
{"Tags", "Թեգեր"},
{"Incoming", "Մուտքային"},
@@ -112,11 +113,10 @@ namespace armenian // language namespace
{"Invalid", "Անվավեր"},
{"Store type", "Պահեստավորման տեսակը"},
{"Expires", "Սպառվում է"},
{"Non Expired Leases", "Չսպառված Lease-եր"},
{"Non Expired Leases", "Չսպառված Lease-եր"},
{"Gateway", "Դարպաս"},
{"TunnelID", "Թունելի ID"},
{"EndDate", "Ավարտ"},
{"not floodfill", "ոչ floodfill-ներ"},
{"Queue size", "Հերթի չափսը"},
{"Run peer test", "Գործարկել փորձարկումը"},
{"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"},
@@ -146,10 +146,7 @@ namespace armenian // language namespace
{"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", "Ուղարկվել"},
@@ -165,43 +162,35 @@ namespace armenian // language namespace
{"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 հարցում"},
{"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 պրոկսիի հետ"},
{"Bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Հոսթ %s Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
{"Unknown outproxy URL", "Արտաքին պրոքսիի անհայտ URL"},
{"Cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
{"Hostname is 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 պրոկսի սերվերին"},
{"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.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"},
{"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", {"վարկյան", "վարկյան"}},
{"%d days", {"%d օր", "%d օր"}},
{"%d hours", {"%d ժամ", "%d ժամ"}},
{"%d minutes", {"%d րոպե", "%d րոպե"}},
{"%d seconds", {"%d վարկյան", "%d վարկյան"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -13,7 +13,6 @@
#include "I18N.h"
// Simplified Chinese localization file
// This is an example translation file without strings in it.
namespace i2p
{
@@ -32,9 +31,9 @@ namespace chinese // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "正在构建"},
{"failed", "连接失败"},
{"expiring", "即将过期"},
@@ -46,7 +45,7 @@ namespace chinese // language namespace
{"Main page", "主页"},
{"Router commands", "路由命令"},
{"Local Destinations", "本地目标"},
{"LeaseSets", ""},
{"LeaseSets", ""},
{"Tunnels", "隧道"},
{"Transit Tunnels", "中转隧道"},
{"Transports", "传输"},
@@ -58,11 +57,12 @@ namespace chinese // language namespace
{"Firewalled", "受到防火墙限制"},
{"Unknown", "未知"},
{"Proxy", "代理"},
{"Mesh", "Mesh组网"},
{"Error", "错误"},
{"Mesh", "组网"},
{"Clock skew", "时钟偏移"},
{"Offline", "离线"},
{"Symmetric NAT", "对称 NAT"},
{"Full cone NAT", "全锥型NAT"},
{"No Descriptors", "无描述符"},
{"Uptime", "运行时间"},
{"Network status", "IPv4 网络状态"},
{"Network status v6", "IPv6 网络状态"},
@@ -70,7 +70,7 @@ namespace chinese // language namespace
{"Family", "家族"},
{"Tunnel creation success rate", "隧道创建成功率"},
{"Received", "已接收"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "已发送"},
{"Transit", "中转"},
{"Data path", "数据文件路径"},
@@ -91,12 +91,12 @@ namespace chinese // language namespace
{"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。"},
{"<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", "毫秒"},
{"%dms", "%dms"},
{"Outbound tunnels", "出站隧道"},
{"Tags", "标签"},
{"Incoming", "传入"},
@@ -109,6 +109,7 @@ namespace chinese // language namespace
{"Local Destination", "本地目标"},
{"Streams", ""},
{"Close stream", "断开流"},
{"Such destination is not found", "找不到此目标"},
{"I2CP session not found", "未找到 I2CP 会话"},
{"I2CP is not enabled", "I2CP 未启用"},
{"Invalid", "无效"},
@@ -118,9 +119,10 @@ namespace chinese // language namespace
{"Gateway", "网关"},
{"TunnelID", "隧道 ID"},
{"EndDate", "结束日期"},
{"not floodfill", "洪泛"},
{"floodfill mode is disabled", "洪泛已禁用"},
{"Queue size", "队列大小"},
{"Run peer test", "运行节点测试"},
{"Reload tunnels configuration", "重新载入隧道配置"},
{"Decline transit tunnels", "拒绝中转隧道"},
{"Accept transit tunnels", "允许中转隧道"},
{"Cancel graceful shutdown", "取消平滑关闭"},
@@ -128,7 +130,7 @@ namespace chinese // language namespace
{"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", "日志记录级别"},
{"Logging level", "日志级别"},
{"Transit tunnels limit", "中转隧道限制"},
{"Change", "修改"},
{"Change language", "更改语言"},
@@ -148,8 +150,8 @@ namespace chinese // language namespace
{"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"},
{"You will be redirected in %d seconds", "您将在%d秒内被重定向"},
{"Transit tunnels count must not exceed %d", "中转隧道数量限制为 %d"},
{"Back to commands list", "返回命令列表"},
{"Register at reg.i2p", "在 reg.i2p 注册域名"},
{"Description", "描述"},
@@ -157,42 +159,42 @@ namespace chinese // language namespace
{"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", "您可以尝试在下方的跳转服务中找到主机"},
{"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到主机"},
{"Invalid request", "无效请求"},
{"Proxy unable to parse your request", "代理无法解析您的请求"},
{"addresshelper is not supported", "不支持地址助手"},
{"Host", "主机"},
{"added to router's addressbook from helper", "将此地址从地址助手添加到路由地址簿"},
{"Click here to proceed:", "点击此处继续:"},
{"Continue", "继续"},
{"Addresshelper found", "已找到地址助手"},
{"already in router's addressbook", "已在路由地址簿中"},
{"Click here to update record:", "点击此处更新地址簿记录"},
{"invalid request uri", "无效的 URL 请求"},
{"Addresshelper is not supported", "不支持地址助手"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。<b>请注意:此地址的来源可能是有害的!</b>点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
{"Addresshelper forced update rejected", "地址助手强制更新被拒绝"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "若要在路由器地址簿中添加主机 <b>%s</b> 请点击这里: <a href=\"%s%s%s\">继续</a>"},
{"Addresshelper request", "请求地址助手"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "主机 %s 已通过地址助手添加到路由地址簿中。点击此处继续:<a href=\"%s\">继续</a>"},
{"Addresshelper adding", "正在添加地址助手"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
{"Addresshelper update", "更新地址助手"},
{"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", "未知的出口代理地址"},
{"cannot resolve upstream proxy", "无法解析上游代理"},
{"hostname too long", "主机名过长"},
{"cannot connect to upstream socks proxy", "无法连接到上游 socks 代理"},
{"Cannot negotiate with socks proxy", "无法与 socks 代理协商"},
{"Bad outproxy settings", "错误的出口代理设置"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "主机 %s 不在 I2P 网络内,但出口代理未启用"},
{"Unknown outproxy URL", "未知的出口代理地址"},
{"Cannot resolve upstream proxy", "无法解析上游代理"},
{"Hostname is too long", "主机名过长"},
{"Cannot connect to upstream SOCKS proxy", "无法连接到上游 SOCKS 代理"},
{"Cannot negotiate with SOCKS proxy", "无法与 SOCKS 代理协商"},
{"CONNECT error", "连接错误"},
{"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 代理"},
{"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.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"},
{"", ""},
@@ -200,10 +202,10 @@ namespace chinese // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {""}},
{"hours", {""}},
{"minutes", {""}},
{"seconds", {""}},
{"%d days", {"%d 天"}},
{"%d hours", {"%d 小"}},
{"%d minutes", {"%d 分钟"}},
{"%d seconds", {"%d "}},
{"", {""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@ namespace czech // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "vytváří se"},
{"failed", "selhalo"},
{"expiring", "končící"},
@@ -58,7 +58,6 @@ namespace czech // language namespace
{"Unknown", "Neznámý"},
{"Proxy", "Proxy"},
{"Mesh", "Síť"},
{"Error", "Chyba"},
{"Clock skew", "Časová nesrovnalost"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symetrický NAT"},
@@ -69,7 +68,7 @@ namespace czech // language namespace
{"Family", "Rodina"},
{"Tunnel creation success rate", "Úspěšnost vytváření tunelů"},
{"Received", "Přijato"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Odesláno"},
{"Transit", "Tranzit"},
{"Data path", "Cesta k data souborům"},
@@ -95,7 +94,7 @@ namespace czech // language namespace
{"Type", "Typ"},
{"EncType", "EncType"},
{"Inbound tunnels", "Příchozí tunely"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Odchozí tunely"},
{"Tags", "Štítky"},
{"Incoming", "Příchozí"},
@@ -117,7 +116,6 @@ namespace czech // language namespace
{"Gateway", "Brána"},
{"TunnelID", "ID tunelu"},
{"EndDate", "Datum ukončení"},
{"not floodfill", "není floodfill"},
{"Queue size", "Velikost fronty"},
{"Run peer test", "Spustit peer test"},
{"Decline transit tunnels", "Odmítnout tranzitní tunely"},
@@ -147,8 +145,6 @@ namespace czech // language namespace
{"Destination not found", "Destinace nenalezena"},
{"StreamID can't be null", "StreamID nemůže být null"},
{"Return to destination page", "Zpět na stránku destinací"},
{"You will be redirected in 5 seconds", "Budete přesměrováni za 5 vteřin"},
{"Transit tunnels count must not exceed 65535", "Počet tranzitních tunelů nesmí přesáhnout 65535"},
{"Back to commands list", "Zpět na list příkazů"},
{"Register at reg.i2p", "Zaregistrovat na reg.i2p"},
{"Description", "Popis"},
@@ -166,32 +162,24 @@ namespace czech // language namespace
{"You may try to find this host on jump services below", "Můžete se pokusit najít tohoto hostitele na startovacích službách níže"},
{"Invalid request", "Neplatný požadavek"},
{"Proxy unable to parse your request", "Proxy server nemohl zpracovat váš požadavek"},
{"addresshelper is not supported", "Adresshelper není podporován"},
{"Host", "Hostitel"},
{"added to router's addressbook from helper", "přidáno do adresáře routeru od pomocníka"},
{"Click here to proceed:", "Pro pokračování, klikněte zde:"},
{"Continue", "Pokračovat"},
{"Addresshelper found", "Adresář nalezen"},
{"already in router's addressbook", "je již v adresáři routeru"},
{"Click here to update record:", "Pro aktualizaci záznamu, klikněte zde:"},
{"invalid request uri", "neplatný URI požadavek"},
{"Invalid request URI", "Neplatný URI požadavek"},
{"Can't detect destination host from request", "Nelze zjistit cílového hostitele z požadavku"},
{"Outproxy failure", "Outproxy selhání"},
{"bad outproxy settings", "špatné outproxy nastavení"},
{"not inside I2P network, but outproxy is not enabled", "není uvnitř I2P sítě a outproxy není nastavena"},
{"unknown outproxy url", "neznámá outproxy URL"},
{"cannot resolve upstream proxy", "nelze rozluštit upstream proxy server"},
{"hostname too long", "Název hostitele je příliš dlouhý"},
{"cannot connect to upstream socks proxy", "nelze se připojit k upstream socks proxy serveru"},
{"Cannot negotiate with socks proxy", "Nelze vyjednávat se socks proxy serverem"},
{"Bad outproxy settings", "Špatné outproxy nastavení"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Hostitel %s není uvnitř I2P sítě a outproxy není nastavena"},
{"Unknown outproxy URL", "Neznámá outproxy URL"},
{"Cannot resolve upstream proxy", "Nelze rozluštit upstream proxy server"},
{"Hostname is too long", "Název hostitele je příliš dlouhý"},
{"Cannot connect to upstream SOCKS proxy", "Nelze se připojit k upstream SOCKS proxy serveru"},
{"Cannot negotiate with SOCKS proxy", "Nelze vyjednávat se SOCKS proxy serverem"},
{"CONNECT error", "Chyba PŘIPOJENÍ"},
{"Failed to Connect", "Připojení se nezdařilo"},
{"socks proxy error", "chyba socks proxy serveru"},
{"failed to send request to upstream", "odeslání žádosti upstream serveru se nezdařilo"},
{"No Reply From socks proxy", "Žádná odpověď od socks proxy serveru"},
{"cannot connect", "nelze se připojit"},
{"http out proxy not implemented", "http out proxy není implementován"},
{"cannot connect to upstream http proxy", "nelze se připojit k upstream socks proxy serveru"},
{"Failed to connect", "Připojení se nezdařilo"},
{"SOCKS proxy error", "Chyba SOCKS proxy serveru"},
{"Failed to send request to upstream", "Odeslání žádosti upstream serveru se nezdařilo"},
{"No reply from SOCKS proxy", "Žádná odpověď od SOCKS proxy serveru"},
{"Cannot connect", "Nelze se připojit"},
{"HTTP out proxy not implemented", "HTTP out proxy není implementován"},
{"Cannot connect to upstream HTTP proxy", "Nelze se připojit k upstream HTTP proxy serveru"},
{"Host is down", "Hostitel je nedostupný"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Připojení k požadovanému hostiteli nelze vytvořit, může být nedostupný. Zkuste to, prosím, znovu později."},
{"", ""},
@@ -199,10 +187,10 @@ namespace czech // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"den", "dny", "dní", "dní"}},
{"hours", {"hodina", "hodiny", "hodin", "hodin"}},
{"minutes", {"minuta", "minuty", "minut", "minut"}},
{"seconds", {"vteřina", "vteřiny", "vteřin", "vteřin"}},
{"%d days", {"%d den", "%d dny", "%d dní", "%d dní"}},
{"%d hours", {"%d hodina", "%d hodiny", "%d hodin", "%d hodin"}},
{"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}},
{"%d seconds", {"%d vteřina", "%d vteřiny", "%d vteřin", "%d vteřin"}},
{"", {"", "", "", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@ namespace french // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "Kio"},
{"MiB", "Mio"},
{"GiB", "Gio"},
{"%.2f KiB", "%.2f Kio"},
{"%.2f MiB", "%.2f Mio"},
{"%.2f GiB", "%.2f Gio"},
{"building", "En construction"},
{"failed", "échoué"},
{"expiring", "expiré"},
@@ -58,18 +58,20 @@ namespace french // language namespace
{"Unknown", "Inconnu"},
{"Proxy", "Proxy"},
{"Mesh", "Maillé"},
{"Error", "Erreur"},
{"Clock skew", "Horloge décalée"},
{"Offline", "Hors ligne"},
{"Symmetric NAT", "NAT symétrique"},
{"Full cone NAT", "NAT à cône complet"},
{"No Descriptors", "Aucuns Descripteurs"},
{"Uptime", "Temps de fonctionnement"},
{"Network status", "État du réseau"},
{"Network status v6", "État du réseau v6"},
{"Stopping in", "Arrêt dans"},
{"Family", "Famille"},
{"Tunnel creation success rate", "Taux de succès de création de tunnels"},
{"Total tunnel creation success rate", "Taux de réussite de création de tunnel"},
{"Received", "Reçu"},
{"KiB/s", "kio/s"},
{"%.2f KiB/s", "%.2f Kio/s"},
{"Sent", "Envoyé"},
{"Transit", "Transité"},
{"Data path", "Emplacement des données"},
@@ -81,6 +83,7 @@ namespace french // language namespace
{"Our external address", "Notre adresse externe"},
{"supported", "supporté"},
{"Routers", "Routeurs"},
{"Floodfills", "Remplisseurs"},
{"Client Tunnels", "Tunnels clients"},
{"Services", "Services"},
{"Enabled", "Activé"},
@@ -89,11 +92,13 @@ namespace french // language namespace
{"Address registration line", "Ligne d'inscription de l'adresse"},
{"Domain", "Domaine"},
{"Generate", "Générer"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note:</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note :</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
{"Address", "Adresse"},
{"Type", "Type"},
{"EncType", "EncType"},
{"Expire LeaseSet", "Expirer le jeu de baux"},
{"Inbound tunnels", "Tunnels entrants"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Tunnels sortants"},
{"Tags", "Balises"},
{"Incoming", "Entrant"},
@@ -106,6 +111,7 @@ namespace french // language namespace
{"Local Destination", "Destination locale"},
{"Streams", "Flux"},
{"Close stream", "Fermer le flux"},
{"Such destination is not found", "Cette destination est introuvable"},
{"I2CP session not found", "Session I2CP introuvable"},
{"I2CP is not enabled", "I2CP est désactivé"},
{"Invalid", "Invalide"},
@@ -115,15 +121,17 @@ namespace french // language namespace
{"Gateway", "Passerelle"},
{"TunnelID", "ID du tunnel"},
{"EndDate", "Date de fin"},
{"floodfill mode is disabled", "le mode de remplissage est désactivé"},
{"Queue size", "Longueur de la file"},
{"Run peer test", "Lancer test des pairs"},
{"Reload tunnels configuration", "Recharger la configuration des tunnels"},
{"Decline transit tunnels", "Refuser les tunnels transitoires"},
{"Accept transit tunnels", "Accepter les tunnels transitoires"},
{"Cancel graceful shutdown", "Annuler l'arrêt gracieux"},
{"Start graceful shutdown", "Démarrer l'arrêt gracieux"},
{"Force shutdown", "Forcer l'arrêt"},
{"Reload external CSS styles", "Rafraîchir les styles CSS externes"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Note:</b> Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Note :</b> Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."},
{"Logging level", "Niveau de journalisation"},
{"Transit tunnels limit", "Limite sur les tunnels transitoires"},
{"Change", "Changer"},
@@ -134,6 +142,8 @@ namespace french // language namespace
{"SAM session not found", "session SAM introuvable"},
{"SAM Session", "Session SAM"},
{"Server Tunnels", "Tunnels serveurs"},
{"Client Forwards", "Transmission du client"},
{"Server Forwards", "Transmission du serveur"},
{"Unknown page", "Page inconnue"},
{"Invalid token", "Jeton invalide"},
{"SUCCESS", "SUCCÈS"},
@@ -142,8 +152,10 @@ namespace french // language namespace
{"Destination not found", "Destination introuvable"},
{"StreamID can't be null", "StreamID ne peut pas être vide"},
{"Return to destination page", "Retourner à la page de destination"},
{"You will be redirected in 5 seconds", "Vous allez être redirigé dans cinq secondes"},
{"Transit tunnels count must not exceed 65535", "Le nombre de tunnels transitoires ne doit pas dépasser 65535"},
{"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"},
{"LeaseSet expiration time updated", "Temps d'expiration du jeu de baux mis à jour"},
{"LeaseSet is not found or already expired", "Le jeu de baux est introuvable ou a déjà expiré"},
{"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"},
{"Back to commands list", "Retour à la liste des commandes"},
{"Register at reg.i2p", "Inscription à reg.i2p"},
{"Description", "Description"},
@@ -151,42 +163,42 @@ namespace french // language namespace
{"Submit", "Soumettre"},
{"Domain can't end with .b32.i2p", "Le domaine ne peut pas terminer par .b32.i2p"},
{"Domain must end with .i2p", "Le domaine doit terminer par .i2p"},
{"Such destination is not found", "Cette destination est introuvable"},
{"Unknown command", "Commande inconnue"},
{"Command accepted", "Commande acceptée"},
{"Proxy error", "Erreur de proxy"},
{"Proxy info", "Information sur le proxy"},
{"Proxy error: Host not found", "Erreur de proxy: Hôte introuvable"},
{"Proxy error: Host not found", "Erreur de proxy : Hôte introuvable"},
{"Remote host not found in router's addressbook", "Hôte distant introuvable dans le carnet d'adresse du routeur"},
{"You may try to find this host on jump services below", "Vous pouvez essayer de trouver cet hôte sur des services de redirection ci-dessous"},
{"Invalid request", "Requête invalide"},
{"Proxy unable to parse your request", "Proxy incapable de comprendre votre requête"},
{"addresshelper is not supported", "Assistant d'adresse non supporté"},
{"Host", "Hôte"},
{"added to router's addressbook from helper", "Ajouté au carnet d'adresse du routeur par l'assistant"},
{"Click here to proceed:", "Cliquez ici pour continuer:"},
{"Continue", "Continuer"},
{"Addresshelper found", "Assistant d'adresse trouvé"},
{"already in router's addressbook", "déjà dans le carnet d'adresses du routeur"},
{"Click here to update record:", "Cliquez ici pour mettre à jour le carnet d'adresse:"},
{"invalid request uri", "uri de la requête invalide"},
{"Addresshelper is not supported", "Assistant d'adresse non supporté"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. <b>Attention : la source de cette URL peut être nuisible !</b> Cliquez ici pour mettre à jour l'enregistrement : <a href=\"%s%s%s&update=true\">Continuer</a>."},
{"Addresshelper forced update rejected", "Mise à jour forcée des assistants d'adresses rejetée"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Pour ajouter l'hôte <b>%s</b> au carnet d'adresses du routeur, cliquez ici : <a href=\"%s%s%s\">Continuer</a>."},
{"Addresshelper request", "Demande à l'assistant d'adresse"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "L'hôte %s a été ajouté au carnet d'adresses du routeur depuis l'assistant. Cliquez ici pour continuer : <a href=\"%s\">Continuer</a>."},
{"Addresshelper adding", "Ajout de l'assistant d'adresse"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. Cliquez ici pour mettre à jour le dossier : <a href=\"%s%s%s&update=true\">Continuer</a>."},
{"Addresshelper update", "Mise à jour de l'assistant d'adresse"},
{"Invalid request URI", "URI de la requête invalide"},
{"Can't detect destination host from request", "Impossible de détecter l'hôte de destination à partir de la requête"},
{"Outproxy failure", "Échec de proxy de sortie"},
{"bad outproxy settings", "Mauvaise configuration du proxy de sortie"},
{"not inside I2P network, but outproxy is not enabled", "pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"},
{"unknown outproxy url", "URL du proxy de sortie inconnu"},
{"cannot resolve upstream proxy", "impossible de résoudre l'adresse du proxy en amont"},
{"hostname too long", "nom d'hôte trop long"},
{"cannot connect to upstream socks proxy", "impossible de se connecter au proxy socks en amont"},
{"Cannot negotiate with socks proxy", "Impossible de négocier avec le proxy socks"},
{"Bad outproxy settings", "Mauvaise configuration du proxy de sortie"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Hôte %s pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"},
{"Unknown outproxy URL", "URL du proxy de sortie inconnu"},
{"Cannot resolve upstream proxy", "Impossible de résoudre l'adresse du proxy en amont"},
{"Hostname is too long", "Nom d'hôte trop long"},
{"Cannot connect to upstream SOCKS proxy", "Impossible de se connecter au proxy SOCKS en amont"},
{"Cannot negotiate with SOCKS proxy", "Impossible de négocier avec le proxy SOCKS"},
{"CONNECT error", "Erreur de connexion"},
{"Failed to Connect", "Échec de connexion"},
{"socks proxy error", "Erreur de proxy socks"},
{"failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"},
{"No Reply From socks proxy", "Pas de réponse du proxy socks"},
{"cannot connect", "impossible de connecter"},
{"http out proxy not implemented", "Proxy de sortie HTTP non implémenté"},
{"cannot connect to upstream http proxy", "impossible de se connecter au proxy HTTP en amont"},
{"Failed to connect", "Échec de connexion"},
{"SOCKS proxy error", "Erreur de proxy SOCKS"},
{"Failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"},
{"No reply from SOCKS proxy", "Pas de réponse du proxy SOCKS"},
{"Cannot connect", "Impossible de connecter"},
{"HTTP out proxy not implemented", "Proxy de sortie HTTP non implémenté"},
{"Cannot connect to upstream HTTP proxy", "Impossible de se connecter au proxy HTTP en amont"},
{"Host is down", "Hôte hors service"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossible d'établir une connexion avec l'hôte, il est peut-être hors service. Veuillez réessayer plus tard."},
{"", ""},
@@ -194,10 +206,10 @@ namespace french // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"jour", "jours"}},
{"hours", {"heure", "heures"}},
{"minutes", {"minute", "minutes"}},
{"seconds", {"seconde", "secondes"}},
{"%d days", {"%d jour", "%d jours"}},
{"%d hours", {"%d heure", "%d heures"}},
{"%d minutes", {"%d minute", "%d minutes"}},
{"%d seconds", {"%d seconde", "%d secondes"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@ namespace german // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "In Bau"},
{"failed", "fehlgeschlagen"},
{"expiring", "läuft ab"},
@@ -58,10 +58,10 @@ namespace german // language namespace
{"Unknown", "Unbekannt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Error", "Fehler"},
{"Clock skew", "Zeitabweichung"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symmetrisches NAT"},
{"No Descriptors", "Keine Beschreibungen"},
{"Uptime", "Laufzeit"},
{"Network status", "Netzwerkstatus"},
{"Network status v6", "Netzwerkstatus v6"},
@@ -69,7 +69,7 @@ namespace german // language namespace
{"Family", "Familie"},
{"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"},
{"Received", "Eingegangen"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Gesendet"},
{"Transit", "Transit"},
{"Data path", "Datenpfad"},
@@ -95,7 +95,7 @@ namespace german // language namespace
{"Type", "Typ"},
{"EncType", "Verschlüsselungstyp"},
{"Inbound tunnels", "Eingehende Tunnel"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Ausgehende Tunnel"},
{"Tags", "Tags"},
{"Incoming", "Eingehend"},
@@ -117,9 +117,10 @@ namespace german // language namespace
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Enddatum"},
{"not floodfill", "kein Floodfill"},
{"floodfill mode is disabled", "Floodfill Modus ist deaktiviert"},
{"Queue size", "Größe der Warteschlange"},
{"Run peer test", "Peer-Test durchführen"},
{"Reload tunnels configuration", "Tunnel Konfiguration neu laden"},
{"Decline transit tunnels", "Transittunnel ablehnen"},
{"Accept transit tunnels", "Transittunnel akzeptieren"},
{"Cancel graceful shutdown", "Beende das kontrollierte Herunterfahren"},
@@ -147,8 +148,8 @@ namespace german // language namespace
{"Destination not found", "Ziel nicht gefunden"},
{"StreamID can't be null", "StreamID kann nicht null sein"},
{"Return to destination page", "Zurück zur Ziel-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"},
{"You will be redirected in %d seconds", "Du wirst umgeleitet in %d Sekunden"},
{"Transit tunnels count must not exceed %d", "Die Anzahl der Transittunnel darf nicht über %d gehen"},
{"Back to commands list", "Zurück zur Befehlsliste"},
{"Register at reg.i2p", "Auf reg.i2p registrieren"},
{"Description", "Beschreibung"},
@@ -166,32 +167,33 @@ namespace german // language namespace
{"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einem der nachfolgenden Jump-Services finden"},
{"Invalid request", "Ungültige Anfrage"},
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht verarbeiten"},
{"addresshelper is not supported", "Addresshelfer 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"},
{"Addresshelper is not supported", "Adresshelfer wird nicht unterstützt"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s ist <font color=red>bereits im Adressbuch des Routers</font>. <b>Vorsicht: Die Quelle dieser URL kann schädlich sein!</b> Klicken Sie hier, um den Datensatz zu aktualisieren: <a href=\"%s%s%s&update=true\">Weiter</a>."},
{"Addresshelper forced update rejected", "Adresshelfer gezwungene Aktualisierung abgelehnt"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Um den Host <b>%s</b> im Adressbuch des Routers hinzuzufügen, klicken Sie hier: <a href=\"%s%s%s\">Weiter</a>."},
{"Addresshelper request", "Adresshelfer gefunden"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Host %s wurde vom Helfer zum Adressbuch des Routers hinzugefügt. Klicken Sie hier, um fortzufahren: <a href=\"%s\">Weiter</a>."},
{"Addresshelper adding", "Adresshelfer hinzufügen"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s ist <font color=red>bereits im Adressbuch des Routers</font>. Klicken Sie hier, um den Eintrag zu aktualisieren: <a href=\"%s%s%s&update=true\">Weiter</a>."},
{"Addresshelper update", "Adresshelfer aktualisieren"},
{"Invalid request URI", "Ungültige Anfrage-URI"},
{"Can't detect destination host from request", "Kann den Ziel-Host von der Anfrage nicht erkennen"},
{"Outproxy failure", "Outproxy-Fehler"},
{"bad outproxy settings", "ungültige Outproxy-Einstellungen"},
{"not inside I2P network, but outproxy is not enabled", "außerhalb 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"},
{"Bad outproxy settings", "Ungültige Outproxy-Einstellungen"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s außerhalb 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 is 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"},
{"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 aufbauen, vielleicht ist er offline. Versuche es später noch mal."},
{"", ""},
@@ -199,10 +201,10 @@ namespace german // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"Tag", "Tage"}},
{"hours", {"Stunde", "Stunden"}},
{"minutes", {"Minute", "Minuten"}},
{"seconds", {"Sekunde", "Sekunden"}},
{"%d days", {"%d Tag", "%d Tage"}},
{"%d hours", {"%d Stunde", "%d Stunden"}},
{"%d minutes", {"%d Minute", "%d Minuten"}},
{"%d seconds", {"%d Sekunde", "%d Sekunden"}},
{"", {"", ""}},
};

View File

@@ -1,11 +1,12 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
* Copyright (c) 2021-2023, 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 <clocale>
#include "ClientContext.h"
#include "I18N_langs.h"
#include "I18N.h"
@@ -18,9 +19,15 @@ namespace i18n
{
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
{
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
setlocale(LC_NUMERIC, "english");
}
else
{
i2p::client::context.SetLanguage (it->second.LocaleFunc());
setlocale(LC_NUMERIC, lang.c_str()); // set decimal point based on language
}
}
std::string translate (const std::string& arg)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -67,17 +67,69 @@ namespace i18n
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
void SetLanguage(const std::string &lang);
std::string translate (const std::string& arg);
std::string translate (const std::string& arg, const std::string& arg2, const int& n);
} // i18n
} // i2p
template<typename... TArgs>
std::string tr (TArgs&&... args)
/**
* @brief Get translation of string
* @param arg String with message
*/
template<typename TValue>
std::string tr (TValue&& arg)
{
return i2p::i18n::translate(std::forward<TArgs>(args)...);
return i2p::i18n::translate(std::forward<TValue>(arg));
}
/**
* @brief Get translation of string and format it
* @param arg String with message
* @param args Array of arguments for string formatting
*/
template<typename TValue, typename... TArgs>
std::string tr (TValue&& arg, TArgs&&... args)
{
std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg));
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
std::string str(size, 0);
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
return str;
}
/**
* @brief Get translation of string with plural forms
* @param arg String with message in singular form
* @param arg2 String with message in plural form
* @param n Integer, used for selection of form
*/
template<typename TValue, typename TValue2>
std::string ntr (TValue&& arg, TValue2&& arg2, int& n)
{
return i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
}
/**
* @brief Get translation of string with plural forms and format it
* @param arg String with message in singular form
* @param arg2 String with message in plural form
* @param n Integer, used for selection of form
* @param args Array of arguments for string formatting
*/
template<typename TValue, typename TValue2, typename... TArgs>
std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args)
{
std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
std::string str(size, 0);
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
return str;
}
#endif // __I18N_H__

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -23,19 +23,23 @@ namespace i18n
};
// 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 chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace spanish { 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 (); }
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace polish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace portuguese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace swedish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkish { 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
@@ -50,8 +54,12 @@ namespace i18n
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
{ "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} },
{ "polish", {"Polski", "pl", i2p::i18n::polish::GetLocale} },
{ "portuguese", {"Português", "pt", i2p::i18n::portuguese::GetLocale} },
{ "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} },
{ "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} },
{ "turkish", {"Türk dili", "tr", i2p::i18n::turkish::GetLocale} },
{ "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} },

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@ namespace italian // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "in costruzione"},
{"failed", "fallito"},
{"expiring", "in scadenza"},
@@ -58,18 +58,20 @@ namespace italian // language namespace
{"Unknown", "Sconosciuto"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Error", "Errore"},
{"Clock skew", "Orologio disallineato"},
{"Offline", "Disconnesso"},
{"Symmetric NAT", "NAT simmetrico"},
{"Full cone NAT", "Cono completo NAT"},
{"No Descriptors", "Nessun descrittore"},
{"Uptime", "In funzione da"},
{"Network status", "Stato della rete"},
{"Network status v6", "Stato della rete v6"},
{"Stopping in", "Arresto in"},
{"Family", "Famiglia"},
{"Tunnel creation success rate", "Percentuale di tunnel creati con successo"},
{"Total tunnel creation success rate", "Percentuale di successo totale nella creazione del tunnel"},
{"Received", "Ricevuti"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Inviati"},
{"Transit", "Transitati"},
{"Data path", "Percorso dati"},
@@ -94,8 +96,9 @@ namespace italian // language namespace
{"Address", "Indirizzo"},
{"Type", "Tipologia"},
{"EncType", "Tipo di crittografia"},
{"Expire LeaseSet", "Scadenza LeaseSet"},
{"Inbound tunnels", "Tunnel in entrata"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Tunnel in uscita"},
{"Tags", "Tag"},
{"Incoming", "In entrata"},
@@ -108,6 +111,7 @@ namespace italian // language namespace
{"Local Destination", "Destinazione locale"},
{"Streams", "Flussi"},
{"Close stream", "Interrompi il flusso"},
{"Such destination is not found", "Questa destinazione non è stata trovata"},
{"I2CP session not found", "Sessione I2CP non trovata"},
{"I2CP is not enabled", "I2CP non è abilitato"},
{"Invalid", "Invalido"},
@@ -117,9 +121,10 @@ namespace italian // language namespace
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Data di fine"},
{"not floodfill", "no floodfill"},
{"floodfill mode is disabled", "la modalità floodfill è disabilitata"},
{"Queue size", "Dimensione della coda"},
{"Run peer test", "Esegui il test dei peer"},
{"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"},
{"Decline transit tunnels", "Rifiuta tunnel di transito"},
{"Accept transit tunnels", "Accetta tunnel di transito"},
{"Cancel graceful shutdown", "Annulla l'interruzione controllata"},
@@ -147,8 +152,10 @@ namespace italian // language namespace
{"Destination not found", "Destinazione non trovata"},
{"StreamID can't be null", "Lo StreamID non può essere null"},
{"Return to destination page", "Ritorna alla pagina di destinazione"},
{"You will be redirected in 5 seconds", "Verrai reindirizzato in 5 secondi"},
{"Transit tunnels count must not exceed 65535", "Il numero di tunnel di transito non può superare i 65535"},
{"You will be redirected in %d seconds", "Sarai reindirizzato tra %d secondi"},
{"LeaseSet expiration time updated", "Tempo di scadenza LeaseSet aggiornato"},
{"LeaseSet is not found or already expired", "LeaseSet non trovato o già scaduto"},
{"Transit tunnels count must not exceed %d", "Il conteggio dei tunnel di transito non deve superare %d"},
{"Back to commands list", "Ritorna alla lista dei comandi"},
{"Register at reg.i2p", "Registra a reg.i2p"},
{"Description", "Descrizione"},
@@ -156,7 +163,6 @@ namespace italian // language namespace
{"Submit", "Invia"},
{"Domain can't end with .b32.i2p", "I domini non possono terminare con .b32.i2p"},
{"Domain must end with .i2p", "I domini devono terminare con .i2p"},
{"Such destination is not found", "Questa destinazione non è stata trovata"},
{"Unknown command", "Comando sconosciuto"},
{"Command accepted", "Comando accettato"},
{"Proxy error", "Errore del proxy"},
@@ -166,32 +172,33 @@ namespace italian // language namespace
{"You may try to find this host on jump services below", "Si può provare a trovare questo host sui servizi di salto qui sotto"},
{"Invalid request", "Richiesta non valida"},
{"Proxy unable to parse your request", "Il proxy non è in grado di elaborare la tua richiesta"},
{"addresshelper is not supported", "addresshelper non è supportato"},
{"Host", "Host"},
{"added to router's addressbook from helper", "aggiunto alla rubrica tramite l'helper"},
{"Click here to proceed:", "Clicca qui per procedere:"},
{"Continue", "Continua"},
{"Addresshelper found", "Addresshelper trovato"},
{"already in router's addressbook", "già presente nella rubrica del router"},
{"Click here to update record:", "Clicca qui per aggiornare l'elemento:"},
{"invalid request uri", "uri della richiesta non valido"},
{"Addresshelper is not supported", "Addresshelper non è supportato"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'host %s è <font color=red>già nella rubrica del router</font>. <b>Attenzione: la fonte di questo URL potrebbe essere dannosa!</b> Fai clic qui per aggiornare il record: <a href=\"%s%s%s&update=true\">Continua</a>."},
{"Addresshelper forced update rejected", "Aggiornamento forzato dell'helper degli indirizzi rifiutato"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Per aggiungere host <b>%s</b> nella rubrica del router, clicca qui: <a href=\"%s%s%s\">Continua</a>."},
{"Addresshelper request", "Richiesta di indirizzo helper"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "L'host %s viene aggiunto alla rubrica del router dall'helper. Fai clic qui per procedere: <a href=\"%s\">Continua</a>."},
{"Addresshelper adding", "Aggiunta di Addresshelper"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'host %s è <font color=red>già nella rubrica del router</font>. Clicca qui per aggiornare il record: <a href=\"%s%s%s&update=true\">Continua</a>."},
{"Addresshelper update", "Aggiornamento dell'helper degli indirizzi"},
{"Invalid request URI", "URI della richiesta non valido"},
{"Can't detect destination host from request", "Impossibile determinare l'host di destinazione dalla richiesta"},
{"Outproxy failure", "Fallimento del proxy di uscita"},
{"bad outproxy settings", "impostazioni errate del proxy di uscita"},
{"not inside I2P network, but outproxy is not enabled", "non all'interno della rete I2P, ma il proxy di uscita non è abilitato"},
{"unknown outproxy url", "url del proxy di uscita sconosciuto"},
{"cannot resolve upstream proxy", "impossibile identificare il flusso a monte del proxy"},
{"hostname too long", "il nome dell'host è troppo lungo"},
{"cannot connect to upstream socks proxy", "impossibile connettersi al flusso a monte del proxy socks"},
{"Cannot negotiate with socks proxy", "Impossibile negoziare con il proxy socks"},
{"Bad outproxy settings", "Impostazioni errate del proxy di uscita"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s non all'interno della rete I2P, ma il proxy di uscita non è abilitato"},
{"Unknown outproxy URL", "URL del proxy di uscita sconosciuto"},
{"Cannot resolve upstream proxy", "Impossibile identificare il flusso a monte del proxy"},
{"Hostname is too long", "Il nome dell'host è troppo lungo"},
{"Cannot connect to upstream SOCKS proxy", "Impossibile connettersi al flusso a monte del proxy SOCKS"},
{"Cannot negotiate with SOCKS proxy", "Impossibile negoziare con il proxy SOCKS"},
{"CONNECT error", "Errore di connessione"},
{"Failed to Connect", "Connessione fallita"},
{"socks proxy error", "errore del proxy socks"},
{"failed to send request to upstream", "invio della richiesta a monte non riuscito"},
{"No Reply From socks proxy", "Nessuna risposta dal proxy socks"},
{"cannot connect", "impossibile connettersi"},
{"http out proxy not implemented", "proxy http di uscita non implementato"},
{"cannot connect to upstream http proxy", "impossibile connettersi al proxy http a monte"},
{"Failed to connect", "Connessione fallita"},
{"SOCKS proxy error", "Errore del proxy SOCKS"},
{"Failed to send request to upstream", "Invio della richiesta a monte non riuscito"},
{"No reply from SOCKS proxy", "Nessuna risposta dal proxy SOCKS"},
{"Cannot connect", "Impossibile connettersi"},
{"HTTP out proxy not implemented", "Proxy HTTP di uscita non implementato"},
{"Cannot connect to upstream HTTP proxy", "Impossibile connettersi al flusso a monte del proxy HTTP"},
{"Host is down", "L'host è offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossibile creare la connessione all'host richiesto, probabilmente è offline. Riprova più tardi."},
{"", ""},
@@ -199,10 +206,10 @@ namespace italian // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"giorno", "giorni"}},
{"hours", {"ora", "ore"}},
{"minutes", {"minuto", "minuti"}},
{"seconds", {"secondo", "secondi"}},
{"%d days", {"%d giorno", "%d giorni"}},
{"%d hours", {"%d ora", "%d ore"}},
{"%d minutes", {"%d minuto", "%d minuti"}},
{"%d seconds", {"%d secondo", "%d secondi"}},
{"", {"", ""}},
};

59
i18n/Polish.cpp Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023, 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"
// Polish localization file
namespace i2p
{
namespace i18n
{
namespace polish // language namespace
{
// language name in lowercase
static std::string language = "polish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
static std::map<std::string, std::string> strings
{
{"building", "Kompilowanie"},
{"failed", "nieudane"},
{"expiring", "wygasający"},
{"established", "ustanowiony"},
{"Main page", "Strona główna"},
{"Router commands", "Komendy routera"},
{"Tunnels", "Tunele"},
{"OK", "Ok"},
{"Uptime", "Czas pracy"},
{"Sent", "Wysłane"},
{"", ""},
};
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

223
i18n/Portuguese.cpp Normal file
View File

@@ -0,0 +1,223 @@
/*
* Copyright (c) 2023, 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"
// Portuguese localization file
namespace i2p
{
namespace i18n
{
namespace portuguese // language namespace
{
// language name in lowercase
static std::string language = "portuguese";
// 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
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "construindo"},
{"failed", "falhou"},
{"expiring", "expirando"},
{"established", "estabelecido"},
{"unknown", "desconhecido"},
{"exploratory", "exploratório"},
{"Purple I2P Webconsole", "Webconsole Purple I2P"},
{"<b>i2pd</b> webconsole", "webconsole <b>i2pd</b>"},
{"Main page", "Página Principal"},
{"Router commands", "Comandos do Roteador"},
{"Local Destinations", "Destinos Locais"},
{"LeaseSets", "LeaseSets"},
{"Tunnels", "Túneis"},
{"Transit Tunnels", "Túneis de Trânsito"},
{"Transports", "Transportes"},
{"I2P tunnels", "Túneis I2P"},
{"SAM sessions", "Sessões do SAM"},
{"ERROR", "ERRO"},
{"OK", "OK"},
{"Testing", "Testando"},
{"Firewalled", "Sob Firewall"},
{"Unknown", "Desconhecido"},
{"Proxy", "Proxy"},
{"Mesh", "Malha"},
{"Clock skew", "Defasagem do Relógio"},
{"Offline", "Desligado"},
{"Symmetric NAT", "NAT Simétrico"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Sem Descritores"},
{"Uptime", "Tempo Ativo"},
{"Network status", "Estado da rede"},
{"Network status v6", "Estado da rede v6"},
{"Stopping in", "Parando em"},
{"Family", "Família"},
{"Tunnel creation success rate", "Taxa de sucesso na criação de túneis"},
{"Total tunnel creation success rate", "Taxa total de sucesso na criação de túneis"},
{"Received", "Recebido"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Enviado"},
{"Transit", "Trânsito"},
{"Data path", "Diretório dos dados"},
{"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."},
{"Router Ident", "Identidade do Roteador"},
{"Router Family", "Família do Roteador"},
{"Router Caps", "Limites do Roteador"},
{"Version", "Versão"},
{"Our external address", "Nosso endereço externo"},
{"supported", "suportado"},
{"Routers", "Roteadores"},
{"Floodfills", "Modo Inundação"},
{"Client Tunnels", "Túneis de Clientes"},
{"Services", "Serviços"},
{"Enabled", "Ativado"},
{"Disabled", "Desativado"},
{"Encrypted B33 address", "Endereço B33 criptografado"},
{"Address registration line", "Linha de cadastro de endereço"},
{"Domain", "Domínio"},
{"Generate", "Gerar"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Nota: </b>A string resultante só pode ser usada para registrar domínios 2LD (exemplo.i2p). Para registrar subdomínios por favor utilize o i2pd-tools."},
{"Address", "Endereço"},
{"Type", "Tipo"},
{"EncType", "Tipo de Criptografia"},
{"Expire LeaseSet", "Expirar LeaseSet"},
{"Inbound tunnels", "Túneis de Entrada"},
{"%dms", "%dms"},
{"Outbound tunnels", "Túneis de Saída"},
{"Tags", "Etiquetas"},
{"Incoming", "Entradas"},
{"Outgoing", "Saídas"},
{"Destination", "Destinos"},
{"Amount", "Quantidade"},
{"Incoming Tags", "Etiquetas de Entrada"},
{"Tags sessions", "Sessões de etiquetas"},
{"Status", "Estado"},
{"Local Destination", "Destinos Locais"},
{"Streams", "Fluxos"},
{"Close stream", "Fechar fluxo"},
{"Such destination is not found", "Tal destino não foi encontrado"},
{"I2CP session not found", "Sessão do I2CP não encontrada"},
{"I2CP is not enabled", "I2CP não está ativado"},
{"Invalid", "Inválido"},
{"Store type", "Tipo de armazenamento"},
{"Expires", "Expira em"},
{"Non Expired Leases", "Sessões não expiradas"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Data final"},
{"floodfill mode is disabled", "Mode de inundação está desativado"},
{"Queue size", "Tamanho da fila"},
{"Run peer test", "Executar teste de peers"},
{"Reload tunnels configuration", "Recarregar a configuração dos túneis"},
{"Decline transit tunnels", "Negar túneis de trânsito"},
{"Accept transit tunnels", "Aceitar túneis de trânsito"},
{"Cancel graceful shutdown", "Cancelar desligamento gracioso"},
{"Start graceful shutdown", "Iniciar desligamento gracioso"},
{"Force shutdown", "Forçar desligamento"},
{"Reload external CSS styles", "Recarregar estilos CSS externos"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b> Nota: </b> Qualquer ação feita aqui não será permanente e não altera os seus arquivos de configuração."},
{"Logging level", "Nível de registro"},
{"Transit tunnels limit", "Limite de túneis de trânsito"},
{"Change", "Mudar"},
{"Change language", "Trocar idioma"},
{"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"},
{"SAM disabled", "SAM desativado"},
{"no sessions currently running", "Nenhuma sessão funcionando no momento"},
{"SAM session not found", "Nenhuma sessão do SAM encontrada"},
{"SAM Session", "Sessão do SAM"},
{"Server Tunnels", "Túneis de Servidor"},
{"Client Forwards", "Túneis de Cliente"},
{"Server Forwards", "Encaminhamentos de Servidor"},
{"Unknown page", "Página desconhecida"},
{"Invalid token", "Token Inválido"},
{"SUCCESS", "SUCESSO"},
{"Stream closed", "Fluxo fechado"},
{"Stream not found or already was closed", "Fluxo não encontrado ou já encerrado"},
{"Destination not found", "Destino não encontrado"},
{"StreamID can't be null", "StreamID não pode ser nulo"},
{"Return to destination page", "Retornar para à página de destino"},
{"You will be redirected in %d seconds", "Você será redirecionado em %d segundos"},
{"LeaseSet expiration time updated", "Tempo de validade do LeaseSet atualizado"},
{"LeaseSet is not found or already expired", "LeaseSet não foi encontrado ou já expirou"},
{"Transit tunnels count must not exceed %d", "A contagem de túneis de trânsito não deve exceder %d"},
{"Back to commands list", "Voltar para a lista de comandos"},
{"Register at reg.i2p", "Registrar na reg.i2p"},
{"Description", "Descrição"},
{"A bit information about service on domain", "Algumas informações sobre o serviço no domínio"},
{"Submit", "Enviar"},
{"Domain can't end with .b32.i2p", "O domínio não pode terminar com .b32.i2p"},
{"Domain must end with .i2p", "O domínio não pode terminar com .i2p"},
{"Unknown command", "Comando desconhecido"},
{"Command accepted", "Comando aceito"},
{"Proxy error", "Erro no proxy"},
{"Proxy info", "Informações do proxy"},
{"Proxy error: Host not found", "Erro no proxy: Host não encontrado"},
{"Remote host not found in router's addressbook", "O host remoto não foi encontrado no livro de endereços do roteador"},
{"You may try to find this host on jump services below", "Você pode tentar encontrar este host nos jump services abaixo"},
{"Invalid request", "Requisição inválida"},
{"Proxy unable to parse your request", "O proxy foi incapaz de processar a sua requisição"},
{"Addresshelper is not supported", "O Auxiliar de Endereços não é suportado"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador</font>. <b>Cuidado: a fonte desta URL pode ser perigosa!</b> Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
{"Addresshelper forced update rejected", "A atualização forçada do Auxiliar de Endereços foi rejeitada"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Para adicionar o host <b> %s </b> ao catálogo de endereços do roteador, clique aqui: <a href='%s%s%s'>Continuar </a>."},
{"Addresshelper request", "Requisição do Auxiliar de Endereços"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "O host %s foi adicionado ao catálogo de endereços do roteador por um auxiliar. Clique aqui para proceder: <a href='%s'> Continuar </a>."},
{"Addresshelper adding", "Auxiliar de Endereço adicionando"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador </font>. Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
{"Addresshelper update", "Atualização do Auxiliar de Endereços"},
{"Invalid request URI", "A URI de requisição é inválida"},
{"Can't detect destination host from request", "Incapaz de detectar o host de destino da requisição"},
{"Outproxy failure", "Falha no outproxy"},
{"Bad outproxy settings", "Configurações ruins de outproxy"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "O host %s não está dentro da rede I2P, mas o outproxy não está ativado"},
{"Unknown outproxy URL", "URL de outproxy desconhecida"},
{"Cannot resolve upstream proxy", "Não é possível resolver o proxy de entrada"},
{"Hostname is too long", "O hostname é muito longo"},
{"Cannot connect to upstream SOCKS proxy", "Não é possível se conectar ao proxy SOCKS de entrada"},
{"Cannot negotiate with SOCKS proxy", "Não é possível negociar com o proxy SOCKS"},
{"CONNECT error", "Erro de CONEXÃO"},
{"Failed to connect", "Falha ao conectar"},
{"SOCKS proxy error", "Erro no proxy SOCKS"},
{"Failed to send request to upstream", "Falha ao enviar requisição para o fluxo de entrada"},
{"No reply from SOCKS proxy", "Sem resposta do proxy SOCKS"},
{"Cannot connect", "Impossível conectar"},
{"HTTP out proxy not implemented", "proxy de saída HTTP não implementado"},
{"Cannot connect to upstream HTTP proxy", "Não é possível conectar ao proxy HTTP de entrada"},
{"Host is down", "Host está desligado"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Não é possível se conectar ao host requisitado, talvez ele esteja for do ar. Por favor, tente novamente mais tarde."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d Dia", "%d Dias"}},
{"%d hours", {"%d hora", "%d horas"}},
{"%d minutes", {"%d minuto", "%d minutos"}},
{"%d seconds", {"%d Segundo", "%d segundos"}},
{"", {"", ""}},
};
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) 2021, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@ namespace russian // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "КиБ"},
{"MiB", "МиБ"},
{"GiB", "ГиБ"},
{"%.2f KiB", "%.2f КиБ"},
{"%.2f MiB", "%.2f МиБ"},
{"%.2f GiB", "%.2f ГиБ"},
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"unknown", "неизвестно"},
{"exploratory", "исследовательский"},
{"Purple I2P Webconsole", "Веб-консоль Purple I2P"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
@@ -57,18 +58,20 @@ namespace russian // language namespace
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
{"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Нет дескрипторов"},
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
{"Total tunnel creation success rate", "Общий процент успешно построенных туннелей"},
{"Received", "Получено"},
{"KiB/s", "КиБ/с"},
{"%.2f KiB/s", "%.2f КиБ/с"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"Data path", "Путь к данным"},
@@ -93,8 +96,9 @@ namespace russian // language namespace
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Expire LeaseSet", "Просрочить Лизсет"},
{"Inbound tunnels", "Входящие туннели"},
{"ms", "мс"},
{"%dms", "%dмс"},
{"Outbound tunnels", "Исходящие туннели"},
{"Tags", "Теги"},
{"Incoming", "Входящие"},
@@ -107,6 +111,7 @@ namespace russian // language namespace
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
{"Invalid", "Некорректный"},
@@ -116,9 +121,10 @@ namespace russian // language namespace
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
{"not floodfill", "не флудфил"},
{"floodfill mode is disabled", "режим флудфила отключен"},
{"Queue size", "Размер очереди"},
{"Run peer test", "Запустить тестирование"},
{"Reload tunnels configuration", "Перезагрузить конфигурацию туннелей"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
@@ -146,8 +152,10 @@ namespace russian // language namespace
{"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"},
{"You will be redirected in %d seconds", "Вы будете переадресованы через %d секунд"},
{"LeaseSet expiration time updated", "Время действия LeaseSet обновлено"},
{"LeaseSet is not found or already expired", "Лизсет не найден или время действия уже истекло"},
{"Transit tunnels count must not exceed %d", "Число транзитных туннелей не должно превышать %d"},
{"Back to commands list", "Вернуться к списку команд"},
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
@@ -155,7 +163,6 @@ namespace russian // language namespace
{"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", "Ошибка прокси"},
@@ -165,32 +172,33 @@ namespace russian // language namespace
{"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 запроса"},
{"Addresshelper is not supported", "Addresshelper не поддерживается"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. <b>Будьте осторожны: источник данной ссылки может быть вредоносным!</b> Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
{"Addresshelper forced update rejected", "Принудительное обновление через Addresshelper отклонено"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Чтобы добавить узел <b>%s</b> в адресную книгу роутера, нажмите здесь: <a href=\"%s%s%s\"родолжить</a>."},
{"Addresshelper request", "Запрос добавления Addresshelper"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Узел %s добавлен в адресную книгу роутера через хелпер. Нажмите здесь, чтобы продолжить: <a href=\"%s\">Продолжить</a>."},
{"Addresshelper adding", "Добавление Addresshelper"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
{"Addresshelper update", "Обновление записи через Addresshelper"},
{"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 прокси"},
{"Bad outproxy settings", "Некорректные настройки внешнего прокси"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Узел %s не в I2P сети, но внешний прокси не включен"},
{"Unknown outproxy URL", "Неизвестный URL внешнего прокси"},
{"Cannot resolve upstream proxy", "Не удается определить вышестоящий прокси"},
{"Hostname is 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 прокси серверу"},
{"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.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
{"", ""},
@@ -198,10 +206,10 @@ namespace russian // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"день", "дня", "дней"}},
{"hours", {"час", "часа", "часов"}},
{"minutes", {"минуту", "минуты", "минут"}},
{"seconds", {"секунду", "секунды", "секунд"}},
{"%d days", {"%d день", "%d дня", "%d дней"}},
{"%d hours", {"%d час", "%d часа", "%d часов"}},
{"%d minutes", {"%d минуту", "%d минуты", "%d минут"}},
{"%d seconds", {"%d секунду", "%d секунды", "%d секунд"}},
{"", {"", "", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, The PurpleI2P Project
* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@ namespace spanish // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "pendiente"},
{"failed", "fallido"},
{"expiring", "expiró"},
@@ -58,7 +58,6 @@ namespace spanish // language namespace
{"Unknown", "Desconocido"},
{"Proxy", "Proxy"},
{"Mesh", "Malla"},
{"Error", "Error"},
{"Clock skew", "Reloj desfasado"},
{"Offline", "Desconectado"},
{"Symmetric NAT", "NAT simétrico"},
@@ -69,7 +68,7 @@ namespace spanish // language namespace
{"Family", "Familia"},
{"Tunnel creation success rate", "Tasa de éxito de creación de túneles"},
{"Received", "Recibido"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Enviado"},
{"Transit", "Tránsito"},
{"Data path", "Ruta de datos"},
@@ -95,7 +94,7 @@ namespace spanish // language namespace
{"Type", "Tipo"},
{"EncType", "TipoEncrip"},
{"Inbound tunnels", "Túneles entrantes"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Túneles salientes"},
{"Tags", "Etiquetas"},
{"Incoming", "Entrante"},
@@ -117,7 +116,6 @@ namespace spanish // language namespace
{"Gateway", "Puerta de enlace"},
{"TunnelID", "TunnelID"},
{"EndDate", "FechaVenc"},
{"not floodfill", "no inundado"},
{"Queue size", "Tamaño de cola"},
{"Run peer test", "Ejecutar prueba de par"},
{"Decline transit tunnels", "Rechazar túneles de tránsito"},
@@ -147,8 +145,6 @@ namespace spanish // language namespace
{"Destination not found", "Destino no encontrado"},
{"StreamID can't be null", "StreamID no puede ser nulo"},
{"Return to destination page", "Volver a la página de destino"},
{"You will be redirected in 5 seconds", "Serás redirigido en 5 segundos"},
{"Transit tunnels count must not exceed 65535", "La cantidad de túneles de tránsito no puede exceder 65535"},
{"Back to commands list", "Volver a lista de comandos"},
{"Register at reg.i2p", "Registrar en reg.i2p"},
{"Description", "Descripción"},
@@ -166,32 +162,24 @@ namespace spanish // language namespace
{"You may try to find this host on jump services below", "Puede intentar encontrar este dominio en los siguientes servicios de salto"},
{"Invalid request", "Solicitud inválida"},
{"Proxy unable to parse your request", "Proxy no puede procesar su solicitud"},
{"addresshelper is not supported", "ayudante de dirección no soportado"},
{"Host", "Dominio"},
{"added to router's addressbook from helper", "añadido a la libreta de direcciones desde el ayudante"},
{"Click here to proceed:", "Haga clic aquí para continuar:"},
{"Continue", "Continuar"},
{"Addresshelper found", "Se encontró ayudante de dirección"},
{"already in router's addressbook", "ya se encontró en libreta de direcciones"},
{"Click here to update record:", "Haga clic aquí para actualizar el registro:"},
{"invalid request uri", "uri de solicitud inválida"},
{"Invalid request URI", "URI de solicitud inválida"},
{"Can't detect destination host from request", "No se puede detectar el host de destino de la solicitud"},
{"Outproxy failure", "Fallo en el proxy saliente"},
{"bad outproxy settings", "configuración de outproxy incorrecta"},
{"not inside I2P network, but outproxy is not enabled", "no está dentro de la red I2P, pero el proxy de salida no está activado"},
{"unknown outproxy url", "url de proxy outproxy desconocido"},
{"cannot resolve upstream proxy", "no se puede resolver el proxy de upstream"},
{"hostname too long", "nombre de dominio muy largo"},
{"cannot connect to upstream socks proxy", "no se puede conectar al proxy socks principal"},
{"Cannot negotiate with socks proxy", "No se puede negociar con el proxy socks"},
{"Bad outproxy settings", "Configuración de outproxy incorrecta"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Dominio %s no está dentro de la red I2P, pero el proxy de salida no está activado"},
{"Unknown outproxy URL", "URL de proxy outproxy desconocido"},
{"Cannot resolve upstream proxy", "No se puede resolver el proxy de upstream"},
{"Hostname is too long", "Nombre de dominio muy largo"},
{"Cannot connect to upstream SOCKS proxy", "No se puede conectar al proxy SOCKS principal"},
{"Cannot negotiate with SOCKS proxy", "No se puede negociar con el proxy SOCKS"},
{"CONNECT error", "Error de CONNECT"},
{"Failed to Connect", "Error al Conectar"},
{"socks proxy error", "error de proxy socks"},
{"failed to send request to upstream", "no se pudo enviar petición al principal"},
{"No Reply From socks proxy", "Sin respuesta del proxy socks"},
{"cannot connect", "no se puede conectar"},
{"http out proxy not implemented", "proxy externo http no implementado"},
{"cannot connect to upstream http proxy", "no se puede conectar al proxy http principal"},
{"Failed to connect", "Error al conectar"},
{"SOCKS proxy error", "Error de proxy SOCKS"},
{"Failed to send request to upstream", "No se pudo enviar petición al principal"},
{"No reply from SOCKS proxy", "Sin respuesta del proxy SOCKS"},
{"Cannot connect", "No se puede conectar"},
{"HTTP out proxy not implemented", "Proxy externo HTTP no implementado"},
{"Cannot connect to upstream HTTP proxy", "No se puede conectar al proxy HTTP principal"},
{"Host is down", "Servidor caído"},
{"Can't create connection to requested host, it may be down. Please try again later.", "No se puede crear la conexión al servidor solicitado, puede estar caído. Intente de nuevo más tarde."},
{"", ""},
@@ -199,10 +187,10 @@ namespace spanish // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"día", "días"}},
{"hours", {"hora", "horas"}},
{"minutes", {"minuto", "minutos"}},
{"seconds", {"segundo", "segundos"}},
{"%d days", {"%d día", "%d días"}},
{"%d hours", {"%d hora", "%d horas"}},
{"%d minutes", {"%d minuto", "%d minutos"}},
{"%d seconds", {"%d segundo", "%d segundos"}},
{"", {"", ""}},
};

220
i18n/Swedish.cpp Normal file
View File

@@ -0,0 +1,220 @@
/*
* Copyright (c) 2023, 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"
// Swedish localization file
namespace i2p
{
namespace i18n
{
namespace swedish // language namespace
{
// language name in lowercase
static std::string language = "swedish";
// 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
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "bygger"},
{"failed", "misslyckad"},
{"expiring", "utgår"},
{"established", "upprättad"},
{"unknown", "okänt"},
{"exploratory", "utforskande"},
{"Purple I2P Webconsole", "Purple I2P Webbkonsoll"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b>-Webbkonsoll"},
{"Main page", "Huvudsida"},
{"Router commands", "Routerkommandon"},
{"Local Destinations", "Lokala Platser"},
{"LeaseSets", "Hyresuppsättningar"},
{"Tunnels", "Tunnlar"},
{"Transit Tunnels", "Förmedlande Tunnlar"},
{"Transports", "Transporter"},
{"I2P tunnels", "I2P-tunnlar"},
{"SAM sessions", "SAM-perioder"},
{"ERROR", "FEL"},
{"OK", "OK"},
{"Testing", "Prövar"},
{"Firewalled", "Bakom Brandvägg"},
{"Unknown", "Okänt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
{"Clock skew", "Tidsförskjutning"},
{"Offline", "Nedkopplad"},
{"Symmetric NAT", "Symmetrisk NAT"},
{"Full cone NAT", "Full kon NAT"},
{"No Descriptors", "Inga Beskrivningar"},
{"Uptime", "Upptid"},
{"Network status", "Nätverkstillstånd"},
{"Network status v6", "Nätverkstillstånd v6"},
{"Stopping in", "Avstängd om"},
{"Family", "Familj"},
{"Tunnel creation success rate", "Andel framgångsrika tunnlar"},
{"Received", "Mottaget"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Skickat"},
{"Transit", "Förmedlat"},
{"Data path", "Sökväg"},
{"Hidden content. Press on text to see.", "Dolt innehåll. Tryck för att visa."},
{"Router Ident", "Routeridentitet"},
{"Router Family", "Routerfamilj"},
{"Router Caps", "Routerbegränsningar"},
{"Version", "Version"},
{"Our external address", "Vår externa adress"},
{"supported", "stöds"},
{"Routers", "Routrar"},
{"Floodfills", "Översvämningsfyllare"},
{"Client Tunnels", "Klienttunnlar"},
{"Services", "Tjänster"},
{"Enabled", "Påslaget"},
{"Disabled", "Avslaget"},
{"Encrypted B33 address", "Krypterad B33-Adress"},
{"Address registration line", "Adressregistreringsrad"},
{"Domain", "Domän"},
{"Generate", "Skapa"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Uppmärksamma:</b> den resulterande strängen kan enbart användas för att registrera 2LD-domäner (exempel.i2p). För att registrera underdomäner, vänligen använd i2pd-tools."},
{"Address", "Adress"},
{"Type", "Typ"},
{"EncType", "EncTyp"},
{"Inbound tunnels", "Ingående Tunnlar"},
{"%dms", "%dms"},
{"Outbound tunnels", "Utgående Tunnlar"},
{"Tags", "Taggar"},
{"Incoming", "Ingående"},
{"Outgoing", "Utgående"},
{"Destination", "Plats"},
{"Amount", "Mängd"},
{"Incoming Tags", "Ingående Taggar"},
{"Tags sessions", "Tagg-perioder"},
{"Status", "Tillstånd"},
{"Local Destination", "Lokal Plats"},
{"Streams", "Strömmar"},
{"Close stream", "Stäng strömmen"},
{"Such destination is not found", "En sådan plats hittas ej"},
{"I2CP session not found", "I2CP-period hittades inte"},
{"I2CP is not enabled", "I2CP är inte påslaget"},
{"Invalid", "Ogiltig"},
{"Store type", "Lagringstyp"},
{"Expires", "Utgångsdatum"},
{"Non Expired Leases", "Ickeutgångna Hyresuppsättningar"},
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "EndDate"},
{"floodfill mode is disabled", "Floodfill läget är inaktiverat"},
{"Queue size", "Köstorlek"},
{"Run peer test", "Utför utsiktstest"},
{"Reload tunnels configuration", "Ladda om tunnelkonfiguration"},
{"Decline transit tunnels", "Avvisa förmedlande tunnlar"},
{"Accept transit tunnels", "Tillåt förmedlande tunnlar"},
{"Cancel graceful shutdown", "Avbryt välvillig avstängning"},
{"Start graceful shutdown", "Påbörja välvillig avstängning"},
{"Force shutdown", "Tvingad avstängning"},
{"Reload external CSS styles", "Ladda om externa CSS-stilar"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Uppmärksamma:</b> inga ändringar här är beständiga eller påverkar dina inställningsfiler."},
{"Logging level", "Protokollförningsnivå"},
{"Transit tunnels limit", "Begränsa förmedlande tunnlar"},
{"Change", "Ändra"},
{"Change language", "Ändra språk"},
{"no transit tunnels currently built", "inga förmedlande tunnlar har byggts"},
{"SAM disabled", "SAM avslaget"},
{"no sessions currently running", "inga perioder igång"},
{"SAM session not found", "SAM-perioder hittades ej"},
{"SAM Session", "SAM-period"},
{"Server Tunnels", "Värdtunnlar"},
{"Client Forwards", "Klientförpassningar"},
{"Server Forwards", "Värdförpassningar"},
{"Unknown page", "Okänd sida"},
{"Invalid token", "Ogiltig polett"},
{"SUCCESS", "FRAMGÅNG"},
{"Stream closed", "Ström stängd"},
{"Stream not found or already was closed", "Strömmen hittades inte eller var redan avslutad"},
{"Destination not found", "Plats hittades ej"},
{"StreamID can't be null", "Ström-ID kan inte vara null"},
{"Return to destination page", "Återvänd till platssidan"},
{"You will be redirected in %d seconds", "Du omdirigeras inom %d sekunder"},
{"Transit tunnels count must not exceed %d", "Förmedlande tunnlar får inte överstiga %d"},
{"Back to commands list", "Tillbaka till kommandolistan"},
{"Register at reg.i2p", "Registrera vid reg.i2p"},
{"Description", "Beskrivning"},
{"A bit information about service on domain", "Ett stycke information om domänens tjänst"},
{"Submit", "Skicka"},
{"Domain can't end with .b32.i2p", "Domänen får inte sluta med .b32.i2p"},
{"Domain must end with .i2p", "Domänen måste sluta med .i2p"},
{"Unknown command", "Okänt kommando"},
{"Command accepted", "Kommando accepterades"},
{"Proxy error", "Proxyfel"},
{"Proxy info", "Proxyinfo"},
{"Proxy error: Host not found", "Proxyfel: Värden hittades ej"},
{"Remote host not found in router's addressbook", "Främmande värd hittades inte i routerns adressbok"},
{"You may try to find this host on jump services below", "Du kan försöka att hitta värden genom hopptjänsterna nedan"},
{"Invalid request", "Ogiltig förfrågan"},
{"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"},
{"Addresshelper is not supported", "Adresshjälparen stöds ej"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. <b>Var försiktig: källan till denna URL kan vara skadlig!</b> Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
{"Addresshelper forced update rejected", "Tvingad uppdatering av adresshjälparen nekad"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "För att lägga till värd <b>%s</b> i routerns adressbok, klicka här: <a href=\"%s%s%s\">Fortsätt</a>."},
{"Addresshelper request", "Adresshjälpare förfrågan"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Värd %s tillagd i routerns adressbok från hjälparen. Klicka här för att fortsätta: <a href=\"%s\">Fortsätt</a>."},
{"Addresshelper adding", "Adresshjälpare tilläggning"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
{"Addresshelper update", "Adresshjälpare uppdatering"},
{"Invalid request URI", "Ogiltig förfrågnings-URI"},
{"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"},
{"Outproxy failure", "Utproxyfel"},
{"Bad outproxy settings", "Ogiltig utproxyinställning"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Värd %s är inte inom I2P-näverket, men utproxy är inte påslaget"},
{"Unknown outproxy URL", "okänt Utproxy-URL"},
{"Cannot resolve upstream proxy", "Hittar inte uppströmsproxyt"},
{"Hostname is too long", "Värdnamnet är för långt"},
{"Cannot connect to upstream SOCKS proxy", "Kan inte ansluta till uppström SOCKS-proxy"},
{"Cannot negotiate with SOCKS proxy", "Kan inte förhandla med SOCKSproxyt"},
{"CONNECT error", "CONNECT-fel"},
{"Failed to connect", "Anslutningen misslyckades"},
{"SOCKS proxy error", "SOCKSproxyfel"},
{"Failed to send request to upstream", "Förfrågan uppströms kunde ej skickas"},
{"No reply from SOCKS proxy", "Fick inget svar från SOCKSproxyt"},
{"Cannot connect", "Kan inte ansluta"},
{"HTTP out proxy not implemented", "HTTP-Utproxy ej implementerat"},
{"Cannot connect to upstream HTTP proxy", "Kan inte ansluta till uppströms HTTP-proxy"},
{"Host is down", "Värden är nere"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Kan inte ansluta till värden, den kan vara nere. Vänligen försök senare."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d dag", "%d dagar"}},
{"%d hours", {"%d timme", "%d timmar"}},
{"%d minutes", {"%d minut", "%d minuter"}},
{"%d seconds", {"%d sekund", "%d sekunder"}},
{"", {"", ""}},
};
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

114
i18n/Turkish.cpp Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2023, 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"
// Turkish localization file
namespace i2p
{
namespace i18n
{
namespace turkish // language namespace
{
// language name in lowercase
static std::string language = "turkish";
// 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
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "kuruluyor"},
{"failed", "başarısız"},
{"expiring", "süresi geçiyor"},
{"established", "kurulmuş"},
{"unknown", "bilinmeyen"},
{"Purple I2P Webconsole", "Mor I2P Webkonsolu"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> webkonsolu"},
{"Main page", "Ana sayfa"},
{"Router commands", "Router komutları"},
{"Local Destinations", "Yerel Hedefler"},
{"Tunnels", "Tüneller"},
{"Transit Tunnels", "Transit Tünelleri"},
{"Transports", "Taşıma"},
{"I2P tunnels", "I2P tünelleri"},
{"SAM sessions", "SAM oturumları"},
{"ERROR", "HATA"},
{"OK", "TAMAM"},
{"Testing", "Test ediliyor"},
{"Firewalled", "Güvenlik Duvarı Kısıtlaması"},
{"Unknown", "Bilinmeyen"},
{"Proxy", "Proxy"},
{"Clock skew", "Saat sorunu"},
{"Offline", "Çevrimdışı"},
{"Symmetric NAT", "Simetrik NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Tanımlayıcı Yok"},
{"Uptime", "Bağlantı süresi"},
{"Network status", "Ağ durumu"},
{"Network status v6", "Ağ durumu v6"},
{"Family", "Aile"},
{"Tunnel creation success rate", "Tünel oluşturma başarı oranı"},
{"Received", "Alındı"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Gönderildi"},
{"Transit", "Transit"},
{"Data path", "Veri yolu"},
{"Hidden content. Press on text to see.", "Gizlenmiş içerik. Görmek için yazıya tıklayınız."},
{"Router Family", "Router Familyası"},
{"Decline transit tunnels", "Transit tünellerini reddet"},
{"Accept transit tunnels", "Transit tünellerini kabul et"},
{"Cancel graceful shutdown", "Düzgün durdurmayı iptal Et"},
{"Start graceful shutdown", "Düzgün durdurmayı başlat"},
{"Force shutdown", "Durdurmaya zorla"},
{"Reload external CSS styles", "Harici CSS stilini yeniden yükle"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Not:</b> burada yapılan ayarların hiçbiri kalıcı değildir ve ayar dosyalarınızı değiştirmez."},
{"Logging level", "Kayıt tutma seviyesi"},
{"Transit tunnels limit", "Transit tünel limiti"},
{"Change", "Değiştir"},
{"Change language", "Dil değiştir"},
{"no transit tunnels currently built", "kurulmuş bir transit tüneli bulunmamakta"},
{"SAM disabled", "SAM devre dışı"},
{"no sessions currently running", "hiçbir oturum şu anda çalışmıyor"},
{"SAM session not found", "SAM oturumu bulunamadı"},
{"SAM Session", "SAM oturumu"},
{"Server Tunnels", "Sunucu Tünelleri"},
{"Unknown page", "Bilinmeyen sayfa"},
{"Invalid token", "Geçersiz token"},
{"SUCCESS", "BAŞARILI"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d gün", "%d gün"}},
{"%d hours", {"%d saat", "%d saat"}},
{"%d minutes", {"%d dakika", "%d dakika"}},
{"%d seconds", {"%d saniye", "%d saniye"}},
{"", {"", ""}},
};
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) 2021-2022, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@ namespace turkmen // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "bina"},
{"failed", "şowsuz"},
{"expiring", "möhleti gutarýar"},
{"established", "işleýär"},
{"unknown", "näbelli"},
{"exploratory", "gözleg"},
{"Purple I2P Webconsole", "Web konsoly Purple I2P"},
{"<b>i2pd</b> webconsole", "Web konsoly <b>i2pd</b>"},
{"Main page", "Esasy sahypa"},
{"Router commands", "Marşrutizator buýruklary"},
@@ -57,7 +58,6 @@ namespace turkmen // language namespace
{"Unknown", "Näbelli"},
{"Proxy", "Proksi"},
{"Mesh", "MESH-tor"},
{"Error", "Ýalňyşlyk"},
{"Clock skew", "Takyk wagt däl"},
{"Offline", "Awtonom"},
{"Symmetric NAT", "Simmetriklik NAT"},
@@ -68,7 +68,7 @@ namespace turkmen // language namespace
{"Family", "Maşgala"},
{"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"},
{"Received", "Alnan"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Ýerleşdirildi"},
{"Transit", "Tranzit"},
{"Data path", "Maglumat ýoly"},
@@ -94,7 +94,7 @@ namespace turkmen // language namespace
{"Type", "Görnüş"},
{"EncType", "Şifrlemek görnüşi"},
{"Inbound tunnels", "Gelýän tuneller"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Çykýan tuneller"},
{"Tags", "Bellikler"},
{"Incoming", "Gelýän"},
@@ -116,7 +116,6 @@ namespace turkmen // language namespace
{"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ň"},
@@ -146,8 +145,6 @@ namespace turkmen // language namespace
{"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"},
@@ -165,32 +162,24 @@ namespace turkmen // language namespace
{"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"},
{"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"},
{"Bad outproxy settings", "Daşarky Daşarky proksi sazlamalary nädogry"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Adres %s 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 is 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"},
{"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 SOCKS 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 jorap HTTP proksi bilen birigip bolmaýar"},
{"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ň."},
{"", ""},
@@ -198,10 +187,10 @@ namespace turkmen // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"gün", "gün"}},
{"hours", {"sagat", "sagat"}},
{"minutes", {"minut", "minut"}},
{"seconds", {"sekunt", "sekunt"}},
{"%d days", {"%d gün", "%d gün"}},
{"%d hours", {"%d sagat", "%d sagat"}},
{"%d minutes", {"%d minut", "%d minut"}},
{"%d seconds", {"%d sekunt", "%d sekunt"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@ namespace ukrainian // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "КіБ"},
{"MiB", "МіБ"},
{"GiB", "ГіБ"},
{"%.2f KiB", "%.2f КіБ"},
{"%.2f MiB", "%.2f МіБ"},
{"%.2f GiB", "%.2f ГіБ"},
{"building", "будується"},
{"failed", "невдалий"},
{"expiring", "завершується"},
{"established", "працює"},
{"unknown", "невідомо"},
{"exploratory", "дослідницький"},
{"Purple I2P Webconsole", "Веб-консоль Purple I2P"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Головна"},
{"Router commands", "Команди маршрутизатора"},
@@ -57,18 +58,20 @@ namespace ukrainian // language namespace
{"Unknown", "Невідомо"},
{"Proxy", "Проксі"},
{"Mesh", "MESH-мережа"},
{"Error", "Помилка"},
{"Clock skew", "Неточний час"},
{"Offline", "Офлайн"},
{"Symmetric NAT", "Симетричний NAT"},
{"Full cone NAT", "Повний NAT"},
{"No Descriptors", "Немає Описів"},
{"Uptime", "У мережі"},
{"Network status", "Мережевий статус"},
{"Network status v6", "Мережевий статус v6"},
{"Stopping in", "Зупинка через"},
{"Family", "Сімейство"},
{"Tunnel creation success rate", "Успішно побудованих тунелів"},
{"Total tunnel creation success rate", "Загальна кількість створених тунелів"},
{"Received", "Отримано"},
{"KiB/s", "КіБ/с"},
{"%.2f KiB/s", "%.2f КіБ/с"},
{"Sent", "Відправлено"},
{"Transit", "Транзит"},
{"Data path", "Шлях до даних"},
@@ -93,8 +96,9 @@ namespace ukrainian // language namespace
{"Address", "Адреса"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Expire LeaseSet", "Завершити LeaseSet"},
{"Inbound tunnels", "Вхідні тунелі"},
{"ms", "мс"},
{"%dms", "%dмс"},
{"Outbound tunnels", "Вихідні тунелі"},
{"Tags", "Теги"},
{"Incoming", "Вхідні"},
@@ -107,6 +111,7 @@ namespace ukrainian // language namespace
{"Local Destination", "Локальні Призначення"},
{"Streams", "Потоки"},
{"Close stream", "Закрити потік"},
{"Such destination is not found", "Така точка призначення не знайдена"},
{"I2CP session not found", "I2CP сесія не знайдена"},
{"I2CP is not enabled", "I2CP не увікнуто"},
{"Invalid", "Некоректний"},
@@ -116,9 +121,10 @@ namespace ukrainian // language namespace
{"Gateway", "Шлюз"},
{"TunnelID", "ID тунеля"},
{"EndDate", "Закінчується"},
{"not floodfill", "не флудфіл"},
{"floodfill mode is disabled", "режим floodfill вимкнено"},
{"Queue size", "Розмір черги"},
{"Run peer test", "Запустити тестування"},
{"Reload tunnels configuration", "Перезавантажити налаштування тунелів"},
{"Decline transit tunnels", "Відхиляти транзитні тунелі"},
{"Accept transit tunnels", "Ухвалювати транзитні тунелі"},
{"Cancel graceful shutdown", "Скасувати плавну зупинку"},
@@ -146,8 +152,10 @@ namespace ukrainian // language namespace
{"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"},
{"You will be redirected in %d seconds", "Ви будете переадресовані через %d секунд"},
{"LeaseSet expiration time updated", "Час закінчення LeaseSet оновлено"},
{"LeaseSet is not found or already expired", "LeaseSet не знайдено або вже закінчився"},
{"Transit tunnels count must not exceed %d", "Кількість транзитних тунелів не повинна перевищувати %d"},
{"Back to commands list", "Повернутися до списку команд"},
{"Register at reg.i2p", "Зареєструвати на reg.i2p"},
{"Description", "Опис"},
@@ -155,7 +163,6 @@ namespace ukrainian // language namespace
{"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", "Помилка проксі"},
@@ -165,32 +172,33 @@ namespace ukrainian // language namespace
{"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 запиту"},
{"Addresshelper is not supported", "Адресна книга не підтримується"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Хост %s <font color=red>вже в адресній книзі маршрутизатора</font>. <b>Будьте обережні: джерело цієї адреси може зашкодити!</b> Натисніть тут, щоб оновити запис: <a href=\"%s%s%s&update=true\">Продовжити</a>."},
{"Addresshelper forced update rejected", "Адресна книга відхилила примусове оновлення"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Щоб додати хост <b>%s</b> в адресі маршрутизатора, натисніть тут: <a href=\"%s%s%s\"родовжити</a>."},
{"Addresshelper request", "Запит на адресну сторінку"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Хост %s доданий в адресну книгу маршрутизатора від помічника. Натисніть тут, щоб продовжити: <a href=\"%s\">Продовжити</a>."},
{"Addresshelper adding", "Адреса додана"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Хост %s <font color=red>вже в адресній книзі маршрутизатора</font>. Натисніть тут, щоб оновити запис: <a href=\"%s%s%s&update=true\">Продовжити</a>."},
{"Addresshelper update", "Оновлення адресної книги"},
{"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 проксі"},
{"Bad outproxy settings", "Некоректні налаштування зовнішнього проксі"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Адрес %s не в I2P мережі, але зовнішній проксі не включений"},
{"Unknown outproxy URL", "Невідомий URL зовнішнього проксі"},
{"Cannot resolve upstream proxy", "Не вдається визначити висхідний проксі"},
{"Hostname is 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 проксі сервера"},
{"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.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."},
{"", ""},
@@ -198,10 +206,10 @@ namespace ukrainian // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"день", "дня", "днів"}},
{"hours", {"годину", "години", "годин"}},
{"minutes", {"хвилину", "хвилини", "хвилин"}},
{"seconds", {"секунду", "секунди", "секунд"}},
{"%d days", {"%d день", "%d дня", "%d днів"}},
{"%d hours", {"%d годину", "%d години", "%d годин"}},
{"%d minutes", {"%d хвилину", "%d хвилини", "%d хвилин"}},
{"%d seconds", {"%d секунду", "%d секунди", "%d секунд"}},
{"", {"", "", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, The PurpleI2P Project
* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@ namespace uzbek // language namespace
static std::map<std::string, std::string> strings
{
{"KiB", "KiB"},
{"MiB", "MiB"},
{"GiB", "GiB"},
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "yaratilmoqda"},
{"failed", "muvaffaqiyatsiz"},
{"expiring", "muddati tugaydi"},
{"established", "aloqa o'rnatildi"},
{"unknown", "noma'lum"},
{"exploratory", "tadqiqiy"},
{"Purple I2P Webconsole", "Veb-konsoli Purple I2P"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> veb-konsoli"},
{"Main page", "Asosiy sahifa"},
{"Router commands", "Router buyruqlari"},
@@ -57,18 +58,20 @@ namespace uzbek // language namespace
{"Unknown", "Notanish"},
{"Proxy", "Proksi"},
{"Mesh", "Mesh To'r"},
{"Error", "Xato"},
{"Clock skew", "Aniq vaqt emas"},
{"Offline", "Oflayn"},
{"Symmetric NAT", "Simmetrik NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Deskriptorlar yo'q"},
{"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"},
{"Total tunnel creation success rate", "Tunnel yaratishning umumiy muvaffaqiyat darajasi"},
{"Received", "Qabul qilindi"},
{"KiB/s", "KiB/s"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Yuborilgan"},
{"Transit", "Tranzit"},
{"Data path", "Ma'lumotlar joylanishi"},
@@ -93,8 +96,9 @@ namespace uzbek // language namespace
{"Address", "Manzil"},
{"Type", "Turi"},
{"EncType", "ShifrlashTuri"},
{"Expire LeaseSet", "LeaseSet muddati tugaydi"},
{"Inbound tunnels", "Kirish tunnellari"},
{"ms", "ms"},
{"%dms", "%dms"},
{"Outbound tunnels", "Chiquvchi tunnellar"},
{"Tags", "Teglar"},
{"Incoming", "Kiruvchi"},
@@ -107,6 +111,7 @@ namespace uzbek // language namespace
{"Local Destination", "Mahalliy joylanish"},
{"Streams", "Strim"},
{"Close stream", "Strimni o'chirish"},
{"Such destination is not found", "Bunday yo'nalish topilmadi"},
{"I2CP session not found", "I2CP sessiyasi topilmadi"},
{"I2CP is not enabled", "I2CP yoqilmagan"},
{"Invalid", "Noto'g'ri"},
@@ -116,9 +121,10 @@ namespace uzbek // language namespace
{"Gateway", "Kirish yo'li"},
{"TunnelID", "TunnelID"},
{"EndDate", "Tugash Sanasi"},
{"not floodfill", "floodfill emas"},
{"floodfill mode is disabled", "floodfill rejimi o'chirilgan"},
{"Queue size", "Navbat hajmi"},
{"Run peer test", "Sinovni boshlang"},
{"Reload tunnels configuration", "Tunnel konfiguratsiyasini qayta yuklash"},
{"Decline transit tunnels", "Tranzit tunnellarini rad etish"},
{"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"},
{"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qilish"},
@@ -146,8 +152,10 @@ namespace uzbek // language namespace
{"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"},
{"You will be redirected in %d seconds", "Siz %d soniyadan song boshqa yonalishga yonaltirilasiz"},
{"LeaseSet expiration time updated", "LeaseSet amal qilish muddati yangilandi"},
{"LeaseSet is not found or already expired", "LeaseSet topilmadi yoki muddati tugagan"},
{"Transit tunnels count must not exceed %d", "Tranzit tunnellar soni %d dan oshmasligi kerak"},
{"Back to commands list", "Buyruqlar ro'yxatiga qaytish"},
{"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"},
{"Description", "Tavsif"},
@@ -155,7 +163,6 @@ namespace uzbek // language namespace
{"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"},
@@ -165,32 +172,33 @@ namespace uzbek // language namespace
{"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"},
{"Addresshelper is not supported", "Addresshelper qo'llab-quvvatlanmaydi"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "%s xosti <font color=red>allaqachon routerning manzillar kitobida</font>. <b>Ehtiyot bo'ling: bu URL manbasi zararli bo'lishi mumkin!</b> Yozuvni yangilash uchun bu yerni bosing: <a href=\"%s%s%s&update=true\">Davom etish</a>."},
{"Addresshelper forced update rejected", "Addresshelperni majburiy yangilash rad etildi"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Routerning manzillar kitobiga <b>%s</b> xostini qo'shish uchun bu yerni bosing: <a href=\"%s%s%s\">Davom etish</a>."},
{"Addresshelper request", "Addresshelper so'rovi"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Yordamchidan router manzillar kitobiga %s xost qoshildi. Davom etish uchun bu yerga bosing: <a href=\"%s\">Davom etish</a>."},
{"Addresshelper adding", "Addresshelperni qo'shish"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "%s xosti <font color=red>allaqachon routerning manzillar kitobida</font>. Yozuvni yangilash uchun shu yerni bosing: <a href=\"%s%s%s&update=true\">Davom etish</a>."},
{"Addresshelper update", "Addresshelperni yangilash"},
{"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"},
{"Bad outproxy settings", "Noto'g'ri tashqi proksi-server sozlamalari"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Xost %s 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 is 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"},
{"Failed to connect", "Ulanib bo'lmayapti"},
{"SOCKS proxy error", "'SOCKS proxy' xatosi"},
{"Failed to send request to upstream", "Yuqori 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'ga 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."},
{"", ""},
@@ -198,10 +206,10 @@ namespace uzbek // language namespace
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"kun", "kun"}},
{"hours", {"soat", "soat"}},
{"minutes", {"daqiqa", "daqiqa"}},
{"seconds", {"soniya", "soniya"}},
{"%d days", {"%d kun", "%d kun"}},
{"%d hours", {"%d soat", "%d soat"}},
{"%d minutes", {"%d daqiqa", "%d daqiqa"}},
{"%d seconds", {"%d soniya", "%d soniya"}},
{"", {"", ""}},
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -28,6 +28,11 @@ namespace data
return T32;
}
bool IsBase32 (char ch)
{
return (ch >= 'a' && ch <= 'z') || (ch >= '2' && ch <= '7');
}
static void iT64Build(void);
/*
@@ -55,6 +60,11 @@ namespace data
return T64;
}
bool IsBase64 (char ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '-' || ch == '~';
}
/*
* Reverse Substitution Table (built in run time)
*/
@@ -187,6 +197,9 @@ namespace data
else
return 0;
if(*InBuffer == P64)
return 0;
ps = (unsigned char *)(InBuffer + InCount - 1);
while ( *ps-- == P64 )
outCount--;
@@ -269,7 +282,7 @@ namespace data
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen)
{
int tmp = 0, bits = 0;
unsigned int tmp = 0, bits = 0;
size_t ret = 0;
for (size_t i = 0; i < len; i++)
{
@@ -298,7 +311,7 @@ namespace data
size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen)
{
size_t ret = 0, pos = 1;
int bits = 8, tmp = inBuf[0];
unsigned int bits = 8, tmp = inBuf[0];
while (ret < outLen && (bits > 0 || pos < len))
{
if (bits < 5)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -19,9 +19,11 @@ namespace data {
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
const char * GetBase32SubstitutionTable ();
const char * GetBase64SubstitutionTable ();
bool IsBase64 (char ch);
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
bool IsBase32 (char ch);
/**
* Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -7,52 +7,62 @@
*/
#include "CPU.h"
#if defined(__x86_64__) || defined(__i386__)
#include <cpuid.h>
#endif
#include "Log.h"
#ifndef bit_AES
#define bit_AES (1 << 25)
#endif
#ifndef bit_AVX
#define bit_AVX (1 << 28)
#define bit_AES (1 << 25)
#endif
#if defined(__GNUC__) && __GNUC__ < 6 && IS_X86
#include <cpuid.h>
#endif
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace i2p
{
namespace cpu
{
bool aesni = false;
bool avx = false;
void Detect(bool AesSwitch, bool AvxSwitch, bool force)
inline bool cpu_support_aes()
{
#if defined(__x86_64__) || defined(__i386__)
int info[4];
__cpuid(0, info[0], info[1], info[2], info[3]);
if (info[0] >= 0x00000001) {
__cpuid(0x00000001, info[0], info[1], info[2], info[3]);
#if defined (_WIN32) && (WINVER == 0x0501) // WinXP
if (AesSwitch && force) { // only if forced
#else
if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) {
#endif
aesni = true;
}
#if defined (_WIN32) && (WINVER == 0x0501) // WinXP
if (AvxSwitch && force) { // only if forced
#else
if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) {
#endif
avx = true;
}
#if IS_X86
#if defined(__clang__)
# if (__clang_major__ >= 6)
__builtin_cpu_init();
# endif
return __builtin_cpu_supports("aes");
#elif (defined(__GNUC__) && __GNUC__ >= 6)
__builtin_cpu_init();
return __builtin_cpu_supports("aes");
#elif (defined(__GNUC__) && __GNUC__ < 6)
int cpu_info[4];
bool flag = false;
__cpuid(0, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
if (cpu_info[0] >= 0x00000001) {
__cpuid(0x00000001, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
flag = ((cpu_info[2] & bit_AES) != 0);
}
return flag;
#elif defined(_MSC_VER)
int cpu_info[4];
__cpuid(cpu_info, 1);
return ((cpu_info[2] & bit_AES) != 0);
#endif
#endif
return false;
}
void Detect(bool AesSwitch, bool force)
{
if ((cpu_support_aes() && AesSwitch) || (AesSwitch && force)) {
aesni = true;
}
#endif // defined(__x86_64__) || defined(__i386__)
LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled"));
LogPrint(eLogInfo, "AVX ", (avx ? "enabled" : "disabled"));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -9,14 +9,31 @@
#ifndef LIBI2PD_CPU_H
#define LIBI2PD_CPU_H
#if defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IX86) || defined(__i386__)
# define IS_X86 1
# if defined(_M_AMD64) || defined(__x86_64__)
# define IS_X86_64 1
# else
# define IS_X86_64 0
# endif
#else
# define IS_X86 0
# define IS_X86_64 0
#endif
#if defined(__AES__) && !defined(_MSC_VER) && IS_X86
# define SUPPORTS_AES 1
#else
# define SUPPORTS_AES 0
#endif
namespace i2p
{
namespace cpu
{
extern bool aesni;
extern bool avx;
void Detect(bool AesSwitch, bool AvxSwitch, bool force);
void Detect(bool AesSwitch, bool force);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -45,7 +45,7 @@ namespace config {
("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)")
("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
("host", value<std::string>()->default_value(""), "External IP")
("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
@@ -77,7 +77,8 @@ namespace config {
limits.add_options()
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
("limits.transittunnels", value<uint16_t>()->default_value(5000), "Maximum active transit tunnels (default:5000)")
("limits.transittunnels", value<uint32_t>()->default_value(10000), "Maximum active transit tunnels (default:10000)")
("limits.zombies", value<double>()->default_value(0), "Minimum percentage of successfully created tunnels under which tunnel cleanup is paused (default [%]: 0.00)")
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")
@@ -95,6 +96,7 @@ namespace config {
("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 )")
("http.showTotalTCSR", value<bool>()->default_value(false), "Show additional value with total TCSR since router's start (default: false)")
;
options_description httpproxy("HTTP Proxy options");
@@ -148,7 +150,8 @@ namespace config {
sam.add_options()
("sam.enabled", value<bool>()->default_value(true), "Enable or disable SAM Application bridge")
("sam.address", value<std::string>()->default_value("127.0.0.1"), "SAM listen address")
("sam.port", value<uint16_t>()->default_value(7656), "SAM listen port")
("sam.port", value<uint16_t>()->default_value(7656), "SAM listen TCP port")
("sam.portudp", value<uint16_t>()->default_value(0), "SAM listen UDP port")
("sam.singlethread", value<bool>()->default_value(true), "Sessions run in the SAM bridge's thread")
;
@@ -190,7 +193,7 @@ namespace config {
options_description precomputation("Precomputation options");
precomputation.add_options()
("precomputation.elgamal",
#if defined(__x86_64__)
#if (defined(_M_AMD64) || defined(__x86_64__))
value<bool>()->default_value(false),
#else
value<bool>()->default_value(true),
@@ -214,17 +217,20 @@ namespace config {
"https://reseed.onion.im/,"
"https://i2pseed.creativecowpat.net:8443/,"
"https://reseed.i2pgit.org/,"
"https://i2p.novg.net/,"
"https://banana.incognet.io/,"
"https://reseed-pl.i2pd.xyz/,"
"https://www2.mk16.de/"
"https://www2.mk16.de/,"
"https://i2p.ghativega.in/,"
"https://i2p.novg.net/,"
"https://reseed.stormycloud.org/"
), "Reseed URLs, separated by comma")
("reseed.yggurls", value<std::string>()->default_value(
"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]/"
"http://[316:f9e0:f22e:a74f::216]/,"
"http://[300:eaff:7fab:181b::e621]:7170"
), "Reseed URLs through the Yggdrasil, separated by comma")
;
@@ -284,7 +290,7 @@ namespace config {
options_description nettime("Time sync options");
nettime.add_options()
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
("nettime.enabled", value<bool>()->default_value(false), "Enable NTP time sync (default: disabled)")
("nettime.ntpservers", value<std::string>()->default_value(
"0.pool.ntp.org,"
"1.pool.ntp.org,"
@@ -304,7 +310,7 @@ namespace config {
options_description cpuext("CPU encryption extensions options");
cpuext.add_options()
("cpuext.aesni", bool_switch()->default_value(true), "Use auto detection for AESNI CPU extensions. If false, AESNI will be not used")
("cpuext.avx", bool_switch()->default_value(true), "Use auto detection for AVX CPU extensions. If false, AVX will be not used")
("cpuext.avx", bool_switch()->default_value(false), "Deprecated option")
("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines")
;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -28,6 +28,7 @@
#include "I2PEndian.h"
#include "Log.h"
namespace i2p
{
namespace crypto
@@ -159,7 +160,7 @@ namespace crypto
// DH/ElGamal
#if !defined(__x86_64__)
#if !IS_X86_64
const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226;
const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1;
#endif
@@ -361,7 +362,7 @@ namespace crypto
BIGNUM * b1 = BN_CTX_get (ctx);
BIGNUM * b = BN_CTX_get (ctx);
// select random k
#if defined(__x86_64__)
#if IS_X86_64
BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64
#else
BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits
@@ -428,7 +429,7 @@ namespace crypto
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub)
{
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
#if IS_X86 || defined(_MSC_VER)
RAND_bytes (priv, 256);
#else
// lower 226 bits (28 bytes and 2 bits) only. short exponent
@@ -555,7 +556,7 @@ namespace crypto
}
// AES
#ifdef __AES__
#if SUPPORTS_AES
#define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \
@@ -580,7 +581,7 @@ namespace crypto
"movaps %%xmm3, "#round1"(%[sched]) \n"
#endif
#ifdef __AES__
#if SUPPORTS_AES
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
{
__asm__
@@ -621,7 +622,7 @@ namespace crypto
#endif
#ifdef __AES__
#if SUPPORTS_AES
#define EncryptAES256(sched) \
"pxor (%["#sched"]), %%xmm0 \n" \
"aesenc 16(%["#sched"]), %%xmm0 \n" \
@@ -642,16 +643,18 @@ namespace crypto
void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
);
(
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
:
: [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out)
: "%xmm0", "memory"
);
}
else
#endif
@@ -660,7 +663,7 @@ namespace crypto
}
}
#ifdef __AES__
#if SUPPORTS_AES
#define DecryptAES256(sched) \
"pxor 224(%["#sched"]), %%xmm0 \n" \
"aesdec 208(%["#sched"]), %%xmm0 \n" \
@@ -681,16 +684,18 @@ namespace crypto
void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
);
(
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
:
: [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out)
: "%xmm0", "memory"
);
}
else
#endif
@@ -699,7 +704,7 @@ namespace crypto
}
}
#ifdef __AES__
#if SUPPORTS_AES
#define CallAESIMC(offset) \
"movaps "#offset"(%[shed]), %%xmm0 \n" \
"aesimc %%xmm0, %%xmm0 \n" \
@@ -708,7 +713,7 @@ namespace crypto
void ECBEncryption::SetKey (const AESKey& key)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
ExpandKey (key);
@@ -722,28 +727,30 @@ namespace crypto
void ECBDecryption::SetKey (const AESKey& key)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
ExpandKey (key); // expand encryption key first
// then invert it using aesimc
__asm__
(
CallAESIMC(16)
CallAESIMC(32)
CallAESIMC(48)
CallAESIMC(64)
CallAESIMC(80)
CallAESIMC(96)
CallAESIMC(112)
CallAESIMC(128)
CallAESIMC(144)
CallAESIMC(160)
CallAESIMC(176)
CallAESIMC(192)
CallAESIMC(208)
: : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory"
);
(
CallAESIMC(16)
CallAESIMC(32)
CallAESIMC(48)
CallAESIMC(64)
CallAESIMC(80)
CallAESIMC(96)
CallAESIMC(112)
CallAESIMC(128)
CallAESIMC(144)
CallAESIMC(160)
CallAESIMC(176)
CallAESIMC(192)
CallAESIMC(208)
:
: [shed]"r"(GetKeySchedule ())
: "%xmm0", "memory"
);
}
else
#endif
@@ -754,28 +761,28 @@ namespace crypto
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%xmm0", "%xmm1", "cc", "memory"
);
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%xmm0", "%xmm1", "cc", "memory"
);
}
else
#endif
@@ -799,22 +806,22 @@ namespace crypto
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
"movups %%xmm0, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
"movups %%xmm0, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
}
else
#endif
@@ -823,29 +830,29 @@ namespace crypto
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
);
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
);
}
else
#endif
@@ -869,22 +876,22 @@ namespace crypto
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"movups %%xmm0, (%[iv]) \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
:
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"movups %%xmm0, (%[iv]) \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
:
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
}
else
#endif
@@ -893,34 +900,34 @@ namespace crypto
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
// encrypt IV
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
EncryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// encrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched_l)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "cc", "memory"
);
(
// encrypt IV
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
EncryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// encrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched_l)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "cc", "memory"
);
}
else
#endif
@@ -934,35 +941,35 @@ namespace crypto
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
#ifdef __AES__
#if SUPPORTS_AES
if(i2p::cpu::aesni)
{
__asm__
(
// decrypt IV
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
DecryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// decrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched_l)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
);
(
// decrypt IV
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
DecryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// decrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched_l)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
);
}
else
#endif
@@ -991,7 +998,7 @@ namespace crypto
EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce);
EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adLen);
EVP_EncryptUpdate(ctx, buf, &outlen, msg, msgLen);
EVP_EncryptFinal_ex(ctx, buf, &outlen);
EVP_EncryptFinal_ex(ctx, buf + outlen, &outlen);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, buf + msgLen);
}
else
@@ -1285,9 +1292,9 @@ namespace crypto
}
}*/
void InitCrypto (bool precomputation, bool aesni, bool avx, bool force)
void InitCrypto (bool precomputation, bool aesni, bool force)
{
i2p::cpu::Detect (aesni, avx, force);
i2p::cpu::Detect (aesni, force);
#if LEGACY_OPENSSL
SSL_library_init ();
#endif
@@ -1297,7 +1304,7 @@ namespace crypto
CRYPTO_set_locking_callback (OpensslLockingCallback);*/
if (precomputation)
{
#if defined(__x86_64__)
#if IS_X86_64
g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255];
PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES);
#else
@@ -1312,7 +1319,7 @@ namespace crypto
if (g_ElggTable)
{
DestroyElggTable (g_ElggTable,
#if defined(__x86_64__)
#if IS_X86_64
ELGAMAL_FULL_EXPONENT_NUM_BYTES
#else
ELGAMAL_SHORT_EXPONENT_NUM_BYTES

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -150,7 +150,7 @@ namespace crypto
};
#ifdef __AES__
#if SUPPORTS_AES
class ECBCryptoAESNI
{
public:
@@ -167,7 +167,7 @@ namespace crypto
};
#endif
#ifdef __AES__
#if SUPPORTS_AES
class ECBEncryption: public ECBCryptoAESNI
#else
class ECBEncryption
@@ -183,7 +183,7 @@ namespace crypto
AES_KEY m_Key;
};
#ifdef __AES__
#if SUPPORTS_AES
class ECBDecryption: public ECBCryptoAESNI
#else
class ECBDecryption
@@ -307,7 +307,7 @@ namespace crypto
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 InitCrypto (bool precomputation, bool aesni, bool force);
void TerminateCrypto ();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -19,7 +19,7 @@ namespace i2p
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)
m_Owner (owner), m_DefaultReceiver (nullptr), m_DefaultRawReceiver (nullptr), m_Gzip (gzip)
{
if (m_Gzip)
m_Deflator.reset (new i2p::data::GzipDeflator);
@@ -119,19 +119,79 @@ namespace datagram
void DatagramDestination::HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
if (m_RawReceiver)
m_RawReceiver (fromPort, toPort, buf, len);
auto r = FindRawReceiver(toPort);
if (r)
r (fromPort, toPort, buf, len);
else
LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram");
}
void DatagramDestination::SetReceiver (const Receiver& receiver, uint16_t port)
{
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
m_ReceiversByPorts[port] = receiver;
if (!m_DefaultReceiver) {
m_DefaultReceiver = receiver;
m_DefaultReceiverPort = port;
}
}
void DatagramDestination::ResetReceiver (uint16_t port)
{
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
m_ReceiversByPorts.erase (port);
if (m_DefaultReceiverPort == port) {
m_DefaultReceiver = nullptr;
m_DefaultReceiverPort = 0;
}
}
void DatagramDestination::SetRawReceiver (const RawReceiver& receiver, uint16_t port)
{
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
m_RawReceiversByPorts[port] = receiver;
if (!m_DefaultRawReceiver) {
m_DefaultRawReceiver = receiver;
m_DefaultRawReceiverPort = port;
}
}
void DatagramDestination::ResetRawReceiver (uint16_t port)
{
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
m_RawReceiversByPorts.erase (port);
if (m_DefaultRawReceiverPort == port) {
m_DefaultRawReceiver = nullptr;
m_DefaultRawReceiverPort = 0;
}
}
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
{
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
Receiver r = m_Receiver;
Receiver r = nullptr;
auto itr = m_ReceiversByPorts.find(port);
if (itr != m_ReceiversByPorts.end())
r = itr->second;
else {
r = m_DefaultReceiver;
}
return r;
}
DatagramDestination::RawReceiver DatagramDestination::FindRawReceiver(uint16_t port)
{
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
RawReceiver r = nullptr;
auto itr = m_RawReceiversByPorts.find(port);
if (itr != m_RawReceiversByPorts.end())
r = itr->second;
else {
r = m_DefaultRawReceiver;
}
return r;
}
@@ -425,7 +485,7 @@ namespace datagram
if (m)
send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m});
}
routingPath->outboundTunnel->SendTunnelDataMsg(send);
routingPath->outboundTunnel->SendTunnelDataMsgs(send);
}
m_SendQueue.clear();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -126,14 +126,12 @@ namespace datagram
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; };
void ResetReceiver () { m_Receiver = nullptr; };
void SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts[port] = receiver; };
void ResetReceiver (uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts.erase (port); };
void SetReceiver (const Receiver& receiver, uint16_t port);
void ResetReceiver (uint16_t port);
void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; };
void ResetRawReceiver () { m_RawReceiver = nullptr; };
void SetRawReceiver (const RawReceiver& receiver, uint16_t port);
void ResetRawReceiver (uint16_t port);
std::shared_ptr<DatagramSession::Info> GetInfoForRemote(const i2p::data::IdentHash & remote);
@@ -150,20 +148,26 @@ namespace datagram
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
Receiver FindReceiver(uint16_t port);
RawReceiver FindRawReceiver(uint16_t port);
private:
std::shared_ptr<i2p::client::ClientDestination> m_Owner;
Receiver m_Receiver; // default
RawReceiver m_RawReceiver; // default
bool m_Gzip; // gzip compression of data messages
std::mutex m_SessionsMutex;
std::map<i2p::data::IdentHash, DatagramSession_ptr > m_Sessions;
std::mutex m_ReceiversMutex;
std::map<uint16_t, Receiver> m_ReceiversByPorts;
Receiver m_DefaultReceiver;
RawReceiver m_DefaultRawReceiver;
uint16_t m_DefaultReceiverPort;
uint16_t m_DefaultRawReceiverPort;
std::mutex m_ReceiversMutex;
std::mutex m_RawReceiversMutex;
std::unordered_map<uint16_t, Receiver> m_ReceiversByPorts;
std::unordered_map<uint16_t, RawReceiver> m_RawReceiversByPorts;
bool m_Gzip; // gzip compression of data messages
i2p::data::GzipInflator m_Inflator;
std::unique_ptr<i2p::data::GzipDeflator> m_Deflator;
std::vector<uint8_t> m_From, m_Signature;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -108,7 +108,7 @@ namespace client
if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
m_AuthType = authType;
else
LogPrint (eLogError, "Destination: Unknown auth type ", authType);
LogPrint (eLogError, "Destination: Unknown auth type: ", authType);
}
}
it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY);
@@ -117,7 +117,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(eLogCritical, "Destination: Invalid value i2cp.leaseSetPrivKey: ", it->second);
m_LeaseSetPrivKey.reset (nullptr);
}
}
@@ -262,17 +262,6 @@ namespace client
return nullptr;
}
}
else
{
auto ls = i2p::data::netdb.FindLeaseSet (ident);
if (ls && !ls->IsExpired ())
{
ls->PopulateLeases (); // since we don't store them in netdb
std::lock_guard<std::mutex> _lock(m_RemoteLeaseSetsMutex);
m_RemoteLeaseSets[ident] = ls;
return ls;
}
}
return nullptr;
}
@@ -378,9 +367,12 @@ namespace client
HandleDataMessage (payload, len);
break;
case eI2NPDeliveryStatus:
// we assume tunnel tests non-encrypted
HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET));
break;
case eI2NPTunnelTest:
if (m_Pool)
m_Pool->ProcessTunnelTest (bufbe32toh (payload + TUNNEL_TEST_MSGID_OFFSET), bufbe64toh (payload + TUNNEL_TEST_TIMESTAMP_OFFSET));
break;
case eI2NPDatabaseStore:
HandleDatabaseStoreMessage (payload, len);
break;
@@ -399,6 +391,11 @@ namespace client
void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len)
{
if (len < DATABASE_STORE_HEADER_SIZE)
{
LogPrint (eLogError, "Destination: Database store msg is too short ", len);
return;
}
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
size_t offset = DATABASE_STORE_HEADER_SIZE;
if (replyToken)
@@ -406,8 +403,14 @@ namespace client
LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore");
offset += 36;
}
if (offset > len || len > i2p::data::MAX_LS_BUFFER_SIZE + offset)
{
LogPrint (eLogError, "Destination: Database store message is too long ", len);
return;
}
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
std::shared_ptr<LeaseSetRequest> request;
switch (buf[DATABASE_STORE_TYPE_OFFSET])
{
case i2p::data::NETDB_STORE_TYPE_LEASESET: // 1
@@ -463,31 +466,59 @@ namespace client
case i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2: // 5
{
auto it2 = m_LeaseSetRequests.find (key);
if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey)
{
auto ls2 = std::make_shared<i2p::data::LeaseSet2> (buf + offset, len - offset,
it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ());
if (ls2->IsValid ())
if (it2 != m_LeaseSetRequests.end ())
{
request = it2->second;
m_LeaseSetRequests.erase (it2);
if (request->requestedBlindedKey)
{
m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key
m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup
leaseSet = ls2;
auto ls2 = std::make_shared<i2p::data::LeaseSet2> (buf + offset, len - offset,
request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ());
if (ls2->IsValid () && !ls2->IsExpired ())
{
leaseSet = ls2;
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key
m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup
}
else
LogPrint (eLogError, "Destination: New remote encrypted LeaseSet2 failed");
}
else
{
// publishing verification doesn't have requestedBlindedKey
auto localLeaseSet = GetLeaseSetMt ();
if (localLeaseSet->GetStoreHash () == key)
{
auto ls = std::make_shared<i2p::data::LeaseSet2> (i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2,
localLeaseSet->GetBuffer (), localLeaseSet->GetBufferLen (), false);
leaseSet = ls;
}
else
LogPrint (eLogWarning, "Destination: Encrypted LeaseSet2 received for request without blinded key");
}
}
else
LogPrint (eLogInfo, "Destination: Couldn't find request for encrypted LeaseSet2");
LogPrint (eLogWarning, "Destination: Couldn't find request for encrypted LeaseSet2");
break;
}
default:
LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped");
}
auto it1 = m_LeaseSetRequests.find (key);
if (it1 != m_LeaseSetRequests.end ())
if (!request)
{
auto it1 = m_LeaseSetRequests.find (key);
if (it1 != m_LeaseSetRequests.end ())
{
request = it1->second;
m_LeaseSetRequests.erase (it1);
}
}
if (request)
{
it1->second->requestTimeoutTimer.cancel ();
if (it1->second) it1->second->Complete (leaseSet);
m_LeaseSetRequests.erase (it1);
request->requestTimeoutTimer.cancel ();
request->Complete (leaseSet);
}
}
@@ -500,38 +531,43 @@ namespace client
if (it != m_LeaseSetRequests.end ())
{
auto request = it->second;
bool found = false;
if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST)
for (int i = 0; i < num; i++)
{
for (int i = 0; i < num; i++)
i2p::data::IdentHash peerHash (buf + 33 + i*32);
if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash))
{
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");
i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory
}
}
auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded);
if (floodfill)
{
LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ());
if (SendLeaseSetRequest (key, floodfill, request))
found = true;
LogPrint (eLogInfo, "Destination: Found new floodfill, request it");
i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory
}
}
if (!found)
{
LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills");
request->Complete (nullptr);
m_LeaseSetRequests.erase (key);
}
SendNextLeaseSetRequest (key, request);
}
else
LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found");
}
void LeaseSetDestination::SendNextLeaseSetRequest (const i2p::data::IdentHash& key,
std::shared_ptr<LeaseSetRequest> request)
{
bool found = false;
if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST)
{
auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded);
if (floodfill)
{
LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ());
if (SendLeaseSetRequest (key, floodfill, request))
found = true;
}
}
if (!found)
{
LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills");
request->Complete (nullptr);
m_LeaseSetRequests.erase (key);
}
}
void LeaseSetDestination::HandleDeliveryStatusMessage (uint32_t msgID)
{
if (msgID == m_PublishReplyToken)
@@ -576,12 +612,7 @@ namespace client
shared_from_this (), std::placeholders::_1));
return;
}
if (!m_Pool->GetInboundTunnels ().size () || !m_Pool->GetOutboundTunnels ().size ())
{
LogPrint (eLogError, "Destination: Can't publish LeaseSet. Destination is not ready");
return;
}
auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetStoreHash (), m_ExcludedFloodfills);
if (!floodfill)
{
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
@@ -592,26 +623,39 @@ namespace client
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)
if (!m_Pool->GetInboundTunnels ().empty () && !m_Pool->GetOutboundTunnels ().empty ())
{
LogPrint (eLogInfo, "Destination: No compatible tunnels with ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another floodfill");
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetStoreHash (), m_ExcludedFloodfills);
if (floodfill)
{
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!inbound)
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
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 outbound tunnels");
}
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
}
else
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
LogPrint (eLogDebug, "Destination: No tunnels in pool");
if (!floodfill || !outbound || !inbound)
{
// we can't publish now
m_ExcludedFloodfills.clear ();
m_PublishReplyToken = 1; // dummy non-zero value
// try again after a while
LogPrint (eLogInfo, "Destination: Can't publish LeasetSet because destination is not ready. Try publishing again after ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds");
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
shared_from_this (), std::placeholders::_1));
return;
}
}
@@ -619,10 +663,19 @@ namespace client
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound));
auto s = shared_from_this ();
msg->onDrop = [s]()
{
s->GetService ().post([s]()
{
s->m_PublishConfirmationTimer.cancel ();
s->HandlePublishConfirmationTimer (boost::system::error_code());
});
};
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
shared_from_this (), std::placeholders::_1));
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg);
outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, msg);
m_LastSubmissionTime = ts;
}
@@ -635,7 +688,7 @@ namespace client
m_PublishReplyToken = 0;
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
{
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds or failed. will try again");
Publish ();
}
else
@@ -763,9 +816,17 @@ namespace client
request->requestTime = ts;
if (!SendLeaseSetRequest (dest, floodfill, request))
{
// request failed
m_LeaseSetRequests.erase (ret.first);
if (requestComplete) requestComplete (nullptr);
// try another
LogPrint (eLogWarning, "Destination: Couldn't send LeaseSet request to ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another");
request->excluded.insert (floodfill->GetIdentHash ());
floodfill = i2p::data::netdb.GetClosestFloodfill (dest, request->excluded);
if (!SendLeaseSetRequest (dest, floodfill, request))
{
// request failed
LogPrint (eLogWarning, "Destination: LeaseSet request for ", dest.ToBase32 (), " was not sent");
m_LeaseSetRequests.erase (ret.first);
if (requestComplete) requestComplete (nullptr);
}
}
}
else // duplicate
@@ -792,11 +853,11 @@ 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 (nullptr, nextFloodfill->GetCompatibleTransports (true));
if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found");
request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); // outbound from floodfill
if (!request->replyTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible inbound tunnels found");
if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ())
request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false));
if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found");
request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); // inbound from floodfill
if (!request->outboundTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible outbound tunnels found");
if (request->replyTunnel && request->outboundTunnel)
{
@@ -812,9 +873,18 @@ namespace client
AddECIESx25519Key (replyKey, replyTag);
else
AddSessionKey (replyKey, replyTag);
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
request->outboundTunnel->SendTunnelDataMsg (
auto msg = WrapMessageForRouter (nextFloodfill,
CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
auto s = shared_from_this ();
msg->onDrop = [s, dest, request]()
{
s->GetService ().post([s, dest, request]()
{
s->SendNextLeaseSetRequest (dest, request);
});
};
request->outboundTunnel->SendTunnelDataMsgs (
{
i2p::tunnel::TunnelMessageBlock
{
@@ -909,7 +979,7 @@ namespace client
bool isPublic, const std::map<std::string, std::string> * params):
LeaseSetDestination (service, isPublic, params),
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS),
m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), m_LastPort (0),
m_DatagramDestination (nullptr), m_RefCounter (0),
m_ReadyChecker(service)
{
@@ -979,7 +1049,7 @@ namespace client
m_StreamingAckDelay = std::stoi(it->second);
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
if (it != params->end ())
m_IsStreamingAnswerPings = (it->second == "true");
m_IsStreamingAnswerPings = std::stoi (it->second); // 1 for true
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
{
@@ -993,12 +1063,12 @@ namespace client
else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params);
else
LogPrint (eLogError, "Destination: Unexpected auth type ", authType);
LogPrint (eLogError, "Destination: Unexpected auth type: ", authType);
if (m_AuthKeys->size ())
LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read");
else
{
LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType);
LogPrint (eLogCritical, "Destination: No auth keys read for auth type: ", authType);
m_AuthKeys = nullptr;
}
}
@@ -1007,7 +1077,7 @@ namespace client
}
catch (std::exception & ex)
{
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
LogPrint(eLogCritical, "Destination: Unable to parse parameters for destination: ", ex.what());
}
}
@@ -1026,22 +1096,30 @@ namespace client
void ClientDestination::Stop ()
{
LogPrint(eLogDebug, "Destination: Stopping destination ", GetIdentHash().ToBase32(), ".b32.i2p");
LeaseSetDestination::Stop ();
m_ReadyChecker.cancel();
LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination");
m_StreamingDestination->Stop ();
//m_StreamingDestination->SetOwner (nullptr);
m_StreamingDestination = nullptr;
LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination by ports");
for (auto& it: m_StreamingDestinationsByPorts)
{
it.second->Stop ();
//it.second->SetOwner (nullptr);
}
m_StreamingDestinationsByPorts.clear ();
m_LastStreamingDestination = nullptr;
if (m_DatagramDestination)
{
LogPrint(eLogDebug, "Destination: -> Stopping Datagram Destination");
delete m_DatagramDestination;
m_DatagramDestination = nullptr;
}
LogPrint(eLogDebug, "Destination: -> Stopping done");
}
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len)
@@ -1061,9 +1139,15 @@ namespace client
case PROTOCOL_TYPE_STREAMING:
{
// streaming protocol
auto dest = GetStreamingDestination (toPort);
if (dest)
dest->HandleDataMessagePayload (buf, length);
if (toPort != m_LastPort || !m_LastStreamingDestination)
{
m_LastStreamingDestination = GetStreamingDestination (toPort);
if (!m_LastStreamingDestination)
m_LastStreamingDestination = m_StreamingDestination; // if no destination on port use default
m_LastPort = toPort;
}
if (m_LastStreamingDestination)
m_LastStreamingDestination->HandleDataMessagePayload (buf, length);
else
LogPrint (eLogError, "Destination: Missing streaming destination");
}
@@ -1087,7 +1171,7 @@ namespace client
}
}
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port)
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, uint16_t port)
{
if (!streamRequestComplete)
{
@@ -1117,7 +1201,7 @@ namespace client
}
}
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port)
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port)
{
if (!streamRequestComplete)
{
@@ -1136,35 +1220,41 @@ namespace client
}
template<typename Dest>
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStreamSync (const Dest& dest, int port)
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStreamSync (const Dest& dest, uint16_t port)
{
volatile bool done = false;
std::shared_ptr<i2p::stream::Stream> stream;
std::condition_variable streamRequestComplete;
std::mutex streamRequestCompleteMutex;
std::unique_lock<std::mutex> l(streamRequestCompleteMutex);
CreateStream (
[&streamRequestComplete, &streamRequestCompleteMutex, &stream](std::shared_ptr<i2p::stream::Stream> s)
[&done, &streamRequestComplete, &streamRequestCompleteMutex, &stream](std::shared_ptr<i2p::stream::Stream> s)
{
stream = s;
std::unique_lock<std::mutex> l(streamRequestCompleteMutex);
streamRequestComplete.notify_all ();
done = true;
},
dest, port);
streamRequestComplete.wait (l);
while (!done)
{
std::unique_lock<std::mutex> l(streamRequestCompleteMutex);
if (!done)
streamRequestComplete.wait (l);
}
return stream;
}
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (const i2p::data::IdentHash& dest, int port)
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (const i2p::data::IdentHash& dest, uint16_t port)
{
return CreateStreamSync (dest, port);
}
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port)
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port)
{
return CreateStreamSync (dest, port);
}
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, uint16_t port)
{
if (m_StreamingDestination)
return m_StreamingDestination->CreateNewOutgoingStream (remote, port);
@@ -1201,7 +1291,7 @@ namespace client
});
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::GetStreamingDestination (int port) const
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::GetStreamingDestination (uint16_t port) const
{
if (port)
{
@@ -1209,8 +1299,9 @@ namespace client
if (it != m_StreamingDestinationsByPorts.end ())
return it->second;
}
// if port is zero or not found, use default destination
return m_StreamingDestination;
else // if port is zero, use default destination
return m_StreamingDestination;
return nullptr;
}
void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor)
@@ -1238,7 +1329,7 @@ namespace client
m_StreamingDestination->AcceptOnce (acceptor);
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::CreateStreamingDestination (int port, bool gzip)
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::CreateStreamingDestination (uint16_t port, bool gzip)
{
auto dest = std::make_shared<i2p::stream::StreamingDestination> (GetSharedFromThis (), port, gzip);
if (port)
@@ -1248,7 +1339,7 @@ namespace client
return dest;
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::RemoveStreamingDestination (int port)
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::RemoveStreamingDestination (uint16_t port)
{
if (port)
{
@@ -1309,7 +1400,7 @@ namespace client
f1.write ((char *)keys->priv, 256);
return;
}
LogPrint(eLogError, "Destinations: Can't save keys to ", path);
LogPrint(eLogCritical, "Destinations: Can't save keys to ", path);
}
void ClientDestination::CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels)
@@ -1386,7 +1477,7 @@ namespace client
if (pubKey.FromBase64 (it.second.substr (pos+1)))
m_AuthKeys->push_back (pubKey);
else
LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1));
LogPrint (eLogCritical, "Destination: Unexpected auth key: ", it.second.substr (pos+1));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -14,6 +14,7 @@
#include <mutex>
#include <memory>
#include <map>
#include <unordered_map>
#include <set>
#include <string>
#include <functional>
@@ -175,6 +176,7 @@ namespace client
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey = nullptr);
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request);
void SendNextLeaseSetRequest (const i2p::data::IdentHash& key, std::shared_ptr<LeaseSetRequest> request);
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
void HandleCleanupTimer (const boost::system::error_code& ecode);
void CleanupRemoteLeaseSets ();
@@ -184,8 +186,8 @@ namespace client
boost::asio::io_service& m_Service;
mutable std::mutex m_RemoteLeaseSetsMutex;
std::map<i2p::data::IdentHash, std::shared_ptr<i2p::data::LeaseSet> > m_RemoteLeaseSets;
std::map<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> > m_LeaseSetRequests;
std::unordered_map<i2p::data::IdentHash, std::shared_ptr<i2p::data::LeaseSet> > m_RemoteLeaseSets;
std::unordered_map<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> > m_LeaseSetRequests;
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
std::mutex m_LeaseSetMutex;
@@ -241,15 +243,15 @@ namespace client
int GetRefCounter () const { return m_RefCounter; };
// 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);
std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (uint16_t port, bool gzip = true); // additional
std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (uint16_t port = 0) const;
std::shared_ptr<i2p::stream::StreamingDestination> RemoveStreamingDestination (uint16_t 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 (const i2p::data::IdentHash& dest, int port = 0); // sync
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port = 0); // sync
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, uint16_t port = 0);
void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port = 0);
std::shared_ptr<i2p::stream::Stream> CreateStream (const i2p::data::IdentHash& dest, uint16_t port = 0); // sync
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port = 0); // sync
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, uint16_t 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);
@@ -285,7 +287,7 @@ namespace client
void ReadAuthKey (const std::string& group, const std::map<std::string, std::string> * params);
template<typename Dest>
std::shared_ptr<i2p::stream::Stream> CreateStreamSync (const Dest& dest, int port);
std::shared_ptr<i2p::stream::Stream> CreateStreamSync (const Dest& dest, uint16_t port);
private:
@@ -297,6 +299,7 @@ namespace client
bool m_IsStreamingAnswerPings;
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
std::shared_ptr<i2p::stream::StreamingDestination> m_LastStreamingDestination; uint16_t m_LastPort; // for server tunnels
i2p::datagram::DatagramDestination * m_DatagramDestination;
int m_RefCounter; // how many clients(tunnels) use this destination

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -117,6 +117,12 @@ namespace garlic
return session->HandleNextMessage (buf, len, shared_from_this (), index);
}
bool ReceiveRatchetTagSet::IsSessionTerminated () const
{
return !m_Session || m_Session->IsTerminated ();
}
SymmetricKeyTagSet::SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key):
ReceiveRatchetTagSet (nullptr), m_Destination (destination)
{
@@ -335,7 +341,8 @@ namespace garlic
case eECIESx25519BlkAckRequest:
{
LogPrint (eLogDebug, "Garlic: Ack request");
m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index});
if (receiveTagset)
m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index});
break;
}
case eECIESx25519BlkTermination:
@@ -856,7 +863,7 @@ namespace garlic
payloadLen += msg->GetPayloadLength () + 13;
if (m_Destination) payloadLen += 32;
}
if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)
if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASESET_CONFIRMATION_TIMEOUT)
{
// resubmit non-confirmed LeaseSet
SetLeaseSetUpdateStatus (eLeaseSetUpdated);
@@ -1147,9 +1154,9 @@ namespace garlic
return len;
}
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<I2NPMessage> msg, const uint8_t * key, uint64_t tag)
{
auto m = NewI2NPMessage ();
auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128);
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;
@@ -1167,15 +1174,21 @@ namespace garlic
htobe32buf (m->GetPayload (), offset);
m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
if (msg->onDrop)
{
// move onDrop to the wrapping I2NP messages
m->onDrop = msg->onDrop;
msg->onDrop = nullptr;
}
return m;
}
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<const I2NPMessage> msg, const uint8_t * routerPublicKey)
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<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 ();
auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128);
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;
@@ -1204,6 +1217,12 @@ namespace garlic
htobe32buf (m->GetPayload (), offset);
m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
if (msg->onDrop)
{
// move onDrop to the wrapping I2NP messages
m->onDrop = msg->onDrop;
msg->onDrop = nullptr;
}
return m;
}
}

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