mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
269 Commits
2.40.0
...
webconsole
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31936f6025 | ||
|
|
f3dcc5364f | ||
|
|
fbe2e734c2 | ||
|
|
78193fc8f8 | ||
|
|
463d43b0bb | ||
|
|
7197fce349 | ||
|
|
5ba387ba2b | ||
|
|
a843be75f3 | ||
|
|
47460d86b2 | ||
|
|
3cd74f0d4f | ||
|
|
690c9f7c6f | ||
|
|
e2718e5a12 | ||
|
|
d9fefe757e | ||
|
|
55e4bf6b65 | ||
|
|
0176e5cf18 | ||
|
|
4670b12d49 | ||
|
|
321ec8ae4d | ||
|
|
1ccbb8d10b | ||
|
|
86c0accdce | ||
|
|
38d6c29ce9 | ||
|
|
0cf9478cd4 | ||
|
|
a04abd304a | ||
|
|
84aec9fe31 | ||
|
|
593b9bb6c5 | ||
|
|
d3a9cc8fde | ||
|
|
87a434c377 | ||
|
|
56022c9442 | ||
|
|
593d6bf466 | ||
|
|
29a4366dcf | ||
|
|
0a42f414bf | ||
|
|
9b2ac4349e | ||
|
|
2d4c7729ad | ||
|
|
6ecab66b0e | ||
|
|
1dded57a1c | ||
|
|
1d6104ecf3 | ||
|
|
14da941ff4 | ||
|
|
06b87311ea | ||
|
|
3b31773117 | ||
|
|
9c87fe79ea | ||
|
|
bd00112562 | ||
|
|
1c9160c37d | ||
|
|
e2ef88229f | ||
|
|
fd7b889a0f | ||
|
|
a7aa056ec1 | ||
|
|
4f74acb2d3 | ||
|
|
22ef1be82b | ||
|
|
9ddbf255ba | ||
|
|
dfb171d32a | ||
|
|
6b4ffcff5a | ||
|
|
d31cd2e5d6 | ||
|
|
396c74e6c6 | ||
|
|
609c658a9b | ||
|
|
ee6bb40736 | ||
|
|
f8c5ea2b42 | ||
|
|
923eb9fdb3 | ||
|
|
2cd3ebbdb3 | ||
|
|
5e25e30330 | ||
|
|
5aa2a8f60f | ||
|
|
0a1e302e8a | ||
|
|
bb705a77cf | ||
|
|
cb6155b946 | ||
|
|
714d1cc993 | ||
|
|
bc8e4494c4 | ||
|
|
c3a064f980 | ||
|
|
eb3feb7dbd | ||
|
|
da3f3ccac9 | ||
|
|
1a1871e8cd | ||
|
|
c22ab7e1fc | ||
|
|
436992b069 | ||
|
|
18cb3912e5 | ||
|
|
a818b0ba02 | ||
|
|
3716b6f988 | ||
|
|
c9e4e78f41 | ||
|
|
9b4e8bf64b | ||
|
|
5aebefe73f | ||
|
|
8f2124beab | ||
|
|
8b8b43df28 | ||
|
|
c42b991bc9 | ||
|
|
ec08333bf9 | ||
|
|
9e5b4e14c9 | ||
|
|
1f5ed89a88 | ||
|
|
2304a2bc2e | ||
|
|
dc82105226 | ||
|
|
5221f3ddc9 | ||
|
|
e970deb92b | ||
|
|
9db7ec6bb0 | ||
|
|
2e691b6655 | ||
|
|
f22e10537b | ||
|
|
6e532c494c | ||
|
|
f9ed0d4aa2 | ||
|
|
78b1afcc8c | ||
|
|
40340cf9c2 | ||
|
|
eb6437050f | ||
|
|
45ebfe378b | ||
|
|
1326597226 | ||
|
|
751da92c13 | ||
|
|
e10ca637da | ||
|
|
c5d9d71a8a | ||
|
|
3e0f5d231d | ||
|
|
6990f177ba | ||
|
|
98e713166b | ||
|
|
4c91ae0085 | ||
|
|
43f74d4d5a | ||
|
|
8c3e716c3f | ||
|
|
05946125b5 | ||
|
|
1e2a0a4549 | ||
|
|
f9f5084dd7 | ||
|
|
b7e7c6db7b | ||
|
|
f9d67b28ec | ||
|
|
46b77cc280 | ||
|
|
2f10decf56 | ||
|
|
678a1ae0fb | ||
|
|
51cbffd097 | ||
|
|
207b13dcab | ||
|
|
3052dbd1e8 | ||
|
|
5891b1ceb2 | ||
|
|
07e14ddda8 | ||
|
|
db5e90787c | ||
|
|
67e501f5c7 | ||
|
|
2160001167 | ||
|
|
f5f4150d17 | ||
|
|
887f292612 | ||
|
|
f5f282af97 | ||
|
|
82f9585b7a | ||
|
|
eb561bb0c2 | ||
|
|
81207999eb | ||
|
|
2fef595b83 | ||
|
|
2024e790ca | ||
|
|
f9925c7374 | ||
|
|
dd774b8dfd | ||
|
|
064b8042a5 | ||
|
|
7923ed9567 | ||
|
|
30b83414ef | ||
|
|
990906c57f | ||
|
|
4c323a666a | ||
|
|
a3f165d374 | ||
|
|
4977f9e6b4 | ||
|
|
7d5f51e357 | ||
|
|
371a339b18 | ||
|
|
7e7aee27b6 | ||
|
|
53148fe58f | ||
|
|
56b6de6962 | ||
|
|
44735681af | ||
|
|
ee1c4f4fdc | ||
|
|
fb6ecdde1e | ||
|
|
861166d8a9 | ||
|
|
70dca81c40 | ||
|
|
2774d72888 | ||
|
|
2440ffbfc9 | ||
|
|
77c5dde320 | ||
|
|
aa49cad279 | ||
|
|
f56ae240ab | ||
|
|
e871a30a78 | ||
|
|
30e6984889 | ||
|
|
324932c758 | ||
|
|
421800bc8f | ||
|
|
86fb47b2b4 | ||
|
|
715f83bf84 | ||
|
|
87bf5c2418 | ||
|
|
5c9af1c613 | ||
|
|
765e0e5c6b | ||
|
|
cc296e16dc | ||
|
|
ab9901525b | ||
|
|
3643a46a0c | ||
|
|
d467e6869d | ||
|
|
db36018849 | ||
|
|
3c5c375f71 | ||
|
|
7473d8c9aa | ||
|
|
33645d7f09 | ||
|
|
9f1106b14a | ||
|
|
3dd952b49b | ||
|
|
6b85bd2cb8 | ||
|
|
60b164c853 | ||
|
|
40c8a1bc1d | ||
|
|
22de695f12 | ||
|
|
e91f588cd7 | ||
|
|
7b72d91549 | ||
|
|
b3c2e86436 | ||
|
|
908bdc7624 | ||
|
|
21c1ec9c8c | ||
|
|
6d7d71bb16 | ||
|
|
6eba061c2a | ||
|
|
f184f550b9 | ||
|
|
bb7c0fef20 | ||
|
|
5c15a12116 | ||
|
|
68d015763e | ||
|
|
7faa732f38 | ||
|
|
11f9eeabf1 | ||
|
|
a152f36894 | ||
|
|
d4ede6ff01 | ||
|
|
35542d803c | ||
|
|
f6ba776c12 | ||
|
|
1511dcb309 | ||
|
|
35afa98112 | ||
|
|
df62b40ca7 | ||
|
|
9f1a125ed9 | ||
|
|
b7e20b9b86 | ||
|
|
a5d6972913 | ||
|
|
e4cb42c599 | ||
|
|
0a34f1f3ad | ||
|
|
7bdeaa9611 | ||
|
|
ab2577ce0a | ||
|
|
34544be423 | ||
|
|
6bf0fdd344 | ||
|
|
6a177cdd1c | ||
|
|
a51ef0cfc6 | ||
|
|
48374d97df | ||
|
|
bf3d7e74f5 | ||
|
|
ab3f3890e4 | ||
|
|
dceb0fb8c5 | ||
|
|
05c1856389 | ||
|
|
dc5cba60d1 | ||
|
|
70409dcdcc | ||
|
|
a92c29e04c | ||
|
|
c4b4dc79cf | ||
|
|
510fe43ec4 | ||
|
|
73e572b66b | ||
|
|
a272a2cb7e | ||
|
|
43b990afe6 | ||
|
|
90130b5492 | ||
|
|
f22faaefeb | ||
|
|
ac25649425 | ||
|
|
04388325a8 | ||
|
|
61ec873842 | ||
|
|
ea1f2d4e26 | ||
|
|
4211c733a2 | ||
|
|
450266818a | ||
|
|
1e019157bb | ||
|
|
c9a1066f02 | ||
|
|
0062f7d764 | ||
|
|
95e994e171 | ||
|
|
31242401e5 | ||
|
|
19cc1c3b3f | ||
|
|
03bcdceb9b | ||
|
|
33ca836ad0 | ||
|
|
53f19e4050 | ||
|
|
54b7d46f5a | ||
|
|
40e6d675c5 | ||
|
|
73b77c83b8 | ||
|
|
632d41e50c | ||
|
|
17acadbfb9 | ||
|
|
2ab5924ec9 | ||
|
|
ac09a4cf0f | ||
|
|
c10ee59de3 | ||
|
|
afad405ed9 | ||
|
|
5a35de8dc9 | ||
|
|
58cf26c304 | ||
|
|
a2de5564ac | ||
|
|
338b17ccf1 | ||
|
|
843a968959 | ||
|
|
dc45c13eef | ||
|
|
0d6e801595 | ||
|
|
2cd50ebaee | ||
|
|
cb6f6a6596 | ||
|
|
e4ab0acc92 | ||
|
|
10237c41d3 | ||
|
|
ac2c6c6010 | ||
|
|
c6b2ce93c4 | ||
|
|
401b7fe883 | ||
|
|
f567417bb3 | ||
|
|
ae5cb3bbe7 | ||
|
|
0eb8e15796 | ||
|
|
1c95c7856f | ||
|
|
daf7551e59 | ||
|
|
5b63d3692e | ||
|
|
5f9972af78 | ||
|
|
1be4cce074 | ||
|
|
935e93eb36 | ||
|
|
5d924cd35a |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build/build_mingw.cmd eol=crlf
|
||||||
39
.github/workflows/build-windows.yml
vendored
39
.github/workflows/build-windows.yml
vendored
@@ -14,6 +14,7 @@ jobs:
|
|||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
include: [
|
include: [
|
||||||
|
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
|
||||||
{ msystem: MINGW64, arch: x86_64, arch_short: x64 },
|
{ msystem: MINGW64, arch: x86_64, arch_short: x64 },
|
||||||
{ msystem: MINGW32, arch: i686, arch_short: x86 }
|
{ msystem: MINGW32, arch: i686, arch_short: x86 }
|
||||||
]
|
]
|
||||||
@@ -34,3 +35,41 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: i2pd-${{ matrix.arch_short }}.exe
|
name: i2pd-${{ matrix.arch_short }}.exe
|
||||||
path: i2pd.exe
|
path: i2pd.exe
|
||||||
|
build-xp:
|
||||||
|
name: Building for Windows XP
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup MSYS2
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: MINGW32
|
||||||
|
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
|
||||||
|
update: true
|
||||||
|
- name: Build WinXP-capable CRT packages
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/msys2/MINGW-packages
|
||||||
|
pushd MINGW-packages
|
||||||
|
pushd mingw-w64-headers-git
|
||||||
|
sed -i 's/0x601/0x501/' PKGBUILD
|
||||||
|
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
|
||||||
|
pacman --noconfirm -U mingw-w64-i686-headers-git-*-any.pkg.tar.zst
|
||||||
|
popd
|
||||||
|
pushd mingw-w64-crt-git
|
||||||
|
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
|
||||||
|
pacman --noconfirm -U mingw-w64-i686-crt-git-*-any.pkg.tar.zst
|
||||||
|
popd
|
||||||
|
pushd mingw-w64-winpthreads-git
|
||||||
|
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
|
||||||
|
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
|
||||||
|
popd
|
||||||
|
popd
|
||||||
|
- name: Build application
|
||||||
|
run: |
|
||||||
|
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
|
||||||
|
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: i2pd-xp.exe
|
||||||
|
path: i2pd.exe
|
||||||
|
|||||||
9
.github/workflows/docker.yml
vendored
9
.github/workflows/docker.yml
vendored
@@ -1,6 +1,11 @@
|
|||||||
name: Build containers
|
name: Build containers
|
||||||
|
|
||||||
on: [push]
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- openssl
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@@ -58,6 +63,8 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
purplei2p/i2pd:latest
|
purplei2p/i2pd:latest
|
||||||
|
purplei2p/i2pd:latest-release
|
||||||
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
ghcr.io/purplei2p/i2pd:latest
|
ghcr.io/purplei2p/i2pd:latest
|
||||||
|
ghcr.io/purplei2p/i2pd:latest-release
|
||||||
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,12 +8,15 @@ netDb
|
|||||||
/libi2pd.a
|
/libi2pd.a
|
||||||
/libi2pdclient.a
|
/libi2pdclient.a
|
||||||
/libi2pdlang.a
|
/libi2pdlang.a
|
||||||
|
/libi2pdwebconsole.a
|
||||||
/libi2pd.so
|
/libi2pd.so
|
||||||
/libi2pdclient.so
|
/libi2pdclient.so
|
||||||
/libi2pdlang.so
|
/libi2pdlang.so
|
||||||
|
/libi2pdwebconsole.so
|
||||||
/libi2pd.dll
|
/libi2pd.dll
|
||||||
/libi2pdclient.dll
|
/libi2pdclient.dll
|
||||||
/libi2pdlang.dll
|
/libi2pdlang.dll
|
||||||
|
/libi2pdwebconsole.dll
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
61
ChangeLog
61
ChangeLog
@@ -1,6 +1,67 @@
|
|||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
|
## [2.42.1] - 2022-05-24
|
||||||
|
### Fixed
|
||||||
|
- Incorrect jump link in HTTP Proxy
|
||||||
|
|
||||||
|
## [2.42.0] - 2022-05-22
|
||||||
|
### Added
|
||||||
|
- Preliminary SSU2 implementation
|
||||||
|
- Tunnel length variance
|
||||||
|
- Localization to French
|
||||||
|
- Daily cleanup of obsolete peer profiles
|
||||||
|
- Ordered jump services list in HTTP proxy
|
||||||
|
- Win32 service
|
||||||
|
- Show port for local non-published SSU addresses in web console
|
||||||
|
### Changed
|
||||||
|
- Maximum RouterInfo length increased to 3K
|
||||||
|
- Skip unknown addresses in RouterInfo
|
||||||
|
- Don't pick own router for peer test
|
||||||
|
- Reseeds list
|
||||||
|
- Internal numeric id for families
|
||||||
|
- Use ipv6 preference only when netinet headers not used
|
||||||
|
- Close stream if delete requested
|
||||||
|
- Remove version from title in web console
|
||||||
|
- Drop MESHNET build option
|
||||||
|
- Set data path before initialization
|
||||||
|
- Don't show registration block in web console if token is not provided
|
||||||
|
### Fixed
|
||||||
|
- Encrypted LeaseSet for EdDSA signature
|
||||||
|
- Clients tunnels are not built if clock is not synced on start
|
||||||
|
- Incorrect processing of i2cp.dontPublishLeaseSet param
|
||||||
|
- UDP tunnels reload
|
||||||
|
- Build for LibreSSL 3.5.2
|
||||||
|
- Race condition in short tunnel build message
|
||||||
|
- Race condition in local RouterInfo buffer allocation
|
||||||
|
|
||||||
|
## [2.41.0] - 2022-02-20
|
||||||
|
### Added
|
||||||
|
- Clock syncronization through SSU
|
||||||
|
- Drop routers older than 6 months on start
|
||||||
|
- Localization to German
|
||||||
|
- Don't send streaming ack too frequently
|
||||||
|
- Select compatible outbound tunnel for I2CP messages
|
||||||
|
- Restart webconsole's acceptor in case of exception
|
||||||
|
### Changed
|
||||||
|
- Use builtin bitswap for endian on windows
|
||||||
|
- Send SessionCreated before connection close if clock skew
|
||||||
|
- Try another floodfill for publishing if no compatible tunnels found
|
||||||
|
- Reduce memory usage for RouterInfo structures
|
||||||
|
- Avoid duplicated addresses in RouterInfo. Check presence of netId and version
|
||||||
|
- Use TCP/IP sockets for I2CP on Android instead local sockets
|
||||||
|
- Return uptime as integer in I2PControl
|
||||||
|
- Reseed servers list/cerificates
|
||||||
|
- Webconsole's dark style colors
|
||||||
|
### Fixed
|
||||||
|
- Attempt to use Yggdrasil on start on Android
|
||||||
|
- Attempts to send peer tests to itself
|
||||||
|
- Severe packets drop in SSU
|
||||||
|
- Crash on tunnel tests
|
||||||
|
- Loading addressbook subscriptions from config
|
||||||
|
- Multiple I2CP session to the same destination
|
||||||
|
- Build on Apple Silicon
|
||||||
|
|
||||||
## [2.40.0] - 2021-11-29
|
## [2.40.0] - 2021-11-29
|
||||||
### Added
|
### Added
|
||||||
- Keep alive parameter for client tunnels
|
- Keep alive parameter for client tunnels
|
||||||
|
|||||||
59
Makefile
59
Makefile
@@ -4,7 +4,7 @@ SYS := $(shell $(CXX) -dumpmachine)
|
|||||||
|
|
||||||
ifneq (, $(findstring darwin, $(SYS)))
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
SHARED_SUFFIX = dylib
|
SHARED_SUFFIX = dylib
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
SHARED_SUFFIX = dll
|
SHARED_SUFFIX = dll
|
||||||
else
|
else
|
||||||
SHARED_SUFFIX = so
|
SHARED_SUFFIX = so
|
||||||
@@ -12,26 +12,28 @@ endif
|
|||||||
|
|
||||||
SHLIB := libi2pd.$(SHARED_SUFFIX)
|
SHLIB := libi2pd.$(SHARED_SUFFIX)
|
||||||
ARLIB := libi2pd.a
|
ARLIB := libi2pd.a
|
||||||
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
|
|
||||||
ARLIB_LANG := libi2pdlang.a
|
|
||||||
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
|
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
|
||||||
ARLIB_CLIENT := libi2pdclient.a
|
ARLIB_CLIENT := libi2pdclient.a
|
||||||
|
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
|
||||||
|
ARLIB_LANG := libi2pdlang.a
|
||||||
|
SHLIB_WEBCONSOLE := libi2pdwebconsole.$(SHARED_SUFFIX)
|
||||||
|
ARLIB_WEBCONSOLE := libi2pdwebconsole.a
|
||||||
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
|
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
|
||||||
ARLIB_WRAP := libi2pdwrapper.a
|
ARLIB_WRAP := libi2pdwrapper.a
|
||||||
I2PD := i2pd
|
I2PD := i2pd
|
||||||
|
|
||||||
LIB_SRC_DIR := libi2pd
|
LIB_SRC_DIR := libi2pd
|
||||||
LIB_CLIENT_SRC_DIR := libi2pd_client
|
LIB_CLIENT_SRC_DIR := libi2pd_client
|
||||||
WRAP_SRC_DIR := libi2pd_wrapper
|
WEBCONSOLE_SRC_DIR := libi2pd_webconsole
|
||||||
LANG_SRC_DIR := i18n
|
LANG_SRC_DIR := i18n
|
||||||
DAEMON_SRC_DIR := daemon
|
DAEMON_SRC_DIR := daemon
|
||||||
|
WRAP_SRC_DIR := libi2pd_wrapper
|
||||||
|
|
||||||
# import source files lists
|
# import source files lists
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
|
|
||||||
USE_AESNI := $(or $(USE_AESNI),yes)
|
USE_AESNI := $(or $(USE_AESNI),yes)
|
||||||
USE_STATIC := $(or $(USE_STATIC),no)
|
USE_STATIC := $(or $(USE_STATIC),no)
|
||||||
USE_MESHNET := $(or $(USE_MESHNET),no)
|
|
||||||
USE_UPNP := $(or $(USE_UPNP),no)
|
USE_UPNP := $(or $(USE_UPNP),no)
|
||||||
DEBUG := $(or $(DEBUG),yes)
|
DEBUG := $(or $(DEBUG),yes)
|
||||||
|
|
||||||
@@ -49,50 +51,48 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (, $(findstring darwin, $(SYS)))
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
||||||
ifeq ($(HOMEBREW),1)
|
ifeq ($(HOMEBREW),1)
|
||||||
include Makefile.homebrew
|
include Makefile.homebrew
|
||||||
else
|
else
|
||||||
include Makefile.osx
|
include Makefile.osx
|
||||||
endif
|
endif
|
||||||
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
||||||
include Makefile.linux
|
include Makefile.linux
|
||||||
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
||||||
include Makefile.bsd
|
include Makefile.bsd
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Not supported platform)
|
$(error Not supported platform)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_MESHNET),yes)
|
|
||||||
NEEDED_CXXFLAGS += -DMESHNET
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_GIT_VERSION),yes)
|
ifeq ($(USE_GIT_VERSION),yes)
|
||||||
GIT_VERSION := $(shell git describe --tags)
|
GIT_VERSION := $(shell git describe --tags)
|
||||||
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
|
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
|
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) -I$(WEBCONSOLE_SRC_DIR) -DOPENSSL_SUPPRESS_DEPRECATED
|
||||||
|
|
||||||
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
||||||
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
||||||
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
||||||
|
WEBCONSOLE_OBJS += $(patsubst %.cpp,obj/%.o,$(WEBCONSOLE_SRC))
|
||||||
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
||||||
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
|
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
|
||||||
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
|
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(WEBCONSOLE_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
|
||||||
|
|
||||||
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
|
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
|
||||||
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD)
|
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(ARLIB_WEBCONSOLE) $(I2PD)
|
||||||
|
|
||||||
mk_obj_dir:
|
mk_obj_dir:
|
||||||
@mkdir -p obj/$(LIB_SRC_DIR)
|
@mkdir -p obj/$(LIB_SRC_DIR)
|
||||||
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
||||||
@mkdir -p obj/$(LANG_SRC_DIR)
|
@mkdir -p obj/$(LANG_SRC_DIR)
|
||||||
|
@mkdir -p obj/$(WEBCONSOLE_SRC_DIR)
|
||||||
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
||||||
@mkdir -p obj/$(WRAP_SRC_DIR)
|
@mkdir -p obj/$(WRAP_SRC_DIR)
|
||||||
@mkdir -p obj/Win32
|
@mkdir -p obj/Win32
|
||||||
@@ -100,7 +100,8 @@ mk_obj_dir:
|
|||||||
api: $(SHLIB) $(ARLIB)
|
api: $(SHLIB) $(ARLIB)
|
||||||
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
lang: $(SHLIB_LANG) $(ARLIB_LANG)
|
lang: $(SHLIB_LANG) $(ARLIB_LANG)
|
||||||
api_client: api client lang
|
webconsole: $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE)
|
||||||
|
api_client: api client lang webconsole
|
||||||
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
||||||
@@ -116,7 +117,7 @@ obj/%.o: %.cpp | mk_obj_dir
|
|||||||
# '-' is 'ignore if missing' on first run
|
# '-' is 'ignore if missing' on first run
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
$(I2PD): $(DAEMON_OBJS) $(ARLIB_WEBCONSOLE) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
||||||
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
|
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
|
||||||
@@ -129,12 +130,17 @@ ifneq ($(USE_STATIC),yes)
|
|||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
|
$(SHLIB_LANG): $(LANG_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(SHLIB_LANG): $(LANG_OBJS)
|
$(SHLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
||||||
|
ifneq ($(USE_STATIC),yes)
|
||||||
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||||
endif
|
endif
|
||||||
@@ -145,18 +151,21 @@ $(ARLIB): $(LIB_OBJS)
|
|||||||
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
|
$(ARLIB_LANG): $(LANG_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
$(ARLIB_LANG): $(LANG_OBJS)
|
$(ARLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS)
|
||||||
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
|
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -r obj
|
$(RM) -r obj
|
||||||
$(RM) -r docs/generated
|
$(RM) -r docs/generated
|
||||||
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP)
|
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE) $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||||
|
|
||||||
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) $(SHLIB_WEBCONSOLE)
|
||||||
strip $^
|
strip $^
|
||||||
|
|
||||||
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
||||||
|
|||||||
@@ -39,13 +39,14 @@ ifeq ($(USE_AESNI),yes)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
|
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
|
||||||
install -m 755 ${I2PD} ${PREFIX}/bin/
|
install -m 755 ${I2PD} ${PREFIX}/bin/
|
||||||
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
||||||
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
|
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
|
||||||
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
||||||
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
||||||
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
|
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
|
||||||
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
|
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
|
||||||
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
||||||
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
||||||
|
|||||||
@@ -62,3 +62,16 @@ ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64
|
|||||||
NEEDED_CXXFLAGS += -D__AES__ -maes
|
NEEDED_CXXFLAGS += -D__AES__ -maes
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
install: all
|
||||||
|
install -d ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/usr ${PREFIX}/usr/share ${PREFIX}/usr/share/doc/i2pd ${PREFIX}/usr/share/i2pd ${PREFIX}/usr/share/man ${PREFIX}/usr/share/man/man1 ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
|
||||||
|
install -m 755 ${I2PD} ${PREFIX}/bin/
|
||||||
|
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
||||||
|
@cp -R contrib/certificates ${PREFIX}/usr/share/i2pd/
|
||||||
|
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/usr/share/doc/i2pd
|
||||||
|
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/usr/share/man/man1
|
||||||
|
@ln -sf ${PREFIX}/usr/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
||||||
|
|||||||
@@ -3,19 +3,11 @@ USE_WIN32_APP := yes
|
|||||||
|
|
||||||
WINDRES = windres
|
WINDRES = windres
|
||||||
|
|
||||||
CXXFLAGS := $(CXX_DEBUG) -DWIN32_LEAN_AND_MEAN -fPIC -msse
|
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
|
||||||
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
|
INCFLAGS = -IWin32
|
||||||
LDFLAGS := ${LD_DEBUG} -static
|
LDFLAGS := ${LD_DEBUG} -static
|
||||||
|
|
||||||
# detect proper flag for c++11 support by compilers
|
NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN
|
||||||
CXXVER := $(shell $(CXX) -dumpversion)
|
|
||||||
ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6
|
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
|
||||||
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
|
|
||||||
NEEDED_CXXFLAGS += -std=c++17
|
|
||||||
else # not supported
|
|
||||||
$(error Compiler too old)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Boost libraries suffix
|
# Boost libraries suffix
|
||||||
BOOST_SUFFIX = -mt
|
BOOST_SUFFIX = -mt
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ BEGIN
|
|||||||
VALUE "FileDescription", "C++ I2P daemon"
|
VALUE "FileDescription", "C++ I2P daemon"
|
||||||
VALUE "FileVersion", I2PD_VERSION
|
VALUE "FileVersion", I2PD_VERSION
|
||||||
VALUE "InternalName", CODENAME
|
VALUE "InternalName", CODENAME
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project"
|
VALUE "LegalCopyright", "Copyright (C) 2013-2022, The PurpleI2P Project"
|
||||||
VALUE "OriginalFilename", "i2pd"
|
VALUE "OriginalFilename", "i2pd"
|
||||||
VALUE "ProductName", "Purple I2P"
|
VALUE "ProductName", "Purple I2P"
|
||||||
VALUE "ProductVersion", I2P_VERSION
|
VALUE "ProductVersion", I2P_VERSION
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "Daemon.h"
|
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
#include "Win32NetState.h"
|
#include "Win32NetState.h"
|
||||||
|
|
||||||
@@ -55,13 +55,15 @@ namespace win32
|
|||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||||
if(!i2p::context.AcceptsTunnels())
|
if(!i2p::context.AcceptsTunnels())
|
||||||
InsertMenu (hPopup, -1,
|
if(m_getIsGraceful)
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING,
|
if(m_getIsGraceful())
|
||||||
ID_ACCEPT_TRANSIT, "Accept &transit");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING | MF_GRAYED, ID_ACCEPT_TRANSIT, "Accept &transit");
|
||||||
|
else
|
||||||
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ACCEPT_TRANSIT, "Accept &transit");
|
||||||
else
|
else
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config");
|
||||||
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
|
if (!m_getIsGraceful)
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||||
else
|
else
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
|
||||||
@@ -270,7 +272,7 @@ namespace win32
|
|||||||
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
||||||
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
|
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
|
||||||
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
if (m_setIsGraceful) m_setIsGraceful(true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ID_STOP_GRACEFUL_SHUTDOWN:
|
case ID_STOP_GRACEFUL_SHUTDOWN:
|
||||||
@@ -279,7 +281,7 @@ namespace win32
|
|||||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
||||||
g_GracefulShutdownEndtime = 0;
|
g_GracefulShutdownEndtime = 0;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
if (m_setIsGraceful) m_setIsGraceful(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ID_RELOAD:
|
case ID_RELOAD:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -22,6 +22,15 @@ namespace win32
|
|||||||
int RunWin32App ();
|
int RunWin32App ();
|
||||||
bool GracefulShutdown ();
|
bool GracefulShutdown ();
|
||||||
bool StopGracefulShutdown ();
|
bool StopGracefulShutdown ();
|
||||||
|
|
||||||
|
inline typedef std::function<void (bool)> DaemonSetIsGraceful;
|
||||||
|
inline DaemonSetIsGraceful m_setIsGraceful;
|
||||||
|
inline void SetIsGraceful (const DaemonSetIsGraceful& f) { m_setIsGraceful = f; };
|
||||||
|
|
||||||
|
inline typedef std::function<bool ()> DaemonGetIsGraceful;
|
||||||
|
inline DaemonGetIsGraceful m_getIsGraceful;
|
||||||
|
inline void GetIsGraceful (const DaemonGetIsGraceful& f) { m_getIsGraceful = f; };
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WIN32APP_H__
|
#endif // WIN32APP_H__
|
||||||
|
|||||||
292
Win32/Win32Service.cpp
Normal file
292
Win32/Win32Service.cpp
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Win32Service.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
I2PService *I2PService::s_service = NULL;
|
||||||
|
|
||||||
|
BOOL I2PService::isService()
|
||||||
|
{
|
||||||
|
BOOL bIsService = FALSE;
|
||||||
|
HWINSTA hWinStation = GetProcessWindowStation();
|
||||||
|
if (hWinStation != NULL)
|
||||||
|
{
|
||||||
|
USEROBJECTFLAGS uof = { 0 };
|
||||||
|
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
|
||||||
|
{
|
||||||
|
bIsService = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bIsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL I2PService::Run(I2PService &service)
|
||||||
|
{
|
||||||
|
s_service = &service;
|
||||||
|
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||||
|
{
|
||||||
|
{ service.m_name, ServiceMain },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
return StartServiceCtrlDispatcher(serviceTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
assert(s_service != NULL);
|
||||||
|
s_service->m_statusHandle = RegisterServiceCtrlHandler(
|
||||||
|
s_service->m_name, ServiceCtrlHandler);
|
||||||
|
if (s_service->m_statusHandle == NULL)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
s_service->Start(dwArgc, pszArgv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WINAPI I2PService::ServiceCtrlHandler(DWORD dwCtrl)
|
||||||
|
{
|
||||||
|
switch (dwCtrl)
|
||||||
|
{
|
||||||
|
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
|
||||||
|
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
|
||||||
|
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
|
||||||
|
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
|
||||||
|
case SERVICE_CONTROL_INTERROGATE: break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
I2PService::I2PService(PSTR pszServiceName,
|
||||||
|
BOOL fCanStop,
|
||||||
|
BOOL fCanShutdown,
|
||||||
|
BOOL fCanPauseContinue)
|
||||||
|
{
|
||||||
|
m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName;
|
||||||
|
m_statusHandle = NULL;
|
||||||
|
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
|
m_status.dwCurrentState = SERVICE_START_PENDING;
|
||||||
|
|
||||||
|
DWORD dwControlsAccepted = 0;
|
||||||
|
if (fCanStop)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_STOP;
|
||||||
|
if (fCanShutdown)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
|
||||||
|
if (fCanPauseContinue)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
|
||||||
|
|
||||||
|
m_status.dwControlsAccepted = dwControlsAccepted;
|
||||||
|
m_status.dwWin32ExitCode = NO_ERROR;
|
||||||
|
m_status.dwServiceSpecificExitCode = 0;
|
||||||
|
m_status.dwCheckPoint = 0;
|
||||||
|
m_status.dwWaitHint = 0;
|
||||||
|
m_fStopping = FALSE;
|
||||||
|
// Create a manual-reset event that is not signaled at first to indicate
|
||||||
|
// the stopped signal of the service.
|
||||||
|
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
if (m_hStoppedEvent == NULL)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
I2PService::~I2PService(void)
|
||||||
|
{
|
||||||
|
if (m_hStoppedEvent)
|
||||||
|
{
|
||||||
|
CloseHandle(m_hStoppedEvent);
|
||||||
|
m_hStoppedEvent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_START_PENDING);
|
||||||
|
OnStart(dwArgc, pszArgv);
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Start error: ", dwError);
|
||||||
|
SetServiceStatus(SERVICE_STOPPED, dwError);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
|
||||||
|
if(m_daemonStart)
|
||||||
|
m_daemonStart();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: failed to start: Unable to call callback");
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::WorkerThread()
|
||||||
|
{
|
||||||
|
while (!m_fStopping)
|
||||||
|
{
|
||||||
|
::Sleep(1000); // Simulate some lengthy operations.
|
||||||
|
}
|
||||||
|
// Signal the stopped event.
|
||||||
|
SetEvent(m_hStoppedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::Stop()
|
||||||
|
{
|
||||||
|
DWORD dwOriginalState = m_status.dwCurrentState;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_STOP_PENDING);
|
||||||
|
OnStop();
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "Win32Service: Stop error: ", dwError);
|
||||||
|
SetServiceStatus(dwOriginalState);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
|
||||||
|
SetServiceStatus(dwOriginalState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::OnStop()
|
||||||
|
{
|
||||||
|
// Log a service stop message to the Application log.
|
||||||
|
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
|
||||||
|
if(m_daemonStop)
|
||||||
|
m_daemonStop();
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "Win32Service: failed to stop: Unable to call callback");
|
||||||
|
|
||||||
|
m_fStopping = TRUE;
|
||||||
|
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
_worker->join();
|
||||||
|
delete _worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::Pause()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_PAUSE_PENDING);
|
||||||
|
OnPause();
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::OnPause()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::Continue()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_CONTINUE_PENDING);
|
||||||
|
OnContinue();
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Continue error: ", dwError);
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::OnContinue()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::Shutdown()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OnShutdown();
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::OnShutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PService::SetServiceStatus(DWORD dwCurrentState,
|
||||||
|
DWORD dwWin32ExitCode,
|
||||||
|
DWORD dwWaitHint)
|
||||||
|
{
|
||||||
|
static DWORD dwCheckPoint = 1;
|
||||||
|
m_status.dwCurrentState = dwCurrentState;
|
||||||
|
m_status.dwWin32ExitCode = dwWin32ExitCode;
|
||||||
|
m_status.dwWaitHint = dwWaitHint;
|
||||||
|
m_status.dwCheckPoint =
|
||||||
|
((dwCurrentState == SERVICE_RUNNING) ||
|
||||||
|
(dwCurrentState == SERVICE_STOPPED)) ?
|
||||||
|
0 : dwCheckPoint++;
|
||||||
|
|
||||||
|
::SetServiceStatus(m_statusHandle, &m_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService)
|
||||||
|
{
|
||||||
|
if (schSCManager)
|
||||||
|
{
|
||||||
|
CloseServiceHandle(schSCManager);
|
||||||
|
schSCManager = NULL;
|
||||||
|
}
|
||||||
|
if (schService)
|
||||||
|
{
|
||||||
|
CloseServiceHandle(schService);
|
||||||
|
schService = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
Win32/Win32Service.h
Normal file
76
Win32/Win32Service.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIN32SERVICE_H__
|
||||||
|
#define WIN32SERVICE_H__
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <thread>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define SERVICE_NAME "i2pdService"
|
||||||
|
|
||||||
|
class I2PService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
I2PService(PSTR pszServiceName,
|
||||||
|
BOOL fCanStop = TRUE,
|
||||||
|
BOOL fCanShutdown = TRUE,
|
||||||
|
BOOL fCanPauseContinue = FALSE);
|
||||||
|
|
||||||
|
virtual ~I2PService(void);
|
||||||
|
|
||||||
|
static BOOL isService();
|
||||||
|
static BOOL Run(I2PService &service);
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
typedef std::function<bool ()> DaemonStart;
|
||||||
|
void SetDaemonStart (const DaemonStart& f) { m_daemonStart = f; };
|
||||||
|
|
||||||
|
typedef std::function<bool ()> DaemonStop;
|
||||||
|
void SetDaemonStop (const DaemonStop& f) { m_daemonStop = f; };
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||||
|
virtual void OnStop();
|
||||||
|
virtual void OnPause();
|
||||||
|
virtual void OnContinue();
|
||||||
|
virtual void OnShutdown();
|
||||||
|
void SetServiceStatus(DWORD dwCurrentState,
|
||||||
|
DWORD dwWin32ExitCode = NO_ERROR,
|
||||||
|
DWORD dwWaitHint = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
||||||
|
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||||
|
void WorkerThread();
|
||||||
|
void Start(DWORD dwArgc, PSTR *pszArgv);
|
||||||
|
void Pause();
|
||||||
|
void Continue();
|
||||||
|
void Shutdown();
|
||||||
|
static I2PService* s_service;
|
||||||
|
PSTR m_name;
|
||||||
|
SERVICE_STATUS m_status;
|
||||||
|
SERVICE_STATUS_HANDLE m_statusHandle;
|
||||||
|
|
||||||
|
BOOL m_fStopping;
|
||||||
|
HANDLE m_hStoppedEvent;
|
||||||
|
|
||||||
|
std::thread* _worker;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DaemonStart m_daemonStart;
|
||||||
|
DaemonStop m_daemonStop;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIN32SERVICE_H__
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
# this addresses CMP0059 with CMake > 3.3 for PCH flags
|
cmake_policy(VERSION 3.7)
|
||||||
cmake_policy(VERSION 2.8.12)
|
|
||||||
project("i2pd")
|
project("i2pd")
|
||||||
|
|
||||||
# for debugging
|
# for debugging
|
||||||
@@ -18,8 +17,6 @@ option(WITH_LIBRARY "Build library" ON)
|
|||||||
option(WITH_BINARY "Build binary" ON)
|
option(WITH_BINARY "Build binary" ON)
|
||||||
option(WITH_STATIC "Static build" OFF)
|
option(WITH_STATIC "Static build" OFF)
|
||||||
option(WITH_UPNP "Include support for UPnP client" OFF)
|
option(WITH_UPNP "Include support for UPnP client" OFF)
|
||||||
option(WITH_PCH "Use precompiled header" OFF)
|
|
||||||
option(WITH_MESHNET "Build for cjdns test network" OFF)
|
|
||||||
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
||||||
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
||||||
|
|
||||||
@@ -36,11 +33,13 @@ target_architecture(ARCHITECTURE)
|
|||||||
|
|
||||||
set(LIBI2PD_SRC_DIR ../libi2pd)
|
set(LIBI2PD_SRC_DIR ../libi2pd)
|
||||||
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
||||||
|
set(WEBCONSOLE_SRC_DIR ../libi2pd_webconsole)
|
||||||
set(LANG_SRC_DIR ../i18n)
|
set(LANG_SRC_DIR ../i18n)
|
||||||
set(DAEMON_SRC_DIR ../daemon)
|
set(DAEMON_SRC_DIR ../daemon)
|
||||||
|
|
||||||
include_directories(${LIBI2PD_SRC_DIR})
|
include_directories(${LIBI2PD_SRC_DIR})
|
||||||
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
||||||
|
include_directories(${WEBCONSOLE_SRC_DIR})
|
||||||
include_directories(${LANG_SRC_DIR})
|
include_directories(${LANG_SRC_DIR})
|
||||||
include_directories(${DAEMON_SRC_DIR})
|
include_directories(${DAEMON_SRC_DIR})
|
||||||
|
|
||||||
@@ -71,6 +70,18 @@ if(WITH_LIBRARY)
|
|||||||
COMPONENT Libraries)
|
COMPONENT Libraries)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
FILE(GLOB WEBCONSOLE_SRC ${WEBCONSOLE_SRC_DIR}/*.cpp)
|
||||||
|
add_library(libi2pdwebconsole ${WEBCONSOLE_SRC})
|
||||||
|
set_target_properties(libi2pdwebconsole PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
if(WITH_LIBRARY)
|
||||||
|
install(TARGETS libi2pdwebconsole
|
||||||
|
EXPORT libi2pdwebconsole
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
COMPONENT Libraries)
|
||||||
|
endif()
|
||||||
|
|
||||||
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
||||||
add_library(libi2pdlang ${LANG_SRC})
|
add_library(libi2pdlang ${LANG_SRC})
|
||||||
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
||||||
@@ -85,20 +96,19 @@ endif()
|
|||||||
|
|
||||||
set(DAEMON_SRC
|
set(DAEMON_SRC
|
||||||
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
||||||
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
|
|
||||||
"${DAEMON_SRC_DIR}/I2PControl.cpp"
|
"${DAEMON_SRC_DIR}/I2PControl.cpp"
|
||||||
"${DAEMON_SRC_DIR}/i2pd.cpp"
|
"${DAEMON_SRC_DIR}/i2pd.cpp"
|
||||||
"${DAEMON_SRC_DIR}/UPnP.cpp"
|
"${DAEMON_SRC_DIR}/UPnP.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_MESHNET)
|
|
||||||
add_definitions(-DMESHNET)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_UPNP)
|
if(WITH_UPNP)
|
||||||
add_definitions(-DUSE_UPNP)
|
add_definitions(-DUSE_UPNP)
|
||||||
endif()
|
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 "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
||||||
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
||||||
@@ -138,7 +148,7 @@ endif()
|
|||||||
|
|
||||||
# compiler flags customization(by system)
|
# compiler flags customization(by system)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/DaemonUnix.cpp")
|
||||||
if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
|
if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
|
||||||
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
||||||
add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1")
|
add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1")
|
||||||
@@ -168,20 +178,8 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
# libraries
|
# libraries
|
||||||
# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826
|
|
||||||
# use imported Threads::Threads instead
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
if(IOS)
|
|
||||||
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
|
||||||
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
|
||||||
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
|
||||||
set(CMAKE_USE_PTHREADS_INIT 1)
|
|
||||||
else()
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
endif()
|
|
||||||
if(THREADS_HAVE_PTHREAD_ARG) # compile time flag
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_STATIC)
|
if(WITH_STATIC)
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
@@ -200,22 +198,7 @@ else()
|
|||||||
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_PCH)
|
target_link_libraries(libi2pdwebconsole libi2pdclient libi2pd libi2pdlang)
|
||||||
include_directories(BEFORE ${CMAKE_BINARY_DIR})
|
|
||||||
add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp")
|
|
||||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BTU)
|
|
||||||
get_directory_property(DEFS DEFINITIONS)
|
|
||||||
string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}")
|
|
||||||
add_custom_command(TARGET stdafx PRE_BUILD
|
|
||||||
COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch
|
|
||||||
)
|
|
||||||
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
|
||||||
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
|
|
||||||
target_compile_options(libi2pdlang PRIVATE -include libi2pd/stdafx.h)
|
|
||||||
target_link_libraries(libi2pd stdafx)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(libi2pdclient libi2pd libi2pdlang)
|
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||||
@@ -227,6 +210,10 @@ if(NOT DEFINED OPENSSL_INCLUDE_DIR)
|
|||||||
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
|
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
|
||||||
|
add_definitions(-DOPENSSL_SUPPRESS_DEPRECATED)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_UPNP)
|
if(WITH_UPNP)
|
||||||
find_package(MiniUPnPc REQUIRED)
|
find_package(MiniUPnPc REQUIRED)
|
||||||
if(NOT MINIUPNPC_FOUND)
|
if(NOT MINIUPNPC_FOUND)
|
||||||
@@ -244,15 +231,7 @@ endif()
|
|||||||
# load includes
|
# load includes
|
||||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
# warn if for meshnet
|
|
||||||
if(WITH_MESHNET)
|
|
||||||
message(STATUS "Building for testnet")
|
|
||||||
message(WARNING "This build will NOT work on mainline i2p")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT MSYS)
|
|
||||||
include(CheckAtomic)
|
include(CheckAtomic)
|
||||||
endif()
|
|
||||||
|
|
||||||
# show summary
|
# show summary
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
@@ -269,8 +248,6 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}")
|
|||||||
message(STATUS " BINARY : ${WITH_BINARY}")
|
message(STATUS " BINARY : ${WITH_BINARY}")
|
||||||
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
|
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
|
||||||
message(STATUS " UPnP : ${WITH_UPNP}")
|
message(STATUS " UPnP : ${WITH_UPNP}")
|
||||||
message(STATUS " PCH : ${WITH_PCH}")
|
|
||||||
message(STATUS " MESHNET : ${WITH_MESHNET}")
|
|
||||||
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
||||||
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
@@ -282,10 +259,6 @@ if(WITH_BINARY)
|
|||||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_PCH)
|
|
||||||
target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now")
|
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now")
|
||||||
endif()
|
endif()
|
||||||
@@ -306,7 +279,7 @@ if(WITH_BINARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
||||||
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
target_link_libraries("${PROJECT_NAME}" libi2pdwebconsole libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
||||||
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
|
|||||||
@@ -2,23 +2,22 @@
|
|||||||
setlocal enableextensions enabledelayedexpansion
|
setlocal enableextensions enabledelayedexpansion
|
||||||
title Building i2pd
|
title Building i2pd
|
||||||
|
|
||||||
REM Copyright (c) 2013-2020, The PurpleI2P Project
|
REM Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
REM This file is part of Purple i2pd project and licensed under BSD3
|
REM This file is part of Purple i2pd project and licensed under BSD3
|
||||||
REM See full license text in LICENSE file at top of project tree
|
REM See full license text in LICENSE file at top of project tree
|
||||||
|
|
||||||
REM To use that script, you must have installed in your MSYS installation these packages:
|
REM To use that script, you must have installed in your MSYS installation these packages:
|
||||||
REM Base: git make zip
|
REM Base: git make zip
|
||||||
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
|
REM UCRT64: mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-gcc
|
||||||
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
REM MINGW32: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
||||||
|
|
||||||
REM setting up variables for MSYS
|
REM setting up variables for MSYS
|
||||||
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)!
|
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)
|
||||||
set "WD=C:\msys64\usr\bin\"
|
|
||||||
set MSYS2_PATH_TYPE=inherit
|
set MSYS2_PATH_TYPE=inherit
|
||||||
set CHERE_INVOKING=enabled_from_arguments
|
set CHERE_INVOKING=enabled_from_arguments
|
||||||
REM set MSYSTEM=MSYS
|
|
||||||
set MSYSTEM=MINGW32
|
set MSYSTEM=MINGW32
|
||||||
|
|
||||||
|
set "WD=C:\msys64\usr\bin\"
|
||||||
set "xSH=%WD%bash -lc"
|
set "xSH=%WD%bash -lc"
|
||||||
|
|
||||||
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d contrib/webconsole"
|
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d contrib/webconsole"
|
||||||
@@ -36,12 +35,12 @@ echo Receiving latest commit and cleaning up...
|
|||||||
%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1
|
%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1
|
||||||
|
|
||||||
REM set to variable current commit hash
|
REM set to variable current commit hash
|
||||||
FOR /F "usebackq" %%a IN (`%xSH% "git describe --tags"`) DO (
|
for /F "usebackq" %%a in (`%xSH% "git describe --tags"`) DO (
|
||||||
set tag=%%a
|
set tag=%%a
|
||||||
)
|
)
|
||||||
|
|
||||||
REM set to variable latest released tag
|
REM set to variable latest released tag
|
||||||
FOR /F "usebackq" %%b IN (`%xSH% "git describe --abbrev=0"`) DO (
|
for /F "usebackq" %%b in (`%xSH% "git describe --abbrev=0"`) DO (
|
||||||
set reltag=%%b
|
set reltag=%%b
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,31 +48,57 @@ echo Preparing configuration files and README for packaging...
|
|||||||
|
|
||||||
%xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
|
%xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
|
||||||
|
|
||||||
REM converting configuration files to DOS format (usable in default notepad)
|
REM converting configuration files to DOS format (make usable in Windows Notepad)
|
||||||
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
|
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
|
||||||
|
|
||||||
|
REM Prepare binary signing command if signing key and password provided
|
||||||
|
if defined SIGN (
|
||||||
|
echo Signing enabled
|
||||||
|
|
||||||
|
for %%X in (signtool.exe) do (set xSIGNTOOL=%%~$PATH:X)
|
||||||
|
if not defined xSIGNTOOL (
|
||||||
|
if not defined SIGNTOOL (
|
||||||
|
echo Error: Can't find signtool. Please provide path to binary using SIGNTOOL variable.
|
||||||
|
exit /b 1
|
||||||
|
) else (
|
||||||
|
set "xSIGNTOOL=%SIGNTOOL%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if defined SIGNKEY (
|
||||||
|
set "xSIGNKEYOPTS=/f ^"%SIGNKEY%^""
|
||||||
|
)
|
||||||
|
|
||||||
|
if defined SIGNPASS (
|
||||||
|
set "xSIGNPASSOPTS=/p ^"%SIGNPASS%^""
|
||||||
|
)
|
||||||
|
|
||||||
|
set "xSIGNOPTS=sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 %xSIGNKEYOPTS% %xSIGNPASSOPTS%"
|
||||||
|
)
|
||||||
|
|
||||||
REM starting building
|
REM starting building
|
||||||
set MSYSTEM=MINGW32
|
set MSYSTEM=MINGW32
|
||||||
set bitness=32
|
set bitness=32
|
||||||
call :BUILDING
|
call :BUILDING
|
||||||
|
|
||||||
set MSYSTEM=MINGW64
|
set MSYSTEM=UCRT64
|
||||||
set bitness=64
|
set bitness=64
|
||||||
call :BUILDING
|
call :BUILDING
|
||||||
|
|
||||||
IF exist C:\msys64-xp\ (
|
REM build for Windows XP
|
||||||
REM building for WinXP
|
if exist C:\msys64-xp\ ( call :BUILDING_XP )
|
||||||
set "WD=C:\msys64-xp\usr\bin\"
|
|
||||||
set MSYSTEM=MINGW32
|
|
||||||
set bitness=32
|
|
||||||
set "xSH=%WD%bash -lc"
|
|
||||||
call :BUILDING_XP
|
|
||||||
echo.
|
echo.
|
||||||
)
|
|
||||||
|
|
||||||
REM compile installer
|
REM compile installer
|
||||||
|
echo Building installer...
|
||||||
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1
|
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1
|
||||||
|
|
||||||
|
REM Sign binary
|
||||||
|
if defined xSIGNOPTS (
|
||||||
|
"%xSIGNTOOL%" %xSIGNOPTS% build\setup_i2pd_v%tag%.exe
|
||||||
|
)
|
||||||
|
|
||||||
%xSH% "git checkout contrib/*" >> build\build.log 2>&1
|
%xSH% "git checkout contrib/*" >> build\build.log 2>&1
|
||||||
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
|
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
|
||||||
|
|
||||||
@@ -84,12 +109,41 @@ exit /b 0
|
|||||||
:BUILDING
|
:BUILDING
|
||||||
%xSH% "make clean" >> nul
|
%xSH% "make clean" >> nul
|
||||||
echo Building i2pd %tag% for win%bitness%...
|
echo Building i2pd %tag% for win%bitness%...
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build\build_win%bitness%_%tag%.log 2>&1
|
REM Build i2pd
|
||||||
|
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads%" > build\build_win%bitness%_%tag%.log 2>&1
|
||||||
|
|
||||||
|
REM Sign binary
|
||||||
|
if defined xSIGNOPTS (
|
||||||
|
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Copy binary for installer and create distribution archive
|
||||||
|
%xSH% "cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST%" >> build\build_win%bitness%_%tag%.log 2>&1
|
||||||
|
|
||||||
|
REM Clean work directory
|
||||||
|
%xSH% "make clean" >> build\build_win%bitness%_%tag%.log 2>&1
|
||||||
goto EOF
|
goto EOF
|
||||||
|
|
||||||
:BUILDING_XP
|
:BUILDING_XP
|
||||||
|
set MSYSTEM=MINGW32
|
||||||
|
set bitness=32
|
||||||
|
set "WD=C:\msys64-xp\usr\bin\"
|
||||||
|
set "xSH=%WD%bash -lc"
|
||||||
|
|
||||||
%xSH% "make clean" >> nul
|
%xSH% "make clean" >> nul
|
||||||
echo Building i2pd %tag% for winxp...
|
echo Building i2pd %tag% for winxp...
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1
|
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads%" > build\build_winxp_%tag%.log 2>&1
|
||||||
|
|
||||||
|
REM Sign binary
|
||||||
|
if defined xSIGNOPTS (
|
||||||
|
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Copy binary for installer and create distribution archive
|
||||||
|
%xSH% "cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST%" >> build\build_winxp_%tag%.log 2>&1
|
||||||
|
|
||||||
|
REM Clean work directory
|
||||||
|
%xSH% "make clean" >> build\build_winxp_%tag%.log 2>&1
|
||||||
|
goto EOF
|
||||||
|
|
||||||
:EOF
|
:EOF
|
||||||
@@ -1,16 +1,30 @@
|
|||||||
|
# Copyright (c) 2017-2022, The PurpleI2P Project
|
||||||
|
# This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
# See full license text in LICENSE file at top of project tree
|
||||||
|
|
||||||
# Based on the Qt 5 processor detection code, so should be very accurate
|
# Based on the Qt 5 processor detection code, so should be very accurate
|
||||||
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
|
# https://github.com/qt/qtbase/blob/dev/src/corelib/global/qprocessordetection.h
|
||||||
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
|
# Currently handles arm (v5, v6, v7, v8), x86 (32/64), ia64, mips (32/64, mipsel, mips64el) and ppc (32/64)
|
||||||
|
|
||||||
# Regarding POWER/PowerPC, just as is noted in the Qt source,
|
# Regarding POWER/PowerPC, just as is noted in the Qt source,
|
||||||
# "There are many more known variants/revisions that we do not handle/detect."
|
# "There are many more known variants/revisions that we do not handle/detect."
|
||||||
|
|
||||||
set(archdetect_c_code "
|
set(archdetect_c_code "
|
||||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
|
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)|| defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||||
|
#if defined(__ARM64_ARCH_8__) \\
|
||||||
|
|| defined(__aarch64__) \\
|
||||||
|
|| defined(__ARMv8__) \\
|
||||||
|
|| defined(__ARMv8_A__) \\
|
||||||
|
|| defined(_M_ARM64) \\
|
||||||
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
|
||||||
|
#error cmake_ARCH arm64
|
||||||
#if defined(__ARM_ARCH_7__) \\
|
#if defined(__ARM_ARCH_7__) \\
|
||||||
|| defined(__ARM_ARCH_7A__) \\
|
|| defined(__ARM_ARCH_7A__) \\
|
||||||
|| defined(__ARM_ARCH_7R__) \\
|
|| defined(__ARM_ARCH_7R__) \\
|
||||||
|| defined(__ARM_ARCH_7M__) \\
|
|| defined(__ARM_ARCH_7M__) \\
|
||||||
|
|| defined(__ARM_ARCH_7S__) \\
|
||||||
|
|| defined(_ARM_ARCH_7) \\
|
||||||
|
|| defined(__CORE_CORTEXA__) \\
|
||||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
|
||||||
#error cmake_ARCH armv7
|
#error cmake_ARCH armv7
|
||||||
#elif defined(__ARM_ARCH_6__) \\
|
#elif defined(__ARM_ARCH_6__) \\
|
||||||
@@ -23,6 +37,7 @@ set(archdetect_c_code "
|
|||||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
|
||||||
#error cmake_ARCH armv6
|
#error cmake_ARCH armv6
|
||||||
#elif defined(__ARM_ARCH_5TEJ__) \\
|
#elif defined(__ARM_ARCH_5TEJ__) \\
|
||||||
|
|| defined(__ARM_ARCH_5TE__) \\
|
||||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
|
||||||
#error cmake_ARCH armv5
|
#error cmake_ARCH armv5
|
||||||
#else
|
#else
|
||||||
@@ -34,6 +49,18 @@ set(archdetect_c_code "
|
|||||||
#error cmake_ARCH x86_64
|
#error cmake_ARCH x86_64
|
||||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||||
#error cmake_ARCH ia64
|
#error cmake_ARCH ia64
|
||||||
|
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||||
|
#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
|
||||||
|
#if defined(__MIPSEL__)
|
||||||
|
#error cmake_ARCH mips64el
|
||||||
|
#else
|
||||||
|
#error cmake_ARCH mips64
|
||||||
|
#endif
|
||||||
|
#elif defined(__MIPSEL__)
|
||||||
|
#error cmake_ARCH mipsel
|
||||||
|
#else
|
||||||
|
#error cmake_ARCH mips
|
||||||
|
#endif
|
||||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|
||||||
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|
||||||
|| defined(_M_MPPC) || defined(_M_PPC)
|
|| defined(_M_MPPC) || defined(_M_PPC)
|
||||||
@@ -47,7 +74,7 @@ set(archdetect_c_code "
|
|||||||
#error cmake_ARCH unknown
|
#error cmake_ARCH unknown
|
||||||
")
|
")
|
||||||
|
|
||||||
# Set ppc_support to TRUE before including this file or ppc and ppc64
|
# Set ppc_support to TRUE before including this file on ppc and ppc64
|
||||||
# will be treated as invalid architectures since they are no longer supported by Apple
|
# will be treated as invalid architectures since they are no longer supported by Apple
|
||||||
|
|
||||||
function(target_architecture output_var)
|
function(target_architecture output_var)
|
||||||
@@ -67,12 +94,14 @@ function(target_architecture output_var)
|
|||||||
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||||
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
||||||
set(osx_arch_ppc TRUE)
|
set(osx_arch_ppc TRUE)
|
||||||
|
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||||
|
set(osx_arch_ppc64 TRUE)
|
||||||
elseif("${osx_arch}" STREQUAL "i386")
|
elseif("${osx_arch}" STREQUAL "i386")
|
||||||
set(osx_arch_i386 TRUE)
|
set(osx_arch_i386 TRUE)
|
||||||
elseif("${osx_arch}" STREQUAL "x86_64")
|
elseif("${osx_arch}" STREQUAL "x86_64")
|
||||||
set(osx_arch_x86_64 TRUE)
|
set(osx_arch_x86_64 TRUE)
|
||||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
elseif("${osx_arch}" STREQUAL "arm64")
|
||||||
set(osx_arch_ppc64 TRUE)
|
set(osx_arch_arm64 TRUE)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
||||||
endif()
|
endif()
|
||||||
@@ -83,6 +112,10 @@ function(target_architecture output_var)
|
|||||||
list(APPEND ARCH ppc)
|
list(APPEND ARCH ppc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(osx_arch_ppc64)
|
||||||
|
list(APPEND ARCH ppc64)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(osx_arch_i386)
|
if(osx_arch_i386)
|
||||||
list(APPEND ARCH i386)
|
list(APPEND ARCH i386)
|
||||||
endif()
|
endif()
|
||||||
@@ -91,8 +124,8 @@ function(target_architecture output_var)
|
|||||||
list(APPEND ARCH x86_64)
|
list(APPEND ARCH x86_64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(osx_arch_ppc64)
|
if(osx_arch_arm64)
|
||||||
list(APPEND ARCH ppc64)
|
list(APPEND ARCH arm64)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
|
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#define I2Pd_AppName "i2pd"
|
#define I2Pd_AppName "i2pd"
|
||||||
#define I2Pd_Publisher "PurpleI2P"
|
#define I2Pd_Publisher "PurpleI2P"
|
||||||
; Get application version from compiled binary
|
|
||||||
; Disabled to use definition from command line
|
|
||||||
;#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe")
|
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName={#I2Pd_AppName}
|
AppName={#I2Pd_AppName}
|
||||||
@@ -27,7 +24,7 @@ ExtraDiskSpaceRequired=15
|
|||||||
|
|
||||||
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
||||||
AppVerName={#I2Pd_AppName}
|
AppVerName={#I2Pd_AppName}
|
||||||
AppCopyright=Copyright (c) 2013-2020, The PurpleI2P Project
|
AppCopyright=Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
AppPublisherURL=http://i2pd.website/
|
AppPublisherURL=http://i2pd.website/
|
||||||
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
|
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
|
||||||
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
|
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
|
||||||
|
|||||||
18
contrib/android_binary_only/.gitignore
vendored
18
contrib/android_binary_only/.gitignore
vendored
@@ -1,18 +0,0 @@
|
|||||||
gen
|
|
||||||
tests
|
|
||||||
bin
|
|
||||||
libs
|
|
||||||
log*
|
|
||||||
obj
|
|
||||||
.gradle
|
|
||||||
.idea
|
|
||||||
.externalNativeBuild
|
|
||||||
ant.properties
|
|
||||||
local.properties
|
|
||||||
build.sh
|
|
||||||
android.iml
|
|
||||||
build
|
|
||||||
gradle
|
|
||||||
gradlew
|
|
||||||
gradlew.bat
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := i2pd
|
|
||||||
LOCAL_CPP_FEATURES := rtti exceptions
|
|
||||||
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
|
|
||||||
LOCAL_STATIC_LIBRARIES := \
|
|
||||||
boost_system \
|
|
||||||
boost_date_time \
|
|
||||||
boost_filesystem \
|
|
||||||
boost_program_options \
|
|
||||||
crypto ssl \
|
|
||||||
miniupnpc
|
|
||||||
LOCAL_LDLIBS := -lz
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(IFADDRS_PATH)/ifaddrs.c \
|
|
||||||
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
|
|
||||||
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
|
|
||||||
$(DAEMON_SRC_PATH)/UnixDaemon.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/Daemon.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/UPnP.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/I2PControl.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/i2pd.cpp
|
|
||||||
include $(BUILD_EXECUTABLE)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := boost_system
|
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := boost_date_time
|
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := boost_filesystem
|
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := boost_program_options
|
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := crypto
|
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := ssl
|
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
|
||||||
LOCAL_STATIC_LIBRARIES := crypto
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := miniupnpc
|
|
||||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
|
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
APP_ABI := all
|
|
||||||
#APP_ABI += x86
|
|
||||||
#APP_ABI += x86_64
|
|
||||||
#APP_ABI += armeabi-v7a
|
|
||||||
#APP_ABI += arm64-v8a
|
|
||||||
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
|
|
||||||
APP_PLATFORM := android-14
|
|
||||||
|
|
||||||
NDK_TOOLCHAIN_VERSION := clang
|
|
||||||
APP_STL := c++_static
|
|
||||||
|
|
||||||
# Enable c++17 extensions in source code
|
|
||||||
APP_CPPFLAGS += -std=c++17 -fvisibility=default -fPIE
|
|
||||||
|
|
||||||
APP_CPPFLAGS += -DANDROID_BINARY -DANDROID -D__ANDROID__ -DUSE_UPNP
|
|
||||||
APP_LDFLAGS += -rdynamic -fPIE -pie
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
|
||||||
APP_CPPFLAGS += -DANDROID_ARM7A
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead.
|
|
||||||
#APP_OPTIM := debug
|
|
||||||
|
|
||||||
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
|
|
||||||
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
|
||||||
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
|
||||||
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
|
||||||
# change to your own
|
|
||||||
I2PD_LIBS_PATH = /path/to/libraries
|
|
||||||
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
|
|
||||||
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
|
|
||||||
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
|
|
||||||
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
|
|
||||||
|
|
||||||
# don't change me
|
|
||||||
I2PD_SRC_PATH = $(PWD)/../..
|
|
||||||
|
|
||||||
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
|
|
||||||
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
|
|
||||||
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon
|
|
||||||
2
contrib/android_binary_pack/.gitignore
vendored
2
contrib/android_binary_pack/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
archive
|
|
||||||
i2pd_*_android_binary.zip
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copyright (c) 2013-2020, The PurpleI2P Project
|
|
||||||
#
|
|
||||||
# This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
#
|
|
||||||
# See full license text in LICENSE file at top of project tree
|
|
||||||
|
|
||||||
GITDESC=$(git describe --tags)
|
|
||||||
|
|
||||||
declare -A ABILIST=(
|
|
||||||
["armeabi-v7a"]="armv7l"
|
|
||||||
["arm64-v8a"]="aarch64"
|
|
||||||
["x86"]="x86"
|
|
||||||
["x86_64"]="x86_64"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Remove old files and archives
|
|
||||||
if [ -d archive ]; then
|
|
||||||
rm -r archive
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f ../i2pd_*_android_binary.zip ]; then
|
|
||||||
rm i2pd_*_android_binary.zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prepare files for package
|
|
||||||
mkdir archive
|
|
||||||
|
|
||||||
for ABI in "${!ABILIST[@]}"; do
|
|
||||||
if [ -f ../android_binary_only/libs/${ABI}/i2pd ]; then
|
|
||||||
cp ../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
cp i2pd archive/i2pd
|
|
||||||
cp -rH ../android/assets/certificates archive/
|
|
||||||
cp -rH ../android/assets/tunnels.conf.d archive/
|
|
||||||
cp -H ../android/assets/i2pd.conf archive/
|
|
||||||
cp -H ../android/assets/tunnels.conf archive/
|
|
||||||
|
|
||||||
# Compress files
|
|
||||||
cd archive
|
|
||||||
zip -r6 ../i2pd_${GITDESC}_android_binary.zip .
|
|
||||||
|
|
||||||
# Remove temporary folder
|
|
||||||
cd ..
|
|
||||||
rm -r archive
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Copyright (c) 2013-2020, The PurpleI2P Project
|
|
||||||
#
|
|
||||||
# This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
#
|
|
||||||
# See full license text in LICENSE file at top of project tree
|
|
||||||
#
|
|
||||||
# That script written for use with Termux.
|
|
||||||
|
|
||||||
# https://stackoverflow.com/a/246128
|
|
||||||
SOURCE="${0}"
|
|
||||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
SOURCE="$(readlink "$SOURCE")"
|
|
||||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
|
||||||
done
|
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
|
|
||||||
arch=$(uname -m)
|
|
||||||
|
|
||||||
screenfind=$(which screen)
|
|
||||||
if [ -z $screenfind ]; then
|
|
||||||
echo "Can't find 'screen' installed. That script needs it!";
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z i2pd-$arch ]; then
|
|
||||||
echo "Can't find i2pd binary for your archtecture.";
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR
|
|
||||||
14
contrib/certificates/family/stormycloud.crt
Normal file
14
contrib/certificates/family/stormycloud.crt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICKDCCAc6gAwIBAgIUcPHZXtYSqGNRCD6z8gp79WUFtI0wCgYIKoZIzj0EAwIw
|
||||||
|
gZMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGlu
|
||||||
|
MRgwFgYDVQQKDA9TdG9ybXlDbG91ZCBJbmMxIzAhBgNVBAMMGnN0b3JteWNsb3Vk
|
||||||
|
LmZhbWlseS5pMnAubmV0MSQwIgYJKoZIhvcNAQkBFhVhZG1pbkBzdG9ybXljbG91
|
||||||
|
ZC5vcmcwHhcNMjIwMzE5MTU1MjU2WhcNMzIwMzE2MTU1MjU2WjCBkzELMAkGA1UE
|
||||||
|
BhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xGDAWBgNVBAoM
|
||||||
|
D1N0b3JteUNsb3VkIEluYzEjMCEGA1UEAwwac3Rvcm15Y2xvdWQuZmFtaWx5Lmky
|
||||||
|
cC5uZXQxJDAiBgkqhkiG9w0BCQEWFWFkbWluQHN0b3JteWNsb3VkLm9yZzBZMBMG
|
||||||
|
ByqGSM49AgEGCCqGSM49AwEHA0IABFUli0hvJEmowNjJVjbKEIWBJhqe973S4VdL
|
||||||
|
cJuA5yY3dC4Y998abWEox7/Y1BhnBbpJuiodA341bXKkLMXQy/kwCgYIKoZIzj0E
|
||||||
|
AwIDSAAwRQIgD12F/TfY3iV1/WDF7BSKgbD5g2MfELUIy1dtUlJQuJUCIQD69mZw
|
||||||
|
V1Z9j2x0ZsuirS3i6AMfVyTDj0RFS3U1jeHzIQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
33
contrib/certificates/reseed/echelon3_at_mail.i2p.crt
Normal file
33
contrib/certificates/reseed/echelon3_at_mail.i2p.crt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFyzCCA7OgAwIBAgIRALWNWsnQ0Vmn/99iCNT7cdQwDQYJKoZIhvcNAQELBQAw
|
||||||
|
cTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
|
||||||
|
ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGjAYBgNVBAMM
|
||||||
|
EWVjaGVsb24zQG1haWwuaTJwMB4XDTIxMTEyOTE5MzU1OVoXDTMxMTEyOTE5MzU1
|
||||||
|
OVowcTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwG
|
||||||
|
A1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGjAYBgNV
|
||||||
|
BAMMEWVjaGVsb24zQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
CgKCAgEA3pccNiQWJUS1t3QHK7rBCNKAsM2dz4szN3+3SrDy1w+rOrK8Vt5aypPU
|
||||||
|
QYUQwG+odjEPacuoRtO/W14KJl5yAI3eQS+X/cYDXmxvfm4zx5JRumYptXwJD57G
|
||||||
|
rlPHnFvk8R+Hvh+/UyqgSAZ9ZaKjEzYK4AtbYEXtopaM4U2VYN8xKjvKyWlhPdxo
|
||||||
|
kI3//qcTlSqGHHeHrkItLG1LubM1EnPu+9zI2WN2zBBRcm8ZtWqHoqFJ1zgJr/49
|
||||||
|
nMK8Lnb3I54ctva8x5+gsSk4dbG/mMsOIZekFqYJJs3+u9w5fmOYI7v9GlQr7UhE
|
||||||
|
G3MwjJ5Cj1LmLVlz/4LApZrDSd2JvwIUdGL3UW8+blaTeCPKIRvmsTeRxo1gORMF
|
||||||
|
ZH0dg39722lK7ScwOlOUX9ggzRUlYCmvnjQJZGJEUoP68QxjlQfkXZyffmMfvm6K
|
||||||
|
V6mcZ5aHMGO1lYAl40kWNJ0jGpmxJqTDhNFDEKr0TlRGVxXGWzObEOrcJ8ysRMc1
|
||||||
|
x6oXQhh79HXZcKwhZaXLx23ZvVoTfhRm4JH0SSP6XqQm35j4NI1SllEsDns29wU3
|
||||||
|
Re4wOWJCCYlPG3CtY32CinwQRoVgtiJk18W8+Pxw7sBFq8sL5L0Z+5bB6nTkBfV6
|
||||||
|
7OrZGWL0i344zQE0e3yIsLih+5Wyqw6RSSMysenl3alnUB9EvE0CAwEAAaNeMFww
|
||||||
|
DgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAP
|
||||||
|
BgNVHRMBAf8EBTADAQH/MBoGA1UdDgQTBBFlY2hlbG9uM0BtYWlsLmkycDANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEAaUMnMYtNFBl9dFON6e4EjYo53Wknj61uIVO11dvLqjnh
|
||||||
|
7X6guPML+GgNZsPQGLu7Bqw4hVgy/cV5AlFc7SXOhzpaYo1ycpjg3Ws1VK2wrk7+
|
||||||
|
4bvUThNcS1KZVFDdRE62549rYNfYNfPxXvccOTW9meTCC1kLHerh65ySDr9J02O6
|
||||||
|
o5Mf685PgBasBH6dlosOLTtee2gRLNFcAluQYKerawS1gDys5239UNHPCqTgO+Od
|
||||||
|
FiKfl48OIOzPGLKEf4lXC+lkwZElewShrHhzd8aGueedTi0UHOtQuY7ocsofqXc8
|
||||||
|
OnyT/y2X6wn/YkzviKgfxYDSI7FJiUgXCPcT0jUNmuwR168yL5BfzoQmrCvlOOQg
|
||||||
|
P7ibdBJ6UkL8pRpv/SYpvaX/kf4agYtwh5IL9FzNCwNu54ZC6JilLUhYAU38Eolq
|
||||||
|
OZ/cGiMoSFQIeBPvB3cdsqEud9W4P+MqN5A76fMzdVV77lGsIS1eCGMceR3CjOiF
|
||||||
|
6SdAskcBZWhFiRNQweC0iv57/nPCeTCuNAqbZSHd7zC1AKhNmmsKSJUJQCGijcce
|
||||||
|
P8Gl0AFfZneN2bVEFvJ/zd71pD8ll1Gkju16bfdWn0V4NRaxFiXNr2bL+ah9blud
|
||||||
|
EXOomE3R6ow1QZk+Gnpy3wh9jfwlrJuFoANvHnv4WREbdjwr//71XjBri5p1wPE=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFfzCCA2egAwIBAgIESg3kkzANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQZWNoZWxvbkBtYWls
|
|
||||||
LmkycDAeFw0xNDA3MzExNjQ3MDJaFw0yNDA3MzAxNjQ3MDJaMHAxCzAJBgNVBAYT
|
|
||||||
AlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9u
|
|
||||||
eW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQDDBBlY2hlbG9uQG1h
|
|
||||||
aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmcEgLwwhzLNe
|
|
||||||
XLOMSrhwB8hWpOhfjo4s6S/wjBtjjUc8nI3D0hSn3HY26p0rvcvNEWexPUpPULmC
|
|
||||||
exGkU463nu7PiFONiORI1eJAiUFHibRiaA7Wboyo38pO73KirwjG07Y+Ua0jp+HS
|
|
||||||
+4FQ/I/9H/bPplReTOU/6hmRbgQ69U8nE68HzZHQxP68yVJ2rPHSXMPhF4R1h0G1
|
|
||||||
1mCAT+TgTsnwHNGF77XHJnY4/M4e2cgycEZjZow36C3t2mNDVkMgF19QQeb9WmLR
|
|
||||||
zREn3nq9BJqHpUkn9yWw0kKXTZSds+7UxESfzf3BzK0+hky2fh5H+qbYAo2lz4yj
|
|
||||||
81MXTAu+4RRkg4DBLlF+2dkclhwQLxxzvkRC6tPkn5i33Yltg7EfzA9IoQ05potJ
|
|
||||||
I+iOcF+aStfFgFj9u3B5UkcF4P0cH1QD3c6BK4hIezQYqRoPly1gHqg+XdwjG/dr
|
|
||||||
4as7HA9FTz3p2E8nClpIC1x3hfgwAdfd29aeBxO1WW/z99iMF7TBAF+u5T86XEW1
|
|
||||||
WpknqCbTli36yJ8a5fPWxZHrryBRJT5yLxejjFeadtutBSwljiVFq+Y38VqwFivq
|
|
||||||
VLiBt7IxAsZ8iilgfnnnAvBH6chWfSKb4H7kB4TJvDiV96QmmvoEaWYNHZozMhyK
|
|
||||||
tO3b5w+xqbJXyCLA3Q75jD0km76hjcECAwEAAaMhMB8wHQYDVR0OBBYEFAHQcAam
|
|
||||||
QRS/EUhuCSr9pB4Ux0rYMA0GCSqGSIb3DQEBDQUAA4ICAQBq1+1QLmgLAjrTg3tb
|
|
||||||
4XKgAVICQRoBDNUEobQg3pYeUX9eFNya2RxNljuvYpwT80ilGMPOXcjddmr5ngiK
|
|
||||||
dbGRcuuJk9MPEHtPaPT3+JJlvKQ3B3g2wva2Wz2OAyLZUGQs389K4nTbwh4QF0n2
|
|
||||||
aHFL8BHiD62hiKnCoNaW4ZovUNNvOxo9lMyAiaFU2gqQNcdad8hP9EAllbvbxDx9
|
|
||||||
Tjww2UbwQUIHS9rna4Tlu+f0hDXTWIutc2A51W2fJCb7L3+lYO7Wv55ND/WtryLZ
|
|
||||||
XpMp27+MpuEnN3kQmz/l9R0hIJsWc/x9GQkjm5wEaIZEyTtenqwRKGmVCtAj0Pgv
|
|
||||||
jn1L3/lWmrNq+OZHb/QeyfKtA3nXfQKVmT98ewQiK/S5i1xIAXCJPytOD887b/o1
|
|
||||||
cdurTmCiZMwgiQ+HLJqCg3MDa5mvKqRkRdZXfE6aQWEcSbpAhpV15R17q7L+Fg0W
|
|
||||||
shLSNucxyGNU8PjiC/nOmqfqUiPiMltJjPmscxBLim8foyxjakC4+6N6m+Jzgznj
|
|
||||||
PocBehFAfKYj66XEwzIBN7Z2uuXoYH9YptkocFjTzvchcryVulDWZ4FWxreUMhpM
|
|
||||||
4oyjjhSB4tB9clXlwMqg577q3D6Ms0zLTqsztyPN3zr6jGev3jpVq7Q1GOlciHPv
|
|
||||||
JNJOWTH/Vas1W6XlwGcOOAARTQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
32
contrib/certificates/reseed/hiduser0_at_mail.i2p.crt
Normal file
32
contrib/certificates/reseed/hiduser0_at_mail.i2p.crt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFgTCCA2mgAwIBAgIETWAY1DANBgkqhkiG9w0BAQ0FADBxMQswCQYDVQQGEwJY
|
||||||
|
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt
|
||||||
|
b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEaMBgGA1UEAwwRaGlkdXNlcjBAbWFp
|
||||||
|
bC5pMnAwHhcNMjExMjEzMTU0MDI3WhcNMzExMjExMTU0MDI3WjBxMQswCQYDVQQG
|
||||||
|
EwJYWDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5v
|
||||||
|
bnltb3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEaMBgGA1UEAwwRaGlkdXNlcjBA
|
||||||
|
bWFpbC5pMnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXnjJ8UQ0f
|
||||||
|
lHHpfPMiHofBPSuL4sbOJY6fOXwPhSg/h6THh9DS/ZWmJXQ3qRD0glDVtv4/Dr/9
|
||||||
|
ldGQ5eltF9iCFXCQlMEy2HjQrBKq0nsl7RpYK12cyMaod0kkzCUk9ITLi9CmHM3Z
|
||||||
|
gQZcmG8TWjFEpDR+idx/QkQt2pcO4vzWlDit3Vh4ivnbX5jGQHbsVjQEMQWxr+pX
|
||||||
|
dsS+YQpjZ6RBmrooGTPO8QDOOeYLAn0lCjmffc/kzIH9E/p4/O0rOpyhVYbdxUD1
|
||||||
|
5wkqN9l4yrtxmORG/PudnRQQ0r4TUq8vsxfGY0Euo9IbhgXF2Parel1ZhDxB1WZV
|
||||||
|
VwWtgLIh9jGA1UMa8SYKnEfp8LWNZ3b3mUUnZb3kMrLk6jGYRWNsHmamhd4mC7AZ
|
||||||
|
qf/8lOkEIw3bPd3YguCDRVcLui5BwIEZmqXg8uoESxfO/sW3pBrN/8M7MkTex9kN
|
||||||
|
vjitGDDXvenK27qmNgZxbBlX72yTSfys7XTYTLnxZC8AwdAo2Wz9Z6HhGiPonf2h
|
||||||
|
vZkc9ZxuE0jFIrsbJra4X7iyjXgi4vV4ARNg/9Ft6F4/OIbECgeDcBQqq4TlT2bZ
|
||||||
|
EfWVrBbqXoj5vNsLigIkd+AyUNwPYEcB5IFSiiOh98pC7BH3pg0m8U5YBjxe1i+9
|
||||||
|
EQOOG0Qtx+JigXZHu6bGE0Twy9zy+UzoKQIDAQABoyEwHzAdBgNVHQ4EFgQUGK1b
|
||||||
|
0DkL6aLalcfBc/Uj/SF08C0wDQYJKoZIhvcNAQENBQADggIBAMpXM82bJDpH1TlH
|
||||||
|
TvhU3Z7nfZdvEhOQfujaFUYiuNripuEKcFGn948+DvAG0FUN+uNlJoqOVs8D7InD
|
||||||
|
gWlA9zpqw5Cl5Hij/Wns9QbXuAHJeA23fVUoaM2A6v9ifcIQ1A+rDuRQAo6/64KW
|
||||||
|
ChTg2e99RBpfGOyqgeh7tLLe0lPPekVpKHFuXabokaKRDuBcVHcUL4tWXe3dcyqa
|
||||||
|
Ej/PJrrS+nWL0EGZ4q80CEd2LPuDzPxNGCJt/R7ZfadENWajcgcXGceh1QBzozrB
|
||||||
|
SL/Ya6wF9SrsB7V/r5wX0LM4ZdDaLWbtmUe5Op0h/ZMH25Sa8xAXVz+O9L6sWSoO
|
||||||
|
FaiYTOvAiyyPz+nsxKa3xYryDHno7eKSt+hGOcaurhxbdZaEFY/CegEc73tCt9xK
|
||||||
|
e9qF8O/WkDLmixuErw3f5en4IfzGR7p3lJAwW/8WD8C6HS39h/eE7dVZNaWgtQnZ
|
||||||
|
SgGjgZMTJqTcQ3aZmfuCZefxGFok8w6AIkdbnd1pdMBRjYu8aXgl2hQSB9ZADDE9
|
||||||
|
R5d3rXi0PkSFLIvsNjVa5KXrZk/tB0Hpfmepq7CufBqjP/LG9TieRoXzLYUKFF74
|
||||||
|
QRwjP+y7AJ+VDUTpY1NV1P+k+2raubU2bOnLF3zL5DtyoyieGPhyeMMvp0fRIxdg
|
||||||
|
bSl5VHgPXHNM8mcnndMAuzvl7jEK
|
||||||
|
-----END CERTIFICATE-----
|
||||||
34
contrib/certificates/reseed/i2p-reseed_at_mk16.de.crt
Normal file
34
contrib/certificates/reseed/i2p-reseed_at_mk16.de.crt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFzTCCA7WgAwIBAgIQeUqFi0fHNQopg6BZlBLhVzANBgkqhkiG9w0BAQsFADBy
|
||||||
|
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
||||||
|
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEbMBkGA1UEAwwS
|
||||||
|
aTJwLXJlc2VlZEBtazE2LmRlMB4XDTIyMDIwNTE3MzkzM1oXDTMyMDIwNTE3Mzkz
|
||||||
|
M1owcjELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwG
|
||||||
|
A1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGzAZBgNV
|
||||||
|
BAMMEmkycC1yZXNlZWRAbWsxNi5kZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
|
||||||
|
AgoCggIBAMYxs2D2xpN/8blGawvAlU9DemHIxApOEwaLNfh8aAvqEdB41NTqcx4U
|
||||||
|
H8VchSormCfkCvezuMHO+K2HX7ihEZ1v6tbr6aX6hY9UZUyDDYsKmJoB1oKEhddv
|
||||||
|
5UYfcWPE2eSykdFsWgTQD6Z+cRQWHEoCzb7qc+Jrw6KcnHMD0VrmBrEQPzTBxMHW
|
||||||
|
4HC97PVkSLJTDArnS6ZiX4IbWRPw/mbpJT6EoVZo8J/it0pdn/X4KodEXDcnEMSe
|
||||||
|
VRulfZH/nSmOOvKhoHPckmgz/u66BlnuSYXEIB0KfDIcAlSYiPDxGnAemTozJYXA
|
||||||
|
UVMeFMs+YE5wiPgzzu+vpC31xtZLq0gyaCfgEi1P9j2ES/8pH3Gw6W2OH4kBx+jO
|
||||||
|
TBsfI+ph6qFZ3WWT23MRVyl3ATuI/GHdczTxD9JaOn74lLI+Hnu8wXnyztVWkTMB
|
||||||
|
4sAnzjdeHkvNDyQ10vSaN0HnGfg6zuAuUSqFQujFF8Vg8ZCcsh8GouWfzYDvi9mj
|
||||||
|
9pfxx8v6UCC719I4J9CgFjWnn2Hqez3fO8fFulY61VPyCCZp4gKWbI2SIQP/n5gz
|
||||||
|
ecYJRrJoem+rYfEQ/fwxROsvm3fCO4D6dt7ILRuX286GDIw2qSvP1zZVAioMwSj3
|
||||||
|
9CAjKLwD/BhTRiMOlpaVv6IWqjtevbiaIKvbHTnoxvkGsDqe3gJhAgMBAAGjXzBd
|
||||||
|
MA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
|
||||||
|
DwYDVR0TAQH/BAUwAwEB/zAbBgNVHQ4EFAQSaTJwLXJlc2VlZEBtazE2LmRlMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4ICAQAb+x6XpJdjpVYw2bvWIUbatQJwq0YaEW5W61xGLgIG
|
||||||
|
a37oll3YZbSY9Vk+N1cE0f61L3ya4Ioz6zlH/MO2zUG/dEk8vqdgIPUYJvyF7wwF
|
||||||
|
w3/G4VMaDKOJx4bAZNmaiRFGYNhCOhCnZx6uZGrLNIJ2Dc+mflrGmGwYphtXVV3e
|
||||||
|
Iv+ki3gSRgfXuMfKi4B5bLPnz7XDe4TSmwZZSRac4ly4KqmZUyntqbilRxaGTej3
|
||||||
|
VYJ1tac8yppyk5N3VopMQNmBarNZG16wSOTD7CtKgn382jgRW8cR7BMeqhORivp0
|
||||||
|
ZnPJFhzh4uthdlPdXXo6lxfvZjfiwlDPytvEu2QBz3urTgopGqRLcTBnLucWg9li
|
||||||
|
OSy9z7hNEnIN3iIJJAwI1wBdDa7K0h3PFBbIUa7X2ybn81VeNSfO25Lo8YTZEKsc
|
||||||
|
wcThJrNV6qOQv8rM/7aXugi6+VzPlCR+18iKRbebCnlqGR2dT1zFtj3negtOkrjo
|
||||||
|
LH4H6VUr3q2Ie56IubS2hUKiUkDm0ckP3Vum35GGntyEAzl6uyog0hJFOJb3aq30
|
||||||
|
YQLzyVEOz8NnA+32oMRzJJdDxQ7pqG5fgq7EF4d++YSgEfdVXxvfgXQ6m3jAyC7Z
|
||||||
|
p/gX4rlxNsjeGU3Ds51wkmhH4IB1aSQr52PE6RaBhhh3SmADEv6S/3eGvE4F4MN5
|
||||||
|
2Q==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -110,8 +110,8 @@ port = 7070
|
|||||||
# user = i2pd
|
# user = i2pd
|
||||||
# pass = changeme
|
# pass = changeme
|
||||||
## Select webconsole language
|
## Select webconsole language
|
||||||
## Currently supported english (default), afrikaans, armenian, russian,
|
## Currently supported english (default), afrikaans, armenian, french, german,
|
||||||
## turkmen, ukrainian and uzbek languages
|
## russian, turkmen, ukrainian and uzbek languages
|
||||||
# lang = english
|
# lang = english
|
||||||
|
|
||||||
[httpproxy]
|
[httpproxy]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
||||||
|
|
||||||
Name: i2pd-git
|
Name: i2pd-git
|
||||||
Version: 2.40.0
|
Version: 2.42.1
|
||||||
Release: git%{git_hash}%{?dist}
|
Release: git%{git_hash}%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd
|
Conflicts: i2pd
|
||||||
@@ -32,7 +32,7 @@ Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
|
|||||||
C++ implementation of I2P.
|
C++ implementation of I2P.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q -n i2pd-openssl
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@@ -57,8 +57,14 @@ cd build
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
%if 0%{?fedora} >= 35
|
%if 0%{?rhel} == 9
|
||||||
pushd redhat-linux-build
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 35
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
%else
|
%else
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?fedora} >= 33
|
||||||
pushd %{_target_platform}
|
pushd %{_target_platform}
|
||||||
@@ -71,10 +77,16 @@ pushd build
|
|||||||
|
|
||||||
make %{?_smp_mflags}
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?rhel} == 9
|
||||||
popd
|
popd
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia} > 7
|
%if 0%{?mageia} > 7
|
||||||
popd
|
popd
|
||||||
%endif
|
%endif
|
||||||
@@ -82,8 +94,14 @@ popd
|
|||||||
%install
|
%install
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
%if 0%{?fedora} >= 35
|
%if 0%{?rhel} == 9
|
||||||
pushd redhat-linux-build
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 35
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
%else
|
%else
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?fedora} >= 33
|
||||||
pushd %{_target_platform}
|
pushd %{_target_platform}
|
||||||
@@ -99,14 +117,14 @@ chrpath -d i2pd
|
|||||||
%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd
|
%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd
|
||||||
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
||||||
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
||||||
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1
|
%{__install} -D -m 644 %{_builddir}/i2pd-openssl/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1
|
||||||
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
%{__cp} -r %{_builddir}/i2pd-openssl/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
||||||
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
|
%{__cp} -r %{_builddir}/i2pd-openssl/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
|
||||||
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
||||||
|
|
||||||
|
|
||||||
@@ -146,6 +164,16 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
|
||||||
|
- update to 2.42.1
|
||||||
|
|
||||||
|
* Sun May 22 2022 orignal <orignal@i2pmail.org> - 2.42.0
|
||||||
|
- update to 2.42.0
|
||||||
|
|
||||||
|
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
||||||
|
- update to 2.41.0
|
||||||
|
- fixed build on Fedora Copr over openssl trunk code
|
||||||
|
|
||||||
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
|
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
|
||||||
- update to 2.40.0
|
- update to 2.40.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.40.0
|
Version: 2.42.1
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd-git
|
Conflicts: i2pd-git
|
||||||
@@ -54,8 +54,14 @@ cd build
|
|||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if 0%{?fedora} >= 35
|
%if 0%{?rhel} == 9
|
||||||
pushd redhat-linux-build
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 35
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
%else
|
%else
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?fedora} >= 33
|
||||||
pushd %{_target_platform}
|
pushd %{_target_platform}
|
||||||
@@ -68,10 +74,16 @@ pushd build
|
|||||||
|
|
||||||
make %{?_smp_mflags}
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?rhel} == 9
|
||||||
popd
|
popd
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia} > 7
|
%if 0%{?mageia} > 7
|
||||||
popd
|
popd
|
||||||
%endif
|
%endif
|
||||||
@@ -79,8 +91,14 @@ popd
|
|||||||
%install
|
%install
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
%if 0%{?fedora} >= 35
|
%if 0%{?rhel} == 9
|
||||||
pushd redhat-linux-build
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 35
|
||||||
|
%if 0%{?fedora} < 37
|
||||||
|
pushd redhat-linux-build
|
||||||
|
%endif
|
||||||
%else
|
%else
|
||||||
%if 0%{?fedora} >= 33
|
%if 0%{?fedora} >= 33
|
||||||
pushd %{_target_platform}
|
pushd %{_target_platform}
|
||||||
@@ -143,6 +161,15 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
|
||||||
|
- update to 2.42.1
|
||||||
|
|
||||||
|
* Sun May 22 2022 orignal <orignal@i2pmail.org> - 2.42.0
|
||||||
|
- update to 2.42.0
|
||||||
|
|
||||||
|
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
||||||
|
- update to 2.41.0
|
||||||
|
|
||||||
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
|
* Mon Nov 29 2021 orignal <i2porignal@yandex.ru> - 2.40.0
|
||||||
- update to 2.40.0
|
- update to 2.40.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2021-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -15,16 +15,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--main-bg-color: #FAFAFA;
|
--main-bg-color: #fafafa;
|
||||||
--main-text-color: #103456;
|
--main-text-color: #103456;
|
||||||
--main-link-color: #894C84;
|
--main-link-color: #894c84;
|
||||||
|
--main-link-hover-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
:root {
|
||||||
--main-bg-color: #181818;
|
--main-bg-color: #242424;
|
||||||
--main-text-color: #156A3D;
|
--main-text-color: #17ab5c;
|
||||||
--main-link-color: #894C84;
|
--main-link-color: #bf64b7;
|
||||||
|
--main-link-hover-color: #000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ a, .slide label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a:hover, .slide label:hover, button[type=submit]:hover {
|
a:hover, .slide label:hover, button[type=submit]:hover {
|
||||||
color: #FAFAFA;
|
color: var(--main-link-hover-color);
|
||||||
background: var(--main-link-color);
|
background: var(--main-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -58,12 +58,16 @@ namespace util
|
|||||||
bool Daemon_Singleton::IsService () const
|
bool Daemon_Singleton::IsService () const
|
||||||
{
|
{
|
||||||
bool service = false;
|
bool service = false;
|
||||||
#ifndef _WIN32
|
|
||||||
i2p::config::GetOption("service", service);
|
i2p::config::GetOption("service", service);
|
||||||
#endif
|
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Daemon_Singleton::setDataDir(std::string path)
|
||||||
|
{
|
||||||
|
if (path != "")
|
||||||
|
DaemonDataDir = path;
|
||||||
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::init(int argc, char* argv[]) {
|
bool Daemon_Singleton::init(int argc, char* argv[]) {
|
||||||
return init(argc, argv, nullptr);
|
return init(argc, argv, nullptr);
|
||||||
}
|
}
|
||||||
@@ -74,7 +78,13 @@ namespace util
|
|||||||
i2p::config::ParseCmdline(argc, argv);
|
i2p::config::ParseCmdline(argc, argv);
|
||||||
|
|
||||||
std::string config; i2p::config::GetOption("conf", config);
|
std::string config; i2p::config::GetOption("conf", config);
|
||||||
std::string datadir; i2p::config::GetOption("datadir", datadir);
|
std::string datadir;
|
||||||
|
if(DaemonDataDir != "") {
|
||||||
|
datadir = DaemonDataDir;
|
||||||
|
} else {
|
||||||
|
i2p::config::GetOption("datadir", datadir);
|
||||||
|
}
|
||||||
|
|
||||||
i2p::fs::DetectDataDir(datadir, IsService());
|
i2p::fs::DetectDataDir(datadir, IsService());
|
||||||
i2p::fs::Init();
|
i2p::fs::Init();
|
||||||
|
|
||||||
@@ -151,11 +161,7 @@ namespace util
|
|||||||
|
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
#ifdef MESHNET
|
|
||||||
// manual override for meshnet
|
|
||||||
ipv4 = false;
|
|
||||||
ipv6 = true;
|
|
||||||
#endif
|
|
||||||
// ifname -> address
|
// ifname -> address
|
||||||
std::string ifname; i2p::config::GetOption("ifname", ifname);
|
std::string ifname; i2p::config::GetOption("ifname", ifname);
|
||||||
if (ipv4 && i2p::config::IsDefault ("address4"))
|
if (ipv4 && i2p::config::IsDefault ("address4"))
|
||||||
@@ -244,6 +250,18 @@ namespace util
|
|||||||
if (!ipv4 && !ipv6)
|
if (!ipv4 && !ipv6)
|
||||||
i2p::context.SetStatus (eRouterStatusMesh);
|
i2p::context.SetStatus (eRouterStatusMesh);
|
||||||
}
|
}
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
bool published; i2p::config::GetOption("ssu2.published", published);
|
||||||
|
if (published)
|
||||||
|
{
|
||||||
|
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
|
||||||
|
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
|
||||||
|
}
|
||||||
|
|
||||||
bool transit; i2p::config::GetOption("notransit", transit);
|
bool transit; i2p::config::GetOption("notransit", transit);
|
||||||
i2p::context.SetAcceptsTunnels (!transit);
|
i2p::context.SetAcceptsTunnels (!transit);
|
||||||
@@ -377,6 +395,7 @@ namespace util
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
|
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
|
||||||
LogPrint(eLogInfo, "Daemon: Starting Transports");
|
LogPrint(eLogInfo, "Daemon: Starting Transports");
|
||||||
@@ -384,7 +403,7 @@ namespace util
|
|||||||
if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled");
|
if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled");
|
||||||
|
|
||||||
i2p::transport::transports.SetCheckReserved(checkInReserved);
|
i2p::transport::transports.SetCheckReserved(checkInReserved);
|
||||||
i2p::transport::transports.Start(ntcp2, ssu);
|
i2p::transport::transports.Start(ntcp2, ssu, ssu2);
|
||||||
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
|
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
|
||||||
LogPrint(eLogInfo, "Daemon: Transports started");
|
LogPrint(eLogInfo, "Daemon: Transports started");
|
||||||
else
|
else
|
||||||
@@ -404,6 +423,10 @@ namespace util
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
||||||
|
d.httpServer->SetDaemonStop (std::bind (Daemon_Singleton::stop, this));
|
||||||
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
|
d.httpServer->SetDaemonGracefulTimer (std::bind (gracefulShutdownInterval, this));
|
||||||
|
#endif
|
||||||
d.httpServer->Start();
|
d.httpServer->Start();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ namespace util
|
|||||||
virtual bool stop ();
|
virtual bool stop ();
|
||||||
virtual void run () {};
|
virtual void run () {};
|
||||||
|
|
||||||
|
virtual void setDataDir (std::string path);
|
||||||
|
|
||||||
bool isDaemon;
|
bool isDaemon;
|
||||||
bool running;
|
bool running;
|
||||||
|
|
||||||
@@ -41,6 +43,10 @@ namespace util
|
|||||||
// d-pointer for httpServer, httpProxy, etc.
|
// d-pointer for httpServer, httpProxy, etc.
|
||||||
class Daemon_Singleton_Private;
|
class Daemon_Singleton_Private;
|
||||||
Daemon_Singleton_Private &d;
|
Daemon_Singleton_Private &d;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string DaemonDataDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(QT_GUI_LIB) // check if QT
|
#if defined(QT_GUI_LIB) // check if QT
|
||||||
@@ -74,9 +80,12 @@ namespace util
|
|||||||
bool stop ();
|
bool stop ();
|
||||||
void run ();
|
void run ();
|
||||||
|
|
||||||
bool isGraceful;
|
void SetIsGraceful (bool state) { m_isGraceful = state; };
|
||||||
|
const bool GetIsGraceful () { return m_isGraceful; };
|
||||||
|
|
||||||
DaemonWin32 ():isGraceful(false) {}
|
private:
|
||||||
|
|
||||||
|
bool m_isGraceful;
|
||||||
};
|
};
|
||||||
#elif (defined(ANDROID) && !defined(ANDROID_BINARY))
|
#elif (defined(ANDROID) && !defined(ANDROID_BINARY))
|
||||||
#define Daemon i2p::util::DaemonAndroid::Instance()
|
#define Daemon i2p::util::DaemonAndroid::Instance()
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ namespace i2p
|
|||||||
if (pid < 0) // error
|
if (pid < 0) // error
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not fork: ", strerror(errno));
|
LogPrint(eLogError, "Daemon: Could not fork: ", strerror(errno));
|
||||||
|
std::cerr << "i2pd: Could not fork: " << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +83,14 @@ namespace i2p
|
|||||||
if (sid < 0)
|
if (sid < 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not create process group.");
|
LogPrint(eLogError, "Daemon: Could not create process group.");
|
||||||
|
std::cerr << "i2pd: Could not create process group." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string d = i2p::fs::GetDataDir();
|
std::string d = i2p::fs::GetDataDir();
|
||||||
if (chdir(d.c_str()) != 0)
|
if (chdir(d.c_str()) != 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not chdir: ", strerror(errno));
|
LogPrint(eLogError, "Daemon: Could not chdir: ", strerror(errno));
|
||||||
|
std::cerr << "i2pd: Could not chdir: " << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +147,7 @@ namespace i2p
|
|||||||
if (pidFH < 0)
|
if (pidFH < 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno));
|
LogPrint(eLogError, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno));
|
||||||
|
std::cerr << "i2pd: Could not create pid file " << pidfile << ": " << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +155,7 @@ namespace i2p
|
|||||||
if (lockf(pidFH, F_TLOCK, 0) != 0)
|
if (lockf(pidFH, F_TLOCK, 0) != 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno));
|
LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno));
|
||||||
|
std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -159,7 +164,8 @@ namespace i2p
|
|||||||
ftruncate(pidFH, 0);
|
ftruncate(pidFH, 0);
|
||||||
if (write(pidFH, pid, strlen(pid)) < 0)
|
if (write(pidFH, pid, strlen(pid)) < 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not write pidfile: ", strerror(errno));
|
LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
|
||||||
|
std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
@@ -13,7 +15,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#include "Win32Service.h"
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
@@ -37,8 +39,26 @@ namespace util
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
i2p::win32::SetIsGraceful (std::bind (&DaemonWin32::SetIsGraceful, this, std::placeholders::_1));
|
||||||
|
i2p::win32::GetIsGraceful (std::bind (&DaemonWin32::GetIsGraceful, this));
|
||||||
|
|
||||||
if (!Daemon_Singleton::init(argc, argv))
|
if (!Daemon_Singleton::init(argc, argv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (isDaemon)
|
||||||
|
{
|
||||||
|
LogPrint(eLogDebug, "Daemon: running as service");
|
||||||
|
I2PService service((PSTR)SERVICE_NAME);
|
||||||
|
service.SetDaemonStart (std::bind (&DaemonWin32::start, this));
|
||||||
|
service.SetDaemonStop (std::bind (&DaemonWin32::stop, this));
|
||||||
|
if (!I2PService::Run(service))
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
|
||||||
*
|
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
*
|
|
||||||
* See full license text in LICENSE file at top of project tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HTTP_SERVER_RESOURCES_H__
|
|
||||||
#define HTTP_SERVER_RESOURCES_H__
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace http
|
|
||||||
{
|
|
||||||
const std::string itoopieFavicon =
|
|
||||||
"data:image/png;base64,"
|
|
||||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx"
|
|
||||||
"jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0"
|
|
||||||
"d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB"
|
|
||||||
"vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn"
|
|
||||||
"cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP"
|
|
||||||
"6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps"
|
|
||||||
"/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X"
|
|
||||||
"+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/"
|
|
||||||
"z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/"
|
|
||||||
"P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am"
|
|
||||||
"+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM"
|
|
||||||
"EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1"
|
|
||||||
"oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ"
|
|
||||||
"JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ"
|
|
||||||
"RU5ErkJggg==";
|
|
||||||
|
|
||||||
// bundled style sheet
|
|
||||||
const std::string internalCSS =
|
|
||||||
"<style>\r\n"
|
|
||||||
":root { --main-bg-color: #FAFAFA; --main-text-color: #103456; --main-link-color: #894C84; }\r\n"
|
|
||||||
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #181818; --main-text-color: #156A3D; --main-link-color: #894C84; } }\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: #FAFAFA; background: var(--main-link-color)}\r\n"
|
|
||||||
"a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color)}\r\n"
|
|
||||||
".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color)}\r\n"
|
|
||||||
".wrapper { margin: 0 auto; padding: 1em; max-width: 64em}\r\n"
|
|
||||||
".menu { display: block; float: left; overflow: hidden; padding: 4px; max-width: 12em; white-space: nowrap; text-overflow: ellipsis}\r\n"
|
|
||||||
".listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap}\r\n"
|
|
||||||
".tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap}\r\n"
|
|
||||||
".content { float: left; font-size: 1em; margin-left: 2em; padding: 4px; max-width: 50em; overflow: auto}\r\n"
|
|
||||||
".tunnel.established { color: #56B734}\r\n"
|
|
||||||
".tunnel.expiring { color: #D3AE3F}\r\n"
|
|
||||||
".tunnel.failed { color: #D33F3F}\r\n"
|
|
||||||
".tunnel.building { color: #434343}\r\n"
|
|
||||||
"caption { font-size: 1.5em; text-align: center; color: var(--main-link-color)}\r\n"
|
|
||||||
"table { display: table; border-collapse: collapse; text-align: center}\r\n"
|
|
||||||
"table.extaddr { text-align: left}\r\n"
|
|
||||||
"table.services { width: 100%}\r\n"
|
|
||||||
"textarea { background-color: var(--main-bg-color); color: var(--main-text-color); word-break: break-all}\r\n"
|
|
||||||
".streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis}\r\n"
|
|
||||||
".slide div.slidecontent, .slide [type=\"checkbox\"] { display: none}\r\n"
|
|
||||||
".slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0}\r\n"
|
|
||||||
".disabled { color: #D33F3F}\r\n"
|
|
||||||
".enabled { color: #56B734}\r\n"
|
|
||||||
"button[type=submit] { background-color: transparent; color: var(--main-link-color); text-decoration: none;\r\n"
|
|
||||||
" padding: 5px; border: 1px solid var(--main-link-color); font-size: 14px}\r\n"
|
|
||||||
"input, select, select option { background-color: var(--main-bg-color); color: var(--main-link-color); padding: 5px;\r\n"
|
|
||||||
" border: 1px solid var(--main-link-color); font-size: 14px}\r\n"
|
|
||||||
"input:focus, select:focus, select option:focus { outline: none}\r\n"
|
|
||||||
"input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none}\r\n"
|
|
||||||
"@media screen and (max-width: 1150px) { /* adaptive style */\r\n"
|
|
||||||
" .wrapper { max-width: 58em; }\r\n"
|
|
||||||
" .content { max-width: 40em; }\r\n"
|
|
||||||
"}\r\n"
|
|
||||||
"@media screen and (max-width: 980px) { body { font: 100%/1.2em sans-serif; padding: 1.2em 0 0 0; }\r\n"
|
|
||||||
" .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px; text-align: center; }\r\n"
|
|
||||||
" .menu a, .commands a { display: inline-block; padding: 4px; }\r\n"
|
|
||||||
" .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%; text-align: center; }\r\n"
|
|
||||||
" a, .slide label { display: block; }\r\n"
|
|
||||||
" .header { margin: unset; font-size: 1.5em; }\r\n"
|
|
||||||
" small { display: block }\r\n"
|
|
||||||
" a.button { appearance: button; text-decoration: none; margin-top: 10px; padding: 6px; border: 2px solid var(--main-link-color);\r\n"
|
|
||||||
" border-radius: 5px; width: -webkit-fill-available; }\r\n"
|
|
||||||
" input, select { width: 35%; text-align: center; padding: 5px; border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 18px; }\r\n"
|
|
||||||
" table.extaddr { margin: auto; text-align: unset; }\r\n"
|
|
||||||
" textarea { width: -webkit-fill-available; height: auto; padding: 5px; border: 2px solid var(--main-link-color);\r\n"
|
|
||||||
" border-radius: 5px; font-size: 12px; }\r\n"
|
|
||||||
" button[type=submit] { padding: 5px 15px; background: transparent; border: 2px solid var(--main-link-color); cursor: pointer;\r\n"
|
|
||||||
" border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
|
||||||
"}\r\n"
|
|
||||||
"</style>\r\n";
|
|
||||||
|
|
||||||
// for external style sheet
|
|
||||||
std::string externalCSS;
|
|
||||||
|
|
||||||
} // http
|
|
||||||
} // i2p
|
|
||||||
|
|
||||||
#endif /* HTTP_SERVER_RESOURCES_H__ */
|
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
@@ -79,8 +87,7 @@ namespace client
|
|||||||
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
||||||
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
|
||||||
&I2PControlService::TunnelsSuccessRateHandler;
|
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||||
|
|
||||||
@@ -278,11 +285,16 @@ namespace client
|
|||||||
ss << "\"" << name << "\":" << value;
|
ss << "\"" << name << "\":" << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const
|
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes) const
|
||||||
{
|
{
|
||||||
ss << "\"" << name << "\":";
|
ss << "\"" << name << "\":";
|
||||||
if (value.length () > 0)
|
if (value.length () > 0)
|
||||||
|
{
|
||||||
|
if (quotes)
|
||||||
ss << "\"" << value << "\"";
|
ss << "\"" << value << "\"";
|
||||||
|
else
|
||||||
|
ss << value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ss << "null";
|
ss << "null";
|
||||||
}
|
}
|
||||||
@@ -406,7 +418,7 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL));
|
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::VersionHandler (std::ostringstream& results)
|
void I2PControlService::VersionHandler (std::ostringstream& results)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -65,7 +65,7 @@ namespace client
|
|||||||
|
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes = true) const;
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
|||||||
19
debian/changelog
vendored
19
debian/changelog
vendored
@@ -1,3 +1,22 @@
|
|||||||
|
i2pd (2.42.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.42.1/0.9.54
|
||||||
|
* remove -O3 optimization flag
|
||||||
|
|
||||||
|
-- r4sas <r4sas@i2pmail.org> Tue, 24 May 2022 12:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.42.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.42.0/0.9.54
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Sun, 22 May 2022 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.41.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.41.0/0.9.53
|
||||||
|
|
||||||
|
-- r4sas <r4sas@i2pmail.org> Sun, 20 Feb 2022 13:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.40.0-1) unstable; urgency=medium
|
i2pd (2.40.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* updated to version 2.40.0/0.9.52
|
* updated to version 2.40.0/0.9.52
|
||||||
|
|||||||
6
debian/patches/02-upnp.patch
vendored
6
debian/patches/02-upnp.patch
vendored
@@ -2,14 +2,14 @@ Description: Enable UPnP usage in package
|
|||||||
Author: r4sas <r4sas@i2pmail.org>
|
Author: r4sas <r4sas@i2pmail.org>
|
||||||
|
|
||||||
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||||
Last-Update: 2021-10-22
|
Last-Update: 2022-03-23
|
||||||
|
|
||||||
--- i2pd.orig/Makefile
|
--- i2pd.orig/Makefile
|
||||||
+++ i2pd/Makefile
|
+++ i2pd/Makefile
|
||||||
@@ -32,7 +32,7 @@ include filelist.mk
|
@@ -31,7 +31,7 @@ include filelist.mk
|
||||||
|
|
||||||
USE_AESNI := $(or $(USE_AESNI),yes)
|
USE_AESNI := $(or $(USE_AESNI),yes)
|
||||||
USE_STATIC := $(or $(USE_STATIC),no)
|
USE_STATIC := $(or $(USE_STATIC),no)
|
||||||
USE_MESHNET := $(or $(USE_MESHNET),no)
|
|
||||||
-USE_UPNP := $(or $(USE_UPNP),no)
|
-USE_UPNP := $(or $(USE_UPNP),no)
|
||||||
+USE_UPNP := $(or $(USE_UPNP),yes)
|
+USE_UPNP := $(or $(USE_UPNP),yes)
|
||||||
DEBUG := $(or $(DEBUG),yes)
|
DEBUG := $(or $(DEBUG),yes)
|
||||||
|
|||||||
9
debian/rules
vendored
9
debian/rules
vendored
@@ -1,16 +1,13 @@
|
|||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
#export DH_VERBOSE=1
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
|
||||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
|
||||||
include /usr/share/dpkg/architecture.mk
|
include /usr/share/dpkg/architecture.mk
|
||||||
|
|
||||||
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic -O3
|
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||||
|
|
||||||
export DEB_LDFLAGS_MAINT_APPEND =
|
export DEB_LDFLAGS_MAINT_APPEND =
|
||||||
|
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@ --parallel
|
dh $@ --parallel
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
|||||||
23
filelist.mk
23
filelist.mk
@@ -1,26 +1,7 @@
|
|||||||
#LIB_SRC = \
|
|
||||||
# BloomFilter.cpp Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
|
|
||||||
# Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
|
|
||||||
# Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
|
|
||||||
# SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
|
||||||
# Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
|
|
||||||
# Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
|
|
||||||
# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Gost.cpp
|
|
||||||
|
|
||||||
LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp)
|
LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp)
|
||||||
|
|
||||||
#LIB_CLIENT_SRC = \
|
|
||||||
# AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \
|
|
||||||
# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp
|
|
||||||
|
|
||||||
LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
|
LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
|
||||||
|
|
||||||
# also: Daemon{Linux,Win32}.cpp will be added later
|
|
||||||
#DAEMON_SRC = \
|
|
||||||
# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
|
|
||||||
|
|
||||||
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
|
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
|
||||||
|
WEBCONSOLE_SRC = $(wildcard $(WEBCONSOLE_SRC_DIR)/*.cpp)
|
||||||
|
|
||||||
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
|
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
|
||||||
|
DAEMON_SRC = $(DAEMON_SRC_DIR)/Daemon.cpp $(DAEMON_SRC_DIR)/I2PControl.cpp $(DAEMON_SRC_DIR)/i2pd.cpp $(DAEMON_SRC_DIR)/UPnP.cpp
|
||||||
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
|
|
||||||
|
|||||||
102
i18n/French.cpp
Normal file
102
i18n/French.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "I18N.h"
|
||||||
|
|
||||||
|
// French localization file
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace i18n
|
||||||
|
{
|
||||||
|
namespace french // language namespace
|
||||||
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "french";
|
||||||
|
|
||||||
|
// See for language plural forms here:
|
||||||
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
|
static int plural (int n) {
|
||||||
|
return n != 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> strings
|
||||||
|
{
|
||||||
|
{"KiB", "Kio"},
|
||||||
|
{"MiB", "Mio"},
|
||||||
|
{"GiB", "Gio"},
|
||||||
|
{"building", "En construction"},
|
||||||
|
{"failed", "echoué"},
|
||||||
|
{"expiring", "expiré"},
|
||||||
|
{"established", "établi"},
|
||||||
|
{"unknown", "inconnu"},
|
||||||
|
{"exploratory", "exploratoire"},
|
||||||
|
{"<b>i2pd</b> webconsole", "Console web <b>i2pd</b>"},
|
||||||
|
{"Main page", "Page principale"},
|
||||||
|
{"Router commands", "Commandes du routeur"},
|
||||||
|
{"Local Destinations", "Destinations locales"},
|
||||||
|
{"Tunnels", "Tunnels"},
|
||||||
|
{"Transit Tunnels", "Tunnels transitoires"},
|
||||||
|
{"I2P tunnels", "Tunnels I2P"},
|
||||||
|
{"SAM sessions", "Sessions SAM"},
|
||||||
|
{"ERROR", "ERREUR"},
|
||||||
|
{"OK", "OK"},
|
||||||
|
{"Firewalled", "Derrière un pare-feu"},
|
||||||
|
{"Error", "Erreur"},
|
||||||
|
{"Offline", "Hors ligne"},
|
||||||
|
{"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"},
|
||||||
|
{"Received", "Reçu"},
|
||||||
|
{"KiB/s", "kio/s"},
|
||||||
|
{"Sent", "Envoyé"},
|
||||||
|
{"Transit", "Transit"},
|
||||||
|
{"Hidden content. Press on text to see.", "Contenu caché. Cliquez sur le texte pour regarder."},
|
||||||
|
{"Router Ident", "Identifiant du routeur"},
|
||||||
|
{"Router Family", "Famille du routeur"},
|
||||||
|
{"Version", "Version"},
|
||||||
|
{"Our external address", "Notre adresse externe"},
|
||||||
|
{"Client Tunnels", "Tunnels clients"},
|
||||||
|
{"Services", "Services"},
|
||||||
|
{"Enabled", "Activé"},
|
||||||
|
{"Disabled", "Désactivé"},
|
||||||
|
{"Encrypted B33 address", "Adresse B33 chiffrée"},
|
||||||
|
{"Domain", "Domaine"},
|
||||||
|
{"<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"},
|
||||||
|
{"ms", "ms"},
|
||||||
|
{"Outbound tunnels", "Tunnels sortants"},
|
||||||
|
{"Destination", "Destination"},
|
||||||
|
{"Local Destination", "Destination locale"},
|
||||||
|
{"", ""},
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
|
{
|
||||||
|
{"days", {"jour", "jours"}},
|
||||||
|
{"hours", {"heure", "heures"}},
|
||||||
|
{"minutes", {"minute", "minutes"}},
|
||||||
|
{"seconds", {"seconde", "secondes"}},
|
||||||
|
{"", {"", ""}},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
|
{
|
||||||
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // language
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
||||||
215
i18n/German.cpp
Normal file
215
i18n/German.cpp
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "I18N.h"
|
||||||
|
|
||||||
|
// German localization file
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace i18n
|
||||||
|
{
|
||||||
|
namespace german // language namespace
|
||||||
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "german";
|
||||||
|
|
||||||
|
// See for language plural forms here:
|
||||||
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
|
static int plural (int n) {
|
||||||
|
return n != 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> strings
|
||||||
|
{
|
||||||
|
{"KiB", "KiB"},
|
||||||
|
{"MiB", "MiB"},
|
||||||
|
{"GiB", "GiB"},
|
||||||
|
{"building", "In Bau"},
|
||||||
|
{"failed", "fehlgeschlagen"},
|
||||||
|
{"expiring", "läuft ab in"},
|
||||||
|
{"established", "hergestellt"},
|
||||||
|
{"unknown", "Unbekannt"},
|
||||||
|
{"exploratory", "erforschende"},
|
||||||
|
{"<b>i2pd</b> webconsole", "<b>i2pd</b> Webkonsole"},
|
||||||
|
{"Main page", "Startseite"},
|
||||||
|
{"Router commands", "Router Befehle"},
|
||||||
|
{"Local Destinations", "Lokale Destination"},
|
||||||
|
{"LeaseSets", "LeaseSets"},
|
||||||
|
{"Tunnels", "Tunnel"},
|
||||||
|
{"Transit Tunnels", "Transittunnel"},
|
||||||
|
{"Transports", "Transporte"},
|
||||||
|
{"I2P tunnels", "I2P Tunnel"},
|
||||||
|
{"SAM sessions", "SAM Sitzungen"},
|
||||||
|
{"ERROR", "FEHLER"},
|
||||||
|
{"OK", "OK"},
|
||||||
|
{"Testing", "Testen"},
|
||||||
|
{"Firewalled", "Hinter eine Firewall"},
|
||||||
|
{"Unknown", "Unbekannt"},
|
||||||
|
{"Proxy", "Proxy"},
|
||||||
|
{"Mesh", "Mesh"},
|
||||||
|
{"Error", "Fehler"},
|
||||||
|
{"Clock skew", "Zeitabweichung"},
|
||||||
|
{"Offline", "Offline"},
|
||||||
|
{"Symmetric NAT", "Symmetrisches NAT"},
|
||||||
|
{"Uptime", "Laufzeit"},
|
||||||
|
{"Network status", "Netzwerkstatus"},
|
||||||
|
{"Network status v6", "Netzwerkstatus v6"},
|
||||||
|
{"Stopping in", "Stoppt in"},
|
||||||
|
{"Family", "Familie"},
|
||||||
|
{"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"},
|
||||||
|
{"Received", "Eingegangen"},
|
||||||
|
{"KiB/s", "KiB/s"},
|
||||||
|
{"Sent", "Gesendet"},
|
||||||
|
{"Transit", "Transit"},
|
||||||
|
{"Data path", "Datenpfad"},
|
||||||
|
{"Hidden content. Press on text to see.", "Versteckter Inhalt. Klicke hier, um ihn zu sehen."},
|
||||||
|
{"Router Ident", "Routeridentität"},
|
||||||
|
{"Router Family", "Routerfamilie"},
|
||||||
|
{"Router Caps", "Routerattribute"},
|
||||||
|
{"Version", "Version"},
|
||||||
|
{"Our external address", "Unsere externe Adresse"},
|
||||||
|
{"supported", "unterstützt"},
|
||||||
|
{"Routers", "Router"},
|
||||||
|
{"Floodfills", "Floodfills"},
|
||||||
|
{"Client Tunnels", "Klienttunnel"},
|
||||||
|
{"Services", "Services"},
|
||||||
|
{"Enabled", "Aktiviert"},
|
||||||
|
{"Disabled", "Deaktiviert"},
|
||||||
|
{"Encrypted B33 address", "Verschlüsselte B33 Adresse"},
|
||||||
|
{"Address registration line", "Adresseregistrierungszeile"},
|
||||||
|
{"Domain", "Domain"},
|
||||||
|
{"Generate", "Generieren"},
|
||||||
|
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Hinweis:</b> Der resultierende String kann nur für die Registrierung einer 2LD Domain (beispiel.i2p) benutzt werden. Für die Registrierung von Subdomains kann i2pd-tools verwendet werden."},
|
||||||
|
{"Address", "Adresse"},
|
||||||
|
{"Type", "Typ"},
|
||||||
|
{"EncType", "Verschlüsselungstyp"},
|
||||||
|
{"Inbound tunnels", "Eingehende Tunnel"},
|
||||||
|
{"ms", "ms"},
|
||||||
|
{"Outbound tunnels", "Ausgehende Tunnel"},
|
||||||
|
{"Tags", "Tags"},
|
||||||
|
{"Incoming", "Eingehend"},
|
||||||
|
{"Outgoing", "Ausgehend"},
|
||||||
|
{"Destination", "Destination"},
|
||||||
|
{"Amount", "Anzahl"},
|
||||||
|
{"Incoming Tags", "Eingehende Tags"},
|
||||||
|
{"Tags sessions", "Tags Sitzungen"},
|
||||||
|
{"Status", "Status"},
|
||||||
|
{"Local Destination", "Lokale Destination"},
|
||||||
|
{"Streams", "Streams"},
|
||||||
|
{"Close stream", "Stream schließen"},
|
||||||
|
{"I2CP session not found", "I2CP Sitzung nicht gefunden"},
|
||||||
|
{"I2CP is not enabled", "I2CP ist nicht aktiviert"},
|
||||||
|
{"Invalid", "Ungültig"},
|
||||||
|
{"Store type", "Speichertyp"},
|
||||||
|
{"Expires", "Ablaufdatum"},
|
||||||
|
{"Non Expired Leases", "Nicht abgelaufene Leases"},
|
||||||
|
{"Gateway", "Gateway"},
|
||||||
|
{"TunnelID", "TunnelID"},
|
||||||
|
{"EndDate", "Enddatum"},
|
||||||
|
{"not floodfill", "kein Floodfill"},
|
||||||
|
{"Queue size", "Warteschlangengröße"},
|
||||||
|
{"Run peer test", "Peer-Test ausführen"},
|
||||||
|
{"Decline transit tunnels", "Transittunnel ablehnen"},
|
||||||
|
{"Accept transit tunnels", "Transittunnel akzeptieren"},
|
||||||
|
{"Cancel graceful shutdown", "Beende das kontrollierte herunterfahren"},
|
||||||
|
{"Start graceful shutdown", "Starte das kontrollierte Herunterfahren"},
|
||||||
|
{"Force shutdown", "Herunterfahren erzwingen"},
|
||||||
|
{"Reload external CSS styles", "Lade externe CSS-Styles neu"},
|
||||||
|
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Hinweis:</b> Alle hier durchgeführten Aktionen sind nicht dauerhaft und ändern die Konfigurationsdateien nicht."},
|
||||||
|
{"Logging level", "Protokollierungslevel"},
|
||||||
|
{"Transit tunnels limit", "Limit für Transittunnel"},
|
||||||
|
{"Change", "Verändern"},
|
||||||
|
{"Change language", "Sprache ändern"},
|
||||||
|
{"no transit tunnels currently built", "derzeit keine Transittunnel aufgebaut"},
|
||||||
|
{"SAM disabled", "SAM deaktiviert"},
|
||||||
|
{"no sessions currently running", "Derzeit keine laufenden Sitzungen"},
|
||||||
|
{"SAM session not found", "SAM Sitzung nicht gefunden"},
|
||||||
|
{"SAM Session", "SAM Sitzung"},
|
||||||
|
{"Server Tunnels", "Servertunnel"},
|
||||||
|
{"Client Forwards", "Klient-Weiterleitungen"},
|
||||||
|
{"Server Forwards", "Server-Weiterleitungen"},
|
||||||
|
{"Unknown page", "Unbekannte Seite"},
|
||||||
|
{"Invalid token", "Ungültiger Token"},
|
||||||
|
{"SUCCESS", "ERFOLGREICH"},
|
||||||
|
{"Stream closed", "Stream geschlossen"},
|
||||||
|
{"Stream not found or already was closed", "Stream nicht gefunden oder bereits geschlossen"},
|
||||||
|
{"Destination not found", "Destination nicht gefunden"},
|
||||||
|
{"StreamID can't be null", "StreamID kann nicht null sein"},
|
||||||
|
{"Return to destination page", "Zurück zur Destination-Seite"},
|
||||||
|
{"You will be redirected in 5 seconds", "Du wirst in 5 Sekunden weitergeleitet"},
|
||||||
|
{"Transit tunnels count must not exceed 65535", "Es darf maximal 65535 Transittunnel geben"},
|
||||||
|
{"Back to commands list", "Zurück zur Kommandoliste"},
|
||||||
|
{"Register at reg.i2p", "Auf reg.i2p registrieren"},
|
||||||
|
{"Description", "Beschreibung"},
|
||||||
|
{"A bit information about service on domain", "Ein bisschen Informationen über den Service auf der Domain"},
|
||||||
|
{"Submit", "Einreichen"},
|
||||||
|
{"Domain can't end with .b32.i2p", "Domain kann nicht mit .b32.i2p enden"},
|
||||||
|
{"Domain must end with .i2p", "Domain muss mit .i2p enden"},
|
||||||
|
{"Such destination is not found", "Eine solche Destination konnte nicht gefunden werden"},
|
||||||
|
{"Unknown command", "Unbekannter Befehl"},
|
||||||
|
{"Command accepted", "Befehl akzeptiert"},
|
||||||
|
{"Proxy error", "Proxy-Fehler"},
|
||||||
|
{"Proxy info", "Proxy-Info"},
|
||||||
|
{"Proxy error: Host not found", "Proxy-Fehler: Host nicht gefunden"},
|
||||||
|
{"Remote host not found in router's addressbook", "Remote-Host nicht im Router Adressbuch gefunden"},
|
||||||
|
{"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einen der Jump-Services unten finden"},
|
||||||
|
{"Invalid request", "Ungültige Anfrage"},
|
||||||
|
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht interpretieren"},
|
||||||
|
{"addresshelper is not supported", "addresshelper wird nicht unterstützt"},
|
||||||
|
{"Host", "Host"},
|
||||||
|
{"added to router's addressbook from helper", "vom Helfer zum Router Adressbuch hinzugefügt"},
|
||||||
|
{"Click here to proceed:", "Klicke hier um fortzufahren:"},
|
||||||
|
{"Continue", "Fortsetzen"},
|
||||||
|
{"Addresshelper found", "Adresshelfer gefunden"},
|
||||||
|
{"already in router's addressbook", "bereits im Adressbuch des Routers"},
|
||||||
|
{"Click here to update record:", "Klicke hier, um den Eintrag zu aktualisieren:"},
|
||||||
|
{"invalid request uri", "ungültige Anfrage-URI"},
|
||||||
|
{"Can't detect destination host from request", "Kann Anhand der Anfrage den Destination-Host nicht erkennen"},
|
||||||
|
{"Outproxy failure", "Outproxy-Fehler"},
|
||||||
|
{"bad outproxy settings", "ungültige Outproxy-Einstellungen"},
|
||||||
|
{"not inside I2P network, but outproxy is not enabled", "nicht innerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
|
||||||
|
{"unknown outproxy url", "unbekannte Outproxy-URL"},
|
||||||
|
{"cannot resolve upstream proxy", "kann den Upstream-Proxy nicht auflösen"},
|
||||||
|
{"hostname too long", "Hostname zu lang"},
|
||||||
|
{"cannot connect to upstream socks proxy", "Kann keine Verbindung zum Upstream-Socks-Proxy herstellen"},
|
||||||
|
{"Cannot negotiate with socks proxy", "Kann nicht mit Socks-Proxy verhandeln"},
|
||||||
|
{"CONNECT error", "CONNECT-Fehler"},
|
||||||
|
{"Failed to Connect", "Verbindung konnte nicht hergestellt werden"},
|
||||||
|
{"socks proxy error", "Socks-Proxy-Fehler"},
|
||||||
|
{"failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
|
||||||
|
{"No Reply From socks proxy", "Keine Antwort vom Socks-Proxy"},
|
||||||
|
{"cannot connect", "kann nicht verbinden"},
|
||||||
|
{"http out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
|
||||||
|
{"cannot connect to upstream http proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
|
||||||
|
{"Host is down", "Host ist offline"},
|
||||||
|
{"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbaunen, vielleicht ist es offline. Versuche es später noch einmal."},
|
||||||
|
{"", ""},
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
|
{
|
||||||
|
{"days", {"Tag", "Tage"}},
|
||||||
|
{"hours", {"Stunde", "Stunden"}},
|
||||||
|
{"minutes", {"Minute", "Minuten"}},
|
||||||
|
{"seconds", {"Sekunde", "Sekunden"}},
|
||||||
|
{"", {"", ""}},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
|
{
|
||||||
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // language
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, The PurpleI2P Project
|
* Copyright (c) 2021-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, The PurpleI2P Project
|
* Copyright (c) 2021-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -74,19 +74,23 @@ namespace i18n
|
|||||||
namespace afrikaans { 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 armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace english { 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 russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace ukrainian { 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 uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* That map contains international language name lower-case and name in it's language
|
* That map contains international language name lower-case, name in it's language and it's code
|
||||||
*/
|
*/
|
||||||
static std::map<std::string, langData> languages
|
static std::map<std::string, langData> languages
|
||||||
{
|
{
|
||||||
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
|
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
|
||||||
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
|
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
|
||||||
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
|
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
|
||||||
|
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
|
||||||
|
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
|
||||||
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
|
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
|
||||||
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
|
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
|
||||||
{ "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
|
{ "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, The PurpleI2P Project
|
* Copyright (c) 2021-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -198,7 +198,6 @@ namespace turkmen // language namespace
|
|||||||
|
|
||||||
static std::map<std::string, std::vector<std::string>> plurals
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
{
|
{
|
||||||
// ShowUptime
|
|
||||||
{"days", {"gün", "gün"}},
|
{"days", {"gün", "gün"}},
|
||||||
{"hours", {"sagat", "sagat"}},
|
{"hours", {"sagat", "sagat"}},
|
||||||
{"minutes", {"minut", "minut"}},
|
{"minutes", {"minut", "minut"}},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, The PurpleI2P Project
|
* Copyright (c) 2021-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -34,7 +34,7 @@ namespace uzbek // language namespace
|
|||||||
{"KiB", "KiB"},
|
{"KiB", "KiB"},
|
||||||
{"MiB", "MiB"},
|
{"MiB", "MiB"},
|
||||||
{"GiB", "GiB"},
|
{"GiB", "GiB"},
|
||||||
{"building", "qurilish"},
|
{"building", "yaratilmoqda"},
|
||||||
{"failed", "muvaffaqiyatsiz"},
|
{"failed", "muvaffaqiyatsiz"},
|
||||||
{"expiring", "muddati tugaydi"},
|
{"expiring", "muddati tugaydi"},
|
||||||
{"established", "aloqa o'rnatildi"},
|
{"established", "aloqa o'rnatildi"},
|
||||||
@@ -43,11 +43,12 @@ namespace uzbek // language namespace
|
|||||||
{"<b>i2pd</b> webconsole", "<b>i2pd</b> veb-konsoli"},
|
{"<b>i2pd</b> webconsole", "<b>i2pd</b> veb-konsoli"},
|
||||||
{"Main page", "Asosiy sahifa"},
|
{"Main page", "Asosiy sahifa"},
|
||||||
{"Router commands", "Router buyruqlari"},
|
{"Router commands", "Router buyruqlari"},
|
||||||
|
{"Local Destinations", "Mahalliy joylanishlar"},
|
||||||
{"LeaseSets", "LeaseSets"},
|
{"LeaseSets", "LeaseSets"},
|
||||||
{"Tunnels", "Tunnellar"},
|
{"Tunnels", "Tunnellar"},
|
||||||
{"Transit Tunnels", "Tranzit Tunellar"},
|
{"Transit Tunnels", "Tranzit Tunellari"},
|
||||||
{"Transports", "Transportlar"},
|
{"Transports", "Transportlar"},
|
||||||
{"I2P tunnels", "I2P tunnellar"},
|
{"I2P tunnels", "I2P tunnellari"},
|
||||||
{"SAM sessions", "SAM sessiyalari"},
|
{"SAM sessions", "SAM sessiyalari"},
|
||||||
{"ERROR", "XATO"},
|
{"ERROR", "XATO"},
|
||||||
{"OK", "OK"},
|
{"OK", "OK"},
|
||||||
@@ -70,25 +71,25 @@ namespace uzbek // language namespace
|
|||||||
{"KiB/s", "KiB/s"},
|
{"KiB/s", "KiB/s"},
|
||||||
{"Sent", "Yuborilgan"},
|
{"Sent", "Yuborilgan"},
|
||||||
{"Transit", "Tranzit"},
|
{"Transit", "Tranzit"},
|
||||||
{"Data path", "Ma'lumotlar yo'li"},
|
{"Data path", "Ma'lumotlar joylanishi"},
|
||||||
{"Hidden content. Press on text to see.", "Yashirin tarkib. Ko'rish uchun matn ustida bosing."},
|
{"Hidden content. Press on text to see.", "Yashirin tarkib. Ko'rish uchun matn ustida bosing."},
|
||||||
{"Router Ident", "Router identifikatori"},
|
{"Router Ident", "Router identifikatori"},
|
||||||
{"Router Family", "Router Oila"},
|
{"Router Family", "Router oilasi"},
|
||||||
{"Router Caps", "Router bayroqlari"},
|
{"Router Caps", "Router Bayroqlari"},
|
||||||
{"Version", "Versiya"},
|
{"Version", "Versiya"},
|
||||||
{"Our external address", "Bizning tashqi manzilimiz"},
|
{"Our external address", "Bizning tashqi manzilimiz"},
|
||||||
{"supported", "qo'llab-quvvatlanadi"},
|
{"supported", "qo'llab-quvvatlanadi"},
|
||||||
{"Routers", "Routerlar"},
|
{"Routers", "Routerlar"},
|
||||||
{"Floodfills", "Floodfills"},
|
{"Floodfills", "Floodfills"},
|
||||||
{"Client Tunnels", "Mijoz tunellari"},
|
{"Client Tunnels", "Mijoz Tunellari"},
|
||||||
{"Services", "Xizmatlar"},
|
{"Services", "Xizmatlar"},
|
||||||
{"Enabled", "Yoqilgan"},
|
{"Enabled", "Yoqilgan"},
|
||||||
{"Disabled", "O'chirilgan"},
|
{"Disabled", "O'chirilgan"},
|
||||||
{"Encrypted B33 address", "Shifrlangan B33 manzil"},
|
{"Encrypted B33 address", "Shifrlangan B33 manzil"},
|
||||||
{"Address registration line", "Manzilni ro'yxatga olish liniyasi"},
|
{"Address registration line", "Manzilni ro'yxatga olish liniyasi"},
|
||||||
{"Domain", "Domen"},
|
{"Domain", "Domen"},
|
||||||
{"Generate", "Varatish"},
|
{"Generate", "Yaratish"},
|
||||||
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Eslatma:</b> natija satridan faqat 2LD domenlarini ro'yxatdan o'tkazish uchun foydalanish mumkin (example.i2p). Subdomenlarni ro'yxatdan o'tkazish uchun i2pd-tools dan foydalaning."},
|
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Eslatma:</b> natija satridan faqat 2LD domenlarini ro'yxatdan o'tkazish uchun foydalanish mumkin (example.i2p). Subdomenlarni ro'yxatdan o'tkazish uchun 'i2pd-tools'dan foydalaning."},
|
||||||
{"Address", "Manzil"},
|
{"Address", "Manzil"},
|
||||||
{"Type", "Turi"},
|
{"Type", "Turi"},
|
||||||
{"EncType", "ShifrlashTuri"},
|
{"EncType", "ShifrlashTuri"},
|
||||||
@@ -99,10 +100,11 @@ namespace uzbek // language namespace
|
|||||||
{"Incoming", "Kiruvchi"},
|
{"Incoming", "Kiruvchi"},
|
||||||
{"Outgoing", "Chiquvchi"},
|
{"Outgoing", "Chiquvchi"},
|
||||||
{"Destination", "Manzilgoh"},
|
{"Destination", "Manzilgoh"},
|
||||||
{"Amount", "Yig'indi"},
|
{"Amount", "Soni"},
|
||||||
{"Incoming Tags", "Kiruvchi teglar"},
|
{"Incoming Tags", "Kiruvchi teglar"},
|
||||||
{"Tags sessions", "Teglar sessiyalari"},
|
{"Tags sessions", "Teglar sessiyalari"},
|
||||||
{"Status", "Holat"},
|
{"Status", "Holat"},
|
||||||
|
{"Local Destination", "Mahalliy joylanish"},
|
||||||
{"Streams", "Strim"},
|
{"Streams", "Strim"},
|
||||||
{"Close stream", "Strimni o'chirish"},
|
{"Close stream", "Strimni o'chirish"},
|
||||||
{"I2CP session not found", "I2CP sessiyasi topilmadi"},
|
{"I2CP session not found", "I2CP sessiyasi topilmadi"},
|
||||||
@@ -117,14 +119,15 @@ namespace uzbek // language namespace
|
|||||||
{"not floodfill", "floodfill emas"},
|
{"not floodfill", "floodfill emas"},
|
||||||
{"Queue size", "Navbat hajmi"},
|
{"Queue size", "Navbat hajmi"},
|
||||||
{"Run peer test", "Sinovni boshlang"},
|
{"Run peer test", "Sinovni boshlang"},
|
||||||
{"Decline transit tunnels", "Tranzit tunnellarni rad etish"},
|
{"Decline transit tunnels", "Tranzit tunnellarini rad etish"},
|
||||||
{"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"},
|
{"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"},
|
||||||
{"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qiling"},
|
{"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qilish"},
|
||||||
{"Start graceful shutdown", "Yumshoq to'xtashni boshlang"},
|
{"Start graceful shutdown", "Yumshoq to'xtashni boshlash"},
|
||||||
{"Force shutdown", "Bizning tashqi manzilimiz"},
|
{"Force shutdown", "Majburiy to'xtatish"},
|
||||||
{"Reload external CSS styles", "Tashqi CSS uslublarini qayta yuklang"},
|
{"Reload external CSS styles", "Tashqi CSS uslublarini qayta yuklang"},
|
||||||
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Eslatma:</b> bu erda qilingan har qanday harakat doimiy emas va konfiguratsiya fayllarini o'zgartirmaydi."},
|
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Eslatma:</b> shu yerda qilingan har qanday harakat doimiy emas va konfiguratsiya fayllarini o'zgartirmaydi."},
|
||||||
{"Transit tunnels limit", "Tranzit tunellar chegarasi"},
|
{"Logging level", "Jurnal darajasi"},
|
||||||
|
{"Transit tunnels limit", "Tranzit tunellarning chegarasi"},
|
||||||
{"Change", "O'zgartirish"},
|
{"Change", "O'zgartirish"},
|
||||||
{"Change language", "Tilni o'zgartirish"},
|
{"Change language", "Tilni o'zgartirish"},
|
||||||
{"no transit tunnels currently built", "qurilgan tranzit tunnellari yo'q"},
|
{"no transit tunnels currently built", "qurilgan tranzit tunnellari yo'q"},
|
||||||
@@ -142,8 +145,8 @@ namespace uzbek // language namespace
|
|||||||
{"Stream not found or already was closed", "Strim topilmadi yoki allaqachon yopilgan"},
|
{"Stream not found or already was closed", "Strim topilmadi yoki allaqachon yopilgan"},
|
||||||
{"Destination not found", "Yo'nalish topilmadi"},
|
{"Destination not found", "Yo'nalish topilmadi"},
|
||||||
{"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"},
|
{"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"},
|
||||||
{"Return to destination page", "Belgilangan sahifaga qaytish"},
|
{"Return to destination page", "Manzilgoh sahifasiga qaytish"},
|
||||||
{"You will be redirected in 5 seconds", "Siz 5 soniyada qayta yo'naltirilasiz"},
|
{"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"},
|
{"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"},
|
||||||
{"Back to commands list", "Buyruqlar ro'yxatiga qaytish"},
|
{"Back to commands list", "Buyruqlar ro'yxatiga qaytish"},
|
||||||
{"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"},
|
{"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"},
|
||||||
@@ -159,29 +162,35 @@ namespace uzbek // language namespace
|
|||||||
{"Proxy info", "Proksi ma'lumotlari"},
|
{"Proxy info", "Proksi ma'lumotlari"},
|
||||||
{"Proxy error: Host not found", "Proksi xatosi: Xost topilmadi"},
|
{"Proxy error: Host not found", "Proksi xatosi: Xost topilmadi"},
|
||||||
{"Remote host not found in router's addressbook", "Masofaviy xost yo'riqnoma manzillar kitobida topilmadi"},
|
{"Remote host not found in router's addressbook", "Masofaviy xost yo'riqnoma manzillar kitobida topilmadi"},
|
||||||
|
{"You may try to find this host on jump services below", "Siz xost quyida o'tish xizmatlari orqali topishga harakat qilishingiz mumkin"},
|
||||||
{"Invalid request", "Noto‘g‘ri so‘rov"},
|
{"Invalid request", "Noto‘g‘ri so‘rov"},
|
||||||
{"Proxy unable to parse your request", "Proksi sizning so'rovingizni tahlil qila olmaydi"},
|
{"Proxy unable to parse your request", "Proksi sizning so'rovingizni aniqlab ololmayapti"},
|
||||||
{"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"},
|
{"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"},
|
||||||
{"Host", "Xost"},
|
{"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"},
|
{"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"},
|
{"invalid request uri", "noto'g'ri URI so'rovi"},
|
||||||
{"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"},
|
{"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"},
|
||||||
{"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"},
|
{"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"},
|
||||||
{"bad outproxy settings", "noto'g'ri tashqi proksi-server sozlamalari"},
|
{"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"},
|
{"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"},
|
||||||
{"unknown outproxy url", "noma'lum outproxy url"},
|
{"unknown outproxy url", "noma'lum outproxy url"},
|
||||||
{"cannot resolve upstream proxy", "yuqoridagi proksi -serverni aniqlab olib bolmaydi"},
|
{"cannot resolve upstream proxy", "yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"},
|
||||||
{"hostname too long", "xost nomi juda uzun"},
|
{"hostname too long", "xost nomi juda uzun"},
|
||||||
{"cannot connect to upstream socks proxy", "yuqori soks proksi -serveriga ulanib bo'lmaydi"},
|
{"cannot connect to upstream socks proxy", "yuqori 'socks proxy'ga ulanib bo'lmayapti"},
|
||||||
{"Cannot negotiate with socks proxy", "Soks proksi bilan muzokara olib bo'lmaydi"},
|
{"Cannot negotiate with socks proxy", "'Socks proxy' bilan muzokara olib bo'lmaydi"},
|
||||||
{"CONNECT error", "CONNECT xatosi"},
|
{"CONNECT error", "CONNECT xatosi"},
|
||||||
{"Failed to Connect", "Ulanmadi"},
|
{"Failed to Connect", "Ulanib bo'lmayapti"},
|
||||||
{"socks proxy error", "soks proksi xatosi"},
|
{"socks proxy error", "'socks proxy' xatosi"},
|
||||||
{"failed to send request to upstream", "yuqori http proksi-serveriga ulanib bo'lmadi"},
|
{"failed to send request to upstream", "yuqori http proksi-serveriga so'rovni uborib bo'lmadi"},
|
||||||
{"No Reply From socks proxy", "Soks-proksidan javob yo'q"},
|
{"No Reply From socks proxy", "'Socks proxy'dan javob yo'q"},
|
||||||
{"cannot connect", "ulab bo'lmaydi"},
|
{"cannot connect", "ulanib bo'lmaydi"},
|
||||||
{"http out proxy not implemented", "tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"},
|
{"http out proxy not implemented", "tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"},
|
||||||
{"cannot connect to upstream http proxy", "yuqori http proksi-serveriga ulanib bo'lmadi"},
|
{"cannot connect to upstream http proxy", "yuqori http 'proxy-server'iga ulanib bo'lmayapti"},
|
||||||
{"Host is down", "Xost ishlamayapti"},
|
{"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."},
|
{"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."},
|
||||||
{"", ""},
|
{"", ""},
|
||||||
@@ -189,10 +198,10 @@ namespace uzbek // language namespace
|
|||||||
|
|
||||||
static std::map<std::string, std::vector<std::string>> plurals
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
{
|
{
|
||||||
{"days", {"kun", "kunlar"}},
|
{"days", {"kun", "kun"}},
|
||||||
{"hours", {"soat", "soat"}},
|
{"hours", {"soat", "soat"}},
|
||||||
{"minutes", {"daqiqa", "daqiqalar"}},
|
{"minutes", {"daqiqa", "daqiqa"}},
|
||||||
{"seconds", {"soniya", "soniyalar"}},
|
{"seconds", {"soniya", "soniya"}},
|
||||||
{"", {"", ""}},
|
{"", {"", ""}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -185,10 +185,7 @@ namespace data
|
|||||||
if (InCount && !m)
|
if (InCount && !m)
|
||||||
outCount = 3 * n;
|
outCount = 3 * n;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
outCount = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
ps = (unsigned char *)(InBuffer + InCount - 1);
|
ps = (unsigned char *)(InBuffer + InCount - 1);
|
||||||
while ( *ps-- == P64 )
|
while ( *ps-- == P64 )
|
||||||
@@ -196,7 +193,7 @@ namespace data
|
|||||||
ps = (unsigned char *)InBuffer;
|
ps = (unsigned char *)InBuffer;
|
||||||
|
|
||||||
if (outCount > len)
|
if (outCount > len)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
pd = OutBuffer;
|
pd = OutBuffer;
|
||||||
auto endOfOutBuffer = OutBuffer + outCount;
|
auto endOfOutBuffer = OutBuffer + outCount;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace data {
|
|||||||
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
* Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
||||||
*/
|
*/
|
||||||
size_t Base64EncodingBufferSize(const size_t input_size);
|
size_t Base64EncodingBufferSize(const size_t input_size);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -146,6 +146,9 @@ namespace data
|
|||||||
m_PublicKey.resize (len);
|
m_PublicKey.resize (len);
|
||||||
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
|
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
|
||||||
m_SigType = identity->GetSigningKeyType ();
|
m_SigType = identity->GetSigningKeyType ();
|
||||||
|
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||||
|
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
|
||||||
|
else
|
||||||
m_BlindedSigType = m_SigType;
|
m_BlindedSigType = m_SigType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -78,9 +78,9 @@ namespace config {
|
|||||||
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
("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.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
||||||
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
||||||
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)")
|
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored")
|
||||||
("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
|
("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
|
||||||
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)")
|
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpserver("HTTP Server options");
|
options_description httpserver("HTTP Server options");
|
||||||
@@ -109,6 +109,8 @@ namespace config {
|
|||||||
("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
|
("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
|
||||||
("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
|
("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
|
||||||
("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity")
|
("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity")
|
||||||
|
("httpproxy.inbound.lengthVariance", value<std::string>()->default_value("0"), "HTTP proxy inbound tunnels length variance")
|
||||||
|
("httpproxy.outbound.lengthVariance", value<std::string>()->default_value("0"), "HTTP proxy outbound tunnels length variance")
|
||||||
("httpproxy.latency.min", value<std::string>()->default_value("0"), "HTTP proxy min latency for tunnels")
|
("httpproxy.latency.min", value<std::string>()->default_value("0"), "HTTP proxy min latency for tunnels")
|
||||||
("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
|
("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
|
||||||
("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
|
("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
|
||||||
@@ -130,6 +132,8 @@ namespace config {
|
|||||||
("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
|
("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
|
||||||
("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")
|
("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")
|
||||||
("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity")
|
("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity")
|
||||||
|
("socksproxy.inbound.lengthVariance", value<std::string>()->default_value("0"), "SOCKS proxy inbound tunnels length variance")
|
||||||
|
("socksproxy.outbound.lengthVariance", value<std::string>()->default_value("0"), "SOCKS proxy outbound tunnels length variance")
|
||||||
("socksproxy.latency.min", value<std::string>()->default_value("0"), "SOCKS proxy min latency for tunnels")
|
("socksproxy.latency.min", value<std::string>()->default_value("0"), "SOCKS proxy min latency for tunnels")
|
||||||
("socksproxy.latency.max", value<std::string>()->default_value("0"), "SOCKS proxy max latency for tunnels")
|
("socksproxy.latency.max", value<std::string>()->default_value("0"), "SOCKS proxy max latency for tunnels")
|
||||||
("socksproxy.outproxy.enabled", value<bool>()->default_value(false), "Enable or disable SOCKS outproxy")
|
("socksproxy.outproxy.enabled", value<bool>()->default_value(false), "Enable or disable SOCKS outproxy")
|
||||||
@@ -203,7 +207,7 @@ namespace config {
|
|||||||
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
||||||
("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
|
("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
|
||||||
("reseed.urls", value<std::string>()->default_value(
|
("reseed.urls", value<std::string>()->default_value(
|
||||||
"https://reseed.i2p-projekt.de/,"
|
"https://reseed2.i2p.net/,"
|
||||||
"https://reseed.diva.exchange/,"
|
"https://reseed.diva.exchange/,"
|
||||||
"https://reseed-fr.i2pd.xyz/,"
|
"https://reseed-fr.i2pd.xyz/,"
|
||||||
"https://reseed.memcpy.io/,"
|
"https://reseed.memcpy.io/,"
|
||||||
@@ -211,21 +215,28 @@ namespace config {
|
|||||||
"https://i2pseed.creativecowpat.net:8443/,"
|
"https://i2pseed.creativecowpat.net:8443/,"
|
||||||
"https://reseed.i2pgit.org/,"
|
"https://reseed.i2pgit.org/,"
|
||||||
"https://i2p.novg.net/,"
|
"https://i2p.novg.net/,"
|
||||||
"https://banana.incognet.io/"
|
"https://banana.incognet.io/,"
|
||||||
|
"https://reseed-pl.i2pd.xyz/,"
|
||||||
|
"https://www2.mk16.de/"
|
||||||
), "Reseed URLs, separated by comma")
|
), "Reseed URLs, separated by comma")
|
||||||
("reseed.yggurls", value<std::string>()->default_value(
|
("reseed.yggurls", value<std::string>()->default_value(
|
||||||
"http://[324:71e:281a:9ed3::ace]:7070/,"
|
"http://[324:71e:281a:9ed3::ace]:7070/,"
|
||||||
"http://[301:65b9:c7cd:9a36::1]:18801/,"
|
"http://[301:65b9:c7cd:9a36::1]:18801/,"
|
||||||
"http://[320:8936:ec1a:31f1::216]/"
|
"http://[320:8936:ec1a:31f1::216]/,"
|
||||||
|
"http://[306:3834:97b9:a00a::1]/,"
|
||||||
|
"http://[316:f9e0:f22e:a74f::216]/"
|
||||||
), "Reseed URLs through the Yggdrasil, separated by comma")
|
), "Reseed URLs through the Yggdrasil, separated by comma")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description addressbook("AddressBook options");
|
options_description addressbook("AddressBook options");
|
||||||
addressbook.add_options()
|
addressbook.add_options()
|
||||||
|
("addressbook.enabled", value<bool>()->default_value(true), "Enable address book lookups and subscritions (default: enabled)")
|
||||||
("addressbook.defaulturl", value<std::string>()->default_value(
|
("addressbook.defaulturl", value<std::string>()->default_value(
|
||||||
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
|
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
|
||||||
), "AddressBook subscription URL for initial setup")
|
), "AddressBook subscription URL for initial setup")
|
||||||
("addressbook.subscriptions", value<std::string>()->default_value("http://reg.i2p/hosts.txt"), "AddressBook subscriptions URLs, separated by comma")
|
("addressbook.subscriptions", value<std::string>()->default_value(
|
||||||
|
"http://reg.i2p/hosts.txt"
|
||||||
|
), "AddressBook subscriptions URLs, separated by comma")
|
||||||
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
|
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
|
||||||
|
|
||||||
options_description trust("Trust options");
|
options_description trust("Trust options");
|
||||||
@@ -261,6 +272,13 @@ namespace config {
|
|||||||
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
|
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
options_description ssu2("SSU2 Options");
|
||||||
|
ssu2.add_options()
|
||||||
|
("ssu2.enabled", value<bool>()->default_value(false), "Enable SSU2 (default: disabled)")
|
||||||
|
("ssu2.published", value<bool>()->default_value(false), "Publish SSU2 (default: disabled)")
|
||||||
|
("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
|
||||||
|
;
|
||||||
|
|
||||||
options_description nettime("Time sync options");
|
options_description nettime("Time sync options");
|
||||||
nettime.add_options()
|
nettime.add_options()
|
||||||
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
||||||
@@ -269,8 +287,9 @@ namespace config {
|
|||||||
"1.pool.ntp.org,"
|
"1.pool.ntp.org,"
|
||||||
"2.pool.ntp.org,"
|
"2.pool.ntp.org,"
|
||||||
"3.pool.ntp.org"
|
"3.pool.ntp.org"
|
||||||
), "Comma separated list of NTCP servers")
|
), "Comma separated list of NTP servers")
|
||||||
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
||||||
|
("nettime.frompeers", value<bool>()->default_value(true), "Sync clock from transport peers (default: enabled)")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description persist("Network information persisting options");
|
options_description persist("Network information persisting options");
|
||||||
@@ -310,6 +329,7 @@ namespace config {
|
|||||||
.add(websocket) // deprecated
|
.add(websocket) // deprecated
|
||||||
.add(exploratory)
|
.add(exploratory)
|
||||||
.add(ntcp2)
|
.add(ntcp2)
|
||||||
|
.add(ssu2)
|
||||||
.add(nettime)
|
.add(nettime)
|
||||||
.add(persist)
|
.add(persist)
|
||||||
.add(cpuext)
|
.add(cpuext)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -1305,6 +1305,16 @@ namespace crypto
|
|||||||
SHA256_Final (m_H, &ctx);
|
SHA256_Final (m_H, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoiseSymmetricState::MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs)
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
SHA256_Init (&ctx);
|
||||||
|
SHA256_Update (&ctx, m_H, 32);
|
||||||
|
for (const auto& it: bufs)
|
||||||
|
SHA256_Update (&ctx, it.first, it.second);
|
||||||
|
SHA256_Final (m_H, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
|
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
|
||||||
{
|
{
|
||||||
HKDF (m_CK, sharedSecret, 32, "", m_CK);
|
HKDF (m_CK, sharedSecret, 32, "", m_CK);
|
||||||
@@ -1336,7 +1346,7 @@ namespace crypto
|
|||||||
|
|
||||||
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
|
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
{
|
{
|
||||||
static const uint8_t protocolNameHash[] =
|
static const uint8_t protocolNameHash[32] =
|
||||||
{
|
{
|
||||||
0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed,
|
0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed,
|
||||||
0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71
|
0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71
|
||||||
@@ -1349,6 +1359,21 @@ namespace crypto
|
|||||||
InitNoiseState (state, protocolNameHash, hh, pub);
|
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
static const uint8_t protocolNameHash[32] =
|
||||||
|
{
|
||||||
|
0xb1, 0x37, 0x22, 0x81, 0x74, 0x23, 0xa8, 0xfd, 0xf4, 0x2d, 0xf2, 0xe6, 0x0e, 0xd1, 0xed, 0xf4,
|
||||||
|
0x1b, 0x93, 0x07, 0x1d, 0xb1, 0xec, 0x24, 0xa3, 0x67, 0xf7, 0x84, 0xec, 0x27, 0x0d, 0x81, 0x32
|
||||||
|
}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
|
||||||
|
static const uint8_t hh[32] =
|
||||||
|
{
|
||||||
|
0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
|
||||||
|
0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
|
||||||
|
}; // SHA256 (protocolNameHash)
|
||||||
|
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||||
|
}
|
||||||
|
|
||||||
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
{
|
{
|
||||||
static const uint8_t protocolNameHash[32] =
|
static const uint8_t protocolNameHash[32] =
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -29,7 +29,9 @@
|
|||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
|
||||||
// recognize openssl version and features
|
// recognize openssl version and features
|
||||||
#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050200fL)) // LibreSSL 3.5.2 and above
|
||||||
|
# define LEGACY_OPENSSL 0
|
||||||
|
#elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
||||||
# define LEGACY_OPENSSL 1
|
# define LEGACY_OPENSSL 1
|
||||||
# define X509_getm_notBefore X509_get_notBefore
|
# define X509_getm_notBefore X509_get_notBefore
|
||||||
# define X509_getm_notAfter X509_get_notAfter
|
# define X509_getm_notAfter X509_get_notAfter
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
# define OPENSSL_HKDF 1
|
# define OPENSSL_HKDF 1
|
||||||
# define OPENSSL_EDDSA 1
|
# define OPENSSL_EDDSA 1
|
||||||
# define OPENSSL_X25519 1
|
# define OPENSSL_X25519 1
|
||||||
# if (OPENSSL_VERSION_NUMBER < 0x030000000) // 3.0.0, regression in SipHash
|
# if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash
|
||||||
# define OPENSSL_SIPHASH 1
|
# define OPENSSL_SIPHASH 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
@@ -317,11 +319,13 @@ namespace crypto
|
|||||||
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
|
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
|
||||||
|
|
||||||
void MixHash (const uint8_t * buf, size_t len);
|
void MixHash (const uint8_t * buf, size_t len);
|
||||||
|
void MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs);
|
||||||
void MixKey (const uint8_t * sharedSecret);
|
void MixKey (const uint8_t * sharedSecret);
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router)
|
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router)
|
||||||
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2)
|
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2)
|
||||||
|
void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (SSU2)
|
||||||
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets)
|
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets)
|
||||||
|
|
||||||
// init and terminate
|
// init and terminate
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "Config.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
@@ -35,6 +34,8 @@ namespace client
|
|||||||
int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY;
|
int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY;
|
||||||
int outLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
|
int outLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
|
||||||
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
||||||
|
int inVar = DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE;
|
||||||
|
int outVar = DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE;
|
||||||
int numTags = DEFAULT_TAGS_TO_SEND;
|
int numTags = DEFAULT_TAGS_TO_SEND;
|
||||||
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
|
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
|
||||||
try
|
try
|
||||||
@@ -53,6 +54,12 @@ namespace client
|
|||||||
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY);
|
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
outQty = std::stoi(it->second);
|
outQty = std::stoi(it->second);
|
||||||
|
it = params->find (I2CP_PARAM_INBOUND_TUNNELS_LENGTH_VARIANCE);
|
||||||
|
if (it != params->end ())
|
||||||
|
inVar = std::stoi(it->second);
|
||||||
|
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_LENGTH_VARIANCE);
|
||||||
|
if (it != params->end ())
|
||||||
|
outVar = std::stoi(it->second);
|
||||||
it = params->find (I2CP_PARAM_TAGS_TO_SEND);
|
it = params->find (I2CP_PARAM_TAGS_TO_SEND);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
numTags = std::stoi(it->second);
|
numTags = std::stoi(it->second);
|
||||||
@@ -86,9 +93,7 @@ namespace client
|
|||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
{
|
{
|
||||||
// oveeride isPublic
|
// oveeride isPublic
|
||||||
bool dontpublish = false;
|
m_IsPublic = (it->second != "true");
|
||||||
i2p::config::GetOption (it->second, dontpublish);
|
|
||||||
m_IsPublic = !dontpublish;
|
|
||||||
}
|
}
|
||||||
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
@@ -123,7 +128,7 @@ namespace client
|
|||||||
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
|
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
|
||||||
}
|
}
|
||||||
SetNumTags (numTags);
|
SetNumTags (numTags);
|
||||||
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty);
|
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty, inVar, outVar);
|
||||||
if (explicitPeers)
|
if (explicitPeers)
|
||||||
m_Pool->SetExplicitPeers (explicitPeers);
|
m_Pool->SetExplicitPeers (explicitPeers);
|
||||||
if(params)
|
if(params)
|
||||||
@@ -331,6 +336,22 @@ namespace client
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeaseSetDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t k[32];
|
||||||
|
uint64_t t;
|
||||||
|
} data;
|
||||||
|
memcpy (data.k, key, 32);
|
||||||
|
data.t = tag;
|
||||||
|
auto s = shared_from_this ();
|
||||||
|
m_Service.post ([s,data](void)
|
||||||
|
{
|
||||||
|
s->AddECIESx25519Key (data.k, data.t);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
|
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
|
||||||
@@ -555,6 +576,11 @@ namespace client
|
|||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
return;
|
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->GetIdentHash (), m_ExcludedFloodfills);
|
||||||
if (!floodfill)
|
if (!floodfill)
|
||||||
{
|
{
|
||||||
@@ -563,16 +589,31 @@ namespace client
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
||||||
if (!outbound)
|
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
|
if (!outbound || !inbound)
|
||||||
{
|
{
|
||||||
|
LogPrint (eLogInfo, "Destination: No compatible tunnels with ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another floodfill");
|
||||||
|
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
||||||
|
floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
|
||||||
|
if (floodfill)
|
||||||
|
{
|
||||||
|
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
||||||
|
if (outbound)
|
||||||
|
{
|
||||||
|
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
|
if (!inbound)
|
||||||
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
||||||
|
}
|
||||||
|
else
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
||||||
|
if (!floodfill || !outbound || !inbound)
|
||||||
|
{
|
||||||
|
m_ExcludedFloodfills.clear ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
|
||||||
if (!inbound)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
||||||
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
||||||
@@ -910,7 +951,7 @@ namespace client
|
|||||||
for (auto& it: encryptionKeyTypes)
|
for (auto& it: encryptionKeyTypes)
|
||||||
{
|
{
|
||||||
auto encryptionKey = new EncryptionKey (it);
|
auto encryptionKey = new EncryptionKey (it);
|
||||||
if (isPublic)
|
if (IsPublic ())
|
||||||
PersistTemporaryKeys (encryptionKey, isSingleKey);
|
PersistTemporaryKeys (encryptionKey, isSingleKey);
|
||||||
else
|
else
|
||||||
encryptionKey->GenerateKeys ();
|
encryptionKey->GenerateKeys ();
|
||||||
@@ -925,7 +966,7 @@ namespace client
|
|||||||
m_StandardEncryptionKey.reset (encryptionKey);
|
m_StandardEncryptionKey.reset (encryptionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPublic)
|
if (IsPublic ())
|
||||||
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -938,7 +979,7 @@ namespace client
|
|||||||
m_StreamingAckDelay = std::stoi(it->second);
|
m_StreamingAckDelay = std::stoi(it->second);
|
||||||
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
i2p::config::GetOption (it->second, m_IsStreamingAnswerPings);
|
m_IsStreamingAnswerPings = (it->second == "true");
|
||||||
|
|
||||||
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -53,6 +53,10 @@ namespace client
|
|||||||
const int DEFAULT_INBOUND_TUNNELS_QUANTITY = 5;
|
const int DEFAULT_INBOUND_TUNNELS_QUANTITY = 5;
|
||||||
const char I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY[] = "outbound.quantity";
|
const char I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY[] = "outbound.quantity";
|
||||||
const int DEFAULT_OUTBOUND_TUNNELS_QUANTITY = 5;
|
const int DEFAULT_OUTBOUND_TUNNELS_QUANTITY = 5;
|
||||||
|
const char I2CP_PARAM_INBOUND_TUNNELS_LENGTH_VARIANCE[] = "inbound.lengthVariance";
|
||||||
|
const int DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE = 0;
|
||||||
|
const char I2CP_PARAM_OUTBOUND_TUNNELS_LENGTH_VARIANCE[] = "outbound.lengthVariance";
|
||||||
|
const int DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE = 0;
|
||||||
const char I2CP_PARAM_EXPLICIT_PEERS[] = "explicitPeers";
|
const char I2CP_PARAM_EXPLICIT_PEERS[] = "explicitPeers";
|
||||||
const int STREAM_REQUEST_TIMEOUT = 60; //in seconds
|
const int STREAM_REQUEST_TIMEOUT = 60; //in seconds
|
||||||
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
|
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
|
||||||
@@ -134,6 +138,7 @@ namespace client
|
|||||||
|
|
||||||
// override GarlicDestination
|
// override GarlicDestination
|
||||||
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag);
|
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag);
|
||||||
|
void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag);
|
||||||
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void SetLeaseSetUpdated ();
|
void SetLeaseSetUpdated ();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -60,10 +60,38 @@ namespace fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
||||||
|
// with 'datadir' option
|
||||||
if (cmdline_param != "") {
|
if (cmdline_param != "") {
|
||||||
dataDir = cmdline_param;
|
dataDir = cmdline_param;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(MAC_OSX) && !defined(ANDROID)
|
||||||
|
// with 'service' option
|
||||||
|
if (isService) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
wchar_t commonAppData[MAX_PATH];
|
||||||
|
if(SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, commonAppData) != S_OK)
|
||||||
|
{
|
||||||
|
#ifdef WIN32_APP
|
||||||
|
MessageBox(NULL, TEXT("Unable to get common AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Error: Unable to get common AppData path!");
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataDir = boost::filesystem::wpath(commonAppData).string() + "\\" + appName;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
dataDir = "/var/lib/" + appName;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detect directory as usual
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t localAppData[MAX_PATH];
|
wchar_t localAppData[MAX_PATH];
|
||||||
|
|
||||||
@@ -117,12 +145,10 @@ namespace fs {
|
|||||||
dataDir = std::string (ext) + "/" + appName;
|
dataDir = std::string (ext) + "/" + appName;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // ANDROID
|
||||||
// otherwise use /data/files
|
// use /home/user/.i2pd or /tmp/i2pd
|
||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
if (isService) {
|
if (home != NULL && strlen(home) > 0) {
|
||||||
dataDir = "/var/lib/" + appName;
|
|
||||||
} else if (home != NULL && strlen(home) > 0) {
|
|
||||||
dataDir = std::string(home) + "/." + appName;
|
dataDir = std::string(home) + "/." + appName;
|
||||||
} else {
|
} else {
|
||||||
dataDir = "/tmp/" + appName;
|
dataDir = "/tmp/" + appName;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -88,7 +88,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
if (verifier && cn)
|
if (verifier && cn)
|
||||||
m_SigningKeys[cn] = verifier;
|
m_SigningKeys.emplace (cn, std::make_pair(verifier, m_SigningKeys.size () + 1));
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
|
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
const char * signature, const char * key)
|
const char * signature, const char * key) const
|
||||||
{
|
{
|
||||||
uint8_t buf[100], signatureBuf[64];
|
uint8_t buf[100], signatureBuf[64];
|
||||||
size_t len = family.length (), signatureLen = strlen (signature);
|
size_t len = family.length (), signatureLen = strlen (signature);
|
||||||
@@ -137,11 +137,19 @@ namespace data
|
|||||||
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
|
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
|
||||||
auto it = m_SigningKeys.find (family);
|
auto it = m_SigningKeys.find (family);
|
||||||
if (it != m_SigningKeys.end ())
|
if (it != m_SigningKeys.end ())
|
||||||
return it->second->Verify (buf, len, signatureBuf);
|
return it->second.first->Verify (buf, len, signatureBuf);
|
||||||
// TODO: process key
|
// TODO: process key
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FamilyID Families::GetFamilyID (const std::string& family) const
|
||||||
|
{
|
||||||
|
auto it = m_SigningKeys.find (family);
|
||||||
|
if (it != m_SigningKeys.end ())
|
||||||
|
return it->second.second;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
|
||||||
{
|
{
|
||||||
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -19,6 +19,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
|
typedef int FamilyID;
|
||||||
class Families
|
class Families
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -27,7 +28,8 @@ namespace data
|
|||||||
~Families ();
|
~Families ();
|
||||||
void LoadCertificates ();
|
void LoadCertificates ();
|
||||||
bool VerifyFamily (const std::string& family, const IdentHash& ident,
|
bool VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
const char * signature, const char * key = nullptr);
|
const char * signature, const char * key = nullptr) const;
|
||||||
|
FamilyID GetFamilyID (const std::string& family) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@ namespace data
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
|
std::map<std::string, std::pair<std::shared_ptr<i2p::crypto::Verifier>, FamilyID> > m_SigningKeys; // family -> (verifier, id)
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -484,6 +484,11 @@ namespace garlic
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
|
||||||
|
{
|
||||||
|
AddECIESx25519Key (key, tag);
|
||||||
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -245,6 +245,7 @@ namespace garlic
|
|||||||
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
||||||
void AddECIESx25519Key (const uint8_t * key, uint64_t tag); // one tag
|
void AddECIESx25519Key (const uint8_t * key, uint64_t tag); // one tag
|
||||||
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
||||||
|
virtual void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag); // from different thread
|
||||||
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
||||||
uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset);
|
uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset);
|
||||||
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -802,13 +802,8 @@ namespace i2p
|
|||||||
break;
|
break;
|
||||||
case eI2NPGarlic:
|
case eI2NPGarlic:
|
||||||
{
|
{
|
||||||
if (msg->from)
|
if (msg->from && msg->from->GetTunnelPool ())
|
||||||
{
|
|
||||||
if (msg->from->GetTunnelPool ())
|
|
||||||
msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
|
msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
|
||||||
else
|
|
||||||
LogPrint (eLogInfo, "I2NP: Local destination for garlic doesn't exist anymore");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
i2p::context.ProcessGarlicMessage (msg);
|
i2p::context.ProcessGarlicMessage (msg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -50,42 +50,3 @@ uint64_t be64toh(uint64_t big64)
|
|||||||
return u64.raw_value;
|
return u64.raw_value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* it can be used in Windows 8
|
|
||||||
#include <Winsock2.h>
|
|
||||||
|
|
||||||
uint16_t htobe16(uint16_t int16)
|
|
||||||
{
|
|
||||||
return htons(int16);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t htobe32(uint32_t int32)
|
|
||||||
{
|
|
||||||
return htonl(int32);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t htobe64(uint64_t int64)
|
|
||||||
{
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/jj710199%28v=vs.85%29.aspx
|
|
||||||
//return htonll(int64);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t be16toh(uint16_t big16)
|
|
||||||
{
|
|
||||||
return ntohs(big16);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t be32toh(uint32_t big32)
|
|
||||||
{
|
|
||||||
return ntohl(big32);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t be64toh(uint64_t big64)
|
|
||||||
{
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/jj710199%28v=vs.85%29.aspx
|
|
||||||
//return ntohll(big64);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -13,10 +13,11 @@
|
|||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
#include <sys/endian.h>
|
#include <sys/endian.h>
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__GLIBC__)
|
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__GLIBC__)
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#elif defined(__APPLE__) && defined(__MACH__)
|
|
||||||
|
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
#include <libkern/OSByteOrder.h>
|
#include <libkern/OSByteOrder.h>
|
||||||
|
|
||||||
#define htobe16(x) OSSwapHostToBigInt16(x)
|
#define htobe16(x) OSSwapHostToBigInt16(x)
|
||||||
@@ -34,6 +35,22 @@
|
|||||||
#define be64toh(x) OSSwapBigToHostInt64(x)
|
#define be64toh(x) OSSwapBigToHostInt64(x)
|
||||||
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define htobe16(x) __builtin_bswap16(x)
|
||||||
|
#define htole16(x) (x)
|
||||||
|
#define be16toh(x) __builtin_bswap16(x)
|
||||||
|
#define le16toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe32(x) __builtin_bswap32(x)
|
||||||
|
#define htole32(x) (x)
|
||||||
|
#define be32toh(x) __builtin_bswap32(x)
|
||||||
|
#define le32toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe64(x) __builtin_bswap64(x)
|
||||||
|
#define htole64(x) (x)
|
||||||
|
#define be64toh(x) __builtin_bswap64(x)
|
||||||
|
#define le64toh(x) (x)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define NEEDS_LOCAL_ENDIAN
|
#define NEEDS_LOCAL_ENDIAN
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ namespace data
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
validate lease set buffer signature and extract expiration timestamp
|
* validate lease set buffer signature and extract expiration timestamp
|
||||||
@returns true if the leaseset is well formed and signature is valid
|
* @returns true if the leaseset is well formed and signature is valid
|
||||||
*/
|
*/
|
||||||
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
|
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && !defined(_NETINET_IN_H)
|
||||||
#include <linux/in6.h>
|
#include <linux/in6.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ namespace transport
|
|||||||
|
|
||||||
void NTCP2Establisher::KDF1Bob ()
|
void NTCP2Establisher::KDF1Bob ()
|
||||||
{
|
{
|
||||||
KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ());
|
KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
|
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
|
||||||
@@ -91,7 +91,7 @@ namespace transport
|
|||||||
void NTCP2Establisher::KDF3Alice ()
|
void NTCP2Establisher::KDF3Alice ()
|
||||||
{
|
{
|
||||||
uint8_t inputKeyMaterial[32];
|
uint8_t inputKeyMaterial[32];
|
||||||
i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial);
|
i2p::context.GetNTCP2StaticKeys ().Agree (GetRemotePub (), inputKeyMaterial);
|
||||||
MixKey (inputKeyMaterial);
|
MixKey (inputKeyMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,8 +195,9 @@ namespace transport
|
|||||||
MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext)
|
MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen)
|
bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew)
|
||||||
{
|
{
|
||||||
|
clockSkew = false;
|
||||||
// decrypt X
|
// decrypt X
|
||||||
i2p::crypto::CBCDecryption decryption;
|
i2p::crypto::CBCDecryption decryption;
|
||||||
decryption.SetKey (i2p::context.GetIdentHash ());
|
decryption.SetKey (i2p::context.GetIdentHash ());
|
||||||
@@ -232,7 +233,8 @@ namespace transport
|
|||||||
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
|
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
|
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
|
||||||
return false;
|
clockSkew = true;
|
||||||
|
// we send SessionCreate to let Alice know our time and then close session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -337,8 +339,8 @@ namespace transport
|
|||||||
m_Establisher->m_RemoteIdentHash = GetRemoteIdentity ()->GetIdentHash ();
|
m_Establisher->m_RemoteIdentHash = GetRemoteIdentity ()->GetIdentHash ();
|
||||||
if (addr)
|
if (addr)
|
||||||
{
|
{
|
||||||
memcpy (m_Establisher->m_RemoteStaticKey, addr->ntcp2->staticKey, 32);
|
memcpy (m_Establisher->m_RemoteStaticKey, addr->s, 32);
|
||||||
memcpy (m_Establisher->m_IV, addr->ntcp2->iv, 16);
|
memcpy (m_Establisher->m_IV, addr->i, 16);
|
||||||
m_RemoteEndpoint = boost::asio::ip::tcp::endpoint (addr->host, addr->port);
|
m_RemoteEndpoint = boost::asio::ip::tcp::endpoint (addr->host, addr->port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -476,9 +478,16 @@ namespace transport
|
|||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "NTCP2: SessionRequest received ", bytes_transferred);
|
LogPrint (eLogDebug, "NTCP2: SessionRequest received ", bytes_transferred);
|
||||||
uint16_t paddingLen = 0;
|
uint16_t paddingLen = 0;
|
||||||
if (m_Establisher->ProcessSessionRequestMessage (paddingLen))
|
bool clockSkew = false;
|
||||||
|
if (m_Establisher->ProcessSessionRequestMessage (paddingLen, clockSkew))
|
||||||
{
|
{
|
||||||
if (paddingLen > 0)
|
if (clockSkew)
|
||||||
|
{
|
||||||
|
// we don't care about padding, send SessionCreated and close session
|
||||||
|
SendSessionCreated ();
|
||||||
|
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
||||||
|
}
|
||||||
|
else if (paddingLen > 0)
|
||||||
{
|
{
|
||||||
if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
|
if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
|
||||||
{
|
{
|
||||||
@@ -891,7 +900,7 @@ namespace transport
|
|||||||
case eNTCP2BlkTermination:
|
case eNTCP2BlkTermination:
|
||||||
if (size >= 9)
|
if (size >= 9)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "NTCP2: Rermination. reason=", (int)(frame[offset + 8]));
|
LogPrint (eLogDebug, "NTCP2: Termination. reason=", (int)(frame[offset + 8]));
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1234,7 +1243,7 @@ namespace transport
|
|||||||
m_NTCP2V6Acceptor->open (boost::asio::ip::tcp::v6());
|
m_NTCP2V6Acceptor->open (boost::asio::ip::tcp::v6());
|
||||||
m_NTCP2V6Acceptor->set_option (boost::asio::ip::v6_only (true));
|
m_NTCP2V6Acceptor->set_option (boost::asio::ip::v6_only (true));
|
||||||
m_NTCP2V6Acceptor->set_option (boost::asio::socket_base::reuse_address (true));
|
m_NTCP2V6Acceptor->set_option (boost::asio::socket_base::reuse_address (true));
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && !defined(_NETINET_IN_H)
|
||||||
if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address
|
if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address
|
||||||
{
|
{
|
||||||
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -107,7 +107,7 @@ namespace transport
|
|||||||
void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
||||||
void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce);
|
void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce);
|
||||||
|
|
||||||
bool ProcessSessionRequestMessage (uint16_t& paddingLen);
|
bool ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew);
|
||||||
bool ProcessSessionCreatedMessage (uint16_t& paddingLen);
|
bool ProcessSessionCreatedMessage (uint16_t& paddingLen);
|
||||||
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
||||||
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
|
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -107,7 +107,10 @@ namespace data
|
|||||||
{
|
{
|
||||||
i2p::util::SetThreadName("NetDB");
|
i2p::util::SetThreadName("NetDB");
|
||||||
|
|
||||||
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
uint64_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
||||||
|
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
int16_t profilesCleanupVariance = 0;
|
||||||
|
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -155,6 +158,7 @@ namespace data
|
|||||||
m_Requests.ManageRequests ();
|
m_Requests.ManageRequests ();
|
||||||
lastManageRequest = ts;
|
lastManageRequest = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
|
if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
|
||||||
{
|
{
|
||||||
if (lastSave)
|
if (lastSave)
|
||||||
@@ -164,12 +168,20 @@ namespace data
|
|||||||
}
|
}
|
||||||
lastSave = ts;
|
lastSave = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
i2p::context.CleanupDestination ();
|
i2p::context.CleanupDestination ();
|
||||||
lastDestinationCleanup = ts;
|
lastDestinationCleanup = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance))
|
||||||
|
{
|
||||||
|
DeleteObsoleteProfiles ();
|
||||||
|
lastProfilesCleanup = ts;
|
||||||
|
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
||||||
|
}
|
||||||
|
|
||||||
// publish
|
// publish
|
||||||
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
||||||
{
|
{
|
||||||
@@ -195,6 +207,7 @@ namespace data
|
|||||||
lastPublish = ts;
|
lastPublish = ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastExploratory >= 30) // exploratory every 30 seconds
|
if (ts - lastExploratory >= 30) // exploratory every 30 seconds
|
||||||
{
|
{
|
||||||
auto numRouters = m_RouterInfos.size ();
|
auto numRouters = m_RouterInfos.size ();
|
||||||
@@ -472,13 +485,13 @@ namespace data
|
|||||||
i2p::transport::transports.SendMessages(ih, requests);
|
i2p::transport::transports.SendMessages(ih, requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetDb::LoadRouterInfo (const std::string & path)
|
bool NetDb::LoadRouterInfo (const std::string& path, uint64_t ts)
|
||||||
{
|
{
|
||||||
auto r = std::make_shared<RouterInfo>(path);
|
auto r = std::make_shared<RouterInfo>(path);
|
||||||
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses ())
|
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses () &&
|
||||||
|
ts < r->GetTimestamp () + 24*60*60*NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT*1000LL)
|
||||||
{
|
{
|
||||||
r->DeleteBuffer ();
|
r->DeleteBuffer ();
|
||||||
r->ClearProperties (); // properties are not used for regular routers
|
|
||||||
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
||||||
{
|
{
|
||||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||||
@@ -487,7 +500,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "NetDb: RI from ", path, " is invalid. Delete");
|
LogPrint(eLogWarning, "NetDb: RI from ", path, " is invalid or too old. Delete");
|
||||||
i2p::fs::Remove(path);
|
i2p::fs::Remove(path);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -568,11 +581,11 @@ namespace data
|
|||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
m_Floodfills.clear ();
|
m_Floodfills.clear ();
|
||||||
|
|
||||||
m_LastLoad = i2p::util::GetSecondsSinceEpoch();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
m_Storage.Traverse(files);
|
m_Storage.Traverse(files);
|
||||||
for (const auto& path : files)
|
for (const auto& path : files)
|
||||||
LoadRouterInfo(path);
|
LoadRouterInfo (path, ts);
|
||||||
|
|
||||||
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)");
|
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)");
|
||||||
}
|
}
|
||||||
@@ -596,10 +609,9 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (it.second == own) continue; // skip own
|
if (it.second == own) continue; // skip own
|
||||||
std::string ident = it.second->GetIdentHashBase64();
|
std::string ident = it.second->GetIdentHashBase64();
|
||||||
std::string path = m_Storage.Path(ident);
|
|
||||||
if (it.second->IsUpdated ())
|
if (it.second->IsUpdated ())
|
||||||
{
|
{
|
||||||
it.second->SaveToFile (path);
|
it.second->SaveToFile (m_Storage.Path(ident));
|
||||||
it.second->SetUpdated (false);
|
it.second->SetUpdated (false);
|
||||||
it.second->SetUnreachable (false);
|
it.second->SetUnreachable (false);
|
||||||
it.second->DeleteBuffer ();
|
it.second->DeleteBuffer ();
|
||||||
@@ -630,6 +642,8 @@ namespace data
|
|||||||
}
|
}
|
||||||
} // m_RouterInfos iteration
|
} // m_RouterInfos iteration
|
||||||
|
|
||||||
|
m_RouterInfoBuffersPool.CleanUpMt ();
|
||||||
|
|
||||||
if (updatedCount > 0)
|
if (updatedCount > 0)
|
||||||
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
||||||
if (deletedCount > 0)
|
if (deletedCount > 0)
|
||||||
@@ -1189,6 +1203,16 @@ namespace data
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const
|
||||||
|
{
|
||||||
|
return GetRandomRouter (
|
||||||
|
[v4, &excluded](std::shared_ptr<const RouterInfo> router)->bool
|
||||||
|
{
|
||||||
|
return !router->IsHidden () && router->IsECIES () &&
|
||||||
|
router->IsSSU2PeerTesting (v4) && !excluded.count (router->GetIdentHash ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSUV6Router () const
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSUV6Router () const
|
||||||
{
|
{
|
||||||
return GetRandomRouter (
|
return GetRandomRouter (
|
||||||
@@ -1363,7 +1387,8 @@ namespace data
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily(const std::string & fam) const {
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const
|
||||||
|
{
|
||||||
return GetRandomRouter(
|
return GetRandomRouter(
|
||||||
[fam](std::shared_ptr<const RouterInfo> router)->bool
|
[fam](std::shared_ptr<const RouterInfo> router)->bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "NetDbRequests.h"
|
#include "NetDbRequests.h"
|
||||||
#include "Family.h"
|
#include "Family.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@@ -41,6 +42,7 @@ namespace data
|
|||||||
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
|
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
|
||||||
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
|
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
|
||||||
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
|
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
|
||||||
|
const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days
|
||||||
const int NETDB_PUBLISH_INTERVAL = 60 * 40;
|
const int NETDB_PUBLISH_INTERVAL = 60 * 40;
|
||||||
const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
|
const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
|
||||||
const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
||||||
@@ -88,13 +90,14 @@ namespace data
|
|||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||||
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
||||||
|
std::shared_ptr<const RouterInfo> GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
|
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
|
||||||
std::shared_ptr<const RouterInfo> GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||||
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
|
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
|
||||||
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||||
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily(const std::string & fam) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily (FamilyID fam) const;
|
||||||
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
||||||
|
|
||||||
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
@@ -120,13 +123,14 @@ namespace data
|
|||||||
size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n);
|
size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n);
|
||||||
|
|
||||||
void ClearRouterInfos () { m_RouterInfos.clear (); };
|
void ClearRouterInfos () { m_RouterInfos.clear (); };
|
||||||
|
std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
|
||||||
|
|
||||||
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Load ();
|
void Load ();
|
||||||
bool LoadRouterInfo (const std::string & path);
|
bool LoadRouterInfo (const std::string& path, uint64_t ts);
|
||||||
void SaveUpdated ();
|
void SaveUpdated ();
|
||||||
void Run (); // exploratory thread
|
void Run (); // exploratory thread
|
||||||
void Explore (int numDestinations);
|
void Explore (int numDestinations);
|
||||||
@@ -153,7 +157,6 @@ namespace data
|
|||||||
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
uint64_t m_LastLoad;
|
|
||||||
std::thread * m_Thread;
|
std::thread * m_Thread;
|
||||||
i2p::util::Queue<std::shared_ptr<const I2NPMessage> > m_Queue; // of I2NPDatabaseStoreMsg
|
i2p::util::Queue<std::shared_ptr<const I2NPMessage> > m_Queue; // of I2NPDatabaseStoreMsg
|
||||||
|
|
||||||
@@ -175,6 +178,8 @@ namespace data
|
|||||||
|
|
||||||
std::set<IdentHash> m_PublishExcluded;
|
std::set<IdentHash> m_PublishExcluded;
|
||||||
uint32_t m_PublishReplyToken = 0;
|
uint32_t m_PublishReplyToken = 0;
|
||||||
|
|
||||||
|
i2p::util::MemoryPoolMt<RouterInfo::Buffer> m_RouterInfoBuffersPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NetDb netdb;
|
extern NetDb netdb;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include "Poly1305.h"
|
|
||||||
/**
|
/**
|
||||||
This code is licensed under the MCGSI Public License
|
* This code is licensed under the MCGSI Public License
|
||||||
Copyright 2018 Jeff Becker
|
* Copyright 2018 Jeff Becker
|
||||||
|
*
|
||||||
Kovri go write your own code
|
*Kovri go write your own code
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Poly1305.h"
|
||||||
|
|
||||||
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
* Kovri go write your own code
|
* Kovri go write your own code
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBI2PD_POLY1305_H
|
#ifndef LIBI2PD_POLY1305_H
|
||||||
#define LIBI2PD_POLY1305_H
|
#define LIBI2PD_POLY1305_H
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -29,6 +29,8 @@ namespace data
|
|||||||
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
||||||
|
|
||||||
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
|
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
|
||||||
|
const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day)
|
||||||
|
const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours)
|
||||||
|
|
||||||
class RouterProfile
|
class RouterProfile
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -84,6 +84,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
|
bool yggdrasil; i2p::config::GetOption("meshnets.yggdrasil", yggdrasil);
|
||||||
|
|
||||||
std::vector<std::string> httpsReseedHostList;
|
std::vector<std::string> httpsReseedHostList;
|
||||||
if (ipv4 || ipv6)
|
if (ipv4 || ipv6)
|
||||||
@@ -94,7 +95,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> yggReseedHostList;
|
std::vector<std::string> yggReseedHostList;
|
||||||
if (!i2p::util::net::GetYggdrasilAddress ().is_unspecified ())
|
if (yggdrasil && !i2p::util::net::GetYggdrasilAddress ().is_unspecified ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Reseed: Yggdrasil is supported");
|
LogPrint (eLogInfo, "Reseed: Yggdrasil is supported");
|
||||||
std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs);
|
std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -57,7 +57,7 @@ namespace i2p
|
|||||||
|
|
||||||
void RouterContext::NewRouterInfo ()
|
void RouterContext::NewRouterInfo ()
|
||||||
{
|
{
|
||||||
i2p::data::RouterInfo routerInfo;
|
i2p::data::LocalRouterInfo routerInfo;
|
||||||
routerInfo.SetRouterIdentity (GetIdentity ());
|
routerInfo.SetRouterIdentity (GetIdentity ());
|
||||||
uint16_t port; i2p::config::GetOption("port", port);
|
uint16_t port; i2p::config::GetOption("port", port);
|
||||||
if (!port)
|
if (!port)
|
||||||
@@ -69,11 +69,14 @@ namespace i2p
|
|||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
||||||
bool nat; i2p::config::GetOption("nat", nat);
|
bool nat; i2p::config::GetOption("nat", nat);
|
||||||
|
|
||||||
if ((ntcp2 || ygg) && !m_NTCP2Keys)
|
if ((ntcp2 || ygg) && !m_NTCP2Keys)
|
||||||
NewNTCP2Keys ();
|
NewNTCP2Keys ();
|
||||||
|
if (ssu2 && !m_SSU2Keys)
|
||||||
|
NewSSU2Keys ();
|
||||||
bool ntcp2Published = false;
|
bool ntcp2Published = false;
|
||||||
if (ntcp2)
|
if (ntcp2)
|
||||||
{
|
{
|
||||||
@@ -84,6 +87,9 @@ namespace i2p
|
|||||||
if (!ntcp2proxy.empty ()) ntcp2Published = false;
|
if (!ntcp2proxy.empty ()) ntcp2Published = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool ssu2Published = false;
|
||||||
|
if (ssu2)
|
||||||
|
i2p::config::GetOption("ssu2.published", ssu2Published);
|
||||||
uint8_t caps = 0, addressCaps = 0;
|
uint8_t caps = 0, addressCaps = 0;
|
||||||
if (ipv4)
|
if (ipv4)
|
||||||
{
|
{
|
||||||
@@ -112,6 +118,16 @@ namespace i2p
|
|||||||
routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
|
routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
|
||||||
caps |= i2p::data::RouterInfo::eReachable; // R
|
caps |= i2p::data::RouterInfo::eReachable; // R
|
||||||
}
|
}
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
if (ssu2Published)
|
||||||
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
|
||||||
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ipv6)
|
if (ipv6)
|
||||||
{
|
{
|
||||||
@@ -147,6 +163,17 @@ namespace i2p
|
|||||||
routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
|
routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
|
||||||
caps |= i2p::data::RouterInfo::eReachable; // R
|
caps |= i2p::data::RouterInfo::eReachable; // R
|
||||||
}
|
}
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
if (ssu2Published)
|
||||||
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ipv4) // no other ssu2 addresses yet
|
||||||
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
||||||
|
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ygg)
|
if (ygg)
|
||||||
{
|
{
|
||||||
@@ -157,7 +184,7 @@ namespace i2p
|
|||||||
|
|
||||||
if (addressCaps)
|
if (addressCaps)
|
||||||
routerInfo.SetUnreachableAddressesTransportCaps (addressCaps);
|
routerInfo.SetUnreachableAddressesTransportCaps (addressCaps);
|
||||||
routerInfo.SetCaps (caps); // caps + L
|
routerInfo.UpdateCaps (caps); // caps + L
|
||||||
routerInfo.SetProperty ("netId", std::to_string (m_NetID));
|
routerInfo.SetProperty ("netId", std::to_string (m_NetID));
|
||||||
routerInfo.SetProperty ("router.version", I2P_VERSION);
|
routerInfo.SetProperty ("router.version", I2P_VERSION);
|
||||||
routerInfo.CreateBuffer (m_Keys);
|
routerInfo.CreateBuffer (m_Keys);
|
||||||
@@ -174,17 +201,30 @@ namespace i2p
|
|||||||
|
|
||||||
void RouterContext::NewNTCP2Keys ()
|
void RouterContext::NewNTCP2Keys ()
|
||||||
{
|
{
|
||||||
m_StaticKeys.reset (new i2p::crypto::X25519Keys ());
|
m_NTCP2StaticKeys.reset (new i2p::crypto::X25519Keys ());
|
||||||
m_StaticKeys->GenerateKeys ();
|
m_NTCP2StaticKeys->GenerateKeys ();
|
||||||
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
|
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
|
||||||
m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
|
m_NTCP2StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
|
||||||
memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32);
|
memcpy (m_NTCP2Keys->staticPublicKey, m_NTCP2StaticKeys->GetPublicKey (), 32);
|
||||||
RAND_bytes (m_NTCP2Keys->iv, 16);
|
RAND_bytes (m_NTCP2Keys->iv, 16);
|
||||||
// save
|
// save
|
||||||
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
|
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
|
||||||
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
|
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::NewSSU2Keys ()
|
||||||
|
{
|
||||||
|
m_SSU2StaticKeys.reset (new i2p::crypto::X25519Keys ());
|
||||||
|
m_SSU2StaticKeys->GenerateKeys ();
|
||||||
|
m_SSU2Keys.reset (new SSU2PrivateKeys ());
|
||||||
|
m_SSU2StaticKeys->GetPrivateKey (m_SSU2Keys->staticPrivateKey);
|
||||||
|
memcpy (m_SSU2Keys->staticPublicKey, m_SSU2StaticKeys->GetPublicKey (), 32);
|
||||||
|
RAND_bytes (m_SSU2Keys->intro, 32);
|
||||||
|
// save
|
||||||
|
std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
|
||||||
|
fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::SetStatus (RouterStatus status)
|
void RouterContext::SetStatus (RouterStatus status)
|
||||||
{
|
{
|
||||||
if (status != m_Status)
|
if (status != m_Status)
|
||||||
@@ -229,7 +269,7 @@ namespace i2p
|
|||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (auto& address : m_RouterInfo.GetAddresses ())
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
{
|
{
|
||||||
if (!address->IsNTCP2 () && address->port != port)
|
if (!address->IsNTCP2 () && !address->IsSSU2 () && address->port != port)
|
||||||
{
|
{
|
||||||
address->port = port;
|
address->port = port;
|
||||||
updated = true;
|
updated = true;
|
||||||
@@ -265,7 +305,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
if (port) address->port = port;
|
if (port) address->port = port;
|
||||||
address->published = publish;
|
address->published = publish;
|
||||||
address->ntcp2->iv = m_NTCP2Keys->iv;
|
memcpy (address->i, m_NTCP2Keys->iv, 16);
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,6 +340,59 @@ namespace i2p
|
|||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6)
|
||||||
|
{
|
||||||
|
if (!m_SSU2Keys || (publish && !port)) return;
|
||||||
|
bool updated = false;
|
||||||
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
|
{
|
||||||
|
if (address->IsSSU2 () && (address->port != port || address->published != publish) &&
|
||||||
|
((v4 && address->IsV4 ()) || (v6 && address->IsV6 ())))
|
||||||
|
{
|
||||||
|
address->port = port;
|
||||||
|
address->published = publish;
|
||||||
|
if (publish)
|
||||||
|
address->caps |= i2p::data::RouterInfo::eSSUIntroducer;
|
||||||
|
else
|
||||||
|
address->caps &= ~i2p::data::RouterInfo::eSSUIntroducer;
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updated)
|
||||||
|
UpdateRouterInfo ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::UpdateSSU2Address (bool enable)
|
||||||
|
{
|
||||||
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
|
bool found = false, updated = false;
|
||||||
|
for (auto it = addresses.begin (); it != addresses.end (); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->IsSSU2 ())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
if (!enable)
|
||||||
|
{
|
||||||
|
addresses.erase (it);
|
||||||
|
updated= true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (enable && !found)
|
||||||
|
{
|
||||||
|
uint8_t addressCaps = 0;
|
||||||
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
|
if (ipv4) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
|
||||||
|
if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
|
||||||
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addressCaps);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
if (updated)
|
||||||
|
UpdateRouterInfo ();
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
@@ -349,10 +442,10 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
m_IsFloodfill = floodfill;
|
m_IsFloodfill = floodfill;
|
||||||
if (floodfill)
|
if (floodfill)
|
||||||
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eFloodfill);
|
m_RouterInfo.UpdateCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eFloodfill);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
|
m_RouterInfo.UpdateCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
|
||||||
// we don't publish number of routers and leaseset for non-floodfill
|
// we don't publish number of routers and leaseset for non-floodfill
|
||||||
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS);
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS);
|
||||||
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS);
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS);
|
||||||
@@ -414,7 +507,7 @@ namespace i2p
|
|||||||
// no break here, extra + high means 'X'
|
// no break here, extra + high means 'X'
|
||||||
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
|
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
|
||||||
}
|
}
|
||||||
m_RouterInfo.SetCaps (caps);
|
m_RouterInfo.UpdateCaps (caps);
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
m_BandwidthLimit = limit;
|
m_BandwidthLimit = limit;
|
||||||
}
|
}
|
||||||
@@ -469,13 +562,13 @@ namespace i2p
|
|||||||
caps |= i2p::data::RouterInfo::eUnreachable;
|
caps |= i2p::data::RouterInfo::eUnreachable;
|
||||||
if (v6 || !SupportsV6 ())
|
if (v6 || !SupportsV6 ())
|
||||||
caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill
|
caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill
|
||||||
m_RouterInfo.SetCaps (caps);
|
m_RouterInfo.UpdateCaps (caps);
|
||||||
}
|
}
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
// delete previous introducers
|
// delete previous introducers
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto& addr : addresses)
|
for (auto& addr : addresses)
|
||||||
if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
|
if (addr->ssu && !addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
|
||||||
{
|
{
|
||||||
addr->published = false;
|
addr->published = false;
|
||||||
addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer
|
addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer
|
||||||
@@ -501,13 +594,13 @@ namespace i2p
|
|||||||
caps |= i2p::data::RouterInfo::eReachable;
|
caps |= i2p::data::RouterInfo::eReachable;
|
||||||
if (m_IsFloodfill)
|
if (m_IsFloodfill)
|
||||||
caps |= i2p::data::RouterInfo::eFloodfill;
|
caps |= i2p::data::RouterInfo::eFloodfill;
|
||||||
m_RouterInfo.SetCaps (caps);
|
m_RouterInfo.UpdateCaps (caps);
|
||||||
}
|
}
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
// delete previous introducers
|
// delete previous introducers
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto& addr : addresses)
|
for (auto& addr : addresses)
|
||||||
if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
|
if (addr->ssu && !addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
|
||||||
{
|
{
|
||||||
addr->published = true;
|
addr->published = true;
|
||||||
addr->caps |= i2p::data::RouterInfo::eSSUIntroducer;
|
addr->caps |= i2p::data::RouterInfo::eSSUIntroducer;
|
||||||
@@ -536,17 +629,26 @@ namespace i2p
|
|||||||
if (supportsV6)
|
if (supportsV6)
|
||||||
{
|
{
|
||||||
// insert v6 addresses if necessary
|
// insert v6 addresses if necessary
|
||||||
bool foundSSU = false, foundNTCP2 = false;
|
bool foundSSU = false, foundNTCP2 = false, foundSSU2 = false;
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto& addr: addresses)
|
for (auto& addr: addresses)
|
||||||
{
|
{
|
||||||
if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host))
|
if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host))
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
switch (addr->transportStyle)
|
||||||
|
{
|
||||||
|
case i2p::data::RouterInfo::eTransportSSU:
|
||||||
foundSSU = true;
|
foundSSU = true;
|
||||||
else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
foundNTCP2 = true;
|
foundNTCP2 = true;
|
||||||
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportSSU2:
|
||||||
|
foundSSU2 = true;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
port = addr->port;
|
port = addr->port;
|
||||||
}
|
}
|
||||||
@@ -583,6 +685,22 @@ namespace i2p
|
|||||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6);
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// SSU2
|
||||||
|
if (!foundSSU2)
|
||||||
|
{
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
|
||||||
|
if (ssu2Published)
|
||||||
|
{
|
||||||
|
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
||||||
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_RouterInfo.EnableV6 ();
|
m_RouterInfo.EnableV6 ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -598,7 +716,7 @@ namespace i2p
|
|||||||
// update
|
// update
|
||||||
if (supportsV4)
|
if (supportsV4)
|
||||||
{
|
{
|
||||||
bool foundSSU = false, foundNTCP2 = false;
|
bool foundSSU = false, foundNTCP2 = false, foundSSU2 = false;
|
||||||
std::string host = "127.0.0.1";
|
std::string host = "127.0.0.1";
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
@@ -606,10 +724,19 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
if (addr->IsV4 ())
|
if (addr->IsV4 ())
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
switch (addr->transportStyle)
|
||||||
|
{
|
||||||
|
case i2p::data::RouterInfo::eTransportSSU:
|
||||||
foundSSU = true;
|
foundSSU = true;
|
||||||
else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
foundNTCP2 = true;
|
foundNTCP2 = true;
|
||||||
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportSSU2:
|
||||||
|
foundSSU2 = true;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (addr->port) port = addr->port;
|
if (addr->port) port = addr->port;
|
||||||
}
|
}
|
||||||
@@ -638,6 +765,22 @@ namespace i2p
|
|||||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4);
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// SSU2
|
||||||
|
if (!foundSSU2)
|
||||||
|
{
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
|
||||||
|
if (ssu2Published)
|
||||||
|
{
|
||||||
|
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
||||||
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_RouterInfo.EnableV4 ();
|
m_RouterInfo.EnableV4 ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -794,6 +937,30 @@ namespace i2p
|
|||||||
else
|
else
|
||||||
UpdateNTCP2Address (false); // disable NTCP2
|
UpdateNTCP2Address (false); // disable NTCP2
|
||||||
|
|
||||||
|
// read SSU2
|
||||||
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
|
if (ssu2)
|
||||||
|
{
|
||||||
|
// read SSU2 keys if available
|
||||||
|
std::ifstream s2k (i2p::fs::DataDirPath (SSU2_KEYS), std::ifstream::in | std::ifstream::binary);
|
||||||
|
if (s2k)
|
||||||
|
{
|
||||||
|
s2k.seekg (0, std::ios::end);
|
||||||
|
size_t len = s2k.tellg();
|
||||||
|
s2k.seekg (0, std::ios::beg);
|
||||||
|
if (len == sizeof (SSU2PrivateKeys))
|
||||||
|
{
|
||||||
|
m_SSU2Keys.reset (new SSU2PrivateKeys ());
|
||||||
|
s2k.read ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
|
||||||
|
}
|
||||||
|
s2k.close ();
|
||||||
|
}
|
||||||
|
if (!m_SSU2Keys) NewSSU2Keys ();
|
||||||
|
UpdateSSU2Address (true); // enable SSU2
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UpdateSSU2Address (false); // disable SSU2
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,17 +1077,31 @@ namespace i2p
|
|||||||
return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE);
|
return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
|
i2p::crypto::X25519Keys& RouterContext::GetNTCP2StaticKeys ()
|
||||||
{
|
{
|
||||||
if (!m_StaticKeys)
|
if (!m_NTCP2StaticKeys)
|
||||||
{
|
{
|
||||||
if (!m_NTCP2Keys) NewNTCP2Keys ();
|
if (!m_NTCP2Keys) NewNTCP2Keys ();
|
||||||
auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey);
|
auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey);
|
||||||
if (!m_StaticKeys)
|
if (!m_NTCP2StaticKeys)
|
||||||
m_StaticKeys.reset (x);
|
m_NTCP2StaticKeys.reset (x);
|
||||||
else
|
else
|
||||||
delete x;
|
delete x;
|
||||||
}
|
}
|
||||||
return *m_StaticKeys;
|
return *m_NTCP2StaticKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2p::crypto::X25519Keys& RouterContext::GetSSU2StaticKeys ()
|
||||||
|
{
|
||||||
|
if (!m_SSU2StaticKeys)
|
||||||
|
{
|
||||||
|
if (!m_SSU2Keys) NewSSU2Keys ();
|
||||||
|
auto x = new i2p::crypto::X25519Keys (m_SSU2Keys->staticPrivateKey, m_SSU2Keys->staticPublicKey);
|
||||||
|
if (!m_SSU2StaticKeys)
|
||||||
|
m_SSU2StaticKeys.reset (x);
|
||||||
|
else
|
||||||
|
delete x;
|
||||||
|
}
|
||||||
|
return *m_SSU2StaticKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -29,6 +29,7 @@ namespace garlic
|
|||||||
const char ROUTER_INFO[] = "router.info";
|
const char ROUTER_INFO[] = "router.info";
|
||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
const char NTCP2_KEYS[] = "ntcp2.keys";
|
const char NTCP2_KEYS[] = "ntcp2.keys";
|
||||||
|
const char SSU2_KEYS[] = "ssu2.keys";
|
||||||
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
||||||
|
|
||||||
enum RouterStatus
|
enum RouterStatus
|
||||||
@@ -61,13 +62,20 @@ namespace garlic
|
|||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SSU2PrivateKeys
|
||||||
|
{
|
||||||
|
uint8_t staticPublicKey[32];
|
||||||
|
uint8_t staticPrivateKey[32];
|
||||||
|
uint8_t intro[32];
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RouterContext ();
|
RouterContext ();
|
||||||
void Init ();
|
void Init ();
|
||||||
|
|
||||||
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
||||||
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
i2p::data::LocalRouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
||||||
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo ()
|
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo ()
|
||||||
{
|
{
|
||||||
return std::shared_ptr<i2p::data::RouterInfo> (&m_RouterInfo,
|
return std::shared_ptr<i2p::data::RouterInfo> (&m_RouterInfo,
|
||||||
@@ -78,10 +86,16 @@ namespace garlic
|
|||||||
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
||||||
[](i2p::garlic::GarlicDestination *) {});
|
[](i2p::garlic::GarlicDestination *) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
||||||
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
|
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
|
||||||
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
||||||
i2p::crypto::X25519Keys& GetStaticKeys ();
|
i2p::crypto::X25519Keys& GetNTCP2StaticKeys ();
|
||||||
|
|
||||||
|
const uint8_t * GetSSU2StaticPublicKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPublicKey : nullptr; };
|
||||||
|
const uint8_t * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
|
||||||
|
const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
|
||||||
|
i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
|
||||||
|
|
||||||
uint32_t GetUptime () const; // in seconds
|
uint32_t GetUptime () const; // in seconds
|
||||||
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
||||||
@@ -102,6 +116,8 @@ namespace garlic
|
|||||||
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
||||||
void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg);
|
void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg);
|
||||||
void UpdateNTCP2Address (bool enable);
|
void UpdateNTCP2Address (bool enable);
|
||||||
|
void PublishSSU2Address (int port, bool publish, bool v4, bool v6);
|
||||||
|
void UpdateSSU2Address (bool enable);
|
||||||
void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later
|
void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later
|
||||||
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
|
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
|
||||||
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||||
@@ -156,6 +172,7 @@ namespace garlic
|
|||||||
void NewRouterInfo ();
|
void NewRouterInfo ();
|
||||||
void UpdateRouterInfo ();
|
void UpdateRouterInfo ();
|
||||||
void NewNTCP2Keys ();
|
void NewNTCP2Keys ();
|
||||||
|
void NewSSU2Keys ();
|
||||||
bool Load ();
|
bool Load ();
|
||||||
void SaveKeys ();
|
void SaveKeys ();
|
||||||
|
|
||||||
@@ -163,7 +180,7 @@ namespace garlic
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
i2p::data::RouterInfo m_RouterInfo;
|
i2p::data::LocalRouterInfo m_RouterInfo;
|
||||||
i2p::data::PrivateKeys m_Keys;
|
i2p::data::PrivateKeys m_Keys;
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor, m_TunnelDecryptor;
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor, m_TunnelDecryptor;
|
||||||
std::shared_ptr<i2p::garlic::RouterIncomingRatchetSession> m_ECIESSession;
|
std::shared_ptr<i2p::garlic::RouterIncomingRatchetSession> m_ECIESSession;
|
||||||
@@ -177,7 +194,8 @@ namespace garlic
|
|||||||
int m_NetID;
|
int m_NetID;
|
||||||
std::mutex m_GarlicMutex;
|
std::mutex m_GarlicMutex;
|
||||||
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
||||||
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
|
||||||
|
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
|
||||||
// for ECIESx25519
|
// for ECIESx25519
|
||||||
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -13,11 +13,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "Profiling.h"
|
#include "Profiling.h"
|
||||||
|
#include "Family.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@@ -50,10 +52,12 @@ namespace data
|
|||||||
|
|
||||||
const uint8_t COST_NTCP2_PUBLISHED = 3;
|
const uint8_t COST_NTCP2_PUBLISHED = 3;
|
||||||
const uint8_t COST_NTCP2_NON_PUBLISHED = 14;
|
const uint8_t COST_NTCP2_NON_PUBLISHED = 14;
|
||||||
|
const uint8_t COST_SSU2_DIRECT = 8;
|
||||||
const uint8_t COST_SSU_DIRECT = 9;
|
const uint8_t COST_SSU_DIRECT = 9;
|
||||||
const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
|
const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
|
||||||
|
const uint8_t COST_SSU2_NON_PUBLISHED = 15;
|
||||||
|
|
||||||
const int MAX_RI_BUFFER_SIZE = 2048; // if RouterInfo exceeds 2048 we consider it as malformed, might be changed later
|
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
|
||||||
class RouterInfo: public RoutingDestination
|
class RouterInfo: public RoutingDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -65,6 +69,8 @@ namespace data
|
|||||||
eSSUV4 = 0x04,
|
eSSUV4 = 0x04,
|
||||||
eSSUV6 = 0x08,
|
eSSUV6 = 0x08,
|
||||||
eNTCP2V6Mesh = 0x10,
|
eNTCP2V6Mesh = 0x10,
|
||||||
|
eSSU2V4 = 0x20,
|
||||||
|
eSSU2V6 = 0x40,
|
||||||
eAllTransports = 0xFF
|
eAllTransports = 0xFF
|
||||||
};
|
};
|
||||||
typedef uint8_t CompatibleTransports;
|
typedef uint8_t CompatibleTransports;
|
||||||
@@ -91,7 +97,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
eTransportUnknown = 0,
|
eTransportUnknown = 0,
|
||||||
eTransportNTCP,
|
eTransportNTCP,
|
||||||
eTransportSSU
|
eTransportSSU,
|
||||||
|
eTransportSSU2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
|
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
|
||||||
@@ -100,7 +107,7 @@ namespace data
|
|||||||
Introducer (): iPort (0), iExp (0) {};
|
Introducer (): iPort (0), iExp (0) {};
|
||||||
boost::asio::ip::address iHost;
|
boost::asio::ip::address iHost;
|
||||||
int iPort;
|
int iPort;
|
||||||
IntroKey iKey;
|
IntroKey iKey; // or ih for SSU2
|
||||||
uint32_t iTag;
|
uint32_t iTag;
|
||||||
uint32_t iExp;
|
uint32_t iExp;
|
||||||
};
|
};
|
||||||
@@ -108,26 +115,19 @@ namespace data
|
|||||||
struct SSUExt
|
struct SSUExt
|
||||||
{
|
{
|
||||||
int mtu;
|
int mtu;
|
||||||
IntroKey key; // intro key for SSU
|
|
||||||
std::vector<Introducer> introducers;
|
std::vector<Introducer> introducers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NTCP2Ext
|
|
||||||
{
|
|
||||||
Tag<32> staticKey;
|
|
||||||
Tag<16> iv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Address
|
struct Address
|
||||||
{
|
{
|
||||||
TransportStyle transportStyle;
|
TransportStyle transportStyle;
|
||||||
boost::asio::ip::address host;
|
boost::asio::ip::address host;
|
||||||
|
Tag<32> s, i; // keys, i is first 16 bytes for NTCP2 and 32 bytes intro key for SSU
|
||||||
int port;
|
int port;
|
||||||
uint64_t date;
|
uint64_t date;
|
||||||
uint8_t caps;
|
uint8_t caps;
|
||||||
bool published = false;
|
bool published = false;
|
||||||
std::unique_ptr<SSUExt> ssu; // not null for SSU
|
std::unique_ptr<SSUExt> ssu; // not null for SSU
|
||||||
std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2
|
|
||||||
|
|
||||||
bool IsCompatible (const boost::asio::ip::address& other) const
|
bool IsCompatible (const boost::asio::ip::address& other) const
|
||||||
{
|
{
|
||||||
@@ -137,7 +137,7 @@ namespace data
|
|||||||
|
|
||||||
bool operator==(const Address& other) const
|
bool operator==(const Address& other) const
|
||||||
{
|
{
|
||||||
return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
|
return transportStyle == other.transportStyle &&
|
||||||
host == other.host && port == other.port;
|
host == other.host && port == other.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,9 +146,10 @@ namespace data
|
|||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNTCP2 () const { return (bool)ntcp2; };
|
bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
|
||||||
|
bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
|
||||||
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
|
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
|
||||||
bool IsReachableSSU () const { return (bool)ssu && (published || !ssu->introducers.empty ()); };
|
bool IsReachableSSU () const { return (bool)ssu && (published || UsesIntroducer ()); };
|
||||||
bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };
|
bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };
|
||||||
|
|
||||||
bool IsIntroducer () const { return caps & eSSUIntroducer; };
|
bool IsIntroducer () const { return caps & eSSUIntroducer; };
|
||||||
@@ -157,49 +158,64 @@ namespace data
|
|||||||
bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); };
|
bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); };
|
||||||
bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); };
|
bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Buffer: public std::array<uint8_t, MAX_RI_BUFFER_SIZE>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Buffer () = default;
|
||||||
|
Buffer (const uint8_t * buf, size_t len);
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::vector<std::shared_ptr<Address> > Addresses;
|
typedef std::vector<std::shared_ptr<Address> > Addresses;
|
||||||
|
|
||||||
RouterInfo ();
|
|
||||||
RouterInfo (const std::string& fullPath);
|
RouterInfo (const std::string& fullPath);
|
||||||
RouterInfo (const RouterInfo& ) = default;
|
RouterInfo (const RouterInfo& ) = default;
|
||||||
RouterInfo& operator=(const RouterInfo& ) = default;
|
RouterInfo& operator=(const RouterInfo& ) = default;
|
||||||
RouterInfo (const uint8_t * buf, int len);
|
RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len);
|
||||||
~RouterInfo ();
|
RouterInfo (const uint8_t * buf, size_t len);
|
||||||
|
virtual ~RouterInfo ();
|
||||||
|
|
||||||
std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
|
std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
|
||||||
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
|
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
|
||||||
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
||||||
uint64_t GetTimestamp () const { return m_Timestamp; };
|
uint64_t GetTimestamp () const { return m_Timestamp; };
|
||||||
int GetVersion () const { return m_Version; };
|
int GetVersion () const { return m_Version; };
|
||||||
|
virtual void SetProperty (const std::string& key, const std::string& value) {};
|
||||||
|
virtual void ClearProperties () {};
|
||||||
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
|
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
|
||||||
std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
|
std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
|
||||||
|
std::shared_ptr<const Address> GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const;
|
||||||
std::shared_ptr<const Address> GetPublishedNTCP2V4Address () const;
|
std::shared_ptr<const Address> GetPublishedNTCP2V4Address () const;
|
||||||
std::shared_ptr<const Address> GetPublishedNTCP2V6Address () const;
|
std::shared_ptr<const Address> GetPublishedNTCP2V6Address () const;
|
||||||
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
|
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
|
||||||
std::shared_ptr<const Address> GetSSUV6Address () const;
|
std::shared_ptr<const Address> GetSSUV6Address () const;
|
||||||
std::shared_ptr<const Address> GetYggdrasilAddress () const;
|
std::shared_ptr<const Address> GetYggdrasilAddress () const;
|
||||||
|
std::shared_ptr<const Address> GetSSU2V4Address () const;
|
||||||
|
std::shared_ptr<const Address> GetSSU2V6Address () const;
|
||||||
|
|
||||||
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
|
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
|
||||||
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||||
const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0);
|
const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0);
|
||||||
|
void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps = 0); // non published
|
||||||
|
void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
|
||||||
|
const boost::asio::ip::address& host, int port); // published
|
||||||
bool AddIntroducer (const Introducer& introducer);
|
bool AddIntroducer (const Introducer& introducer);
|
||||||
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||||
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
|
|
||||||
void DeleteProperty (const std::string& key); // called from RouterContext only
|
|
||||||
std::string GetProperty (const std::string& key) const; // called from RouterContext only
|
|
||||||
void ClearProperties () { m_Properties.clear (); };
|
|
||||||
void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
|
void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
|
||||||
void UpdateSupportedTransports ();
|
void UpdateSupportedTransports ();
|
||||||
bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
|
bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
|
||||||
bool IsReachable () const { return m_Caps & Caps::eReachable; };
|
bool IsReachable () const { return m_Caps & Caps::eReachable; };
|
||||||
bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
|
bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
|
||||||
bool IsSSU (bool v4only = true) const;
|
bool IsSSU (bool v4only = true) const;
|
||||||
bool IsSSUV6 () const;
|
bool IsSSUV6 () const { return m_SupportedTransports & eSSUV6; };
|
||||||
bool IsNTCP2 (bool v4only = true) const;
|
bool IsNTCP2 (bool v4only = true) const;
|
||||||
bool IsNTCP2V6 () const;
|
bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; };
|
||||||
bool IsV6 () const;
|
bool IsSSU2V4 () const { return m_SupportedTransports & eSSU2V4; };
|
||||||
bool IsV4 () const;
|
bool IsSSU2V6 () const { return m_SupportedTransports & eSSU2V6; };
|
||||||
bool IsMesh () const;
|
bool IsV6 () const { return m_SupportedTransports & (eSSUV6 | eNTCP2V6 | eSSU2V6); };
|
||||||
|
bool IsV4 () const { return m_SupportedTransports & (eSSUV4 | eNTCP2V4 | eSSU2V4); };
|
||||||
|
bool IsMesh () const { return m_SupportedTransports & eNTCP2V6Mesh; };
|
||||||
void EnableV6 ();
|
void EnableV6 ();
|
||||||
void DisableV6 ();
|
void DisableV6 ();
|
||||||
void EnableV4 ();
|
void EnableV4 ();
|
||||||
@@ -216,19 +232,18 @@ namespace data
|
|||||||
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
||||||
bool IsEligibleFloodfill () const;
|
bool IsEligibleFloodfill () const;
|
||||||
bool IsPeerTesting (bool v4) const;
|
bool IsPeerTesting (bool v4) const;
|
||||||
|
bool IsSSU2PeerTesting (bool v4) const;
|
||||||
bool IsIntroducer (bool v4) const;
|
bool IsIntroducer (bool v4) const;
|
||||||
|
|
||||||
uint8_t GetCaps () const { return m_Caps; };
|
uint8_t GetCaps () const { return m_Caps; };
|
||||||
void SetCaps (uint8_t caps);
|
void SetCaps (uint8_t caps) { m_Caps = caps; };
|
||||||
void SetCaps (const char * caps);
|
|
||||||
|
|
||||||
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
||||||
bool IsUnreachable () const { return m_IsUnreachable; };
|
bool IsUnreachable () const { return m_IsUnreachable; };
|
||||||
|
|
||||||
const uint8_t * GetBuffer () const { return m_Buffer; };
|
const uint8_t * GetBuffer () const { return m_Buffer->data (); };
|
||||||
const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary
|
const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary
|
||||||
int GetBufferLen () const { return m_BufferLen; };
|
size_t GetBufferLen () const { return m_BufferLen; };
|
||||||
void CreateBuffer (const PrivateKeys& privateKeys);
|
|
||||||
|
|
||||||
bool IsUpdated () const { return m_IsUpdated; };
|
bool IsUpdated () const { return m_IsUpdated; };
|
||||||
void SetUpdated (bool updated) { m_IsUpdated = updated; };
|
void SetUpdated (bool updated) { m_IsUpdated = updated; };
|
||||||
@@ -238,11 +253,11 @@ namespace data
|
|||||||
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
|
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
|
||||||
|
|
||||||
void Update (const uint8_t * buf, size_t len);
|
void Update (const uint8_t * buf, size_t len);
|
||||||
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
void DeleteBuffer () { m_Buffer = nullptr; };
|
||||||
bool IsNewer (const uint8_t * buf, size_t len) const;
|
bool IsNewer (const uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
/** return true if we are in a router family and the signature is valid */
|
/** return true if we are in a router family and the signature is valid */
|
||||||
bool IsFamily(const std::string & fam) const;
|
bool IsFamily (FamilyID famid) const;
|
||||||
|
|
||||||
// implements RoutingDestination
|
// implements RoutingDestination
|
||||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
||||||
@@ -250,36 +265,67 @@ namespace data
|
|||||||
|
|
||||||
bool IsDestination () const { return false; };
|
bool IsDestination () const { return false; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
RouterInfo ();
|
||||||
|
uint8_t * GetBufferPointer (size_t offset = 0 ) { return m_Buffer->data () + offset; };
|
||||||
|
void UpdateBuffer (const uint8_t * buf, size_t len);
|
||||||
|
void SetBufferLen (size_t len) { m_BufferLen = len; };
|
||||||
|
void RefreshTimestamp ();
|
||||||
|
const Addresses& GetAddresses () const { return *m_Addresses; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool LoadFile (const std::string& fullPath);
|
bool LoadFile (const std::string& fullPath);
|
||||||
void ReadFromFile (const std::string& fullPath);
|
void ReadFromFile (const std::string& fullPath);
|
||||||
void ReadFromStream (std::istream& s);
|
void ReadFromStream (std::istream& s);
|
||||||
void ReadFromBuffer (bool verifySignature);
|
void ReadFromBuffer (bool verifySignature);
|
||||||
void WriteToStream (std::ostream& s) const;
|
|
||||||
size_t ReadString (char* str, size_t len, std::istream& s) const;
|
size_t ReadString (char* str, size_t len, std::istream& s) const;
|
||||||
void WriteString (const std::string& str, std::ostream& s) const;
|
|
||||||
void ExtractCaps (const char * value);
|
void ExtractCaps (const char * value);
|
||||||
uint8_t ExtractAddressCaps (const char * value) const;
|
uint8_t ExtractAddressCaps (const char * value) const;
|
||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<const Address> GetAddress (Filter filter) const;
|
std::shared_ptr<const Address> GetAddress (Filter filter) const;
|
||||||
void UpdateCapsProperty ();
|
virtual std::shared_ptr<Buffer> NewBuffer () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Family;
|
FamilyID m_FamilyID;
|
||||||
std::shared_ptr<const IdentityEx> m_RouterIdentity;
|
std::shared_ptr<const IdentityEx> m_RouterIdentity;
|
||||||
uint8_t * m_Buffer;
|
std::shared_ptr<Buffer> m_Buffer;
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
uint64_t m_Timestamp;
|
uint64_t m_Timestamp;
|
||||||
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
|
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
|
||||||
std::map<std::string, std::string> m_Properties;
|
|
||||||
bool m_IsUpdated, m_IsUnreachable;
|
bool m_IsUpdated, m_IsUnreachable;
|
||||||
CompatibleTransports m_SupportedTransports, m_ReachableTransports;
|
CompatibleTransports m_SupportedTransports, m_ReachableTransports;
|
||||||
uint8_t m_Caps;
|
uint8_t m_Caps;
|
||||||
int m_Version;
|
int m_Version;
|
||||||
mutable std::shared_ptr<RouterProfile> m_Profile;
|
mutable std::shared_ptr<RouterProfile> m_Profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LocalRouterInfo: public RouterInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
LocalRouterInfo () = default;
|
||||||
|
void CreateBuffer (const PrivateKeys& privateKeys);
|
||||||
|
void UpdateCaps (uint8_t caps);
|
||||||
|
|
||||||
|
void SetProperty (const std::string& key, const std::string& value) override;
|
||||||
|
void DeleteProperty (const std::string& key);
|
||||||
|
std::string GetProperty (const std::string& key) const;
|
||||||
|
void ClearProperties () override { m_Properties.clear (); };
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void WriteToStream (std::ostream& s) const;
|
||||||
|
void UpdateCapsProperty ();
|
||||||
|
void WriteString (const std::string& str, std::ostream& s) const;
|
||||||
|
std::shared_ptr<Buffer> NewBuffer () const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::map<std::string, std::string> m_Properties;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -11,10 +11,11 @@
|
|||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "NetDb.hpp"
|
#include "NetDb.hpp"
|
||||||
#include "SSU.h"
|
#include "Config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "SSU.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && !defined(_NETINET_IN_H)
|
||||||
#include <linux/in6.h>
|
#include <linux/in6.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ namespace transport
|
|||||||
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
|
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
|
||||||
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
|
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
|
||||||
m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service),
|
m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service),
|
||||||
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service)
|
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service),
|
||||||
|
m_IsSyncClockFromPeers (true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ namespace transport
|
|||||||
m_SocketV6.set_option (boost::asio::ip::v6_only (true));
|
m_SocketV6.set_option (boost::asio::ip::v6_only (true));
|
||||||
m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
||||||
m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && !defined(_NETINET_IN_H)
|
||||||
if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address
|
if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address
|
||||||
{
|
{
|
||||||
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
||||||
@@ -90,6 +92,7 @@ namespace transport
|
|||||||
|
|
||||||
void SSUServer::Start ()
|
void SSUServer::Start ()
|
||||||
{
|
{
|
||||||
|
i2p::config::GetOption("nettime.frompeers", m_IsSyncClockFromPeers);
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
|
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
|
||||||
if (context.SupportsV4 ())
|
if (context.SupportsV4 ())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -69,6 +69,7 @@ namespace transport
|
|||||||
i2p::util::MemoryPool<SentMessage>& GetSentMessagesPool () { return m_SentMessagesPool; };
|
i2p::util::MemoryPool<SentMessage>& GetSentMessagesPool () { return m_SentMessagesPool; };
|
||||||
|
|
||||||
uint16_t GetPort () const { return m_Endpoint.port (); };
|
uint16_t GetPort () const { return m_Endpoint.port (); };
|
||||||
|
bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; };
|
||||||
void SetLocalAddress (const boost::asio::ip::address& localAddress);
|
void SetLocalAddress (const boost::asio::ip::address& localAddress);
|
||||||
|
|
||||||
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
||||||
@@ -136,6 +137,7 @@ namespace transport
|
|||||||
boost::asio::ip::udp::socket m_Socket, m_SocketV6;
|
boost::asio::ip::udp::socket m_Socket, m_SocketV6;
|
||||||
boost::asio::deadline_timer m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6,
|
boost::asio::deadline_timer m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6,
|
||||||
m_PeerTestsCleanupTimer, m_TerminationTimer, m_TerminationTimerV6;
|
m_PeerTestsCleanupTimer, m_TerminationTimer, m_TerminationTimerV6;
|
||||||
|
bool m_IsSyncClockFromPeers;
|
||||||
std::list<boost::asio::ip::udp::endpoint> m_Introducers, m_IntroducersV6; // introducers we are connected to
|
std::list<boost::asio::ip::udp::endpoint> m_Introducers, m_IntroducersV6; // introducers we are connected to
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
|
||||||
std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer
|
std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer
|
||||||
|
|||||||
567
libi2pd/SSU2.cpp
Normal file
567
libi2pd/SSU2.cpp
Normal file
@@ -0,0 +1,567 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
#include "RouterContext.h"
|
||||||
|
#include "Transports.h"
|
||||||
|
#include "NetDb.hpp"
|
||||||
|
#include "Config.h"
|
||||||
|
#include "SSU2.h"
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace transport
|
||||||
|
{
|
||||||
|
SSU2Server::SSU2Server ():
|
||||||
|
RunnableServiceWithWork ("SSU2"), m_ReceiveService ("SSU2r"),
|
||||||
|
m_SocketV4 (m_ReceiveService.GetService ()), m_SocketV6 (m_ReceiveService.GetService ()),
|
||||||
|
m_TerminationTimer (GetService ()), m_ResendTimer (GetService ())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::Start ()
|
||||||
|
{
|
||||||
|
if (!IsRunning ())
|
||||||
|
{
|
||||||
|
StartIOService ();
|
||||||
|
bool found = false;
|
||||||
|
auto& addresses = i2p::context.GetRouterInfo ().GetAddresses ();
|
||||||
|
for (const auto& address: addresses)
|
||||||
|
{
|
||||||
|
if (!address) continue;
|
||||||
|
if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2)
|
||||||
|
{
|
||||||
|
auto port = address->port;
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
||||||
|
if (ssu2Port) port = ssu2Port;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t p; i2p::config::GetOption ("port", p);
|
||||||
|
if (p) port = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (port)
|
||||||
|
{
|
||||||
|
if (address->IsV4 ())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v4(), port));
|
||||||
|
m_ReceiveService.GetService ().post(
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
Receive (m_SocketV4);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (address->IsV6 ())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v6(), port));
|
||||||
|
m_ReceiveService.GetService ().post(
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
Receive (m_SocketV6);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "SSU2: Can't start server because port not specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
m_ReceiveService.Start ();
|
||||||
|
ScheduleTermination ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::Stop ()
|
||||||
|
{
|
||||||
|
if (context.SupportsV4 () || context.SupportsV6 ())
|
||||||
|
m_ReceiveService.Stop ();
|
||||||
|
|
||||||
|
if (IsRunning ())
|
||||||
|
m_TerminationTimer.cancel ();
|
||||||
|
|
||||||
|
StopIOService ();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::ip::udp::socket& SSU2Server::OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint)
|
||||||
|
{
|
||||||
|
boost::asio::ip::udp::socket& socket = localEndpoint.address ().is_v6 () ? m_SocketV6 : m_SocketV4;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.open (localEndpoint.protocol ());
|
||||||
|
if (localEndpoint.address ().is_v6 ())
|
||||||
|
socket.set_option (boost::asio::ip::v6_only (true));
|
||||||
|
socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU2_SOCKET_RECEIVE_BUFFER_SIZE));
|
||||||
|
socket.set_option (boost::asio::socket_base::send_buffer_size (SSU2_SOCKET_SEND_BUFFER_SIZE));
|
||||||
|
socket.bind (localEndpoint);
|
||||||
|
LogPrint (eLogInfo, "SSU2: Start listening on ", localEndpoint);
|
||||||
|
}
|
||||||
|
catch (std::exception& ex )
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what());
|
||||||
|
ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ());
|
||||||
|
}
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::Receive (boost::asio::ip::udp::socket& socket)
|
||||||
|
{
|
||||||
|
Packet * packet = m_PacketsPool.AcquireMt ();
|
||||||
|
socket.async_receive_from (boost::asio::buffer (packet->buf, SSU2_MTU), packet->from,
|
||||||
|
std::bind (&SSU2Server::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet, std::ref (socket)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred,
|
||||||
|
Packet * packet, boost::asio::ip::udp::socket& socket)
|
||||||
|
{
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
i2p::transport::transports.UpdateReceivedBytes (bytes_transferred);
|
||||||
|
packet->len = bytes_transferred;
|
||||||
|
|
||||||
|
boost::system::error_code ec;
|
||||||
|
size_t moreBytes = socket.available (ec);
|
||||||
|
if (!ec && moreBytes)
|
||||||
|
{
|
||||||
|
std::vector<Packet *> packets;
|
||||||
|
packets.push_back (packet);
|
||||||
|
while (moreBytes && packets.size () < 32)
|
||||||
|
{
|
||||||
|
packet = m_PacketsPool.AcquireMt ();
|
||||||
|
packet->len = socket.receive_from (boost::asio::buffer (packet->buf, SSU2_MTU), packet->from, 0, ec);
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
i2p::transport::transports.UpdateReceivedBytes (packet->len);
|
||||||
|
packets.push_back (packet);
|
||||||
|
moreBytes = socket.available(ec);
|
||||||
|
if (ec) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "SSU2: receive_from error: code ", ec.value(), ": ", ec.message ());
|
||||||
|
m_PacketsPool.ReleaseMt (packet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GetService ().post (std::bind (&SSU2Server::HandleReceivedPackets, this, packets));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GetService ().post (std::bind (&SSU2Server::HandleReceivedPacket, this, packet));
|
||||||
|
Receive (socket);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_PacketsPool.ReleaseMt (packet);
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "SSU2: Receive error: code ", ecode.value(), ": ", ecode.message ());
|
||||||
|
auto ep = socket.local_endpoint ();
|
||||||
|
socket.close ();
|
||||||
|
OpenSocket (ep);
|
||||||
|
Receive (socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::HandleReceivedPacket (Packet * packet)
|
||||||
|
{
|
||||||
|
if (packet)
|
||||||
|
{
|
||||||
|
ProcessNextPacket (packet->buf, packet->len, packet->from);
|
||||||
|
m_PacketsPool.ReleaseMt (packet);
|
||||||
|
if (m_LastSession) m_LastSession->FlushData ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::HandleReceivedPackets (std::vector<Packet *> packets)
|
||||||
|
{
|
||||||
|
for (auto& packet: packets)
|
||||||
|
ProcessNextPacket (packet->buf, packet->len, packet->from);
|
||||||
|
m_PacketsPool.ReleaseMt (packets);
|
||||||
|
if (m_LastSession) m_LastSession->FlushData ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::AddSession (std::shared_ptr<SSU2Session> session)
|
||||||
|
{
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
m_Sessions.emplace (session->GetConnID (), session);
|
||||||
|
AddSessionByRouterHash (session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::RemoveSession (uint64_t connID)
|
||||||
|
{
|
||||||
|
auto it = m_Sessions.find (connID);
|
||||||
|
if (it != m_Sessions.end ())
|
||||||
|
{
|
||||||
|
auto ident = it->second->GetRemoteIdentity ();
|
||||||
|
if (ident)
|
||||||
|
m_SessionsByRouterHash.erase (ident->GetIdentHash ());
|
||||||
|
m_Sessions.erase (it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::AddSessionByRouterHash (std::shared_ptr<SSU2Session> session)
|
||||||
|
{
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
auto ident = session->GetRemoteIdentity ();
|
||||||
|
if (ident)
|
||||||
|
{
|
||||||
|
auto ret = m_SessionsByRouterHash.emplace (ident->GetIdentHash (), session);
|
||||||
|
if (!ret.second)
|
||||||
|
{
|
||||||
|
// session already exists
|
||||||
|
LogPrint (eLogWarning, "SSU2: Session to ", ident->GetIdentHash ().ToBase64 (), " aready exists");
|
||||||
|
// terminate existing
|
||||||
|
GetService ().post (std::bind (&SSU2Session::Terminate, ret.first->second));
|
||||||
|
// update session
|
||||||
|
ret.first->second = session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session)
|
||||||
|
{
|
||||||
|
if (session)
|
||||||
|
m_PendingOutgoingSessions.emplace (session->GetRemoteEndpoint (), session);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<SSU2Session> SSU2Server::FindSession (const i2p::data::IdentHash& ident) const
|
||||||
|
{
|
||||||
|
auto it = m_SessionsByRouterHash.find (ident);
|
||||||
|
if (it != m_SessionsByRouterHash.end ())
|
||||||
|
return it->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay)
|
||||||
|
{
|
||||||
|
m_Relays.emplace (tag, relay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::RemoveRelay (uint32_t tag)
|
||||||
|
{
|
||||||
|
m_Relays.erase (tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<SSU2Session> SSU2Server::FindRelaySession (uint32_t tag)
|
||||||
|
{
|
||||||
|
auto it = m_Relays.find (tag);
|
||||||
|
if (it != m_Relays.end ())
|
||||||
|
{
|
||||||
|
if (it->second->IsEstablished ())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
m_Relays.erase (it);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
|
||||||
|
{
|
||||||
|
if (len < 24) return;
|
||||||
|
uint64_t connID;
|
||||||
|
memcpy (&connID, buf, 8);
|
||||||
|
connID ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 24));
|
||||||
|
if (!m_LastSession || m_LastSession->GetConnID () != connID)
|
||||||
|
{
|
||||||
|
if (m_LastSession) m_LastSession->FlushData ();
|
||||||
|
auto it = m_Sessions.find (connID);
|
||||||
|
if (it != m_Sessions.end ())
|
||||||
|
m_LastSession = it->second;
|
||||||
|
else
|
||||||
|
m_LastSession = nullptr;
|
||||||
|
}
|
||||||
|
if (m_LastSession)
|
||||||
|
{
|
||||||
|
switch (m_LastSession->GetState ())
|
||||||
|
{
|
||||||
|
case eSSU2SessionStateEstablished:
|
||||||
|
m_LastSession->ProcessData (buf, len);
|
||||||
|
break;
|
||||||
|
case eSSU2SessionStateUnknown:
|
||||||
|
m_LastSession->ProcessSessionConfirmed (buf, len);
|
||||||
|
break;
|
||||||
|
case eSSU2SessionStateIntroduced:
|
||||||
|
m_LastSession->SetRemoteEndpoint (senderEndpoint);
|
||||||
|
m_LastSession->ProcessHolePunch (buf, len);
|
||||||
|
break;
|
||||||
|
case eSSU2SessionStatePeerTest:
|
||||||
|
m_LastSession->SetRemoteEndpoint (senderEndpoint);
|
||||||
|
m_LastSession->ProcessPeerTest (buf, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LogPrint (eLogWarning, "SSU2: Invalid session state ", (int)m_LastSession->GetState ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check pending sessions if it's SessionCreated or Retry
|
||||||
|
auto it1 = m_PendingOutgoingSessions.find (senderEndpoint);
|
||||||
|
if (it1 != m_PendingOutgoingSessions.end ())
|
||||||
|
{
|
||||||
|
if (it1->second->ProcessSessionCreated (buf, len))
|
||||||
|
m_PendingOutgoingSessions.erase (it1); // we are done with that endpoint
|
||||||
|
else
|
||||||
|
it1->second->ProcessRetry (buf, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assume new incoming session
|
||||||
|
auto session = std::make_shared<SSU2Session> (*this);
|
||||||
|
session->SetRemoteEndpoint (senderEndpoint);
|
||||||
|
session->ProcessFirstIncomingMessage (connID, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
|
||||||
|
const boost::asio::ip::udp::endpoint& to)
|
||||||
|
{
|
||||||
|
std::vector<boost::asio::const_buffer> bufs
|
||||||
|
{
|
||||||
|
boost::asio::buffer (header, headerLen),
|
||||||
|
boost::asio::buffer (payload, payloadLen)
|
||||||
|
};
|
||||||
|
boost::system::error_code ec;
|
||||||
|
if (to.address ().is_v6 ())
|
||||||
|
m_SocketV6.send_to (bufs, to, 0, ec);
|
||||||
|
else
|
||||||
|
m_SocketV4.send_to (bufs, to, 0, ec);
|
||||||
|
if (!ec)
|
||||||
|
i2p::transport::transports.UpdateSentBytes (headerLen + payloadLen);
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "SSU2: Send exception: ", ec.message (), " to ", to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
|
||||||
|
const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to)
|
||||||
|
{
|
||||||
|
std::vector<boost::asio::const_buffer> bufs
|
||||||
|
{
|
||||||
|
boost::asio::buffer (header, headerLen),
|
||||||
|
boost::asio::buffer (headerX, headerXLen),
|
||||||
|
boost::asio::buffer (payload, payloadLen)
|
||||||
|
};
|
||||||
|
boost::system::error_code ec;
|
||||||
|
if (to.address ().is_v6 ())
|
||||||
|
m_SocketV6.send_to (bufs, to, 0, ec);
|
||||||
|
else
|
||||||
|
m_SocketV4.send_to (bufs, to, 0, ec);
|
||||||
|
|
||||||
|
if (!ec)
|
||||||
|
i2p::transport::transports.UpdateSentBytes (headerLen + headerXLen + payloadLen);
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "SSU2: Send exception: ", ec.message (), " to ", to);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SSU2Server::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address)
|
||||||
|
{
|
||||||
|
if (router && address)
|
||||||
|
{
|
||||||
|
if (address->UsesIntroducer ())
|
||||||
|
GetService ().post (std::bind (&SSU2Server::ConnectThroughIntroducer, this, router, address));
|
||||||
|
else
|
||||||
|
GetService ().post (
|
||||||
|
[this, router, address]()
|
||||||
|
{
|
||||||
|
auto session = std::make_shared<SSU2Session> (*this, router, address);
|
||||||
|
session->Connect ();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address)
|
||||||
|
{
|
||||||
|
auto session = std::make_shared<SSU2Session> (*this, router, address);
|
||||||
|
session->SetState (eSSU2SessionStateIntroduced);
|
||||||
|
// try to find existing session first
|
||||||
|
for (auto& it: address->ssu->introducers)
|
||||||
|
{
|
||||||
|
auto it1 = m_SessionsByRouterHash.find (it.iKey);
|
||||||
|
if (it1 != m_SessionsByRouterHash.end ())
|
||||||
|
{
|
||||||
|
it1->second->Introduce (session, it.iTag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we have to start a new session to an introducer
|
||||||
|
std::shared_ptr<i2p::data::RouterInfo> r;
|
||||||
|
uint32_t relayTag = 0;
|
||||||
|
for (auto& it: address->ssu->introducers)
|
||||||
|
{
|
||||||
|
r = i2p::data::netdb.FindRouter (it.iKey);
|
||||||
|
if (r && r->IsReachableFrom (i2p::context.GetRouterInfo ()))
|
||||||
|
{
|
||||||
|
relayTag = it.iTag;
|
||||||
|
if (relayTag) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
if (relayTag)
|
||||||
|
{
|
||||||
|
// introducer and tag found connect to it through SSU2
|
||||||
|
auto addr = address->IsV6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
|
||||||
|
if (addr)
|
||||||
|
{
|
||||||
|
auto s = std::make_shared<SSU2Session> (*this, r, addr);
|
||||||
|
s->SetOnEstablished (
|
||||||
|
[session, s, relayTag]()
|
||||||
|
{
|
||||||
|
s->Introduce (session, relayTag);
|
||||||
|
});
|
||||||
|
s->Connect ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// introducers not found, try to request them
|
||||||
|
for (auto& it: address->ssu->introducers)
|
||||||
|
i2p::data::netdb.RequestDestination (it.iKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SSU2Server::StartPeerTest (std::shared_ptr<const i2p::data::RouterInfo> router, bool v4)
|
||||||
|
{
|
||||||
|
if (!router) return false;
|
||||||
|
auto addr = v4 ? router->GetSSU2V4Address () : router->GetSSU2V6Address ();
|
||||||
|
if (!addr) return false;
|
||||||
|
auto it = m_SessionsByRouterHash.find (router->GetIdentHash ());
|
||||||
|
if (it != m_SessionsByRouterHash.end ())
|
||||||
|
{
|
||||||
|
if (it->second->IsEstablished ())
|
||||||
|
it->second->SendPeerTest ();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto s = it->second;
|
||||||
|
s->SetOnEstablished ([s]() { s->SendPeerTest (); });
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto s = std::make_shared<SSU2Session> (*this, router, addr);
|
||||||
|
s->SetOnEstablished ([s]() {s->SendPeerTest (); });
|
||||||
|
s->Connect ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::ScheduleTermination ()
|
||||||
|
{
|
||||||
|
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU2_TERMINATION_CHECK_TIMEOUT));
|
||||||
|
m_TerminationTimer.async_wait (std::bind (&SSU2Server::HandleTerminationTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::HandleTerminationTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
for (auto it = m_PendingOutgoingSessions.begin (); it != m_PendingOutgoingSessions.end ();)
|
||||||
|
{
|
||||||
|
if (it->second->IsTerminationTimeoutExpired (ts))
|
||||||
|
{
|
||||||
|
//it->second->Terminate ();
|
||||||
|
it = m_PendingOutgoingSessions.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = m_Sessions.begin (); it != m_Sessions.end ();)
|
||||||
|
{
|
||||||
|
if (it->second->IsTerminationTimeoutExpired (ts))
|
||||||
|
{
|
||||||
|
if (it->second->IsEstablished ())
|
||||||
|
it->second->TerminateByTimeout ();
|
||||||
|
if (it->second == m_LastSession)
|
||||||
|
m_LastSession = nullptr;
|
||||||
|
it = m_Sessions.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it->second->CleanUp (ts);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = m_IncomingTokens.begin (); it != m_IncomingTokens.end (); )
|
||||||
|
{
|
||||||
|
if (ts > it->second.second)
|
||||||
|
it = m_IncomingTokens.erase (it);
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = m_OutgoingTokens.begin (); it != m_OutgoingTokens.end (); )
|
||||||
|
{
|
||||||
|
if (ts > it->second.second)
|
||||||
|
it = m_OutgoingTokens.erase (it);
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScheduleTermination ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::ScheduleResend ()
|
||||||
|
{
|
||||||
|
m_ResendTimer.expires_from_now (boost::posix_time::seconds(SSU2_RESEND_INTERVAL));
|
||||||
|
m_ResendTimer.async_wait (std::bind (&SSU2Server::HandleResendTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::HandleResendTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
for (auto it: m_Sessions)
|
||||||
|
it.second->Resend (ts);
|
||||||
|
ScheduleResend ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSU2Server::UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp)
|
||||||
|
{
|
||||||
|
m_OutgoingTokens[ep] = {token, exp};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SSU2Server::FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const
|
||||||
|
{
|
||||||
|
auto it = m_OutgoingTokens.find (ep);
|
||||||
|
if (it != m_OutgoingTokens.end ())
|
||||||
|
return it->second.first;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SSU2Server::GetIncomingToken (const boost::asio::ip::udp::endpoint& ep)
|
||||||
|
{
|
||||||
|
auto it = m_IncomingTokens.find (ep);
|
||||||
|
if (it != m_IncomingTokens.end ())
|
||||||
|
return it->second.first;
|
||||||
|
uint64_t token;
|
||||||
|
RAND_bytes ((uint8_t *)&token, 8);
|
||||||
|
m_IncomingTokens.emplace (ep, std::make_pair (token, i2p::util::GetSecondsSinceEpoch () + SSU2_TOKEN_EXPIRATION_TIMEOUT));
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
libi2pd/SSU2.h
Normal file
115
libi2pd/SSU2.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SSU2_H__
|
||||||
|
#define SSU2_H__
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "util.h"
|
||||||
|
#include "SSU2Session.h"
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace transport
|
||||||
|
{
|
||||||
|
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
||||||
|
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
|
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
|
|
||||||
|
class SSU2Server: private i2p::util::RunnableServiceWithWork
|
||||||
|
{
|
||||||
|
struct Packet
|
||||||
|
{
|
||||||
|
uint8_t buf[SSU2_MTU];
|
||||||
|
size_t len;
|
||||||
|
boost::asio::ip::udp::endpoint from;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReceiveService: public i2p::util::RunnableService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReceiveService (const std::string& name): RunnableService (name) {};
|
||||||
|
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||||
|
void Start () { StartIOService (); };
|
||||||
|
void Stop () { StopIOService (); };
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SSU2Server ();
|
||||||
|
~SSU2Server () {};
|
||||||
|
|
||||||
|
void Start ();
|
||||||
|
void Stop ();
|
||||||
|
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||||
|
|
||||||
|
void AddSession (std::shared_ptr<SSU2Session> session);
|
||||||
|
void RemoveSession (uint64_t connID);
|
||||||
|
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
|
||||||
|
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
|
||||||
|
std::shared_ptr<SSU2Session> FindSession (const i2p::data::IdentHash& ident) const;
|
||||||
|
|
||||||
|
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
|
||||||
|
void RemoveRelay (uint32_t tag);
|
||||||
|
std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag);
|
||||||
|
|
||||||
|
void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
|
||||||
|
const boost::asio::ip::udp::endpoint& to);
|
||||||
|
void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
|
||||||
|
const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to);
|
||||||
|
|
||||||
|
bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
||||||
|
bool StartPeerTest (std::shared_ptr<const i2p::data::RouterInfo> router, bool v4);
|
||||||
|
|
||||||
|
void UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp);
|
||||||
|
uint64_t FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const;
|
||||||
|
uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
|
||||||
|
void Receive (boost::asio::ip::udp::socket& socket);
|
||||||
|
void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred,
|
||||||
|
Packet * packet, boost::asio::ip::udp::socket& socket);
|
||||||
|
void HandleReceivedPacket (Packet * packet);
|
||||||
|
void HandleReceivedPackets (std::vector<Packet *> packets);
|
||||||
|
void ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||||
|
|
||||||
|
void ScheduleTermination ();
|
||||||
|
void HandleTerminationTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
|
void ScheduleResend ();
|
||||||
|
void HandleResendTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
|
void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ReceiveService m_ReceiveService;
|
||||||
|
boost::asio::ip::udp::socket m_SocketV4, m_SocketV6;
|
||||||
|
std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
|
||||||
|
std::map<i2p::data::IdentHash, std::shared_ptr<SSU2Session> > m_SessionsByRouterHash;
|
||||||
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
|
||||||
|
std::map<boost::asio::ip::udp::endpoint, std::pair<uint64_t, uint32_t> > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds)
|
||||||
|
std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
|
||||||
|
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
|
||||||
|
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
|
||||||
|
std::shared_ptr<SSU2Session> m_LastSession;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// for HTTP/I2PControl
|
||||||
|
const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
1843
libi2pd/SSU2Session.cpp
Normal file
1843
libi2pd/SSU2Session.cpp
Normal file
File diff suppressed because it is too large
Load Diff
273
libi2pd/SSU2Session.h
Normal file
273
libi2pd/SSU2Session.h
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SSU2_SESSION_H__
|
||||||
|
#define SSU2_SESSION_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "Crypto.h"
|
||||||
|
#include "RouterInfo.h"
|
||||||
|
#include "TransportSession.h"
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace transport
|
||||||
|
{
|
||||||
|
const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||||
|
const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||||
|
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in seconds
|
||||||
|
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
|
||||||
|
const int SSU2_PEER_TEST_EXPIRATION_TIMEOUT = 60; // 60 seconds
|
||||||
|
const size_t SSU2_MTU = 1488;
|
||||||
|
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
|
||||||
|
const int SSU2_RESEND_INTERVAL = 3; // in seconds
|
||||||
|
const int SSU2_MAX_NUM_RESENDS = 5;
|
||||||
|
const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds
|
||||||
|
const size_t SSU2_MAX_WINDOW_SIZE = 128; // in packets
|
||||||
|
|
||||||
|
enum SSU2MessageType
|
||||||
|
{
|
||||||
|
eSSU2SessionRequest = 0,
|
||||||
|
eSSU2SessionCreated = 1,
|
||||||
|
eSSU2SessionConfirmed = 2,
|
||||||
|
eSSU2Data = 6,
|
||||||
|
eSSU2PeerTest = 7,
|
||||||
|
eSSU2Retry = 9,
|
||||||
|
eSSU2TokenRequest = 10,
|
||||||
|
eSSU2HolePunch = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSU2BlockType
|
||||||
|
{
|
||||||
|
eSSU2BlkDateTime = 0,
|
||||||
|
eSSU2BlkOptions, // 1
|
||||||
|
eSSU2BlkRouterInfo, // 2
|
||||||
|
eSSU2BlkI2NPMessage, // 3
|
||||||
|
eSSU2BlkFirstFragment, // 4
|
||||||
|
eSSU2BlkFollowOnFragment, // 5
|
||||||
|
eSSU2BlkTermination, // 6
|
||||||
|
eSSU2BlkRelayRequest, // 7
|
||||||
|
eSSU2BlkRelayResponse, // 8
|
||||||
|
eSSU2BlkRelayIntro, // 9
|
||||||
|
eSSU2BlkPeerTest, // 10
|
||||||
|
eSSU2BlkNextNonce, // 11
|
||||||
|
eSSU2BlkAck, // 12
|
||||||
|
eSSU2BlkAddress, // 13
|
||||||
|
eSSU2BlkIntroKey, // 14
|
||||||
|
eSSU2BlkRelayTagRequest, // 15
|
||||||
|
eSSU2BlkRelayTag, // 16
|
||||||
|
eSSU2BlkNewToken, // 17
|
||||||
|
eSSU2BlkPathChallenge, // 18
|
||||||
|
eSSU2BlkPathResponse, // 19
|
||||||
|
eSSU2BlkFirstPacketNumber, // 20
|
||||||
|
eSSU2BlkPadding = 254
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSU2SessionState
|
||||||
|
{
|
||||||
|
eSSU2SessionStateUnknown,
|
||||||
|
eSSU2SessionStateIntroduced,
|
||||||
|
eSSU2SessionStatePeerTest,
|
||||||
|
eSSU2SessionStateEstablished,
|
||||||
|
eSSU2SessionStateTerminated,
|
||||||
|
eSSU2SessionStateFailed
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSU2PeerTestCode
|
||||||
|
{
|
||||||
|
eSSU2PeerTestCodeAccept = 0,
|
||||||
|
eSSU2PeerTestCodeBobReasonUnspecified = 1,
|
||||||
|
eSSU2PeerTestCodeBobNoCharlieAvailable = 2,
|
||||||
|
eSSU2PeerTestCodeBobLimitExceeded = 3,
|
||||||
|
eSSU2PeerTestCodeBobSignatureFailure = 4,
|
||||||
|
eSSU2PeerTestCodeCharlieReasonUnspecified = 64,
|
||||||
|
eSSU2PeerTestCodeCharlieUnsupportedAddress = 65,
|
||||||
|
eSSU2PeerTestCodeCharlieLimitExceeded = 66,
|
||||||
|
eSSU2PeerTestCodeCharlieSignatureFailure = 67,
|
||||||
|
eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected = 68,
|
||||||
|
eSSU2PeerTestCodeCharlieAliceIsBanned = 69,
|
||||||
|
eSSU2PeerTestCodeCharlieAliceIsUnknown = 70,
|
||||||
|
eSSU2PeerTestCodeUnspecified = 128
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SSU2IncompleteMessage
|
||||||
|
{
|
||||||
|
struct Fragment
|
||||||
|
{
|
||||||
|
uint8_t buf[SSU2_MTU];
|
||||||
|
size_t len;
|
||||||
|
bool isLast;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<I2NPMessage> msg;
|
||||||
|
int nextFragmentNum;
|
||||||
|
uint32_t lastFragmentInsertTime; // in seconds
|
||||||
|
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RouterInfo flags
|
||||||
|
const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
|
||||||
|
const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02;
|
||||||
|
|
||||||
|
class SSU2Server;
|
||||||
|
class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
|
||||||
|
{
|
||||||
|
union Header
|
||||||
|
{
|
||||||
|
uint64_t ll[2];
|
||||||
|
uint8_t buf[16];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint64_t connID;
|
||||||
|
uint32_t packetNum;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t flags[3];
|
||||||
|
} h;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SentPacket
|
||||||
|
{
|
||||||
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
|
size_t payloadSize = 0;
|
||||||
|
uint32_t nextResendTime; // in seconds
|
||||||
|
int numResends = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SessionConfirmedFragment
|
||||||
|
{
|
||||||
|
Header header;
|
||||||
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
|
size_t payloadSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::function<void ()> OnEstablished;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> addr = nullptr);
|
||||||
|
~SSU2Session ();
|
||||||
|
|
||||||
|
void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
|
||||||
|
const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
|
||||||
|
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
|
||||||
|
|
||||||
|
void Connect ();
|
||||||
|
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
|
||||||
|
void SendPeerTest (); // Alice, Data message
|
||||||
|
void Terminate ();
|
||||||
|
void TerminateByTimeout ();
|
||||||
|
void CleanUp (uint64_t ts);
|
||||||
|
void FlushData ();
|
||||||
|
void Done () override;
|
||||||
|
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) override;
|
||||||
|
void Resend (uint64_t ts);
|
||||||
|
bool IsEstablished () const { return m_State == eSSU2SessionStateEstablished; };
|
||||||
|
uint64_t GetConnID () const { return m_SourceConnID; };
|
||||||
|
SSU2SessionState GetState () const { return m_State; };
|
||||||
|
void SetState (SSU2SessionState state) { m_State = state; };
|
||||||
|
|
||||||
|
bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
|
||||||
|
bool ProcessSessionCreated (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessRetry (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessHolePunch (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessPeerTest (uint8_t * buf, size_t len);
|
||||||
|
void ProcessData (uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void Established ();
|
||||||
|
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
|
||||||
|
bool SendQueue ();
|
||||||
|
void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
|
void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len);
|
||||||
|
void ProcessTokenRequest (Header& header, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
void SendSessionRequest (uint64_t token = 0);
|
||||||
|
void SendSessionCreated (const uint8_t * X);
|
||||||
|
void SendSessionConfirmed (const uint8_t * Y);
|
||||||
|
void KDFDataPhase (uint8_t * keydata_ab, uint8_t * keydata_ba);
|
||||||
|
void SendTokenRequest ();
|
||||||
|
void SendRetry ();
|
||||||
|
uint32_t SendData (const uint8_t * buf, size_t len); // returns packet num
|
||||||
|
void SendQuickAck ();
|
||||||
|
void SendTermination ();
|
||||||
|
void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey);
|
||||||
|
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey); // PeerTest message
|
||||||
|
|
||||||
|
void HandlePayload (const uint8_t * buf, size_t len);
|
||||||
|
void HandleAck (const uint8_t * buf, size_t len);
|
||||||
|
void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum);
|
||||||
|
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
|
||||||
|
size_t CreateEndpoint (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> FindLocalAddress () const;
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo> ExtractRouterInfo (const uint8_t * buf, size_t size);
|
||||||
|
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
||||||
|
bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate
|
||||||
|
void HandleFirstFragment (const uint8_t * buf, size_t len);
|
||||||
|
void HandleFollowOnFragment (const uint8_t * buf, size_t len);
|
||||||
|
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
||||||
|
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
||||||
|
void HandleRelayIntro (const uint8_t * buf, size_t len);
|
||||||
|
void HandleRelayResponse (const uint8_t * buf, size_t len);
|
||||||
|
void HandlePeerTest (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
|
||||||
|
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
|
||||||
|
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
||||||
|
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
|
||||||
|
size_t CreateI2NPBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage>&& msg);
|
||||||
|
size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
|
||||||
|
size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
|
||||||
|
size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
|
||||||
|
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
|
||||||
|
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
|
||||||
|
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SSU2Server& m_Server;
|
||||||
|
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
||||||
|
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_NoiseState;
|
||||||
|
std::unique_ptr<SessionConfirmedFragment> m_SessionConfirmedFragment1; // for Bob if applicable
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> m_Address;
|
||||||
|
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||||
|
uint64_t m_DestConnID, m_SourceConnID;
|
||||||
|
SSU2SessionState m_State;
|
||||||
|
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
||||||
|
uint32_t m_SendPacketNum, m_ReceivePacketNum;
|
||||||
|
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
||||||
|
std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
|
||||||
|
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
|
||||||
|
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
|
||||||
|
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_PeerTests; // same as for relay sessions
|
||||||
|
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||||
|
i2p::I2NPMessagesHandler m_Handler;
|
||||||
|
bool m_IsDataReceived;
|
||||||
|
size_t m_WindowSize;
|
||||||
|
uint32_t m_RelayTag; // between Bob and Charlie
|
||||||
|
OnEstablished m_OnEstablished; // callback from Established
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)
|
||||||
|
{
|
||||||
|
uint64_t data = 0;
|
||||||
|
i2p::crypto::ChaCha20 ((uint8_t *)&data, 8, kh, nonce, (uint8_t *)&data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -176,11 +176,10 @@ namespace transport
|
|||||||
if (it == m_IncompleteMessages.end ())
|
if (it == m_IncompleteMessages.end ())
|
||||||
{
|
{
|
||||||
// create new message
|
// create new message
|
||||||
auto msg = (!fragmentNum && fragmentSize > 0 && buf[I2NP_SHORT_HEADER_TYPEID_OFFSET] == eI2NPTunnelData) ?
|
auto msg = NewI2NPShortMessage ();
|
||||||
NewI2NPTunnelMessage (true) : NewI2NPShortMessage ();
|
|
||||||
msg->len -= I2NP_SHORT_HEADER_SIZE;
|
msg->len -= I2NP_SHORT_HEADER_SIZE;
|
||||||
it = m_IncompleteMessages.insert (std::make_pair (msgID,
|
it = m_IncompleteMessages.insert (std::make_pair (msgID,
|
||||||
m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (msg))).first;
|
m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (std::move (msg)))).first;
|
||||||
}
|
}
|
||||||
auto& incompleteMessage = it->second;
|
auto& incompleteMessage = it->second;
|
||||||
// mark fragment as received
|
// mark fragment as received
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -26,11 +26,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
|
|
||||||
const size_t SSU_MTU_V4 = 1484;
|
const size_t SSU_MTU_V4 = 1484;
|
||||||
#ifdef MESHNET
|
|
||||||
const size_t SSU_MTU_V6 = 1286;
|
|
||||||
#else
|
|
||||||
const size_t SSU_MTU_V6 = 1488;
|
const size_t SSU_MTU_V6 = 1488;
|
||||||
#endif
|
|
||||||
const size_t IPV4_HEADER_SIZE = 20;
|
const size_t IPV4_HEADER_SIZE = 20;
|
||||||
const size_t IPV6_HEADER_SIZE = 40;
|
const size_t IPV6_HEADER_SIZE = 40;
|
||||||
const size_t UDP_HEADER_SIZE = 8;
|
const size_t UDP_HEADER_SIZE = 8;
|
||||||
@@ -79,7 +75,7 @@ namespace transport
|
|||||||
uint64_t receivedFragmentsBits;
|
uint64_t receivedFragmentsBits;
|
||||||
std::set<std::shared_ptr<Fragment>, FragmentCmp> savedFragments;
|
std::set<std::shared_ptr<Fragment>, FragmentCmp> savedFragments;
|
||||||
|
|
||||||
IncompleteMessage (std::shared_ptr<I2NPMessage> m): msg (m), nextFragmentNum (0),
|
IncompleteMessage (std::shared_ptr<I2NPMessage>&& m): msg (m), nextFragmentNum (0),
|
||||||
lastFragmentInsertTime (0), receivedFragmentsBits (0) {};
|
lastFragmentInsertTime (0), receivedFragmentsBits (0) {};
|
||||||
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
|
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -31,7 +31,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
// we are client
|
// we are client
|
||||||
auto address = IsV6 () ? router->GetSSUV6Address () : router->GetSSUAddress (true);
|
auto address = IsV6 () ? router->GetSSUV6Address () : router->GetSSUAddress (true);
|
||||||
if (address) m_IntroKey = address->ssu->key;
|
if (address) m_IntroKey = address->i;
|
||||||
m_Data.AdjustPacketSize (router); // mtu
|
m_Data.AdjustPacketSize (router); // mtu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -39,7 +39,7 @@ namespace transport
|
|||||||
// we are server
|
// we are server
|
||||||
auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () :
|
auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () :
|
||||||
i2p::context.GetRouterInfo ().GetSSUAddress (true);
|
i2p::context.GetRouterInfo ().GetSSUAddress (true);
|
||||||
if (address) m_IntroKey = address->ssu->key;
|
if (address) m_IntroKey = address->i;
|
||||||
}
|
}
|
||||||
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
@@ -127,8 +127,8 @@ namespace transport
|
|||||||
LogPrint (eLogInfo, "SSU: SSU is not supported");
|
LogPrint (eLogInfo, "SSU: SSU is not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Validate (buf, len, address->ssu->key))
|
if (Validate (buf, len, address->i))
|
||||||
Decrypt (buf, len, address->ssu->key);
|
Decrypt (buf, len, address->i);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: MAC verification failed ", len, " bytes from ", senderEndpoint);
|
LogPrint (eLogWarning, "SSU: MAC verification failed ", len, " bytes from ", senderEndpoint);
|
||||||
@@ -274,16 +274,7 @@ namespace transport
|
|||||||
s.Insert (payload, 8); // relayTag and signed on time
|
s.Insert (payload, 8); // relayTag and signed on time
|
||||||
m_RelayTag = bufbe32toh (payload);
|
m_RelayTag = bufbe32toh (payload);
|
||||||
payload += 4; // relayTag
|
payload += 4; // relayTag
|
||||||
if (ourIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting)
|
|
||||||
{
|
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
|
||||||
uint32_t signedOnTime = bufbe32toh(payload);
|
uint32_t signedOnTime = bufbe32toh(payload);
|
||||||
if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "SSU: Clock skew detected ", (int)ts - signedOnTime, ". Check your clock");
|
|
||||||
i2p::context.SetError (eRouterErrorClockSkew);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
payload += 4; // signed on time
|
payload += 4; // signed on time
|
||||||
// decrypt signature
|
// decrypt signature
|
||||||
size_t signatureLen = m_RemoteIdentity->GetSignatureLen ();
|
size_t signatureLen = m_RemoteIdentity->GetSignatureLen ();
|
||||||
@@ -295,6 +286,24 @@ namespace transport
|
|||||||
// verify signature
|
// verify signature
|
||||||
if (s.Verify (m_RemoteIdentity, payload))
|
if (s.Verify (m_RemoteIdentity, payload))
|
||||||
{
|
{
|
||||||
|
if (ourIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting)
|
||||||
|
{
|
||||||
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
int offset = (int)ts - signedOnTime;
|
||||||
|
if (m_Server.IsSyncClockFromPeers ())
|
||||||
|
{
|
||||||
|
if (std::abs (offset) > SSU_CLOCK_THRESHOLD)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
|
||||||
|
i2p::util::AdjustTimeOffset (-offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (std::abs (offset) > SSU_CLOCK_SKEW)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock");
|
||||||
|
i2p::context.SetError (eRouterErrorClockSkew);
|
||||||
|
}
|
||||||
|
}
|
||||||
LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort);
|
LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort);
|
||||||
if (!i2p::util::net::IsInReservedRange (ourIP))
|
if (!i2p::util::net::IsInReservedRange (ourIP))
|
||||||
{
|
{
|
||||||
@@ -427,7 +436,7 @@ namespace transport
|
|||||||
payload += 2;
|
payload += 2;
|
||||||
*payload = 0; // challenge
|
*payload = 0; // challenge
|
||||||
payload++;
|
payload++;
|
||||||
memcpy (payload, (const uint8_t *)address->ssu->key, 32);
|
memcpy (payload, (const uint8_t *)address->i, 32);
|
||||||
payload += 32;
|
payload += 32;
|
||||||
htobe32buf (payload, nonce); // nonce
|
htobe32buf (payload, nonce); // nonce
|
||||||
|
|
||||||
@@ -1174,7 +1183,7 @@ namespace transport
|
|||||||
auto addr = address.is_v4 () ? i2p::context.GetRouterInfo ().GetSSUAddress (true) : // ipv4
|
auto addr = address.is_v4 () ? i2p::context.GetRouterInfo ().GetSSUAddress (true) : // ipv4
|
||||||
i2p::context.GetRouterInfo ().GetSSUV6Address ();
|
i2p::context.GetRouterInfo ().GetSSUV6Address ();
|
||||||
if (addr)
|
if (addr)
|
||||||
memcpy (payload, addr->ssu->key, 32); // intro key
|
memcpy (payload, addr->i, 32); // intro key
|
||||||
else
|
else
|
||||||
LogPrint (eLogInfo, "SSU: SSU is not supported. Can't send peer test");
|
LogPrint (eLogInfo, "SSU: SSU is not supported. Can't send peer test");
|
||||||
}
|
}
|
||||||
@@ -1213,7 +1222,7 @@ namespace transport
|
|||||||
if (!nonce) nonce = 1;
|
if (!nonce) nonce = 1;
|
||||||
m_IsPeerTest = false;
|
m_IsPeerTest = false;
|
||||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1, shared_from_this ());
|
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1, shared_from_this ());
|
||||||
SendPeerTest (nonce, boost::asio::ip::address(), 0, address->ssu->key, false, false); // address and port always zero for Alice
|
SendPeerTest (nonce, boost::asio::ip::address(), 0, address->i, false, false); // address and port always zero for Alice
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUSession::SendKeepAlive ()
|
void SSUSession::SendKeepAlive ()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -36,6 +36,7 @@ namespace transport
|
|||||||
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
|
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||||
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||||
const int SSU_CLOCK_SKEW = 60; // in seconds
|
const int SSU_CLOCK_SKEW = 60; // in seconds
|
||||||
|
const int SSU_CLOCK_THRESHOLD = 15; // in seconds, if more we should adjust
|
||||||
const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768;
|
const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768;
|
||||||
|
|
||||||
// payload types (4 bits)
|
// payload types (4 bits)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -182,6 +182,7 @@ namespace stream
|
|||||||
m_IsAckSendScheduled = true;
|
m_IsAckSendScheduled = true;
|
||||||
auto ackTimeout = m_RTT/10;
|
auto ackTimeout = m_RTT/10;
|
||||||
if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay;
|
if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay;
|
||||||
|
else if (ackTimeout < MIN_SEND_ACK_TIMEOUT) ackTimeout = MIN_SEND_ACK_TIMEOUT;
|
||||||
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ackTimeout));
|
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ackTimeout));
|
||||||
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
@@ -1272,6 +1273,11 @@ namespace stream
|
|||||||
m_IncomingStreams.erase (stream->GetSendStreamID ());
|
m_IncomingStreams.erase (stream->GetSendStreamID ());
|
||||||
if (m_LastStream == stream) m_LastStream = nullptr;
|
if (m_LastStream == stream) m_LastStream = nullptr;
|
||||||
}
|
}
|
||||||
|
if (m_Streams.empty ())
|
||||||
|
{
|
||||||
|
m_PacketsPool.CleanUp ();
|
||||||
|
m_I2NPMsgsPool.CleanUp ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
|
bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
|
||||||
@@ -1279,7 +1285,13 @@ namespace stream
|
|||||||
auto it = m_Streams.find (recvStreamID);
|
auto it = m_Streams.find (recvStreamID);
|
||||||
if (it == m_Streams.end ())
|
if (it == m_Streams.end ())
|
||||||
return false;
|
return false;
|
||||||
DeleteStream (it->second);
|
auto s = it->second;
|
||||||
|
m_Owner->GetService ().post ([this, s] ()
|
||||||
|
{
|
||||||
|
s->Close (); // try to send FIN
|
||||||
|
s->Terminate (false);
|
||||||
|
DeleteStream (s);
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ namespace stream
|
|||||||
const int MAX_WINDOW_SIZE = 128;
|
const int MAX_WINDOW_SIZE = 128;
|
||||||
const int INITIAL_RTT = 8000; // in milliseconds
|
const int INITIAL_RTT = 8000; // in milliseconds
|
||||||
const int INITIAL_RTO = 9000; // in milliseconds
|
const int INITIAL_RTO = 9000; // in milliseconds
|
||||||
|
const int MIN_SEND_ACK_TIMEOUT = 2; // in milliseconds
|
||||||
const int SYN_TIMEOUT = 200; // how long we wait for SYN after follow-on, in milliseconds
|
const int SYN_TIMEOUT = 200; // how long we wait for SYN after follow-on, in milliseconds
|
||||||
const size_t MAX_PENDING_INCOMING_BACKLOG = 128;
|
const size_t MAX_PENDING_INCOMING_BACKLOG = 128;
|
||||||
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
|
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -9,14 +9,6 @@
|
|||||||
#ifndef TAG_H__
|
#ifndef TAG_H__
|
||||||
#define TAG_H__
|
#define TAG_H__
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2017, 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 <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
@@ -64,17 +56,17 @@ namespace data {
|
|||||||
RAND_bytes(m_Buf, sz);
|
RAND_bytes(m_Buf, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToBase64 () const
|
std::string ToBase64 (size_t len = sz) const
|
||||||
{
|
{
|
||||||
char str[sz*2];
|
char str[sz*2];
|
||||||
size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
size_t l = i2p::data::ByteStreamToBase64 (m_Buf, len, str, sz*2);
|
||||||
return std::string (str, str + l);
|
return std::string (str, str + l);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToBase32 () const
|
std::string ToBase32 (size_t len = sz) const
|
||||||
{
|
{
|
||||||
char str[sz*2];
|
char str[sz*2];
|
||||||
size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
size_t l = i2p::data::ByteStreamToBase32 (m_Buf, len, str, sz*2);
|
||||||
return std::string (str, str + l);
|
return std::string (str, str + l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -250,5 +250,10 @@ namespace util
|
|||||||
sprintf(date, "%04i%02i%02i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
sprintf(date, "%04i%02i%02i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdjustTimeOffset (int64_t offset)
|
||||||
|
{
|
||||||
|
g_TimeOffset += offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -26,6 +26,7 @@ namespace util
|
|||||||
|
|
||||||
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
|
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
|
||||||
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
|
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
|
||||||
|
void AdjustTimeOffset (int64_t offset); // in seconds from current
|
||||||
|
|
||||||
class NTPTimeSync
|
class NTPTimeSync
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -136,7 +136,7 @@ namespace transport
|
|||||||
Transports::Transports ():
|
Transports::Transports ():
|
||||||
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr),
|
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr),
|
||||||
m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
|
m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
|
||||||
m_SSUServer (nullptr), m_NTCP2Server (nullptr),
|
m_SSUServer (nullptr), m_SSU2Server (nullptr), m_NTCP2Server (nullptr),
|
||||||
m_X25519KeysPairSupplier (15), // 15 pre-generated keys
|
m_X25519KeysPairSupplier (15), // 15 pre-generated keys
|
||||||
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
|
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
|
||||||
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
|
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
|
||||||
@@ -157,7 +157,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transports::Start (bool enableNTCP2, bool enableSSU)
|
void Transports::Start (bool enableNTCP2, bool enableSSU, bool enableSSU2)
|
||||||
{
|
{
|
||||||
if (!m_Service)
|
if (!m_Service)
|
||||||
{
|
{
|
||||||
@@ -217,6 +217,8 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// create SSU2 server
|
||||||
|
if (enableSSU2) m_SSU2Server = new SSU2Server ();
|
||||||
|
|
||||||
// bind to interfaces
|
// bind to interfaces
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
@@ -266,6 +268,7 @@ namespace transport
|
|||||||
|
|
||||||
// start servers
|
// start servers
|
||||||
if (m_NTCP2Server) m_NTCP2Server->Start ();
|
if (m_NTCP2Server) m_NTCP2Server->Start ();
|
||||||
|
if (m_SSU2Server) m_SSU2Server->Start ();
|
||||||
if (m_SSUServer)
|
if (m_SSUServer)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort);
|
LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort);
|
||||||
@@ -305,6 +308,13 @@ namespace transport
|
|||||||
m_SSUServer = nullptr;
|
m_SSUServer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_SSU2Server)
|
||||||
|
{
|
||||||
|
m_SSU2Server->Stop ();
|
||||||
|
delete m_SSU2Server;
|
||||||
|
m_SSU2Server = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_NTCP2Server)
|
if (m_NTCP2Server)
|
||||||
{
|
{
|
||||||
m_NTCP2Server->Stop ();
|
m_NTCP2Server->Stop ();
|
||||||
@@ -526,6 +536,40 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (peer.numAttempts == 5 || peer.numAttempts == 6) // SSU2
|
||||||
|
{
|
||||||
|
if (m_SSU2Server)
|
||||||
|
{
|
||||||
|
std::shared_ptr<const RouterInfo::Address> address;
|
||||||
|
if (peer.numAttempts == 5) // SSU2 ipv6
|
||||||
|
{
|
||||||
|
if (context.GetRouterInfo ().IsSSU2V6 () && peer.router->IsReachableBy (RouterInfo::eSSU2V6))
|
||||||
|
{
|
||||||
|
address = peer.router->GetSSU2V6Address ();
|
||||||
|
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||||
|
address = nullptr;
|
||||||
|
}
|
||||||
|
peer.numAttempts++;
|
||||||
|
}
|
||||||
|
if (!address && peer.numAttempts == 6) // SSU2 ipv4
|
||||||
|
{
|
||||||
|
if (context.GetRouterInfo ().IsSSU2V4 () && peer.router->IsReachableBy (RouterInfo::eSSU2V4))
|
||||||
|
{
|
||||||
|
address = peer.router->GetSSU2V4Address ();
|
||||||
|
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||||
|
address = nullptr;
|
||||||
|
}
|
||||||
|
peer.numAttempts++;
|
||||||
|
}
|
||||||
|
if (address && address->IsReachableSSU ())
|
||||||
|
{
|
||||||
|
if (m_SSU2Server->CreateSession (peer.router, address))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
peer.numAttempts += 2;
|
||||||
|
}
|
||||||
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
||||||
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
||||||
peer.Done ();
|
peer.Done ();
|
||||||
@@ -588,6 +632,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Transports: Started peer test IPv4");
|
LogPrint (eLogInfo, "Transports: Started peer test IPv4");
|
||||||
std::set<i2p::data::IdentHash> excluded;
|
std::set<i2p::data::IdentHash> excluded;
|
||||||
|
excluded.insert (i2p::context.GetIdentHash ()); // don't pick own router
|
||||||
bool statusChanged = false;
|
bool statusChanged = false;
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
@@ -609,11 +654,22 @@ namespace transport
|
|||||||
}
|
}
|
||||||
if (!statusChanged)
|
if (!statusChanged)
|
||||||
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv4");
|
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv4");
|
||||||
|
|
||||||
|
// SSU2
|
||||||
|
if (m_SSU2Server)
|
||||||
|
{
|
||||||
|
excluded.clear ();
|
||||||
|
excluded.insert (i2p::context.GetIdentHash ());
|
||||||
|
auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (true, excluded); // v4
|
||||||
|
if (router)
|
||||||
|
m_SSU2Server->StartPeerTest (router, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ipv6 && i2p::context.SupportsV6 ())
|
if (ipv6 && i2p::context.SupportsV6 ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Transports: Started peer test IPv6");
|
LogPrint (eLogInfo, "Transports: Started peer test IPv6");
|
||||||
std::set<i2p::data::IdentHash> excluded;
|
std::set<i2p::data::IdentHash> excluded;
|
||||||
|
excluded.insert (i2p::context.GetIdentHash ()); // don't pick own router
|
||||||
bool statusChanged = false;
|
bool statusChanged = false;
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
@@ -635,6 +691,16 @@ namespace transport
|
|||||||
}
|
}
|
||||||
if (!statusChanged)
|
if (!statusChanged)
|
||||||
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv6");
|
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv6");
|
||||||
|
|
||||||
|
// SSU2
|
||||||
|
if (m_SSU2Server)
|
||||||
|
{
|
||||||
|
excluded.clear ();
|
||||||
|
excluded.insert (i2p::context.GetIdentHash ());
|
||||||
|
auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (false, excluded); // v6
|
||||||
|
if (router)
|
||||||
|
m_SSU2Server->StartPeerTest (router, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,12 +849,18 @@ namespace transport
|
|||||||
}
|
}
|
||||||
return i2p::data::netdb.FindRouter (ident);
|
return i2p::data::netdb.FindRouter (ident);
|
||||||
}
|
}
|
||||||
void Transports::RestrictRoutesToFamilies(std::set<std::string> families)
|
|
||||||
|
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
||||||
m_TrustedFamilies.clear();
|
m_TrustedFamilies.clear();
|
||||||
for ( const auto& fam : families )
|
for (auto fam : families)
|
||||||
m_TrustedFamilies.push_back(fam);
|
{
|
||||||
|
boost::to_lower (fam);
|
||||||
|
auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam);
|
||||||
|
if (id)
|
||||||
|
m_TrustedFamilies.push_back (id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
|
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
|
||||||
@@ -810,20 +882,19 @@ namespace transport
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(m_FamilyMutex);
|
std::lock_guard<std::mutex> l(m_FamilyMutex);
|
||||||
std::string fam;
|
i2p::data::FamilyID fam = 0;
|
||||||
auto sz = m_TrustedFamilies.size();
|
auto sz = m_TrustedFamilies.size();
|
||||||
if(sz > 1)
|
if(sz > 1)
|
||||||
{
|
{
|
||||||
auto it = m_TrustedFamilies.begin ();
|
auto it = m_TrustedFamilies.begin ();
|
||||||
std::advance(it, rand() % sz);
|
std::advance(it, rand() % sz);
|
||||||
fam = *it;
|
fam = *it;
|
||||||
boost::to_lower(fam);
|
|
||||||
}
|
}
|
||||||
else if (sz == 1)
|
else if (sz == 1)
|
||||||
{
|
{
|
||||||
fam = m_TrustedFamilies[0];
|
fam = m_TrustedFamilies[0];
|
||||||
}
|
}
|
||||||
if (fam.size())
|
if (fam)
|
||||||
return i2p::data::netdb.GetRandomRouterInFamily(fam);
|
return i2p::data::netdb.GetRandomRouterInFamily(fam);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "TransportSession.h"
|
#include "TransportSession.h"
|
||||||
#include "SSU.h"
|
#include "SSU.h"
|
||||||
|
#include "SSU2.h"
|
||||||
#include "NTCP2.h"
|
#include "NTCP2.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
@@ -86,7 +87,7 @@ namespace transport
|
|||||||
Transports ();
|
Transports ();
|
||||||
~Transports ();
|
~Transports ();
|
||||||
|
|
||||||
void Start (bool enableNTCP2=true, bool enableSSU=true);
|
void Start (bool enableNTCP2=true, bool enableSSU=true, bool enableSSU2=false);
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
bool IsBoundSSU() const { return m_SSUServer != nullptr; }
|
bool IsBoundSSU() const { return m_SSUServer != nullptr; }
|
||||||
@@ -125,7 +126,7 @@ namespace transport
|
|||||||
/** do we want to use restricted routes? */
|
/** do we want to use restricted routes? */
|
||||||
bool RoutesRestricted() const;
|
bool RoutesRestricted() const;
|
||||||
/** restrict routes to use only these router families for first hops */
|
/** restrict routes to use only these router families for first hops */
|
||||||
void RestrictRoutesToFamilies(std::set<std::string> families);
|
void RestrictRoutesToFamilies(const std::set<std::string>& families);
|
||||||
/** restrict routes to use only these routers for first hops */
|
/** restrict routes to use only these routers for first hops */
|
||||||
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
|
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
|
||||||
|
|
||||||
@@ -159,6 +160,7 @@ namespace transport
|
|||||||
boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer;
|
boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer;
|
||||||
|
|
||||||
SSUServer * m_SSUServer;
|
SSUServer * m_SSUServer;
|
||||||
|
SSU2Server * m_SSU2Server;
|
||||||
NTCP2Server * m_NTCP2Server;
|
NTCP2Server * m_NTCP2Server;
|
||||||
mutable std::mutex m_PeersMutex;
|
mutable std::mutex m_PeersMutex;
|
||||||
std::unordered_map<i2p::data::IdentHash, Peer> m_Peers;
|
std::unordered_map<i2p::data::IdentHash, Peer> m_Peers;
|
||||||
@@ -171,7 +173,7 @@ namespace transport
|
|||||||
uint64_t m_LastBandwidthUpdateTime;
|
uint64_t m_LastBandwidthUpdateTime;
|
||||||
|
|
||||||
/** which router families to trust for first hops */
|
/** which router families to trust for first hops */
|
||||||
std::vector<std::string> m_TrustedFamilies;
|
std::vector<i2p::data::FamilyID> m_TrustedFamilies;
|
||||||
mutable std::mutex m_FamilyMutex;
|
mutable std::mutex m_FamilyMutex;
|
||||||
|
|
||||||
/** which routers for first hop to trust */
|
/** which routers for first hop to trust */
|
||||||
@@ -185,6 +187,7 @@ namespace transport
|
|||||||
// for HTTP only
|
// for HTTP only
|
||||||
const SSUServer * GetSSUServer () const { return m_SSUServer; };
|
const SSUServer * GetSSUServer () const { return m_SSUServer; };
|
||||||
const NTCP2Server * GetNTCP2Server () const { return m_NTCP2Server; };
|
const NTCP2Server * GetNTCP2Server () const { return m_NTCP2Server; };
|
||||||
|
const SSU2Server * GetSSU2Server () const { return m_SSU2Server; };
|
||||||
const decltype(m_Peers)& GetPeers () const { return m_Peers; };
|
const decltype(m_Peers)& GetPeers () const { return m_Peers; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -114,7 +114,7 @@ namespace tunnel
|
|||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key);
|
uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key);
|
||||||
if (m_Pool && m_Pool->GetLocalDestination ())
|
if (m_Pool && m_Pool->GetLocalDestination ())
|
||||||
m_Pool->GetLocalDestination ()->AddECIESx25519Key (key, tag);
|
m_Pool->GetLocalDestination ()->SubmitECIESx25519Key (key, tag);
|
||||||
else
|
else
|
||||||
i2p::context.AddECIESx25519Key (key, tag);
|
i2p::context.AddECIESx25519Key (key, tag);
|
||||||
}
|
}
|
||||||
@@ -235,15 +235,11 @@ namespace tunnel
|
|||||||
m_State = state;
|
m_State = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tunnel::VisitTunnelHops(TunnelHopVisitor v)
|
||||||
void Tunnel::PrintHops (std::stringstream& s) const
|
|
||||||
{
|
{
|
||||||
// hops are in inverted order, we must print in direct order
|
// hops are in inverted order, we must return in direct order
|
||||||
for (auto it = m_Hops.rbegin (); it != m_Hops.rend (); it++)
|
for (auto it = m_Hops.rbegin (); it != m_Hops.rend (); it++)
|
||||||
{
|
v((*it).ident);
|
||||||
s << " ⇒ ";
|
|
||||||
s << i2p::data::GetIdentHashAbbreviation ((*it).ident->GetIdentHash ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg)
|
void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg)
|
||||||
@@ -254,12 +250,6 @@ namespace tunnel
|
|||||||
m_Endpoint.HandleDecryptedTunnelDataMsg (msg);
|
m_Endpoint.HandleDecryptedTunnelDataMsg (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InboundTunnel::Print (std::stringstream& s) const
|
|
||||||
{
|
|
||||||
PrintHops (s);
|
|
||||||
s << " ⇒ " << GetTunnelID () << ":me";
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
||||||
InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
||||||
m_NumReceivedBytes (0)
|
m_NumReceivedBytes (0)
|
||||||
@@ -276,11 +266,6 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroHopsInboundTunnel::Print (std::stringstream& s) const
|
|
||||||
{
|
|
||||||
s << " ⇒ " << GetTunnelID () << ":me";
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
TunnelMessageBlock block;
|
TunnelMessageBlock block;
|
||||||
@@ -315,13 +300,6 @@ namespace tunnel
|
|||||||
LogPrint (eLogError, "Tunnel: Incoming message for outbound tunnel ", GetTunnelID ());
|
LogPrint (eLogError, "Tunnel: Incoming message for outbound tunnel ", GetTunnelID ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutboundTunnel::Print (std::stringstream& s) const
|
|
||||||
{
|
|
||||||
s << GetTunnelID () << ":me";
|
|
||||||
PrintHops (s);
|
|
||||||
s << " ⇒ ";
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
||||||
OutboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
OutboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
||||||
m_NumSentBytes (0)
|
m_NumSentBytes (0)
|
||||||
@@ -351,11 +329,6 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const
|
|
||||||
{
|
|
||||||
s << GetTunnelID () << ":me ⇒ ";
|
|
||||||
}
|
|
||||||
|
|
||||||
Tunnels tunnels;
|
Tunnels tunnels;
|
||||||
|
|
||||||
Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr),
|
Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr),
|
||||||
@@ -430,10 +403,10 @@ namespace tunnel
|
|||||||
return tunnel;
|
return tunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops,
|
std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops,
|
||||||
int numOutboundHops, int numInboundTunnels, int numOutboundTunnels)
|
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance)
|
||||||
{
|
{
|
||||||
auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels);
|
auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance);
|
||||||
std::unique_lock<std::mutex> l(m_PoolsMutex);
|
std::unique_lock<std::mutex> l(m_PoolsMutex);
|
||||||
m_Pools.push_back (pool);
|
m_Pools.push_back (pool);
|
||||||
return pool;
|
return pool;
|
||||||
@@ -783,7 +756,7 @@ namespace tunnel
|
|||||||
int obLen; i2p::config::GetOption("exploratory.outbound.length", obLen);
|
int obLen; i2p::config::GetOption("exploratory.outbound.length", obLen);
|
||||||
int ibNum; i2p::config::GetOption("exploratory.inbound.quantity", ibNum);
|
int ibNum; i2p::config::GetOption("exploratory.inbound.quantity", ibNum);
|
||||||
int obNum; i2p::config::GetOption("exploratory.outbound.quantity", obNum);
|
int obNum; i2p::config::GetOption("exploratory.outbound.quantity", obNum);
|
||||||
m_ExploratoryPool = CreateTunnelPool (ibLen, obLen, ibNum, obNum);
|
m_ExploratoryPool = CreateTunnelPool (ibLen, obLen, ibNum, obNum, 0, 0);
|
||||||
m_ExploratoryPool->SetLocalDestination (i2p::context.GetSharedDestination ());
|
m_ExploratoryPool->SetLocalDestination (i2p::context.GetSharedDestination ());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -67,6 +67,9 @@ namespace tunnel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** function for visiting a hops stored in a tunnel */
|
||||||
|
typedef std::function<void(std::shared_ptr<const i2p::data::IdentityEx>)> TunnelHopVisitor;
|
||||||
|
|
||||||
Tunnel (std::shared_ptr<const TunnelConfig> config);
|
Tunnel (std::shared_ptr<const TunnelConfig> config);
|
||||||
~Tunnel ();
|
~Tunnel ();
|
||||||
|
|
||||||
@@ -91,8 +94,6 @@ namespace tunnel
|
|||||||
|
|
||||||
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
||||||
|
|
||||||
virtual void Print (std::stringstream&) const {};
|
|
||||||
|
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
||||||
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
||||||
@@ -107,9 +108,8 @@ namespace tunnel
|
|||||||
bool LatencyIsKnown() const { return m_Latency > 0; }
|
bool LatencyIsKnown() const { return m_Latency > 0; }
|
||||||
bool IsSlow () const { return LatencyIsKnown() && (int)m_Latency > HIGH_LATENCY_PER_HOP*GetNumHops (); }
|
bool IsSlow () const { return LatencyIsKnown() && (int)m_Latency > HIGH_LATENCY_PER_HOP*GetNumHops (); }
|
||||||
|
|
||||||
protected:
|
/** visit all hops we currently store */
|
||||||
|
void VisitTunnelHops(TunnelHopVisitor v);
|
||||||
void PrintHops (std::stringstream& s) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -134,7 +134,6 @@ namespace tunnel
|
|||||||
virtual void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
virtual void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
||||||
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
|
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
|
||||||
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
||||||
void Print (std::stringstream& s) const;
|
|
||||||
|
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
||||||
@@ -155,7 +154,6 @@ namespace tunnel
|
|||||||
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg);
|
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg);
|
||||||
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
||||||
void Print (std::stringstream& s) const;
|
|
||||||
bool IsInbound() const { return true; }
|
bool IsInbound() const { return true; }
|
||||||
|
|
||||||
// override TunnelBase
|
// override TunnelBase
|
||||||
@@ -172,7 +170,6 @@ namespace tunnel
|
|||||||
|
|
||||||
ZeroHopsInboundTunnel ();
|
ZeroHopsInboundTunnel ();
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
||||||
void Print (std::stringstream& s) const;
|
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -186,7 +183,6 @@ namespace tunnel
|
|||||||
|
|
||||||
ZeroHopsOutboundTunnel ();
|
ZeroHopsOutboundTunnel ();
|
||||||
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs);
|
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs);
|
||||||
void Print (std::stringstream& s) const;
|
|
||||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -219,8 +215,8 @@ namespace tunnel
|
|||||||
void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
||||||
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
|
||||||
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
|
||||||
std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops,
|
std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops, int numOuboundHops,
|
||||||
int numOuboundHops, int numInboundTunnels, int numOutboundTunnels);
|
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
||||||
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
|
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
|
||||||
void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
|
void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -40,15 +40,25 @@ namespace tunnel
|
|||||||
std::reverse (peers.begin (), peers.end ());
|
std::reverse (peers.begin (), peers.end ());
|
||||||
}
|
}
|
||||||
|
|
||||||
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
||||||
|
int numOutboundTunnels, int inboundVariance, int outboundVariance):
|
||||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
|
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
|
||||||
|
m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance),
|
||||||
m_IsActive (true), m_CustomPeerSelector(nullptr)
|
m_IsActive (true), m_CustomPeerSelector(nullptr)
|
||||||
{
|
{
|
||||||
if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
|
if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
|
||||||
m_NumInboundTunnels = TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY;
|
m_NumInboundTunnels = TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY;
|
||||||
if (m_NumOutboundTunnels > TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY)
|
if (m_NumOutboundTunnels > TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY)
|
||||||
m_NumOutboundTunnels = TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY;
|
m_NumOutboundTunnels = TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY;
|
||||||
|
if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0)
|
||||||
|
m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0;
|
||||||
|
if (m_OutboundVariance < 0 && m_NumOutboundHops + m_OutboundVariance <= 0)
|
||||||
|
m_OutboundVariance = m_NumOutboundHops ? -m_NumOutboundHops + 1 : 0;
|
||||||
|
if (m_InboundVariance > 0 && m_NumInboundHops + m_InboundVariance > STANDARD_NUM_RECORDS)
|
||||||
|
m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0;
|
||||||
|
if (m_OutboundVariance > 0 && m_NumOutboundHops + m_OutboundVariance > STANDARD_NUM_RECORDS)
|
||||||
|
m_OutboundVariance = (m_NumOutboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumOutboundHops : 0;
|
||||||
m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL;
|
m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +348,9 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// new tests
|
// new tests
|
||||||
|
std::unique_lock<std::mutex> l1(m_OutboundTunnelsMutex);
|
||||||
auto it1 = m_OutboundTunnels.begin ();
|
auto it1 = m_OutboundTunnels.begin ();
|
||||||
|
std::unique_lock<std::mutex> l2(m_InboundTunnelsMutex);
|
||||||
auto it2 = m_InboundTunnels.begin ();
|
auto it2 = m_InboundTunnels.begin ();
|
||||||
while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ())
|
while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ())
|
||||||
{
|
{
|
||||||
@@ -370,7 +382,7 @@ namespace tunnel
|
|||||||
|
|
||||||
void TunnelPool::ManageTunnels (uint64_t ts)
|
void TunnelPool::ManageTunnels (uint64_t ts)
|
||||||
{
|
{
|
||||||
if (ts > m_NextManageTime)
|
if (ts > m_NextManageTime || ts + 2*TUNNEL_POOL_MANAGE_INTERVAL < m_NextManageTime) // in case if clock was adjusted
|
||||||
{
|
{
|
||||||
CreateTunnels ();
|
CreateTunnels ();
|
||||||
TestTunnels ();
|
TestTunnels ();
|
||||||
@@ -409,13 +421,18 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
uint64_t dlt = i2p::util::GetMillisecondsSinceEpoch () - timestamp;
|
uint64_t dlt = i2p::util::GetMillisecondsSinceEpoch () - timestamp;
|
||||||
LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
|
LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
|
||||||
uint64_t latency = dlt / 2;
|
int numHops = 0;
|
||||||
|
if (test.first) numHops += test.first->GetNumHops ();
|
||||||
|
if (test.second) numHops += test.second->GetNumHops ();
|
||||||
// restore from test failed state if any
|
// restore from test failed state if any
|
||||||
if (test.first)
|
if (test.first)
|
||||||
{
|
{
|
||||||
if (test.first->GetState () == eTunnelStateTestFailed)
|
if (test.first->GetState () == eTunnelStateTestFailed)
|
||||||
test.first->SetState (eTunnelStateEstablished);
|
test.first->SetState (eTunnelStateEstablished);
|
||||||
// update latency
|
// update latency
|
||||||
|
uint64_t latency = 0;
|
||||||
|
if (numHops) latency = dlt*test.first->GetNumHops ()/numHops;
|
||||||
|
if (!latency) latency = dlt/2;
|
||||||
test.first->AddLatencySample(latency);
|
test.first->AddLatencySample(latency);
|
||||||
}
|
}
|
||||||
if (test.second)
|
if (test.second)
|
||||||
@@ -423,6 +440,9 @@ namespace tunnel
|
|||||||
if (test.second->GetState () == eTunnelStateTestFailed)
|
if (test.second->GetState () == eTunnelStateTestFailed)
|
||||||
test.second->SetState (eTunnelStateEstablished);
|
test.second->SetState (eTunnelStateEstablished);
|
||||||
// update latency
|
// update latency
|
||||||
|
uint64_t latency = 0;
|
||||||
|
if (numHops) latency = dlt*test.second->GetNumHops ()/numHops;
|
||||||
|
if (!latency) latency = dlt/2;
|
||||||
test.second->AddLatencySample(latency);
|
test.second->AddLatencySample(latency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,7 +525,30 @@ namespace tunnel
|
|||||||
|
|
||||||
bool TunnelPool::SelectPeers (Path& path, bool isInbound)
|
bool TunnelPool::SelectPeers (Path& path, bool isInbound)
|
||||||
{
|
{
|
||||||
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
|
// explicit peers in use
|
||||||
|
if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound);
|
||||||
|
// calculate num hops
|
||||||
|
int numHops;
|
||||||
|
if (isInbound)
|
||||||
|
{
|
||||||
|
numHops = m_NumInboundHops;
|
||||||
|
if (m_InboundVariance)
|
||||||
|
{
|
||||||
|
int offset = rand () % (std::abs (m_InboundVariance) + 1);
|
||||||
|
if (m_InboundVariance < 0) offset = -offset;
|
||||||
|
numHops += offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numHops = m_NumOutboundHops;
|
||||||
|
if (m_OutboundVariance)
|
||||||
|
{
|
||||||
|
int offset = rand () % (std::abs (m_OutboundVariance) + 1);
|
||||||
|
if (m_OutboundVariance < 0) offset = -offset;
|
||||||
|
numHops += offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
// peers is empty
|
// peers is empty
|
||||||
if (numHops <= 0) return true;
|
if (numHops <= 0) return true;
|
||||||
// custom peer selector in use ?
|
// custom peer selector in use ?
|
||||||
@@ -514,8 +557,6 @@ namespace tunnel
|
|||||||
if (m_CustomPeerSelector)
|
if (m_CustomPeerSelector)
|
||||||
return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound);
|
return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound);
|
||||||
}
|
}
|
||||||
// explicit peers in use
|
|
||||||
if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound);
|
|
||||||
return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2));
|
return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -61,7 +61,8 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels);
|
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
||||||
|
int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
||||||
~TunnelPool ();
|
~TunnelPool ();
|
||||||
|
|
||||||
std::shared_ptr<i2p::garlic::GarlicDestination> GetLocalDestination () const { return m_LocalDestination; };
|
std::shared_ptr<i2p::garlic::GarlicDestination> GetLocalDestination () const { return m_LocalDestination; };
|
||||||
@@ -81,7 +82,6 @@ namespace tunnel
|
|||||||
std::shared_ptr<InboundTunnel> GetNextInboundTunnel (std::shared_ptr<InboundTunnel> excluded = nullptr,
|
std::shared_ptr<InboundTunnel> GetNextInboundTunnel (std::shared_ptr<InboundTunnel> excluded = nullptr,
|
||||||
i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const;
|
i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const;
|
||||||
std::shared_ptr<OutboundTunnel> GetNewOutboundTunnel (std::shared_ptr<OutboundTunnel> old) const;
|
std::shared_ptr<OutboundTunnel> GetNewOutboundTunnel (std::shared_ptr<OutboundTunnel> old) const;
|
||||||
void TestTunnels ();
|
|
||||||
void ManageTunnels (uint64_t ts);
|
void ManageTunnels (uint64_t ts);
|
||||||
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg);
|
void ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg);
|
||||||
@@ -118,6 +118,7 @@ namespace tunnel
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void TestTunnels ();
|
||||||
void CreateInboundTunnel ();
|
void CreateInboundTunnel ();
|
||||||
void CreateOutboundTunnel ();
|
void CreateOutboundTunnel ();
|
||||||
void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel);
|
void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel);
|
||||||
@@ -130,7 +131,8 @@ namespace tunnel
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination;
|
std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination;
|
||||||
int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels;
|
int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels,
|
||||||
|
m_InboundVariance, m_OutboundVariance;
|
||||||
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
|
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
|
||||||
mutable std::mutex m_InboundTunnelsMutex;
|
mutable std::mutex m_InboundTunnelsMutex;
|
||||||
std::set<std::shared_ptr<InboundTunnel>, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
|
std::set<std::shared_ptr<InboundTunnel>, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user