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
|
||||||
41
.github/workflows/build-windows.yml
vendored
41
.github/workflows/build-windows.yml
vendored
@@ -14,8 +14,9 @@ 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 }
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -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
|
||||||
|
|||||||
67
Makefile
67
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,59 +51,58 @@ 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
|
||||||
|
|
||||||
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)
|
||||||
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
api_client: api client lang webconsole
|
||||||
|
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
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
@@ -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)
|
find_package(Threads REQUIRED)
|
||||||
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)
|
|
||||||
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
|
include(CheckAtomic)
|
||||||
if(WITH_MESHNET)
|
|
||||||
message(STATUS "Building for testnet")
|
|
||||||
message(WARNING "This build will NOT work on mainline i2p")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT MSYS)
|
|
||||||
include(CheckAtomic)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# 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
|
echo.
|
||||||
set bitness=32
|
|
||||||
set "xSH=%WD%bash -lc"
|
|
||||||
call :BUILDING_XP
|
|
||||||
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
|
||||||
|
|
||||||
:EOF
|
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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -73,8 +77,14 @@ namespace util
|
|||||||
i2p::config::Init();
|
i2p::config::Init();
|
||||||
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();
|
||||||
|
|
||||||
@@ -99,9 +109,9 @@ namespace util
|
|||||||
|
|
||||||
certsdir = i2p::fs::GetCertsDir();
|
certsdir = i2p::fs::GetCertsDir();
|
||||||
|
|
||||||
std::string logs = ""; i2p::config::GetOption("log", logs);
|
std::string logs = ""; i2p::config::GetOption("log", logs);
|
||||||
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
||||||
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
||||||
bool logclftime; i2p::config::GetOption("logclftime", logclftime);
|
bool logclftime; i2p::config::GetOption("logclftime", logclftime);
|
||||||
|
|
||||||
/* setup logging */
|
/* setup logging */
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -20,27 +20,33 @@ namespace util
|
|||||||
class Daemon_Singleton_Private;
|
class Daemon_Singleton_Private;
|
||||||
class Daemon_Singleton
|
class Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
virtual bool init (int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
||||||
virtual bool init(int argc, char* argv[]);
|
virtual bool init (int argc, char* argv[]);
|
||||||
virtual bool start();
|
virtual bool start ();
|
||||||
virtual bool stop();
|
virtual bool stop ();
|
||||||
virtual void run () {};
|
virtual void run () {};
|
||||||
|
|
||||||
bool isDaemon;
|
virtual void setDataDir (std::string path);
|
||||||
bool running;
|
|
||||||
|
|
||||||
protected:
|
bool isDaemon;
|
||||||
|
bool running;
|
||||||
|
|
||||||
Daemon_Singleton();
|
protected:
|
||||||
virtual ~Daemon_Singleton();
|
|
||||||
|
|
||||||
bool IsService () const;
|
Daemon_Singleton ();
|
||||||
|
virtual ~Daemon_Singleton ();
|
||||||
|
|
||||||
// d-pointer for httpServer, httpProxy, etc.
|
bool IsService () const;
|
||||||
class Daemon_Singleton_Private;
|
|
||||||
Daemon_Singleton_Private &d;
|
// d-pointer for httpServer, httpProxy, etc.
|
||||||
|
class Daemon_Singleton_Private;
|
||||||
|
Daemon_Singleton_Private &d;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string DaemonDataDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(QT_GUI_LIB) // check if QT
|
#if defined(QT_GUI_LIB) // check if QT
|
||||||
@@ -69,14 +75,17 @@ namespace util
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(int argc, char* argv[]);
|
bool init (int argc, char* argv[]);
|
||||||
bool start();
|
bool start ();
|
||||||
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()
|
||||||
@@ -103,8 +112,8 @@ namespace util
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start();
|
bool start ();
|
||||||
bool stop();
|
bool stop ();
|
||||||
void run ();
|
void run ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -58,29 +66,28 @@ namespace client
|
|||||||
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||||
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||||
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||||
|
|
||||||
// RouterInfo
|
// RouterInfo
|
||||||
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
||||||
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;
|
||||||
|
|
||||||
@@ -96,10 +103,10 @@ namespace client
|
|||||||
// ClientServicesInfo
|
// ClientServicesInfo
|
||||||
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
I2PControlService::~I2PControlService ()
|
I2PControlService::~I2PControlService ()
|
||||||
@@ -160,7 +167,7 @@ namespace client
|
|||||||
Accept ();
|
Accept ();
|
||||||
|
|
||||||
if (ecode) {
|
if (ecode) {
|
||||||
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
|
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
|
||||||
@@ -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)
|
||||||
ss << "\"" << value << "\"";
|
{
|
||||||
|
if (quotes)
|
||||||
|
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)
|
||||||
@@ -466,7 +478,7 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -494,7 +506,7 @@ namespace client
|
|||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
Daemon.running = 0;
|
Daemon.running = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -508,7 +520,7 @@ namespace client
|
|||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
Daemon.running = 0;
|
Daemon.running = 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
|
||||||
*
|
*
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace transport
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
isError = err != UPNPDISCOVER_SUCCESS;
|
isError = err != UPNPDISCOVER_SUCCESS;
|
||||||
#else // MINIUPNPC_API_VERSION >= 8
|
#else // MINIUPNPC_API_VERSION >= 8
|
||||||
err = 0;
|
err = 0;
|
||||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
||||||
isError = m_Devlist == NULL;
|
isError = m_Devlist == NULL;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace transport
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void Discover ();
|
void Discover ();
|
||||||
int CheckMapping (const char* port, const char* type);
|
int CheckMapping (const char* port, const char* type);
|
||||||
void PortMapping ();
|
void PortMapping ();
|
||||||
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
void CloseMapping ();
|
void CloseMapping ();
|
||||||
@@ -80,7 +80,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // USE_UPNP
|
#else // USE_UPNP
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace transport {
|
namespace transport {
|
||||||
/* class stub */
|
/* class stub */
|
||||||
|
|||||||
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,20 +34,21 @@ 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"},
|
||||||
{"unknown", "noma'lum"},
|
{"unknown", "noma'lum"},
|
||||||
{"exploratory", "tadqiqiy"},
|
{"exploratory", "tadqiqiy"},
|
||||||
{"<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,8 +24,8 @@ 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);
|
||||||
|
|
||||||
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
@@ -99,7 +99,7 @@ namespace data
|
|||||||
static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args)
|
static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args)
|
||||||
// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
|
// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
|
||||||
{
|
{
|
||||||
size_t publicKeyLength = 0;
|
size_t publicKeyLength = 0;
|
||||||
EC_GROUP * group = nullptr;
|
EC_GROUP * group = nullptr;
|
||||||
switch (sigType)
|
switch (sigType)
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,10 @@ 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 ();
|
||||||
m_BlindedSigType = m_SigType;
|
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||||
|
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
|
||||||
|
else
|
||||||
|
m_BlindedSigType = m_SigType;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlindedPublicKey::BlindedPublicKey (const std::string& b33):
|
BlindedPublicKey::BlindedPublicKey (const std::string& b33):
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ namespace data
|
|||||||
|
|
||||||
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
|
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
|
||||||
size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
|
size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
|
||||||
SigningKeyType GetSigType () const { return m_SigType; };
|
SigningKeyType GetSigType () const { return m_SigType; };
|
||||||
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
|
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
|
||||||
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
|
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
|
||||||
|
|
||||||
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ namespace config {
|
|||||||
extern boost::program_options::variables_map m_Options;
|
extern boost::program_options::variables_map m_Options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize list of acceptable parameters
|
* @brief Initialize list of acceptable parameters
|
||||||
*
|
*
|
||||||
* Should be called before any Parse* functions.
|
* Should be called before any Parse* functions.
|
||||||
*/
|
*/
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parse cmdline parameters, and show help if requested
|
* @brief Parse cmdline parameters, and show help if requested
|
||||||
* @param argc Cmdline arguments count, should be passed from main().
|
* @param argc Cmdline arguments count, should be passed from main().
|
||||||
* @param argv Cmdline parameters array, should be passed from main()
|
* @param argv Cmdline parameters array, should be passed from main()
|
||||||
*
|
*
|
||||||
* If --help is given in parameters, shows its list with description
|
* If --help is given in parameters, shows its list with description
|
||||||
* and terminates the program with exitcode 0.
|
* and terminates the program with exitcode 0.
|
||||||
@@ -52,8 +52,8 @@ namespace config {
|
|||||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load and parse given config file
|
* @brief Load and parse given config file
|
||||||
* @param path Path to config file
|
* @param path Path to config file
|
||||||
*
|
*
|
||||||
* If error occurred when opening file path is points to,
|
* If error occurred when opening file path is points to,
|
||||||
* we show the error message and terminate program.
|
* we show the error message and terminate program.
|
||||||
@@ -67,14 +67,14 @@ namespace config {
|
|||||||
void ParseConfig(const std::string& path);
|
void ParseConfig(const std::string& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to combine options from cmdline, config and default values
|
* @brief Used to combine options from cmdline, config and default values
|
||||||
*/
|
*/
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accessor to parameters by name
|
* @brief Accessor to parameters by name
|
||||||
* @param name Name of the requested parameter
|
* @param name Name of the requested parameter
|
||||||
* @param value Variable where to store option
|
* @param value Variable where to store option
|
||||||
* @return this function returns false if parameter not found
|
* @return this function returns false if parameter not found
|
||||||
*
|
*
|
||||||
* Example: uint16_t port; GetOption("sam.port", port);
|
* Example: uint16_t port; GetOption("sam.port", port);
|
||||||
@@ -98,9 +98,9 @@ namespace config {
|
|||||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set value of given parameter
|
* @brief Set value of given parameter
|
||||||
* @param name Name of settable parameter
|
* @param name Name of settable parameter
|
||||||
* @param value New parameter value
|
* @param value New parameter value
|
||||||
* @return true if value set up successful, false otherwise
|
* @return true if value set up successful, false otherwise
|
||||||
*
|
*
|
||||||
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
||||||
@@ -116,8 +116,8 @@ namespace config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check is value explicitly given or default
|
* @brief Check is value explicitly given or default
|
||||||
* @param name Name of checked parameter
|
* @param name Name of checked parameter
|
||||||
* @return true if value set to default, false otherwise
|
* @return true if value set to default, false otherwise
|
||||||
*/
|
*/
|
||||||
bool IsDefault(const char *name);
|
bool IsDefault(const char *name);
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -1320,7 +1330,7 @@ namespace crypto
|
|||||||
SHA256_Init (&ctx);
|
SHA256_Init (&ctx);
|
||||||
SHA256_Update (&ctx, hh, 32);
|
SHA256_Update (&ctx, hh, 32);
|
||||||
SHA256_Update (&ctx, pub, 32);
|
SHA256_Update (&ctx, pub, 32);
|
||||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
@@ -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,23 +29,25 @@
|
|||||||
#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 1
|
# define LEGACY_OPENSSL 0
|
||||||
# define X509_getm_notBefore X509_get_notBefore
|
#elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
||||||
# define X509_getm_notAfter X509_get_notAfter
|
# define LEGACY_OPENSSL 1
|
||||||
|
# define X509_getm_notBefore X509_get_notBefore
|
||||||
|
# define X509_getm_notAfter X509_get_notAfter
|
||||||
#else
|
#else
|
||||||
# define LEGACY_OPENSSL 0
|
# define LEGACY_OPENSSL 0
|
||||||
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
# 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
|
||||||
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
||||||
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@@ -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
|
||||||
@@ -381,7 +385,7 @@ inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
|||||||
if (dh->p) BN_free (dh->p);
|
if (dh->p) BN_free (dh->p);
|
||||||
if (dh->q) BN_free (dh->q);
|
if (dh->q) BN_free (dh->q);
|
||||||
if (dh->g) BN_free (dh->g);
|
if (dh->g) BN_free (dh->g);
|
||||||
dh->p = p; dh->q = q; dh->g = g; return 1;
|
dh->p = p; dh->q = q; dh->g = g; return 1;
|
||||||
}
|
}
|
||||||
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ namespace datagram
|
|||||||
|
|
||||||
auto path = m_RoutingSession->GetSharedRoutingPath();
|
auto path = m_RoutingSession->GetSharedRoutingPath();
|
||||||
if (path && m_RoutingSession->IsRatchets () &&
|
if (path && m_RoutingSession->IsRatchets () &&
|
||||||
m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
|
m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
|
||||||
{
|
{
|
||||||
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
||||||
path = nullptr;
|
path = nullptr;
|
||||||
|
|||||||
@@ -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));
|
||||||
@@ -396,7 +417,7 @@ namespace client
|
|||||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||||
auto it = m_RemoteLeaseSets.find (key);
|
auto it = m_RemoteLeaseSets.find (key);
|
||||||
if (it != m_RemoteLeaseSets.end () &&
|
if (it != m_RemoteLeaseSets.end () &&
|
||||||
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
|
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
|
||||||
{
|
{
|
||||||
leaseSet = it->second;
|
leaseSet = it->second;
|
||||||
if (leaseSet->IsNewer (buf + offset, len - offset))
|
if (leaseSet->IsNewer (buf + offset, len - offset))
|
||||||
@@ -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)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
if (!inbound)
|
if (!outbound || !inbound)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
LogPrint (eLogInfo, "Destination: No compatible tunnels with ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another floodfill");
|
||||||
return;
|
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
||||||
|
floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
|
||||||
|
if (floodfill)
|
||||||
|
{
|
||||||
|
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
||||||
|
if (outbound)
|
||||||
|
{
|
||||||
|
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
|
if (!inbound)
|
||||||
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
||||||
|
if (!floodfill || !outbound || !inbound)
|
||||||
|
{
|
||||||
|
m_ExcludedFloodfills.clear ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
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 ();
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ namespace garlic
|
|||||||
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
||||||
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
||||||
SessionState m_State = eSessionStateNew;
|
SessionState m_State = eSessionStateNew;
|
||||||
uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds)
|
uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds)
|
||||||
m_LastSentTimestamp = 0; // in milliseconds
|
m_LastSentTimestamp = 0; // in milliseconds
|
||||||
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
|
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
|
||||||
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
||||||
@@ -229,7 +229,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// single session for all incoming messages
|
// single session for all incoming messages
|
||||||
class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession
|
class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace crypto
|
|||||||
BN_add (l, l, tmp);
|
BN_add (l, l, tmp);
|
||||||
BN_sub_word (two_252_2, 2); // 2^252 - 2
|
BN_sub_word (two_252_2, 2); // 2^252 - 2
|
||||||
|
|
||||||
// -121665*inv(121666)
|
// -121665*inv(121666)
|
||||||
d = BN_new ();
|
d = BN_new ();
|
||||||
BN_set_word (tmp, 121666);
|
BN_set_word (tmp, 121666);
|
||||||
BN_mod_inverse (tmp, tmp, q, ctx);
|
BN_mod_inverse (tmp, tmp, q, ctx);
|
||||||
@@ -61,7 +61,7 @@ namespace crypto
|
|||||||
BN_mod (By, By, q, ctx); // % q
|
BN_mod (By, By, q, ctx); // % q
|
||||||
|
|
||||||
// precalculate Bi256 table
|
// precalculate Bi256 table
|
||||||
Bi256Carry = { Bx, By }; // B
|
Bi256Carry = { Bx, By }; // B
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
Bi256[i][0] = Bi256Carry; // first point
|
Bi256[i][0] = Bi256Carry; // first point
|
||||||
@@ -215,7 +215,7 @@ namespace crypto
|
|||||||
if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
|
if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
|
||||||
if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
|
if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
|
||||||
BN_mul (t3, t1, t2, ctx);
|
BN_mul (t3, t1, t2, ctx);
|
||||||
BN_mul (t3, t3, d, ctx); // C = d*t1*t2
|
BN_mul (t3, t3, d, ctx); // C = d*t1*t2
|
||||||
|
|
||||||
if (p1.z)
|
if (p1.z)
|
||||||
{
|
{
|
||||||
@@ -264,9 +264,9 @@ namespace crypto
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BN_mul (t2, p.x, p.y, ctx); // t = x*y
|
BN_mul (t2, p.x, p.y, ctx); // t = x*y
|
||||||
BN_sqr (t2, t2, ctx); // t2 = t^2
|
BN_sqr (t2, t2, ctx); // t2 = t^2
|
||||||
}
|
}
|
||||||
BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
|
BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
|
||||||
if (p.z)
|
if (p.z)
|
||||||
BN_sqr (z2, p.z, ctx); // z2 = D = z^2
|
BN_sqr (z2, p.z, ctx); // z2 = D = z^2
|
||||||
else
|
else
|
||||||
@@ -349,7 +349,7 @@ namespace crypto
|
|||||||
BN_mod_inverse (y, p.z, q, ctx);
|
BN_mod_inverse (y, p.z, q, ctx);
|
||||||
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
|
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
|
||||||
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
|
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
|
||||||
return EDDSAPoint{x, y};
|
return EDDSAPoint{x, y};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
|
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
|
||||||
@@ -506,13 +506,13 @@ namespace crypto
|
|||||||
std::swap (z2, z3);
|
std::swap (z2, z3);
|
||||||
}
|
}
|
||||||
BN_mod_inverse (z2, z2, q, ctx);
|
BN_mod_inverse (z2, z2, q, ctx);
|
||||||
BIGNUM * res = BN_new (); // not from ctx
|
BIGNUM * res = BN_new (); // not from ctx
|
||||||
BN_mod_mul(res, x2, z2, q, ctx);
|
BN_mod_mul(res, x2, z2, q, ctx);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
BIGNUM * p1 = DecodeBN<32> (p);
|
BIGNUM * p1 = DecodeBN<32> (p);
|
||||||
uint8_t k[32];
|
uint8_t k[32];
|
||||||
@@ -524,7 +524,7 @@ namespace crypto
|
|||||||
BN_free (p1); BN_free (n); BN_free (q1);
|
BN_free (p1); BN_free (n); BN_free (q1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
|
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
|
||||||
uint8_t k[32];
|
uint8_t k[32];
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ namespace crypto
|
|||||||
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
||||||
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
#if !OPENSSL_X25519
|
#if !OPENSSL_X25519
|
||||||
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
||||||
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
#endif
|
#endif
|
||||||
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ namespace crypto
|
|||||||
// assume a < p, so don't check for a % p = 0, but a = 0 only
|
// assume a < p, so don't check for a % p = 0, but a = 0 only
|
||||||
if (BN_is_zero(a)) return 0;
|
if (BN_is_zero(a)) return 0;
|
||||||
BIGNUM * r = BN_CTX_get (ctx);
|
BIGNUM * r = BN_CTX_get (ctx);
|
||||||
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
||||||
if (BN_is_word(r, 1))
|
if (BN_is_word(r, 1))
|
||||||
return 1;
|
return 1;
|
||||||
else if (BN_is_zero(r))
|
else if (BN_is_zero(r))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
12
libi2pd/FS.h
12
libi2pd/FS.h
@@ -83,8 +83,8 @@ namespace fs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set datadir either from cmdline option or using autodetection
|
* @brief Set datadir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||||
* @param isService Value of cmdline parameter --service
|
* @param isService Value of cmdline parameter --service
|
||||||
*
|
*
|
||||||
* Examples of autodetected paths:
|
* Examples of autodetected paths:
|
||||||
*
|
*
|
||||||
@@ -93,11 +93,11 @@ namespace fs {
|
|||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||||
*/
|
*/
|
||||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set certsdir either from cmdline option or using autodetection
|
* @brief Set certsdir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
|
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
|
||||||
*
|
*
|
||||||
* Examples of autodetected paths:
|
* Examples of autodetected paths:
|
||||||
*
|
*
|
||||||
@@ -106,7 +106,7 @@ namespace fs {
|
|||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
|
||||||
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
|
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
|
||||||
*/
|
*/
|
||||||
void SetCertsDir(const std::string & cmdline_certsdir);
|
void SetCertsDir(const std::string & cmdline_certsdir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create subdirectories inside datadir
|
* @brief Create subdirectories inside datadir
|
||||||
@@ -115,7 +115,7 @@ namespace fs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get list of files in directory
|
* @brief Get list of files in directory
|
||||||
* @param path Path to directory
|
* @param path Path to directory
|
||||||
* @param files Vector to store found files
|
* @param files Vector to store found files
|
||||||
* @return true on success and false if directory not exists
|
* @return true on success and false if directory not exists
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
@@ -293,14 +293,14 @@ namespace garlic
|
|||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (isDestination)
|
if (isDestination)
|
||||||
{
|
{
|
||||||
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
|
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
|
||||||
size++;
|
size++;
|
||||||
memcpy (buf + size, m_Destination->GetIdentHash (), 32);
|
memcpy (buf + size, m_Destination->GetIdentHash (), 32);
|
||||||
size += 32;
|
size += 32;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf[size] = 0;// delivery instructions flag local
|
buf[size] = 0;// delivery instructions flag local
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 ();
|
||||||
@@ -739,7 +744,7 @@ namespace garlic
|
|||||||
LogPrint (eLogError, "Garlic: Message is too short");
|
LogPrint (eLogError, "Garlic: Message is too short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf += GetI2NPMessageLength (buf, len - offset); // I2NP
|
buf += GetI2NPMessageLength (buf, len - offset); // I2NP
|
||||||
buf += 4; // CloveID
|
buf += 4; // CloveID
|
||||||
buf += 8; // Date
|
buf += 8; // Date
|
||||||
buf += 3; // Certificate
|
buf += 3; // Certificate
|
||||||
@@ -1019,7 +1024,7 @@ namespace garlic
|
|||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto it: files)
|
for (auto it: files)
|
||||||
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
i2p::fs::Remove (it);
|
i2p::fs::Remove (it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace crypto
|
|||||||
EC_POINT * C = EC_POINT_new (m_Group);
|
EC_POINT * C = EC_POINT_new (m_Group);
|
||||||
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
|
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
|
||||||
BIGNUM * x = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx);
|
||||||
GetXY (C, x, nullptr); // Cx
|
GetXY (C, x, nullptr); // Cx
|
||||||
BN_mod (x, x, q, ctx); // Cx % q
|
BN_mod (x, x, q, ctx); // Cx % q
|
||||||
bool ret = !BN_cmp (x, r); // Cx = r ?
|
bool ret = !BN_cmp (x, r); // Cx = r ?
|
||||||
EC_POINT_free (C);
|
EC_POINT_free (C);
|
||||||
@@ -111,8 +111,8 @@ namespace crypto
|
|||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
|
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
|
||||||
EC_POINT * Q = nullptr;
|
EC_POINT * Q = nullptr;
|
||||||
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
|
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
|
||||||
{
|
{
|
||||||
EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
|
EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
|
||||||
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
|
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ namespace http
|
|||||||
method = tokens[0];
|
method = tokens[0];
|
||||||
uri = tokens[1];
|
uri = tokens[1];
|
||||||
version = tokens[2];
|
version = tokens[2];
|
||||||
expect = HEADER_LINE;
|
expect = HEADER_LINE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -363,7 +363,7 @@ namespace http
|
|||||||
return false; /* no header */
|
return false; /* no header */
|
||||||
if (it->second.find("gzip") != std::string::npos)
|
if (it->second.find("gzip") != std::string::npos)
|
||||||
return true; /* gotcha! */
|
return true; /* gotcha! */
|
||||||
if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos)
|
if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -409,7 +409,7 @@ namespace http
|
|||||||
/* all ok */
|
/* all ok */
|
||||||
version = tokens[0];
|
version = tokens[0];
|
||||||
status = tokens[2];
|
status = tokens[2];
|
||||||
expect = HEADER_LINE;
|
expect = HEADER_LINE;
|
||||||
} else {
|
} else {
|
||||||
std::string line = str.substr(pos, eol - pos);
|
std::string line = str.substr(pos, eol - pos);
|
||||||
auto p = parse_header_line(line);
|
auto p = parse_header_line(line);
|
||||||
@@ -460,7 +460,7 @@ namespace http
|
|||||||
case 304: ptr = "Not Modified"; break;
|
case 304: ptr = "Not Modified"; break;
|
||||||
case 307: ptr = "Temporary Redirect"; break;
|
case 307: ptr = "Temporary Redirect"; break;
|
||||||
/* client error */
|
/* client error */
|
||||||
case 400: ptr = "Bad Request"; break;
|
case 400: ptr = "Bad Request"; break;
|
||||||
case 401: ptr = "Unauthorized"; break;
|
case 401: ptr = "Unauthorized"; break;
|
||||||
case 403: ptr = "Forbidden"; break;
|
case 403: ptr = "Forbidden"; break;
|
||||||
case 404: ptr = "Not Found"; break;
|
case 404: ptr = "Not Found"; break;
|
||||||
@@ -471,7 +471,7 @@ namespace http
|
|||||||
case 502: ptr = "Bad Gateway"; break;
|
case 502: ptr = "Bad Gateway"; break;
|
||||||
case 503: ptr = "Not Implemented"; break;
|
case 503: ptr = "Not Implemented"; break;
|
||||||
case 504: ptr = "Gateway Timeout"; break;
|
case 504: ptr = "Gateway Timeout"; break;
|
||||||
default: ptr = "Unknown Status"; break;
|
default: ptr = "Unknown Status"; break;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace http
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Merge HTTP response content with Transfer-Encoding: chunked
|
* @brief Merge HTTP response content with Transfer-Encoding: chunked
|
||||||
* @param in Input stream
|
* @param in Input stream
|
||||||
* @param out Output stream
|
* @param out Output stream
|
||||||
* @return true on success, false otherwise
|
* @return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
@@ -171,7 +171,7 @@ namespace i2p
|
|||||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
||||||
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
||||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
||||||
const uint8_t * replyTag, bool replyECIES)
|
const uint8_t * replyTag, bool replyECIES)
|
||||||
{
|
{
|
||||||
int cnt = excludedFloodfills.size ();
|
int cnt = excludedFloodfills.size ();
|
||||||
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
|
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
|
||||||
@@ -244,7 +244,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
||||||
{
|
{
|
||||||
if (!router) // we send own RouterInfo
|
if (!router) // we send own RouterInfo
|
||||||
router = context.GetSharedRouterInfo ();
|
router = context.GetSharedRouterInfo ();
|
||||||
@@ -629,7 +629,7 @@ namespace i2p
|
|||||||
// we send it to reply tunnel
|
// we send it to reply tunnel
|
||||||
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
|
i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -802,13 +802,8 @@ namespace i2p
|
|||||||
break;
|
break;
|
||||||
case eI2NPGarlic:
|
case eI2NPGarlic:
|
||||||
{
|
{
|
||||||
if (msg->from)
|
if (msg->from && msg->from->GetTunnelPool ())
|
||||||
{
|
msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
|
||||||
if (msg->from->GetTunnelPool ())
|
|
||||||
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;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace tunnel
|
|||||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from;
|
std::shared_ptr<i2p::tunnel::InboundTunnel> from;
|
||||||
|
|
||||||
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
|
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
|
||||||
offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header
|
offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header
|
||||||
|
|
||||||
// header accessors
|
// header accessors
|
||||||
uint8_t * GetHeader () { return GetBuffer (); };
|
uint8_t * GetHeader () { return GetBuffer (); };
|
||||||
@@ -274,8 +274,8 @@ namespace tunnel
|
|||||||
uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
|
uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
|
||||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
||||||
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
||||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
|
||||||
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
|
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
|
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||||
{
|
{
|
||||||
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
|
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
|
||||||
RAND_bytes (m_StandardIdentity.signingKey, padding);
|
RAND_bytes (m_StandardIdentity.signingKey, padding);
|
||||||
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
|
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
|
||||||
break;
|
break;
|
||||||
@@ -788,7 +788,7 @@ namespace data
|
|||||||
keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
|
keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
|
||||||
htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
|
htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
|
||||||
htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type
|
htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type
|
||||||
GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key
|
GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key
|
||||||
Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
|
Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
|
||||||
// recreate signer
|
// recreate signer
|
||||||
keys.m_Signer = nullptr;
|
keys.m_Signer = nullptr;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ namespace data
|
|||||||
CryptoKeyType GetCryptoKeyType () const;
|
CryptoKeyType GetCryptoKeyType () const;
|
||||||
void DropVerifier () const; // to save memory
|
void DropVerifier () const; // to save memory
|
||||||
|
|
||||||
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
||||||
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
||||||
|
|
||||||
static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
|
static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
|
||||||
@@ -222,7 +222,7 @@ namespace data
|
|||||||
RoutingDestination () {};
|
RoutingDestination () {};
|
||||||
virtual ~RoutingDestination () {};
|
virtual ~RoutingDestination () {};
|
||||||
|
|
||||||
virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0;
|
virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0;
|
||||||
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
|
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
|
||||||
virtual bool IsDestination () const = 0; // for garlic
|
virtual bool IsDestination () const = 0; // for garlic
|
||||||
|
|
||||||
|
|||||||
@@ -582,7 +582,7 @@ namespace data
|
|||||||
// helper for ExtractClientAuthData
|
// helper for ExtractClientAuthData
|
||||||
static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie)
|
static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie)
|
||||||
{
|
{
|
||||||
// try to find clientCookie_i for clientID_i = okm[44:51]
|
// try to find clientCookie_i for clientID_i = okm[44:51]
|
||||||
for (int i = 0; i < numClients; i++)
|
for (int i = 0; i < numClients; i++)
|
||||||
{
|
{
|
||||||
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
|
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
|
||||||
@@ -606,7 +606,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
|
const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
|
||||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||||
if (offset > len)
|
if (offset > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data");
|
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data");
|
||||||
@@ -632,7 +632,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
|
const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
|
||||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||||
if (offset > len)
|
if (offset > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
|
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
|
||||||
@@ -737,7 +737,7 @@ namespace data
|
|||||||
htobe64buf (m_Buffer + offset, ts);
|
htobe64buf (m_Buffer + offset, ts);
|
||||||
offset += 8; // end date
|
offset += 8; // end date
|
||||||
}
|
}
|
||||||
// we don't sign it yet. must be signed later on
|
// we don't sign it yet. must be signed later on
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len):
|
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len):
|
||||||
@@ -995,7 +995,7 @@ namespace data
|
|||||||
ek.GenerateKeys (); // esk and epk
|
ek.GenerateKeys (); // esk and epk
|
||||||
memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
|
memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
|
||||||
htobe16buf (authData, authKeys->size ()); authData += 2; // num clients
|
htobe16buf (authData, authKeys->size ()); authData += 2; // num clients
|
||||||
uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp
|
uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp
|
||||||
memcpy (authInput + 64, subcredential, 36);
|
memcpy (authInput + 64, subcredential, 36);
|
||||||
for (auto& it: *authKeys)
|
for (auto& it: *authKeys)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace log {
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/**
|
/**
|
||||||
* @brief Maps our log levels to syslog one
|
* @brief Maps our log levels to syslog one
|
||||||
* @return syslog priority LOG_*, as defined in syslog.h
|
* @return syslog priority LOG_*, as defined in syslog.h
|
||||||
*/
|
*/
|
||||||
static inline int GetSyslogPrio (enum LogLevel l) {
|
static inline int GetSyslogPrio (enum LogLevel l) {
|
||||||
@@ -113,11 +113,11 @@ namespace log {
|
|||||||
|
|
||||||
std::string str_tolower(std::string s) {
|
std::string str_tolower(std::string s) {
|
||||||
std::transform(s.begin(), s.end(), s.begin(),
|
std::transform(s.begin(), s.end(), s.begin(),
|
||||||
// static_cast<int(*)(int)>(std::tolower) // wrong
|
// static_cast<int(*)(int)>(std::tolower) // wrong
|
||||||
// [](int c){ return std::tolower(c); } // wrong
|
// [](int c){ return std::tolower(c); } // wrong
|
||||||
// [](char c){ return std::tolower(c); } // wrong
|
// [](char c){ return std::tolower(c); } // wrong
|
||||||
[](unsigned char c){ return std::tolower(c); } // correct
|
[](unsigned char c){ return std::tolower(c); } // correct
|
||||||
);
|
);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ namespace log {
|
|||||||
break;
|
break;
|
||||||
case eLogStdout:
|
case eLogStdout:
|
||||||
default:
|
default:
|
||||||
std::cout << TimeAsString(msg->timestamp)
|
std::cout << TimeAsString(msg->timestamp)
|
||||||
<< "@" << short_tid
|
<< "@" << short_tid
|
||||||
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
|
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
|
||||||
<< " - " << msg->text << std::endl;
|
<< " - " << msg->text << std::endl;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace log {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum LogType m_Destination;
|
enum LogType m_Destination;
|
||||||
enum LogLevel m_MinLevel;
|
enum LogLevel m_MinLevel;
|
||||||
std::shared_ptr<std::ostream> m_LogStream;
|
std::shared_ptr<std::ostream> m_LogStream;
|
||||||
std::string m_Logfile;
|
std::string m_Logfile;
|
||||||
@@ -75,7 +75,7 @@ namespace log {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Makes formatted string from unix timestamp
|
* @brief Makes formatted string from unix timestamp
|
||||||
* @param ts Second since epoch
|
* @param ts Second since epoch
|
||||||
*
|
*
|
||||||
* This function internally caches the result for last provided value
|
* This function internally caches the result for last provided value
|
||||||
*/
|
*/
|
||||||
@@ -86,52 +86,52 @@ namespace log {
|
|||||||
Log ();
|
Log ();
|
||||||
~Log ();
|
~Log ();
|
||||||
|
|
||||||
LogType GetLogType () { return m_Destination; };
|
LogType GetLogType () { return m_Destination; };
|
||||||
LogLevel GetLogLevel () { return m_MinLevel; };
|
LogLevel GetLogLevel () { return m_MinLevel; };
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets minimal allowed level for log messages
|
* @brief Sets minimal allowed level for log messages
|
||||||
* @param level String with wanted minimal msg level
|
* @param level String with wanted minimal msg level
|
||||||
*/
|
*/
|
||||||
void SetLogLevel (const std::string& level);
|
void SetLogLevel (const std::string& level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to logfile
|
* @brief Sets log destination to logfile
|
||||||
* @param path Path to logfile
|
* @param path Path to logfile
|
||||||
*/
|
*/
|
||||||
void SendTo (const std::string &path);
|
void SendTo (const std::string &path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to given output stream
|
* @brief Sets log destination to given output stream
|
||||||
* @param os Output stream
|
* @param os Output stream
|
||||||
*/
|
*/
|
||||||
void SendTo (std::shared_ptr<std::ostream> os);
|
void SendTo (std::shared_ptr<std::ostream> os);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets format for timestamps in log
|
* @brief Sets format for timestamps in log
|
||||||
* @param format String with timestamp format
|
* @param format String with timestamp format
|
||||||
*/
|
*/
|
||||||
void SetTimeFormat (std::string format) { m_TimeFormat = format; };
|
void SetTimeFormat (std::string format) { m_TimeFormat = format; };
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to syslog
|
* @brief Sets log destination to syslog
|
||||||
* @param name Wanted program name
|
* @param name Wanted program name
|
||||||
* @param facility Wanted log category
|
* @param facility Wanted log category
|
||||||
*/
|
*/
|
||||||
void SendTo (const char *name, int facility);
|
void SendTo (const char *name, int facility);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Format log message and write to output stream/syslog
|
* @brief Format log message and write to output stream/syslog
|
||||||
* @param msg Pointer to processed message
|
* @param msg Pointer to processed message
|
||||||
*/
|
*/
|
||||||
void Append(std::shared_ptr<i2p::log::LogMsg> &);
|
void Append(std::shared_ptr<i2p::log::LogMsg> &);
|
||||||
|
|
||||||
/** @brief Reopen log file */
|
/** @brief Reopen log file */
|
||||||
void Reopen();
|
void Reopen();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,8 +144,8 @@ namespace log {
|
|||||||
*/
|
*/
|
||||||
struct LogMsg {
|
struct LogMsg {
|
||||||
std::time_t timestamp;
|
std::time_t timestamp;
|
||||||
std::string text; /**< message text as single string */
|
std::string text; /**< message text as single string */
|
||||||
LogLevel level; /**< message level */
|
LogLevel level; /**< message level */
|
||||||
std::thread::id tid; /**< id of thread that generated message */
|
std::thread::id tid; /**< id of thread that generated message */
|
||||||
|
|
||||||
LogMsg (LogLevel lvl, std::time_t ts, std::string&& txt): timestamp(ts), text(std::move(txt)), level(lvl) {}
|
LogMsg (LogLevel lvl, std::time_t ts, std::string&& txt): timestamp(ts), text(std::move(txt)), level(lvl) {}
|
||||||
@@ -153,7 +153,7 @@ namespace log {
|
|||||||
|
|
||||||
Log & Logger();
|
Log & Logger();
|
||||||
|
|
||||||
typedef std::function<void (const std::string&)> ThrowFunction;
|
typedef std::function<void (const std::string&)> ThrowFunction;
|
||||||
ThrowFunction GetThrowFunction ();
|
ThrowFunction GetThrowFunction ();
|
||||||
void SetThrowFunction (ThrowFunction f);
|
void SetThrowFunction (ThrowFunction f);
|
||||||
} // log
|
} // log
|
||||||
|
|||||||
@@ -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,14 +59,14 @@ 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)
|
||||||
{
|
{
|
||||||
MixHash (sessionRequest + 32, 32); // encrypted payload
|
MixHash (sessionRequest + 32, 32); // encrypted payload
|
||||||
|
|
||||||
int paddingLength = sessionRequestLen - 64;
|
int paddingLength = sessionRequestLen - 64;
|
||||||
if (paddingLength > 0)
|
if (paddingLength > 0)
|
||||||
MixHash (sessionRequest + 64, paddingLength);
|
MixHash (sessionRequest + 64, paddingLength);
|
||||||
MixHash (epub, 32);
|
MixHash (epub, 32);
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ namespace transport
|
|||||||
// m3p2Len
|
// m3p2Len
|
||||||
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
|
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
|
||||||
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
|
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
|
||||||
htobe16buf (options + 4, m3p2Len);
|
htobe16buf (options + 4, m3p2Len);
|
||||||
// fill m3p2 payload (RouterInfo block)
|
// fill m3p2 payload (RouterInfo block)
|
||||||
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
|
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
|
||||||
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
||||||
@@ -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
|
||||||
@@ -318,7 +320,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
|
|
||||||
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
|
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
|
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
|
||||||
TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
|
TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
|
||||||
m_Server (server), m_Socket (m_Server.GetService ()),
|
m_Server (server), m_Socket (m_Server.GetService ()),
|
||||||
m_IsEstablished (false), m_IsTerminated (false),
|
m_IsEstablished (false), m_IsTerminated (false),
|
||||||
@@ -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
|
||||||
@@ -416,7 +418,7 @@ namespace transport
|
|||||||
void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
|
void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
|
||||||
{
|
{
|
||||||
if (m_NextReceivedBuffer && !m_IsReceiving &&
|
if (m_NextReceivedBuffer && !m_IsReceiving &&
|
||||||
ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
|
ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
|
||||||
{
|
{
|
||||||
delete[] m_NextReceivedBuffer;
|
delete[] m_NextReceivedBuffer;
|
||||||
m_NextReceivedBuffer = nullptr;
|
m_NextReceivedBuffer = nullptr;
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -487,7 +496,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
|
LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -540,7 +549,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
|
LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -748,7 +757,7 @@ namespace transport
|
|||||||
if (IsTerminated ()) return;
|
if (IsTerminated ()) return;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
const int one = 1;
|
const int one = 1;
|
||||||
setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
|
setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
|
||||||
#endif
|
#endif
|
||||||
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_NextReceivedLen, 2), boost::asio::transfer_all (),
|
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_NextReceivedLen, 2), boost::asio::transfer_all (),
|
||||||
std::bind(&NTCP2Session::HandleReceivedLength, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
std::bind(&NTCP2Session::HandleReceivedLength, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||||
@@ -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
|
||||||
@@ -1117,11 +1126,11 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (!m_SendKey ||
|
if (!m_SendKey ||
|
||||||
#if OPENSSL_SIPHASH
|
#if OPENSSL_SIPHASH
|
||||||
!m_SendMDCtx
|
!m_SendMDCtx
|
||||||
#else
|
#else
|
||||||
!m_SendSipKey
|
!m_SendSipKey
|
||||||
#endif
|
#endif
|
||||||
) return;
|
) return;
|
||||||
m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
|
m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
|
||||||
// termination block
|
// termination block
|
||||||
m_NextSendBuffer[2] = eNTCP2BlkTermination;
|
m_NextSendBuffer[2] = eNTCP2BlkTermination;
|
||||||
@@ -1155,7 +1164,7 @@ namespace transport
|
|||||||
else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
|
else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
|
LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
|
||||||
GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
|
GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1168,7 +1177,7 @@ namespace transport
|
|||||||
|
|
||||||
NTCP2Server::NTCP2Server ():
|
NTCP2Server::NTCP2Server ():
|
||||||
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
|
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
|
||||||
m_ProxyType(eNoProxy), m_Resolver(GetService ())
|
m_ProxyType(eNoProxy), m_Resolver(GetService ())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 ();
|
||||||
@@ -608,7 +620,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
// make router reachable back if too few routers or floodfills
|
// make router reachable back if too few routers or floodfills
|
||||||
if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS ||
|
if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS ||
|
||||||
(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
|
(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
|
||||||
it.second->SetUnreachable (false);
|
it.second->SetUnreachable (false);
|
||||||
// find & mark expired routers
|
// find & mark expired routers
|
||||||
if (!it.second->IsReachable () && it.second->IsSSU (false))
|
if (!it.second->IsReachable () && it.second->IsSSU (false))
|
||||||
@@ -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)
|
||||||
@@ -674,7 +688,7 @@ namespace data
|
|||||||
if (floodfill)
|
if (floodfill)
|
||||||
{
|
{
|
||||||
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
|
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
|
||||||
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
||||||
direct = false; // floodfill can't be reached directly
|
direct = false; // floodfill can't be reached directly
|
||||||
if (direct)
|
if (direct)
|
||||||
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
|
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
|
||||||
@@ -957,7 +971,7 @@ namespace data
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
||||||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
||||||
{
|
{
|
||||||
auto router = FindRouter (ident);
|
auto router = FindRouter (ident);
|
||||||
if (router)
|
if (router)
|
||||||
@@ -1122,7 +1136,7 @@ namespace data
|
|||||||
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
||||||
m_PublishReplyToken = replyToken;
|
m_PublishReplyToken = replyToken;
|
||||||
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
||||||
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
||||||
// send directly
|
// send directly
|
||||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
||||||
else
|
else
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace data
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
|
void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
|
||||||
std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
|
std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
|
||||||
void ManageRequests ();
|
void ManageRequests ();
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace util
|
|||||||
|
|
||||||
void Put (Element e)
|
void Put (Element e)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
m_Queue.push (std::move(e));
|
m_Queue.push (std::move(e));
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
if (!vec.empty ())
|
if (!vec.empty ())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
for (const auto& it: vec)
|
for (const auto& it: vec)
|
||||||
m_Queue.push (std::move(it));
|
m_Queue.push (std::move(it));
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
@@ -82,8 +82,9 @@ namespace data
|
|||||||
*/
|
*/
|
||||||
int Reseeder::ReseedFromServers ()
|
int Reseeder::ReseedFromServers ()
|
||||||
{
|
{
|
||||||
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);
|
||||||
@@ -186,31 +187,31 @@ namespace data
|
|||||||
}
|
}
|
||||||
s.seekg (1, std::ios::cur); // su3 file format version
|
s.seekg (1, std::ios::cur); // su3 file format version
|
||||||
SigningKeyType signatureType;
|
SigningKeyType signatureType;
|
||||||
s.read ((char *)&signatureType, 2); // signature type
|
s.read ((char *)&signatureType, 2); // signature type
|
||||||
signatureType = be16toh (signatureType);
|
signatureType = be16toh (signatureType);
|
||||||
uint16_t signatureLength;
|
uint16_t signatureLength;
|
||||||
s.read ((char *)&signatureLength, 2); // signature length
|
s.read ((char *)&signatureLength, 2); // signature length
|
||||||
signatureLength = be16toh (signatureLength);
|
signatureLength = be16toh (signatureLength);
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t versionLength;
|
uint8_t versionLength;
|
||||||
s.read ((char *)&versionLength, 1); // version length
|
s.read ((char *)&versionLength, 1); // version length
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t signerIDLength;
|
uint8_t signerIDLength;
|
||||||
s.read ((char *)&signerIDLength, 1); // signer ID length
|
s.read ((char *)&signerIDLength, 1); // signer ID length
|
||||||
uint64_t contentLength;
|
uint64_t contentLength;
|
||||||
s.read ((char *)&contentLength, 8); // content length
|
s.read ((char *)&contentLength, 8); // content length
|
||||||
contentLength = be64toh (contentLength);
|
contentLength = be64toh (contentLength);
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t fileType;
|
uint8_t fileType;
|
||||||
s.read ((char *)&fileType, 1); // file type
|
s.read ((char *)&fileType, 1); // file type
|
||||||
if (fileType != 0x00) // zip file
|
if (fileType != 0x00) // zip file
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
|
LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t contentType;
|
uint8_t contentType;
|
||||||
s.read ((char *)&contentType, 1); // content type
|
s.read ((char *)&contentType, 1); // content type
|
||||||
if (contentType != 0x03) // reseed data
|
if (contentType != 0x03) // reseed data
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
|
LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
|
||||||
@@ -687,7 +688,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
boost::asio::ip::tcp::endpoint ep = *it;
|
boost::asio::ip::tcp::endpoint ep = *it;
|
||||||
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
||||||
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
||||||
{
|
{
|
||||||
s.lowest_layer().connect (ep, ecode);
|
s.lowest_layer().connect (ep, ecode);
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -65,15 +65,18 @@ namespace i2p
|
|||||||
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
||||||
if (port == 9150) port = 9151; // Tor browser
|
if (port == 9150) port = 9151; // Tor browser
|
||||||
}
|
}
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
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 ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
bool nat; i2p::config::GetOption("nat", nat);
|
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
||||||
|
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,13 +340,66 @@ 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;
|
||||||
for (auto& address : m_RouterInfo.GetAddresses ())
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
{
|
{
|
||||||
if (address->host != host && address->IsCompatible (host) &&
|
if (address->host != host && address->IsCompatible (host) &&
|
||||||
!i2p::util::net::IsYggdrasilAddress (address->host))
|
!i2p::util::net::IsYggdrasilAddress (address->host))
|
||||||
{
|
{
|
||||||
address->host = host;
|
address->host = host;
|
||||||
if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
||||||
@@ -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)
|
||||||
foundSSU = true;
|
{
|
||||||
else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
case i2p::data::RouterInfo::eTransportSSU:
|
||||||
foundNTCP2 = true;
|
foundSSU = true;
|
||||||
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
|
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)
|
||||||
foundSSU = true;
|
{
|
||||||
else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
case i2p::data::RouterInfo::eTransportSSU:
|
||||||
foundNTCP2 = true;
|
foundSSU = true;
|
||||||
|
break;
|
||||||
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
|
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
|
||||||
@@ -740,7 +883,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
|
std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
|
||||||
if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
|
if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
|
||||||
m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
||||||
{
|
{
|
||||||
// update keys
|
// update keys
|
||||||
LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
|
LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
|
||||||
@@ -792,7 +935,31 @@ namespace i2p
|
|||||||
UpdateNTCP2Address (true); // enable NTCP2
|
UpdateNTCP2Address (true); // enable NTCP2
|
||||||
}
|
}
|
||||||
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,10 +146,11 @@ 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; };
|
||||||
bool IsPeerTesting () const { return caps & eSSUTesting; };
|
bool IsPeerTesting () const { return caps & eSSUTesting; };
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user