mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
410 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
436a3e7f54 | ||
|
|
7015bad905 | ||
|
|
cf8665748b | ||
|
|
1b8da90cbb | ||
|
|
6012585067 | ||
|
|
f162876600 | ||
|
|
6555ae5b0a | ||
|
|
f5af059ef4 | ||
|
|
cb8651ec68 | ||
|
|
7c0b0a4e3e | ||
|
|
880d1a7ccd | ||
|
|
744b25190a | ||
|
|
3792bb4928 | ||
|
|
9049902ced | ||
|
|
5f93dc72fd | ||
|
|
09dadd7e01 | ||
|
|
60b92f98db | ||
|
|
97f315d488 | ||
|
|
f3676d7f18 | ||
|
|
742dbdb68a | ||
|
|
2d59c968ca | ||
|
|
ad22247c9e | ||
|
|
f38920c338 | ||
|
|
8f90b21a5d | ||
|
|
ff0e6813c6 | ||
|
|
fa5e4d57fd | ||
|
|
876973f071 | ||
|
|
b994af9209 | ||
|
|
1f6cde652e | ||
|
|
3bf6db1c08 | ||
|
|
e70ffc9d7c | ||
|
|
065cfe3b9d | ||
|
|
def9873a70 | ||
|
|
618aa26454 | ||
|
|
924a7bc533 | ||
|
|
ef85277a1b | ||
|
|
876375f2c3 | ||
|
|
f70ee480ba | ||
|
|
6d88c3ab05 | ||
|
|
57c969b0ed | ||
|
|
ae58a7007b | ||
|
|
11c924bbe7 | ||
|
|
8bab4f60ef | ||
|
|
bef9a54f4a | ||
|
|
288b19c3f7 | ||
|
|
40f7e9d33e | ||
|
|
fab53dda66 | ||
|
|
a4e8bf9857 | ||
|
|
2cdf84cdab | ||
|
|
fbe83f729d | ||
|
|
4371a084ec | ||
|
|
d13f58088a | ||
|
|
f75bef7c03 | ||
|
|
3d7e93a688 | ||
|
|
a4dda304d2 | ||
|
|
124c3ef2d7 | ||
|
|
c3a2fca76a | ||
|
|
b60ebfe1c6 | ||
|
|
1d7639b3f4 | ||
|
|
2d972752ff | ||
|
|
616f0b2a21 | ||
|
|
94659ba890 | ||
|
|
d65bc068de | ||
|
|
1ca0354cf2 | ||
|
|
b1fcd4d27b | ||
|
|
74aa07eba8 | ||
|
|
d1a98212ee | ||
|
|
75a31c79ae | ||
|
|
da0b36cb91 | ||
|
|
aa206d034d | ||
|
|
765ab60753 | ||
|
|
44e4ec573d | ||
|
|
0ed793d6d0 | ||
|
|
272e25ff07 | ||
|
|
63127ab181 | ||
|
|
004f3532a0 | ||
|
|
abe1af7b4f | ||
|
|
01df1647bc | ||
|
|
9d8eaf0ccb | ||
|
|
7e4c33d27e | ||
|
|
c164601acf | ||
|
|
3b32da4f5c | ||
|
|
1bc3de8df4 | ||
|
|
374e0cbbc3 | ||
|
|
313921da56 | ||
|
|
2d0e219197 | ||
|
|
dc64d1738a | ||
|
|
89e8d99294 | ||
|
|
66a238045f | ||
|
|
33b82b5669 | ||
|
|
f59d509b15 | ||
|
|
6966539b86 | ||
|
|
0e5dc15005 | ||
|
|
a74f685a5d | ||
|
|
05c7aacfa5 | ||
|
|
ace80c29e7 | ||
|
|
bfb1380dd2 | ||
|
|
ea19802d3f | ||
|
|
fef4f13b8f | ||
|
|
c4fc0f4ecf | ||
|
|
ba3acdac75 | ||
|
|
aad2d68edb | ||
|
|
9e5935aea5 | ||
|
|
129b4a2135 | ||
|
|
82649ab2a7 | ||
|
|
1ba5d25819 | ||
|
|
daa3f8699b | ||
|
|
df7fda9e0c | ||
|
|
484f69f16b | ||
|
|
7c8280934a | ||
|
|
85902b358a | ||
|
|
5931cb59ab | ||
|
|
fd73aab7d0 | ||
|
|
d13fbe5549 | ||
|
|
ed4c00e4f4 | ||
|
|
07282ec39f | ||
|
|
2d998aba43 | ||
|
|
2e0019c8c8 | ||
|
|
96e9608036 | ||
|
|
9d5bb1b2b6 | ||
|
|
67dab9b6d2 | ||
|
|
6fc5f88a3b | ||
|
|
e0cec79ad6 | ||
|
|
1a9e11d86d | ||
|
|
1235d18d67 | ||
|
|
8f25b66760 | ||
|
|
2bc0850b0f | ||
|
|
29176dd9bf | ||
|
|
aedcd1bcc0 | ||
|
|
b1262d54de | ||
|
|
bc4a97774f | ||
|
|
ee3cd44f97 | ||
|
|
726bd0d63b | ||
|
|
ce9640773c | ||
|
|
7ce92118e4 | ||
|
|
e12c5fe007 | ||
|
|
86ff0d86db | ||
|
|
b4236b04c6 | ||
|
|
d34dc397e8 | ||
|
|
f2e4d5f06c | ||
|
|
da7e2f2580 | ||
|
|
e07a20a771 | ||
|
|
ae1b1da342 | ||
|
|
a61d7fe115 | ||
|
|
b4d1e89696 | ||
|
|
a0d90717c3 | ||
|
|
5c2f1f36e8 | ||
|
|
0b084956e6 | ||
|
|
8c61e7d227 | ||
|
|
d7342586a6 | ||
|
|
242e3d007c | ||
|
|
d4b6485102 | ||
|
|
370ab6307a | ||
|
|
83b10fba62 | ||
|
|
1921bce4c7 | ||
|
|
669fb62a54 | ||
|
|
1a5920ee47 | ||
|
|
9c6e3ff1d7 | ||
|
|
ca78601ada | ||
|
|
2edce12759 | ||
|
|
ccc604c0f4 | ||
|
|
d3bf8c2417 | ||
|
|
dc774f0f94 | ||
|
|
f2059947bf | ||
|
|
eccd5b6ff0 | ||
|
|
776dc7ec52 | ||
|
|
082c4f1104 | ||
|
|
06a7e181cd | ||
|
|
bf91e16b5d | ||
|
|
65945b3462 | ||
|
|
31f0c35077 | ||
|
|
fc2dc9a019 | ||
|
|
04645aacc4 | ||
|
|
c91a8711e3 | ||
|
|
7373dae026 | ||
|
|
ca3b819151 | ||
|
|
ba79b94e06 | ||
|
|
bfc3acb834 | ||
|
|
ac67cd7f9a | ||
|
|
9a2c6a7619 | ||
|
|
3100d4f902 | ||
|
|
aace200899 | ||
|
|
a843165cb4 | ||
|
|
36473e3889 | ||
|
|
e2fcab34b7 | ||
|
|
abdf92c084 | ||
|
|
32fc6482cc | ||
|
|
ce14ea6fe5 | ||
|
|
2f57013e02 | ||
|
|
ad84944d20 | ||
|
|
0ab95b1b87 | ||
|
|
58153c3579 | ||
|
|
746f53ba07 | ||
|
|
ff971563db | ||
|
|
242fb7db14 | ||
|
|
ad36738f57 | ||
|
|
c833b16544 | ||
|
|
1c5b350c2b | ||
|
|
9301e39af7 | ||
|
|
86e3b977e4 | ||
|
|
bc330ff0ea | ||
|
|
771480e368 | ||
|
|
c875ff923a | ||
|
|
3dfb44de31 | ||
|
|
2266c3877c | ||
|
|
f4486bc075 | ||
|
|
0436a65baa | ||
|
|
30d6bd144b | ||
|
|
d8381e9486 | ||
|
|
feaecbe177 | ||
|
|
85d796f906 | ||
|
|
0a3af12ee9 | ||
|
|
3925540517 | ||
|
|
3b630fe546 | ||
|
|
c69c4ae8a0 | ||
|
|
b4369470cb | ||
|
|
4a44b18b97 | ||
|
|
2bd6daeb8d | ||
|
|
1ae98b7fe1 | ||
|
|
44ca315c75 | ||
|
|
af20b13c7a | ||
|
|
1f6be38145 | ||
|
|
8b3a7486c7 | ||
|
|
62cd9fffa3 | ||
|
|
7e874eaa7c | ||
|
|
1c7780a423 | ||
|
|
07b77443dd | ||
|
|
4ba1be2dc0 | ||
|
|
6362a7bba5 | ||
|
|
1740715c00 | ||
|
|
21501cbf81 | ||
|
|
d5f3d6111e | ||
|
|
bd04f92087 | ||
|
|
942b2b05e7 | ||
|
|
b8064b9b4b | ||
|
|
f94d03465a | ||
|
|
4e7aafeec1 | ||
|
|
d820b8036e | ||
|
|
3907c17cf5 | ||
|
|
b12fa97a38 | ||
|
|
b9b431e82d | ||
|
|
9f2a2e44a3 | ||
|
|
aaf6c1ea8b | ||
|
|
b2f0278180 | ||
|
|
530eba1b91 | ||
|
|
812d312a9e | ||
|
|
5d256e1d80 | ||
|
|
d02a0c9b3a | ||
|
|
bdbd060229 | ||
|
|
bf04962994 | ||
|
|
33f2ddb696 | ||
|
|
e444519889 | ||
|
|
a47aa8c282 | ||
|
|
0c29aeb9be | ||
|
|
2b4a91cc80 | ||
|
|
9ffc4155dd | ||
|
|
979282a0d4 | ||
|
|
c63818f355 | ||
|
|
c400372a79 | ||
|
|
56f3bdd746 | ||
|
|
cc0367b079 | ||
|
|
e41bbcb2bb | ||
|
|
b35f43d79e | ||
|
|
e9f11e204e | ||
|
|
1b63c9f6ad | ||
|
|
21d99e355c | ||
|
|
f0adbcd5e1 | ||
|
|
bfcf3cfbf1 | ||
|
|
ef5495bfb2 | ||
|
|
c93ee0d65d | ||
|
|
db3e48a81a | ||
|
|
d9b87e877d | ||
|
|
b6175132eb | ||
|
|
57d6c7a3b3 | ||
|
|
d65a282e9d | ||
|
|
801ecaa41c | ||
|
|
49bf735c22 | ||
|
|
cb55944ff6 | ||
|
|
9c225f8d77 | ||
|
|
365fce922c | ||
|
|
fbfc5ecda3 | ||
|
|
4001f48a28 | ||
|
|
22124c25d1 | ||
|
|
17f5bcbd1c | ||
|
|
b7ebb3ea3d | ||
|
|
387830e07a | ||
|
|
da94d40738 | ||
|
|
417b5ed6cc | ||
|
|
005581ef62 | ||
|
|
050390c5c4 | ||
|
|
2648f1ba89 | ||
|
|
d9d31521f9 | ||
|
|
8e24d1b909 | ||
|
|
36fc0daa12 | ||
|
|
44d3854a13 | ||
|
|
1dbc35f13d | ||
|
|
11691fb44a | ||
|
|
acc5592f59 | ||
|
|
614921276e | ||
|
|
3f45a11f12 | ||
|
|
e3464add50 | ||
|
|
18bb4a71c2 | ||
|
|
85e9da82b0 | ||
|
|
99d046ca11 | ||
|
|
0b372a344c | ||
|
|
ffa0f0afd9 | ||
|
|
e21dac21c8 | ||
|
|
0108745065 | ||
|
|
e2a1cd12c3 | ||
|
|
f6ff232106 | ||
|
|
b0c690d836 | ||
|
|
7246624983 | ||
|
|
471c46ad8e | ||
|
|
59032d515b | ||
|
|
d218c9a983 | ||
|
|
243f6e755b | ||
|
|
67b76809ea | ||
|
|
77231bfc6c | ||
|
|
e614226926 | ||
|
|
65e15d74fc | ||
|
|
7ceb81cc83 | ||
|
|
d3f7eea0a3 | ||
|
|
c2f13a1496 | ||
|
|
faae2709d9 | ||
|
|
d595006d1f | ||
|
|
a8d23b5439 | ||
|
|
cfda807057 | ||
|
|
c601a2986f | ||
|
|
8483464aab | ||
|
|
dca69e9b6e | ||
|
|
9450dc84da | ||
|
|
3a2724ec58 | ||
|
|
ee84291997 | ||
|
|
fd9229c467 | ||
|
|
ac5a4fe70f | ||
|
|
873b4f3178 | ||
|
|
beb5d26e6d | ||
|
|
221b7cbf76 | ||
|
|
7d34f1e883 | ||
|
|
208707c00b | ||
|
|
cb41c04551 | ||
|
|
730c6aff11 | ||
|
|
3d40c7603d | ||
|
|
dec7a9a01c | ||
|
|
5f42888b61 | ||
|
|
489c38ec5b | ||
|
|
949fc47f31 | ||
|
|
4d85079372 | ||
|
|
335f9394a5 | ||
|
|
f939a7b349 | ||
|
|
09fdb068d2 | ||
|
|
024c29b180 | ||
|
|
2b0d1a2190 | ||
|
|
d0d71c93af | ||
|
|
da1e52357f | ||
|
|
a05a54b38e | ||
|
|
a0685d804d | ||
|
|
954781262c | ||
|
|
0777bad2c3 | ||
|
|
3159b06988 | ||
|
|
e7ff6fbffc | ||
|
|
6fec92c012 | ||
|
|
e50abbb250 | ||
|
|
8e25226574 | ||
|
|
9636d82b37 | ||
|
|
c3aa6b9cda | ||
|
|
3ef8b3dcbb | ||
|
|
c41554109b | ||
|
|
67b94d3533 | ||
|
|
d52c0633c8 | ||
|
|
4e4c117023 | ||
|
|
cb0d30cf42 | ||
|
|
2d65402ced | ||
|
|
e15b2cc5d6 | ||
|
|
c024905d56 | ||
|
|
6f17624742 | ||
|
|
6f2e6ed887 | ||
|
|
5f1e66d64b | ||
|
|
1f31fdc257 | ||
|
|
df9965e129 | ||
|
|
61e9c31f0d | ||
|
|
a0b35ebd3e | ||
|
|
951ec567c7 | ||
|
|
31494267e5 | ||
|
|
70e4cbc023 | ||
|
|
8d903a09e2 | ||
|
|
63451fb781 | ||
|
|
1e609acb03 | ||
|
|
69194118df | ||
|
|
0f309377ec | ||
|
|
49a19a52c8 | ||
|
|
1a39f7e5c6 | ||
|
|
a5fed64f38 | ||
|
|
79858d4372 | ||
|
|
61897ae16c | ||
|
|
5e0a8ed232 | ||
|
|
5993cc857a | ||
|
|
6a0174293e | ||
|
|
44bb8f6f16 | ||
|
|
a33cad4b70 | ||
|
|
0639cce784 | ||
|
|
a8f227f759 | ||
|
|
f077836bf5 | ||
|
|
6d7847f2df | ||
|
|
221c14cf0e | ||
|
|
6735b2686b | ||
|
|
55ff6beb7d | ||
|
|
4ae41513ac | ||
|
|
438a225487 | ||
|
|
e135696530 |
20
.github/workflows/build-freebsd.yml
vendored
Normal file
20
.github/workflows/build-freebsd.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Build on FreeBSD
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: macos-latest
|
||||||
|
name: with UPnP
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Test in FreeBSD
|
||||||
|
id: test
|
||||||
|
uses: vmactions/freebsd-vm@v0.1.2
|
||||||
|
with:
|
||||||
|
usesh: true
|
||||||
|
prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
|
||||||
|
gmake -j2
|
||||||
20
.github/workflows/build-osx.yml
vendored
Normal file
20
.github/workflows/build-osx.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Build on OSX
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: With USE_UPNP=${{ matrix.with_upnp }}
|
||||||
|
runs-on: macOS-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
with_upnp: ['yes', 'no']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: install packages
|
||||||
|
run: |
|
||||||
|
brew update
|
||||||
|
brew install boost miniupnpc openssl@1.1
|
||||||
|
- name: build application
|
||||||
|
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3
|
||||||
35
.github/workflows/build-windows.yml
vendored
Normal file
35
.github/workflows/build-windows.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: Build on Windows
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: msys2 {0}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Building for ${{ matrix.arch }}
|
||||||
|
runs-on: windows-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
include: [
|
||||||
|
{ msystem: MINGW64, arch: x86_64 },
|
||||||
|
{ msystem: MINGW32, arch: i686 }
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup MSYS2
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: ${{ matrix.msystem }}
|
||||||
|
install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
|
||||||
|
update: true
|
||||||
|
- name: build application
|
||||||
|
run: |
|
||||||
|
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
|
||||||
|
make USE_UPNP=yes DEBUG=no -j3
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
path: i2pd.exe
|
||||||
21
.github/workflows/build.yml
vendored
Normal file
21
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: Build on Ubuntu
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: With USE_UPNP=${{ matrix.with_upnp }}
|
||||||
|
runs-on: ubuntu-16.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
with_upnp: ['yes', 'no']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: install packages
|
||||||
|
run: |
|
||||||
|
sudo add-apt-repository ppa:mhier/libboost-latest
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||||
|
- name: build application
|
||||||
|
run: make USE_UPNP=${{ matrix.with_upnp }} -j3
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,11 +3,12 @@
|
|||||||
router.info
|
router.info
|
||||||
router.keys
|
router.keys
|
||||||
i2p
|
i2p
|
||||||
libi2pd.so
|
|
||||||
netDb
|
netDb
|
||||||
/i2pd
|
/i2pd
|
||||||
/libi2pd.a
|
/libi2pd.a
|
||||||
/libi2pdclient.a
|
/libi2pdclient.a
|
||||||
|
/libi2pd.so
|
||||||
|
/libi2pdclient.so
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
.gitmodules
vendored
0
.gitmodules
vendored
140
ChangeLog
140
ChangeLog
@@ -1,6 +1,146 @@
|
|||||||
# 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.37.0] - 2021-03-15
|
||||||
|
### Added
|
||||||
|
- Address registration line for reg.i2p and stats.i2p through the web console
|
||||||
|
- "4" and "6" caps for addresses without published IP address
|
||||||
|
- Mesh and Proxy network statuses
|
||||||
|
- Symmetric NAT network status error
|
||||||
|
- Bind server tunnel connection to specified address
|
||||||
|
- lookuplocal BOB extended command
|
||||||
|
- address4 and address6 parameters to bind outgoing connections to
|
||||||
|
- Rekey of low-bandwidth routers to ECIES
|
||||||
|
- Popup notification windows when unable to parse config for Windows
|
||||||
|
### Changed
|
||||||
|
- Floodfills with "U" cap are not ignored anymore
|
||||||
|
- Check transports reachability between tunnel peers and between router and floodfill
|
||||||
|
- NTCP2 and reseed HTTP proxy support authorization now
|
||||||
|
- Show actual IP addresses for proxy connections
|
||||||
|
- Publish and handle SSU addreses without host
|
||||||
|
- Outbound tunnel endpoint must be ipv4 compatible
|
||||||
|
- Logging optimization
|
||||||
|
- Removed Windows service
|
||||||
|
### Fixed
|
||||||
|
- Incoming SSU session terminates after 5 seconds
|
||||||
|
- Outgoing NTCP2 ipv4 session even if ipv4 is disabled
|
||||||
|
- No incoming Yggdrasil connection if connected through NTCP2 proxy
|
||||||
|
- Race condition between tunnel build and floodfill requests decryption for ECIES routers
|
||||||
|
- Numeric bandwidth limitation
|
||||||
|
- Yggdrasil for Android
|
||||||
|
|
||||||
|
## [2.36.0] - 2021-02-15
|
||||||
|
### Added
|
||||||
|
- Encrypted lookup and publications to ECIES-x25519 floodfiils
|
||||||
|
- Yggdrasil transports and reseeds
|
||||||
|
- Dump addressbook in hosts.txt format
|
||||||
|
- Request RouterInfo through exploratory tunnels if direct connection to fllodfill is not possible
|
||||||
|
- Threads naming
|
||||||
|
- Check if public x25519 key is valid
|
||||||
|
- ECIES-X25519-AEAD-Ratchet for shared local destination
|
||||||
|
- LeaseSet creation timeout for I2CP session
|
||||||
|
- Resend RouterInfo after some interval for longer NTCP2 sessions
|
||||||
|
- Select reachable router of inbound tunnel gateway
|
||||||
|
- Reseed if no compatible routers in netdb
|
||||||
|
- Refresh on swipe in Android webconsole
|
||||||
|
### Changed
|
||||||
|
- reg.i2p for default addressbook instead inr.i2p
|
||||||
|
- ECIES-x25519 (crypto type 4) for new routers
|
||||||
|
- Try to connect to all compatible addresses from peer's RouterInfo
|
||||||
|
- Replace LeaseSet completely if store type changes
|
||||||
|
- Try ECIES-X25519-AEAD-Ratchet tag before ElGamal
|
||||||
|
- Don't detach ECIES-X25519-AEAD-Ratchet session from destination immediately
|
||||||
|
- Viewport and styles on error in HTTP proxy
|
||||||
|
- Don't create notification when Windows taskbar restarted
|
||||||
|
- Cumulative SSU ACK bitfields
|
||||||
|
- limit tunnel length to 8 hops
|
||||||
|
- Limit tunnels quantity to 16
|
||||||
|
### Fixed
|
||||||
|
- Handling chunked HTTP response in addressbook
|
||||||
|
- Missing ECIES-X25519-AEAD-Ratchet tags for multiple streams with the same destination
|
||||||
|
- Correct NAME for NAMING REPLY in SAM
|
||||||
|
- SSU crash on termination
|
||||||
|
- Offline signature length for stream close packet
|
||||||
|
- Don't send updated LeaseSet through a terminated session
|
||||||
|
- Decryption of follow-on ECIES-X25519-AEAD-Ratchet NSR messages
|
||||||
|
- Non-confirmed LeaseSet is resent too late for ECIES-X25519-AEAD-Ratchet session
|
||||||
|
|
||||||
|
## [2.35.0] - 2020-11-30
|
||||||
|
### Added
|
||||||
|
- ECIES-x25519 routers
|
||||||
|
- Random intro keys for SSU
|
||||||
|
- Graceful shutdown timer for windows
|
||||||
|
- Send queue for I2CP messages
|
||||||
|
- Update DSA router keys to EdDSA
|
||||||
|
- TCP_QUICKACK for NTCP2 sockets on Linux
|
||||||
|
### Changed
|
||||||
|
- Exclude floodfills with DSA signatures and < 0.9.28
|
||||||
|
- Random intervals between tunnel tests and manage for tunnel pools
|
||||||
|
- Don't replace an addressbook record by one with DSA signature
|
||||||
|
- Publish RouterInfo after update
|
||||||
|
- Create paired inbound tunnels if no inbound tunnels yet
|
||||||
|
- Reseed servers list
|
||||||
|
### Fixed
|
||||||
|
- Transient signature length, if different from identity
|
||||||
|
- Terminate I2CP session if destroyed
|
||||||
|
- RouterInfo publishing confirmation
|
||||||
|
- Check if ECIES-X25519-AEAD-Ratchet session expired before generating more tags
|
||||||
|
- Correct block size for delivery type local for ECIES-X25519-AEAD-Ratchet
|
||||||
|
|
||||||
|
## [2.34.0] - 2020-10-27
|
||||||
|
### Added
|
||||||
|
- Ping responses for streaming
|
||||||
|
- STREAM FORWARD for SAM
|
||||||
|
- Tunnels through ECIES-x25519 routers
|
||||||
|
- Single thread for I2CP
|
||||||
|
- Shared transient destination between proxies
|
||||||
|
- Database lookups from ECIES destinations with ratchets response
|
||||||
|
- Handle WebDAV HTTP methods
|
||||||
|
- Don't try to connect or build tunnels if offline
|
||||||
|
- Validate IP when trying connect to remote peer
|
||||||
|
- Handle ICMP responses and WinAPI errors for SSU
|
||||||
|
### Changed
|
||||||
|
- Removed NTCP
|
||||||
|
- Dropped gcc 4.7 support
|
||||||
|
- Encyption type 0,4 by default for client tunnels
|
||||||
|
- Stripped out some HTTP header for HTTP server response
|
||||||
|
- HTTP 1.1 addressbook requests
|
||||||
|
- Set LeaseSet type to 3 for ratchets if not specified
|
||||||
|
- Handle SSU v4 and v6 messages in one thread
|
||||||
|
- Eliminate DH keys thread
|
||||||
|
### Fixed
|
||||||
|
- Random crashes on I2CP session disconnect
|
||||||
|
- Stream through racthets hangs if first SYN was not acked
|
||||||
|
- Check "Last-Modified" instead "If-Modified-Since" for addressbook reponse
|
||||||
|
- Trim behind ECIESx25519 tags
|
||||||
|
- Few bugs with Android main activity
|
||||||
|
- QT visual and layout issues
|
||||||
|
|
||||||
|
## [2.33.0] - 2020-08-24
|
||||||
|
### Added
|
||||||
|
- Shared transient addresses
|
||||||
|
- crypto.ratchet.inboundTags paramater
|
||||||
|
- Multiple encryption keys through I2CP
|
||||||
|
- Pre-calculated x25519 ephemeral keys
|
||||||
|
- Change datagram routing path if nothing comes back in 10 seconds
|
||||||
|
- Shared routing path for datagram session
|
||||||
|
### Changed
|
||||||
|
- UDP tunnels send mix of repliable and raw datagrams in bulk
|
||||||
|
- Encrypt SSU packet again upon resend
|
||||||
|
- Start new tunnel message if remaining buffer is too small
|
||||||
|
- Use LeaseSet2 for ECIES-X25519-AEAD-Ratchet automatically
|
||||||
|
- Save new ECIES-X25519-AEAD-Ratchet session with NSR tagset
|
||||||
|
- Generate random padding lengths for ECIES-X25519-AEAD-Ratchet in bulk
|
||||||
|
- Webconsole layout
|
||||||
|
- Reseed servers list
|
||||||
|
### Fixed
|
||||||
|
- Don't connect through terminated SAM destination
|
||||||
|
- Differentiate UDP server sessions by port
|
||||||
|
- ECIES-X25519-AEAD-Ratchet through I2CP
|
||||||
|
- Don't save invalid address to AddressBook
|
||||||
|
- ECDSA signatures names in SAM
|
||||||
|
- AppArmor profile
|
||||||
|
|
||||||
## [2.32.1] - 2020-06-02
|
## [2.32.1] - 2020-06-02
|
||||||
### Added
|
### Added
|
||||||
- Read explicit peers in tunnels config
|
- Read explicit peers in tunnels config
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2013-2015, The PurpleI2P Project
|
Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|||||||
40
Makefile
40
Makefile
@@ -4,17 +4,15 @@ ARLIB := libi2pd.a
|
|||||||
SHLIB_CLIENT := libi2pdclient.so
|
SHLIB_CLIENT := libi2pdclient.so
|
||||||
ARLIB_CLIENT := libi2pdclient.a
|
ARLIB_CLIENT := libi2pdclient.a
|
||||||
I2PD := i2pd
|
I2PD := i2pd
|
||||||
GREP := grep
|
|
||||||
DEPS := obj/make.dep
|
|
||||||
|
|
||||||
LIB_SRC_DIR := libi2pd
|
LIB_SRC_DIR := libi2pd
|
||||||
LIB_CLIENT_SRC_DIR := libi2pd_client
|
LIB_CLIENT_SRC_DIR := libi2pd_client
|
||||||
DAEMON_SRC_DIR := daemon
|
DAEMON_SRC_DIR := daemon
|
||||||
|
|
||||||
|
# import source files lists
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
|
|
||||||
USE_AESNI := yes
|
USE_AESNI := yes
|
||||||
USE_AVX := yes
|
|
||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
USE_MESHNET := no
|
USE_MESHNET := no
|
||||||
USE_UPNP := no
|
USE_UPNP := no
|
||||||
@@ -41,7 +39,7 @@ else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
|||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.bsd
|
include Makefile.bsd
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp
|
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Not supported platform)
|
$(error Not supported platform)
|
||||||
@@ -51,7 +49,12 @@ ifeq ($(USE_MESHNET),yes)
|
|||||||
NEEDED_CXXFLAGS += -DMESHNET
|
NEEDED_CXXFLAGS += -DMESHNET
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
|
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
|
||||||
|
|
||||||
|
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
||||||
|
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
||||||
|
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
||||||
|
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
|
||||||
|
|
||||||
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
|
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
|
||||||
|
|
||||||
@@ -63,6 +66,7 @@ mk_obj_dir:
|
|||||||
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
||||||
|
|
||||||
api: mk_obj_dir $(SHLIB) $(ARLIB)
|
api: mk_obj_dir $(SHLIB) $(ARLIB)
|
||||||
|
client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
||||||
@@ -72,32 +76,29 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
|||||||
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
||||||
## custom FLAGS to work at build-time.
|
## custom FLAGS to work at build-time.
|
||||||
|
|
||||||
deps: mk_obj_dir
|
|
||||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) -MM *.cpp > $(DEPS)
|
|
||||||
@sed -i -e '/\.o:/ s/^/obj\//' $(DEPS)
|
|
||||||
|
|
||||||
obj/%.o: %.cpp
|
obj/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(CPU_FLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
# '-' is 'ignore if missing' on first run
|
# '-' is 'ignore if missing' on first run
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
|
||||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
||||||
$(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
$(SHLIB): $(LIB_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
$(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||||
$(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^
|
ifneq ($(USE_STATIC),yes)
|
||||||
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB)
|
||||||
|
endif
|
||||||
|
|
||||||
$(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
$(ARLIB): $(LIB_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
$(ARLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@@ -123,11 +124,12 @@ doxygen:
|
|||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
.PHONY: deps
|
|
||||||
.PHONY: doxygen
|
.PHONY: doxygen
|
||||||
.PHONY: dist
|
.PHONY: dist
|
||||||
.PHONY: last-dist
|
.PHONY: last-dist
|
||||||
.PHONY: api
|
.PHONY: api
|
||||||
.PHONY: api_client
|
.PHONY: api_client
|
||||||
|
.PHONY: client
|
||||||
.PHONY: mk_obj_dir
|
.PHONY: mk_obj_dir
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
|
.PHONY: strip
|
||||||
|
|||||||
@@ -35,10 +35,7 @@ endif
|
|||||||
# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2
|
# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2
|
||||||
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
|
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
|
||||||
ifeq ($(USE_AESNI),yes)
|
ifeq ($(USE_AESNI),yes)
|
||||||
CXXFLAGS += -maes
|
CXXFLAGS += -D__AES__ -maes
|
||||||
endif
|
|
||||||
ifeq ($(USE_AVX),1)
|
|
||||||
CXXFLAGS += -mavx
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@@ -51,4 +48,4 @@ install: all
|
|||||||
@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/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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# set defaults instead redefine
|
# set defaults instead redefine
|
||||||
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation -Wno-psabi
|
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi
|
||||||
LDFLAGS ?= ${LD_DEBUG}
|
LDFLAGS ?= ${LD_DEBUG}
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time
|
||||||
@@ -15,7 +15,7 @@ ifeq ($(shell expr match $(CXX) 'clang'),5)
|
|||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
|
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9
|
else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9
|
||||||
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
|
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
@@ -33,7 +33,7 @@ ifeq ($(USE_STATIC),yes)
|
|||||||
# NOTE: on glibc you will get this warning:
|
# NOTE: on glibc you will get this warning:
|
||||||
# Using 'getaddrinfo' in statically linked applications requires at runtime
|
# Using 'getaddrinfo' in statically linked applications requires at runtime
|
||||||
# the shared libraries from the glibc version used for linking
|
# the shared libraries from the glibc version used for linking
|
||||||
LIBDIR := /usr/lib
|
LIBDIR := /usr/lib/$(SYS)
|
||||||
LDLIBS += $(LIBDIR)/libboost_system.a
|
LDLIBS += $(LIBDIR)/libboost_system.a
|
||||||
LDLIBS += $(LIBDIR)/libboost_date_time.a
|
LDLIBS += $(LIBDIR)/libboost_date_time.a
|
||||||
LDLIBS += $(LIBDIR)/libboost_filesystem.a
|
LDLIBS += $(LIBDIR)/libboost_filesystem.a
|
||||||
@@ -41,37 +41,24 @@ ifeq ($(USE_STATIC),yes)
|
|||||||
LDLIBS += $(LIBDIR)/libssl.a
|
LDLIBS += $(LIBDIR)/libssl.a
|
||||||
LDLIBS += $(LIBDIR)/libcrypto.a
|
LDLIBS += $(LIBDIR)/libcrypto.a
|
||||||
LDLIBS += $(LIBDIR)/libz.a
|
LDLIBS += $(LIBDIR)/libz.a
|
||||||
LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl
|
ifeq ($(USE_UPNP),yes)
|
||||||
USE_AESNI := no
|
LDLIBS += $(LIBDIR)/libminiupnpc.a
|
||||||
|
endif
|
||||||
|
LDLIBS += -lpthread -ldl
|
||||||
else
|
else
|
||||||
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
|
||||||
|
|
||||||
# UPNP Support (miniupnpc 1.5 and higher)
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
CXXFLAGS += -DUSE_UPNP
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
|
||||||
LDLIBS += $(LIBDIR)/libminiupnpc.a
|
|
||||||
else
|
|
||||||
LDLIBS += -lminiupnpc
|
LDLIBS += -lminiupnpc
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),yes)
|
# UPNP Support (miniupnpc 1.5 and higher)
|
||||||
#check if AES-NI is supported by CPU
|
ifeq ($(USE_UPNP),yes)
|
||||||
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
|
NEEDED_CXXFLAGS += -DUSE_UPNP
|
||||||
machine := $(shell uname -m)
|
|
||||||
ifeq ($(machine), aarch64)
|
|
||||||
CXXFLAGS += -DARM64AES
|
|
||||||
else
|
|
||||||
CPU_FLAGS += -maes
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AVX),yes)
|
ifeq ($(USE_AESNI),yes)
|
||||||
#check if AVX supported by CPU
|
ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that
|
||||||
ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0)
|
NEEDED_CXXFLAGS += -D__AES__ -maes
|
||||||
CPU_FLAGS += -mavx
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
USE_WIN32_APP=yes
|
# Build application with GUI (tray, main window)
|
||||||
CXX = g++
|
USE_WIN32_APP := yes
|
||||||
|
|
||||||
WINDRES = windres
|
WINDRES = windres
|
||||||
CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
|
|
||||||
INCFLAGS = -Idaemon -I.
|
CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse
|
||||||
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
|
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
|
||||||
|
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc
|
||||||
|
|
||||||
# detect proper flag for c++11 support by compilers
|
# detect proper flag for c++11 support by compilers
|
||||||
CXXVER := $(shell $(CXX) -dumpversion)
|
CXXVER := $(shell $(CXX) -dumpversion)
|
||||||
@@ -38,29 +40,21 @@ LDLIBS += \
|
|||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-lole32 \
|
-lole32 \
|
||||||
-luuid \
|
-luuid \
|
||||||
-lstdc++ \
|
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
ifeq ($(USE_WIN32_APP), yes)
|
ifeq ($(USE_WIN32_APP), yes)
|
||||||
CXXFLAGS += -DWIN32_APP
|
NEEDED_CXXFLAGS += -DWIN32_APP
|
||||||
LDFLAGS += -mwindows
|
LDFLAGS += -mwindows
|
||||||
DAEMON_RC += Win32/Resource.rc
|
DAEMON_RC += Win32/Resource.rc
|
||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_WINXP_FLAGS), yes)
|
ifeq ($(USE_WINXP_FLAGS), yes)
|
||||||
CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# don't change following line to ifeq ($(USE_AESNI),yes) !!!
|
ifeq ($(USE_AESNI),yes)
|
||||||
ifeq ($(USE_AESNI),1)
|
NEEDED_CXXFLAGS += -D__AES__ -maes
|
||||||
CPU_FLAGS += -maes
|
|
||||||
else
|
|
||||||
CPU_FLAGS += -msse
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_AVX),1)
|
|
||||||
CPU_FLAGS += -mavx
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_ASLR),yes)
|
ifeq ($(USE_ASLR),yes)
|
||||||
|
|||||||
@@ -22,12 +22,8 @@ ifeq ($(USE_UPNP),yes)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),1)
|
ifeq ($(USE_AESNI),yes)
|
||||||
CXXFLAGS += -maes
|
CXXFLAGS += -D__AES__ -maes
|
||||||
else
|
else
|
||||||
CXXFLAGS += -msse
|
CXXFLAGS += -msse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AVX),1)
|
|
||||||
CXXFLAGS += -mavx
|
|
||||||
endif
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
[](https://repology.org/project/i2pd/versions)
|
[](https://repology.org/project/i2pd/versions)
|
||||||
[](https://hub.docker.com/r/purplei2p/i2pd)
|
[](https://hub.docker.com/r/purplei2p/i2pd)
|
||||||
|
|
||||||
|
*note: i2pd for Android can be found in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository and with Qt GUI in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository*
|
||||||
|
|
||||||
i2pd
|
i2pd
|
||||||
====
|
====
|
||||||
|
|
||||||
@@ -53,6 +55,8 @@ Building
|
|||||||
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
||||||
i2pd from source on your OS.
|
i2pd from source on your OS.
|
||||||
|
|
||||||
|
note: i2pd with Qt GUI can be found in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository and for android in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository.
|
||||||
|
|
||||||
|
|
||||||
Build instructions:
|
Build instructions:
|
||||||
|
|
||||||
@@ -70,7 +74,7 @@ Build instructions:
|
|||||||
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
||||||
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* Docker image - [](https://hub.docker.com/r/purplei2p/i2pd/builds/)
|
* Docker image - [](https://hub.docker.com/r/purplei2p/i2pd/builds/)
|
||||||
* Snap - [](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap)
|
* Snap
|
||||||
* FreeBSD
|
* FreeBSD
|
||||||
* Android
|
* Android
|
||||||
* iOS
|
* iOS
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "Win32/Win32Service.h"
|
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "Win32/Win32App.h"
|
#include "Win32App.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@@ -35,45 +34,11 @@ namespace util
|
|||||||
i2p::log::SetThrowFunction ([](const std::string& s)
|
i2p::log::SetThrowFunction ([](const std::string& s)
|
||||||
{
|
{
|
||||||
MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK );
|
MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK );
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!Daemon_Singleton::init(argc, argv))
|
if (!Daemon_Singleton::init(argc, argv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
|
||||||
if (serviceControl == "install")
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
|
||||||
InstallService(
|
|
||||||
SERVICE_NAME, // Name of service
|
|
||||||
SERVICE_DISPLAY_NAME, // Name to display
|
|
||||||
SERVICE_START_TYPE, // Service start type
|
|
||||||
SERVICE_DEPENDENCIES, // Dependencies
|
|
||||||
SERVICE_ACCOUNT, // Service running account
|
|
||||||
SERVICE_PASSWORD // Password of the account
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (serviceControl == "remove")
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
|
|
||||||
UninstallService(SERVICE_NAME);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDaemon)
|
|
||||||
{
|
|
||||||
LogPrint(eLogDebug, "Daemon: running as service");
|
|
||||||
I2PService service((PSTR)SERVICE_NAME);
|
|
||||||
if (!I2PService::Run(service))
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint(eLogDebug, "Daemon: running as user");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,9 +51,6 @@ namespace util
|
|||||||
setlocale(LC_TIME, "C");
|
setlocale(LC_TIME, "C");
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
if (!i2p::win32::StartWin32App ()) return false;
|
if (!i2p::win32::StartWin32App ()) return false;
|
||||||
|
|
||||||
// override log
|
|
||||||
i2p::config::SetOption("log", std::string ("file"));
|
|
||||||
#endif
|
#endif
|
||||||
bool ret = Daemon_Singleton::start();
|
bool ret = Daemon_Singleton::start();
|
||||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
||||||
|
|||||||
@@ -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-2017, The PurpleI2P Project"
|
VALUE "LegalCopyright", "Copyright (C) 2013-2020, 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
|
||||||
|
|||||||
@@ -43,10 +43,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace win32
|
namespace win32
|
||||||
{
|
{
|
||||||
static DWORD GracefulShutdownEndtime = 0;
|
DWORD g_GracefulShutdownEndtime = 0;
|
||||||
|
|
||||||
typedef DWORD (* IPN)();
|
|
||||||
IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount");
|
|
||||||
|
|
||||||
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
|
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
|
||||||
{
|
{
|
||||||
@@ -83,18 +80,19 @@ namespace win32
|
|||||||
DestroyMenu(hPopup);
|
DestroyMenu(hPopup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddTrayIcon (HWND hWnd)
|
static void AddTrayIcon (HWND hWnd, bool notify = false)
|
||||||
{
|
{
|
||||||
NOTIFYICONDATA nid;
|
NOTIFYICONDATA nid;
|
||||||
memset(&nid, 0, sizeof(nid));
|
memset(&nid, 0, sizeof(nid));
|
||||||
nid.cbSize = sizeof(nid);
|
nid.cbSize = sizeof(nid);
|
||||||
nid.hWnd = hWnd;
|
nid.hWnd = hWnd;
|
||||||
nid.uID = ID_TRAY_ICON;
|
nid.uID = ID_TRAY_ICON;
|
||||||
|
nid.uFlags = notify ? NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO : NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||||
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
|
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
|
||||||
nid.uCallbackMessage = WM_TRAYICON;
|
nid.uCallbackMessage = WM_TRAYICON;
|
||||||
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
|
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
|
||||||
strcpy (nid.szTip, "i2pd");
|
strcpy (nid.szTip, "i2pd");
|
||||||
strcpy (nid.szInfo, "i2pd is starting");
|
if (notify) strcpy (nid.szInfo, "i2pd is starting");
|
||||||
Shell_NotifyIcon(NIM_ADD, &nid );
|
Shell_NotifyIcon(NIM_ADD, &nid );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,9 +165,9 @@ namespace win32
|
|||||||
s << "; ";
|
s << "; ";
|
||||||
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
|
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
|
||||||
s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ());
|
s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ());
|
||||||
if (GracefulShutdownEndtime != 0)
|
if (g_GracefulShutdownEndtime != 0)
|
||||||
{
|
{
|
||||||
DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000;
|
DWORD GracefulTimeLeft = (g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
||||||
s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft);
|
s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -198,7 +196,7 @@ namespace win32
|
|||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||||
AddTrayIcon (hWnd);
|
AddTrayIcon (hWnd, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
@@ -247,7 +245,7 @@ namespace win32
|
|||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
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
|
||||||
GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000;
|
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -256,7 +254,7 @@ namespace win32
|
|||||||
i2p::context.SetAcceptsTunnels (true);
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
||||||
GracefulShutdownEndtime = 0;
|
g_GracefulShutdownEndtime = 0;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -343,7 +341,7 @@ namespace win32
|
|||||||
{
|
{
|
||||||
case IDT_GRACEFUL_SHUTDOWN_TIMER:
|
case IDT_GRACEFUL_SHUTDOWN_TIMER:
|
||||||
{
|
{
|
||||||
GracefulShutdownEndtime = 0;
|
g_GracefulShutdownEndtime = 0;
|
||||||
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
|
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -383,7 +381,7 @@ namespace win32
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (uMsg == s_uTaskbarRestart)
|
if (uMsg == s_uTaskbarRestart)
|
||||||
AddTrayIcon (hWnd);
|
AddTrayIcon (hWnd, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace win32
|
namespace win32
|
||||||
{
|
{
|
||||||
|
extern DWORD g_GracefulShutdownEndtime;
|
||||||
|
|
||||||
bool StartWin32App ();
|
bool StartWin32App ();
|
||||||
void StopWin32App ();
|
void StopWin32App ();
|
||||||
int RunWin32App ();
|
int RunWin32App ();
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
Result = E_NOINTERFACE;
|
Result = E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
AddRef();
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,4 +91,4 @@ void SubscribeToEvents() { }
|
|||||||
void UnSubscribeFromEvents() { }
|
void UnSubscribeFromEvents() { }
|
||||||
|
|
||||||
#endif // WINVER
|
#endif // WINVER
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,414 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS // to use freopen
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Win32Service.h"
|
|
||||||
#include <assert.h>
|
|
||||||
//#include <strsafe.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "Daemon.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
I2PService *I2PService::s_service = NULL;
|
|
||||||
|
|
||||||
BOOL I2PService::isService()
|
|
||||||
{
|
|
||||||
BOOL bIsService = FALSE;
|
|
||||||
HWINSTA hWinStation = GetProcessWindowStation();
|
|
||||||
if (hWinStation != NULL)
|
|
||||||
{
|
|
||||||
USEROBJECTFLAGS uof = { 0 };
|
|
||||||
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
|
|
||||||
{
|
|
||||||
bIsService = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bIsService;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL I2PService::Run(I2PService &service)
|
|
||||||
{
|
|
||||||
s_service = &service;
|
|
||||||
SERVICE_TABLE_ENTRY serviceTable[] =
|
|
||||||
{
|
|
||||||
{ service.m_name, ServiceMain },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
return StartServiceCtrlDispatcher(serviceTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv)
|
|
||||||
{
|
|
||||||
assert(s_service != NULL);
|
|
||||||
s_service->m_statusHandle = RegisterServiceCtrlHandler(
|
|
||||||
s_service->m_name, ServiceCtrlHandler);
|
|
||||||
if (s_service->m_statusHandle == NULL)
|
|
||||||
{
|
|
||||||
throw GetLastError();
|
|
||||||
}
|
|
||||||
s_service->Start(dwArgc, pszArgv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WINAPI I2PService::ServiceCtrlHandler(DWORD dwCtrl)
|
|
||||||
{
|
|
||||||
switch (dwCtrl)
|
|
||||||
{
|
|
||||||
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
|
|
||||||
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
|
|
||||||
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
|
|
||||||
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
|
|
||||||
case SERVICE_CONTROL_INTERROGATE: break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
I2PService::I2PService(PSTR pszServiceName,
|
|
||||||
BOOL fCanStop,
|
|
||||||
BOOL fCanShutdown,
|
|
||||||
BOOL fCanPauseContinue)
|
|
||||||
{
|
|
||||||
m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName;
|
|
||||||
m_statusHandle = NULL;
|
|
||||||
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
|
||||||
m_status.dwCurrentState = SERVICE_START_PENDING;
|
|
||||||
|
|
||||||
DWORD dwControlsAccepted = 0;
|
|
||||||
if (fCanStop)
|
|
||||||
dwControlsAccepted |= SERVICE_ACCEPT_STOP;
|
|
||||||
if (fCanShutdown)
|
|
||||||
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
|
|
||||||
if (fCanPauseContinue)
|
|
||||||
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
|
|
||||||
|
|
||||||
m_status.dwControlsAccepted = dwControlsAccepted;
|
|
||||||
m_status.dwWin32ExitCode = NO_ERROR;
|
|
||||||
m_status.dwServiceSpecificExitCode = 0;
|
|
||||||
m_status.dwCheckPoint = 0;
|
|
||||||
m_status.dwWaitHint = 0;
|
|
||||||
m_fStopping = FALSE;
|
|
||||||
// Create a manual-reset event that is not signaled at first to indicate
|
|
||||||
// the stopped signal of the service.
|
|
||||||
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
||||||
if (m_hStoppedEvent == NULL)
|
|
||||||
{
|
|
||||||
throw GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
I2PService::~I2PService(void)
|
|
||||||
{
|
|
||||||
if (m_hStoppedEvent)
|
|
||||||
{
|
|
||||||
CloseHandle(m_hStoppedEvent);
|
|
||||||
m_hStoppedEvent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SetServiceStatus(SERVICE_START_PENDING);
|
|
||||||
OnStart(dwArgc, pszArgv);
|
|
||||||
SetServiceStatus(SERVICE_RUNNING);
|
|
||||||
}
|
|
||||||
catch (DWORD dwError)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Win32Service Start", dwError);
|
|
||||||
SetServiceStatus(SERVICE_STOPPED, dwError);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Win32Service failed to start.", EVENTLOG_ERROR_TYPE);
|
|
||||||
SetServiceStatus(SERVICE_STOPPED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Win32Service in OnStart", EVENTLOG_INFORMATION_TYPE);
|
|
||||||
Daemon.start();
|
|
||||||
//i2p::util::config::OptionParser(dwArgc, pszArgv);
|
|
||||||
//i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
|
||||||
//i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
|
|
||||||
// i2p::util::config::GetArg("-port", 17070));
|
|
||||||
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PService::WorkerThread()
|
|
||||||
{
|
|
||||||
while (!m_fStopping)
|
|
||||||
{
|
|
||||||
::Sleep(1000); // Simulate some lengthy operations.
|
|
||||||
}
|
|
||||||
// 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", dwError);
|
|
||||||
SetServiceStatus(dwOriginalState);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE);
|
|
||||||
SetServiceStatus(dwOriginalState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PService::OnStop()
|
|
||||||
{
|
|
||||||
// Log a service stop message to the Application log.
|
|
||||||
LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE);
|
|
||||||
Daemon.stop();
|
|
||||||
m_fStopping = TRUE;
|
|
||||||
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
throw GetLastError();
|
|
||||||
}
|
|
||||||
_worker->join();
|
|
||||||
delete _worker;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PService::Pause()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SetServiceStatus(SERVICE_PAUSE_PENDING);
|
|
||||||
OnPause();
|
|
||||||
SetServiceStatus(SERVICE_PAUSED);
|
|
||||||
}
|
|
||||||
catch (DWORD dwError)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Win32Service Pause", 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", 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", 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InstallService(PCSTR pszServiceName, PCSTR pszDisplayName, DWORD dwStartType, PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword)
|
|
||||||
{
|
|
||||||
printf("Try to install Win32Service (%s).\n", pszServiceName);
|
|
||||||
|
|
||||||
char szPath[MAX_PATH];
|
|
||||||
SC_HANDLE schSCManager = NULL;
|
|
||||||
SC_HANDLE schService = NULL;
|
|
||||||
|
|
||||||
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
|
||||||
{
|
|
||||||
printf("GetModuleFileName failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char SvcOpt[] = " --daemon";
|
|
||||||
strncat(szPath, SvcOpt, strlen(SvcOpt));
|
|
||||||
|
|
||||||
// Open the local default service control manager database
|
|
||||||
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
|
||||||
if (schSCManager == NULL)
|
|
||||||
{
|
|
||||||
printf("OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install the service into SCM by calling CreateService
|
|
||||||
schService = CreateService(
|
|
||||||
schSCManager, // SCManager database
|
|
||||||
pszServiceName, // Name of service
|
|
||||||
pszDisplayName, // Name to display
|
|
||||||
SERVICE_QUERY_STATUS, // Desired access
|
|
||||||
SERVICE_WIN32_OWN_PROCESS, // Service type
|
|
||||||
dwStartType, // Service start type
|
|
||||||
SERVICE_ERROR_NORMAL, // Error control type
|
|
||||||
szPath, // Service's binary
|
|
||||||
NULL, // No load ordering group
|
|
||||||
NULL, // No tag identifier
|
|
||||||
pszDependencies, // Dependencies
|
|
||||||
pszAccount, // Service running account
|
|
||||||
pszPassword // Password of the account
|
|
||||||
);
|
|
||||||
|
|
||||||
if (schService == NULL)
|
|
||||||
{
|
|
||||||
printf("CreateService failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Win32Service is installed as %s.\n", pszServiceName);
|
|
||||||
|
|
||||||
// Centralized cleanup for all allocated resources.
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UninstallService(PCSTR pszServiceName)
|
|
||||||
{
|
|
||||||
printf("Try to uninstall Win32Service (%s).\n", pszServiceName);
|
|
||||||
|
|
||||||
SC_HANDLE schSCManager = NULL;
|
|
||||||
SC_HANDLE schService = NULL;
|
|
||||||
SERVICE_STATUS ssSvcStatus = {};
|
|
||||||
|
|
||||||
// Open the local default service control manager database
|
|
||||||
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
|
||||||
if (schSCManager == NULL)
|
|
||||||
{
|
|
||||||
printf("OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the service with delete, stop, and query status permissions
|
|
||||||
schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);
|
|
||||||
if (schService == NULL)
|
|
||||||
{
|
|
||||||
printf("OpenService failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to stop the service
|
|
||||||
if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
|
|
||||||
{
|
|
||||||
printf("Stopping %s.\n", pszServiceName);
|
|
||||||
Sleep(1000);
|
|
||||||
|
|
||||||
while (QueryServiceStatus(schService, &ssSvcStatus))
|
|
||||||
{
|
|
||||||
if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
|
|
||||||
{
|
|
||||||
printf(".");
|
|
||||||
Sleep(1000);
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED)
|
|
||||||
{
|
|
||||||
printf("\n%s is stopped.\n", pszServiceName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("\n%s failed to stop.\n", pszServiceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove the service by calling DeleteService.
|
|
||||||
if (!DeleteService(schService))
|
|
||||||
{
|
|
||||||
printf("DeleteService failed w/err 0x%08lx\n", GetLastError());
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s is removed.\n", pszServiceName);
|
|
||||||
|
|
||||||
// Centralized cleanup for all allocated resources.
|
|
||||||
FreeHandles(schSCManager, schService);
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WIN_32_SERVICE_H__
|
|
||||||
#define WIN_32_SERVICE_H__
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Internal name of the service
|
|
||||||
#define SERVICE_NAME "i2pdService"
|
|
||||||
|
|
||||||
// Displayed name of the service
|
|
||||||
#define SERVICE_DISPLAY_NAME "i2pd router service"
|
|
||||||
|
|
||||||
// Service start options.
|
|
||||||
#define SERVICE_START_TYPE SERVICE_DEMAND_START
|
|
||||||
|
|
||||||
// List of service dependencies - "dep1\0dep2\0\0"
|
|
||||||
#define SERVICE_DEPENDENCIES ""
|
|
||||||
|
|
||||||
// The name of the account under which the service should run
|
|
||||||
#define SERVICE_ACCOUNT "NT AUTHORITY\\LocalService"
|
|
||||||
|
|
||||||
// The password to the service account name
|
|
||||||
#define SERVICE_PASSWORD NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class I2PService
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
I2PService(PSTR pszServiceName,
|
|
||||||
BOOL fCanStop = TRUE,
|
|
||||||
BOOL fCanShutdown = TRUE,
|
|
||||||
BOOL fCanPauseContinue = FALSE);
|
|
||||||
|
|
||||||
virtual ~I2PService(void);
|
|
||||||
|
|
||||||
static BOOL isService();
|
|
||||||
static BOOL Run(I2PService &service);
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
|
||||||
virtual void OnStop();
|
|
||||||
virtual void OnPause();
|
|
||||||
virtual void OnContinue();
|
|
||||||
virtual void OnShutdown();
|
|
||||||
void SetServiceStatus(DWORD dwCurrentState,
|
|
||||||
DWORD dwWin32ExitCode = NO_ERROR,
|
|
||||||
DWORD dwWaitHint = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
|
||||||
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
|
||||||
void WorkerThread();
|
|
||||||
void Start(DWORD dwArgc, PSTR *pszArgv);
|
|
||||||
void Pause();
|
|
||||||
void Continue();
|
|
||||||
void Shutdown();
|
|
||||||
static I2PService* s_service;
|
|
||||||
PSTR m_name;
|
|
||||||
SERVICE_STATUS m_status;
|
|
||||||
SERVICE_STATUS_HANDLE m_statusHandle;
|
|
||||||
|
|
||||||
BOOL m_fStopping;
|
|
||||||
HANDLE m_hStoppedEvent;
|
|
||||||
|
|
||||||
std::thread* _worker;
|
|
||||||
};
|
|
||||||
|
|
||||||
void InstallService(
|
|
||||||
PCSTR pszServiceName,
|
|
||||||
PCSTR pszDisplayName,
|
|
||||||
DWORD dwStartType,
|
|
||||||
PCSTR pszDependencies,
|
|
||||||
PCSTR pszAccount,
|
|
||||||
PCSTR pszPassword
|
|
||||||
);
|
|
||||||
|
|
||||||
void UninstallService(PCSTR pszServiceName);
|
|
||||||
|
|
||||||
#endif // WIN_32_SERVICE_H__
|
|
||||||
18
android/.gitignore
vendored
18
android/.gitignore
vendored
@@ -1,18 +0,0 @@
|
|||||||
gen
|
|
||||||
tests
|
|
||||||
bin
|
|
||||||
libs
|
|
||||||
log*
|
|
||||||
obj
|
|
||||||
.cxx
|
|
||||||
.gradle
|
|
||||||
.idea
|
|
||||||
.externalNativeBuild
|
|
||||||
ant.properties
|
|
||||||
local.properties
|
|
||||||
build.sh
|
|
||||||
android.iml
|
|
||||||
build
|
|
||||||
*.iml
|
|
||||||
*.local
|
|
||||||
*.jks
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="org.purplei2p.i2pd"
|
|
||||||
android:installLocation="auto">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@drawable/icon"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
|
||||||
android:requestLegacyExternalStorage="true"
|
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
>
|
|
||||||
|
|
||||||
<receiver android:name=".NetworkStateChangeReceiver">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".I2PDPermsAskerActivity"
|
|
||||||
android:label="@string/app_name">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".I2PDActivity"
|
|
||||||
android:label="@string/app_name" />
|
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".ForegroundService"
|
|
||||||
android:enabled="true" />
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".I2PDPermsExplanationActivity"
|
|
||||||
android:label="@string/title_activity_i2_pdperms_asker_prompt"
|
|
||||||
android:parentActivityName=".I2PDPermsAskerActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" />
|
|
||||||
</activity>
|
|
||||||
</application>
|
|
||||||
</manifest>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# how to compile?
|
|
||||||
## Install the gradle + NDK or use android-studio
|
|
||||||
[https://gradle.org/install/](https://gradle.org/install/)
|
|
||||||
|
|
||||||
## Install the depencies
|
|
||||||
```
|
|
||||||
git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
|
|
||||||
git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
|
||||||
git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
|
||||||
git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
|
||||||
```
|
|
||||||
## Set libs in jni/Application.mk on 24 line:
|
|
||||||
```
|
|
||||||
# change to your own
|
|
||||||
I2PD_LIBS_PATH = /home/user/i2pd/android/
|
|
||||||
```
|
|
||||||
|
|
||||||
## compile apk file
|
|
||||||
gradle clean assembleRelease
|
|
||||||
@@ -1,693 +0,0 @@
|
|||||||
00.i2p,zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
|
|
||||||
0ipfs.i2p,cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
|
|
||||||
0xcc.i2p,gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
|
|
||||||
1.fcp.freenet.i2p,cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
|
|
||||||
102chan.i2p,xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
|
|
||||||
1st.i2p,rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
|
|
||||||
2.fcp.freenet.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
|
|
||||||
333.i2p,ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
|
|
||||||
55cancri.i2p,b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
|
|
||||||
adab.i2p,pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
|
|
||||||
alice.i2p,iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
|
|
||||||
always.i2p,wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
|
|
||||||
amazone.i2p,e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
|
|
||||||
amiga.i2p,edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
|
|
||||||
amobius.i2p,rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
|
|
||||||
anarchistfaq.i2p,xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
|
|
||||||
animal.i2p,5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
|
|
||||||
anodex.i2p,25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
|
|
||||||
anoncoin.i2p,nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
|
|
||||||
anongw.i2p,owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
|
|
||||||
anonsfw.i2p,ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
|
|
||||||
anonymnet.i2p,77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
|
|
||||||
anonynanny.i2p,l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
|
|
||||||
anonyradio.i2p,cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
|
|
||||||
antipiracyagency.i2p,by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
|
|
||||||
antipiratbyran.i2p,y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
|
|
||||||
aosp.i2p,ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
|
|
||||||
arc2.i2p,rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
|
|
||||||
archaicbinarybbs.i2p,t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
|
|
||||||
archiv.tutorials.i2p,lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
|
|
||||||
archive.i2p,x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
|
|
||||||
archive.syndie.i2p,abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
|
|
||||||
ardor-wallet.i2p,tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
|
|
||||||
ardvark.i2p,jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
|
|
||||||
arf.i2p,o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
|
|
||||||
arkan.i2p,7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
|
|
||||||
asciiwhite.i2p,itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
|
|
||||||
aspnet.i2p,tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
|
|
||||||
asylum.i2p,p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
|
|
||||||
auchan.i2p,6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
|
|
||||||
aum.i2p,ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
|
|
||||||
awup.i2p,v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
|
|
||||||
b.i2p,272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
|
|
||||||
bacardi.i2p,hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
|
|
||||||
backup.i2p,kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
|
|
||||||
badfish.i2p,f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
|
|
||||||
badtoyz.i2p,3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
|
|
||||||
barry.i2p,4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
|
|
||||||
bash.i2p,s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
|
|
||||||
bdl.i2p,kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
|
|
||||||
bdsm.i2p,pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
|
|
||||||
betaguru.i2p,d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
|
|
||||||
beyond.i2p,uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
|
|
||||||
bible.i2p,pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
|
|
||||||
bible4u.i2p,xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
|
|
||||||
bigbrother.i2p,tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
|
|
||||||
bitlox.i2p,lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
|
|
||||||
bittorrent.i2p,pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
|
|
||||||
bk1k.i2p,nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
|
|
||||||
bl.i2p,e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
|
|
||||||
black.i2p,sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
|
|
||||||
blackbox.i2p,7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
|
|
||||||
blackexchange.i2p,ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
|
|
||||||
blog.curiosity.i2p,yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
|
|
||||||
blog.polecat.i2p,orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
|
|
||||||
blog.tinlans.i2p,ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
|
|
||||||
bluebeam.i2p,lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
|
|
||||||
blueheron.i2p,anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
|
|
||||||
bnc.i2p,fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
|
|
||||||
bob.i2p,i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
|
|
||||||
bobcat.i2p,ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
|
|
||||||
bobthebuilder.i2p,qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
|
|
||||||
boerse.i2p,7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
|
|
||||||
bofh.i2p,auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
|
|
||||||
boing.i2p,bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
|
|
||||||
books.manveru.i2p,eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
|
|
||||||
bote.i2p,bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
|
|
||||||
bozo.i2p,7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
|
|
||||||
brittanyworld.i2p,e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
|
|
||||||
bt.i2p,uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
|
|
||||||
bugfuzz.i2p,ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
|
|
||||||
burntout.i2p,lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
|
|
||||||
bytepay.i2p,7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
|
|
||||||
ca.i2pd.i2p,u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
|
|
||||||
cases.i2p,kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
|
|
||||||
cathugger.i2p,vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
|
|
||||||
cbs.i2p,u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
|
|
||||||
cerapadus.i2p,zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
|
|
||||||
cerebrum.i2p,u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
|
|
||||||
cgan.i2p,43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
|
|
||||||
chat.i2p,ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
|
|
||||||
chess.fillament.i2p,tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
|
|
||||||
chess.i2p,sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
|
|
||||||
china.i2p,wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
|
|
||||||
chitanka.i2p,u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
|
|
||||||
ciaran.i2p,2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
|
|
||||||
ciphercraft.i2p,7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
|
|
||||||
closedshop.i2p,6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
|
|
||||||
cneal.i2p,g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
|
|
||||||
co.i2p,3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
|
|
||||||
codevoid.i2p,2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
|
|
||||||
colombo-bt.i2p,cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
|
|
||||||
complication.i2p,x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
|
|
||||||
comwiz.i2p,6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
|
|
||||||
confessions.i2p,lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
|
|
||||||
connelly.i2p,5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
|
|
||||||
costeira.i2p,abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
|
|
||||||
cowsay.i2p,q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
|
|
||||||
crstrack.i2p,mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
|
|
||||||
crypthost.i2p,zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
|
|
||||||
crypto.i2p,vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
|
|
||||||
cryptostorm.i2p,mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
|
|
||||||
curiosity.i2p,eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
|
|
||||||
cvs.i2p,yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
|
|
||||||
danwin1210.i2p,eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
|
|
||||||
darknetnow.i2p,gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
|
|
||||||
darknut.i2p,2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
|
|
||||||
darkrealm.i2p,gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
|
|
||||||
darrob.i2p,hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
|
|
||||||
dashninja.i2p,dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
|
|
||||||
davidkra.i2p,nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
|
|
||||||
dcherukhin.i2p,qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
|
|
||||||
de-ebook-archiv.i2p,6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
|
|
||||||
de-ebooks.i2p,epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
|
|
||||||
dead.i2p,7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
|
|
||||||
deadgod.i2p,63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
|
|
||||||
debian-multimedia.i2p,cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
|
|
||||||
decadence.i2p,pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
|
|
||||||
deepwebradio.i2p,2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
|
|
||||||
def2.i2p,cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
|
|
||||||
def3.i2p,xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
|
|
||||||
def4.i2p,yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
|
|
||||||
deploy.i2p,ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
|
|
||||||
det.i2p,y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
|
|
||||||
detonate.i2p,nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
|
|
||||||
dev.i2p,cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
|
|
||||||
di.i2p,3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
|
|
||||||
diasporg.i2p,edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
|
|
||||||
diftracker.i2p,m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
|
|
||||||
dm.i2p,heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
|
|
||||||
docs.i2p,ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
|
|
||||||
docs.i2p2.i2p,las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
|
|
||||||
downloads.legion.i2p,xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
|
|
||||||
dox.i2p,vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
|
|
||||||
dropbox.i2p,omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
|
|
||||||
duck.i2p,3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
|
|
||||||
dumpteam.i2p,2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
|
|
||||||
dust.i2p,u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
|
|
||||||
dvdr-core.i2p,fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
|
|
||||||
dyad.i2p,7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
|
|
||||||
e-reading.i2p,z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
|
|
||||||
easygpg2.i2p,bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
|
|
||||||
eboochka.i2p,ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
|
|
||||||
ebooks.i2p,bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
|
|
||||||
echelon.i2p,afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
|
|
||||||
echo.baffled.i2p,bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
|
|
||||||
eco.i2p,2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
|
|
||||||
eddysblog.i2p,ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
|
|
||||||
edge.i2p,aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
|
|
||||||
eepdot.i2p,t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
|
|
||||||
eepshare-project.i2p,sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
|
|
||||||
eepsites.i2p,isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
|
|
||||||
elf.i2p,duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
|
|
||||||
elgoog.i2p,z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
|
|
||||||
ems.i2p,734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
|
|
||||||
epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
|
|
||||||
es.hiddenanswers.i2p,cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
|
|
||||||
eschaton.i2p,xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
|
|
||||||
esuwiki.i2p,cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
|
|
||||||
evil.i2p,ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
|
|
||||||
evilchat.i2p,s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
|
|
||||||
evilgit.i2p,mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
|
|
||||||
exch.i2p,vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
|
|
||||||
exchange.gostcoin.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
|
|
||||||
exchanged.i2p,ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
|
|
||||||
exitpoint.i2p,5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
|
|
||||||
exotrack.i2p,blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
|
|
||||||
explorer.gostcoin.i2p,ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
|
|
||||||
fa.i2p,6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
|
|
||||||
falafel.i2p,djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
|
|
||||||
false.i2p,77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
|
|
||||||
false2.i2p,j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
|
|
||||||
fantasy-worlds.i2p,62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
|
|
||||||
fcp.entropy.i2p,de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
|
|
||||||
fcp.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
|
|
||||||
fedo.i2p,zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
|
|
||||||
feedspace.i2p,kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
|
|
||||||
ferret.i2p,kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
|
|
||||||
fido.r4sas.i2p,i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
|
|
||||||
fifi4all.i2p,v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
|
|
||||||
files.hypercubus.i2p,qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
|
|
||||||
files.i2p,w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
|
|
||||||
files.nickster.i2p,yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
|
|
||||||
fillament.i2p,udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
|
|
||||||
firerabbit.i2p,awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
|
|
||||||
flibs.i2p,ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
|
|
||||||
flibusta.i2p,zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
|
|
||||||
flipkick.i2p,aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
|
|
||||||
flock.i2p,hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
|
|
||||||
floureszination.i2p,vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
|
|
||||||
forum.fr.i2p,onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
|
|
||||||
forum.i2p,33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
|
|
||||||
forum.rus.i2p,zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
|
|
||||||
forums.i2p,tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
|
|
||||||
fproxy.i2p,keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
|
|
||||||
fproxy.tino.i2p,fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
|
|
||||||
fproxy2.i2p,r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
|
|
||||||
fr.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
|
|
||||||
freeciv.nightblade.i2p,rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
|
|
||||||
freedomarchives.i2p,4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
|
|
||||||
freedomforum.i2p,abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
|
|
||||||
freefallheavens.i2p,giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
|
|
||||||
freenet.eco.i2p,2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
|
|
||||||
freshcoffee.i2p,sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
|
|
||||||
frooze.i2p,m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
|
|
||||||
frosk.i2p,63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
|
|
||||||
frostmirror.i2p,ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
|
|
||||||
fs.i2p,ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
|
|
||||||
fsoc.i2p,vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
|
|
||||||
galen.i2p,4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
|
|
||||||
gaming.i2p,rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
|
|
||||||
garden.i2p,qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
|
|
||||||
gaytorrents.i2p,fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
|
|
||||||
general.i2p,5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
|
|
||||||
gernika.i2p,wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
|
|
||||||
ginnegappen.i2p,kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
|
|
||||||
git-ssh.crypthost.i2p,llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
|
|
||||||
git.crypthost.i2p,7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
|
|
||||||
git.psi.i2p,em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
|
|
||||||
git.repo.i2p,vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
|
|
||||||
git.volatile.i2p,gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
|
|
||||||
glog.i2p,ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
|
|
||||||
gloinsblog.i2p,zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
|
|
||||||
go.i2p,ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
|
|
||||||
gonzo2000.i2p,nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
|
|
||||||
google.i2p,4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
|
|
||||||
gostcoin.i2p,4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
|
|
||||||
gott.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
|
|
||||||
greenflog.i2p,zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
|
|
||||||
gstbtc.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
|
|
||||||
gusion.i2p,4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
|
|
||||||
guttersnipe.i2p,kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
|
|
||||||
hack8.i2p,un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
|
|
||||||
hagen.i2p,e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
|
|
||||||
heisenberg.i2p,jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
|
|
||||||
heligoland.i2p,gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
|
|
||||||
hidden.i2p,iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
|
|
||||||
hiddenanswers.i2p,kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
|
|
||||||
hiddenbooru.i2p,zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
|
|
||||||
hiddenchan.i2p,6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
|
|
||||||
hiddengate.i2p,rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
|
|
||||||
home.duck.i2p,jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
|
|
||||||
hopekiller.i2p,kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
|
|
||||||
hotline.i2p,6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
|
|
||||||
hq.postman.i2p,27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
|
|
||||||
http.entropy.i2p,ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
|
|
||||||
human.i2p,nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
|
|
||||||
i2host.i2p,awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
|
|
||||||
i2jump.i2p,633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
|
|
||||||
i2p-bt.postman.i2p,jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
|
|
||||||
i2p-epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
|
|
||||||
i2p-javadocs.i2p,icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
|
|
||||||
i2p-projekt.i2p,udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
|
|
||||||
i2pbote.i2p,tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
|
|
||||||
i2pbuggenie.i2p,bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
|
|
||||||
i2pchan.i2p,tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
|
|
||||||
i2pd.i2p,4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
|
|
||||||
i2pdocs.str4d.i2p,yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
|
|
||||||
i2peek-a-boo.i2p,qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
|
|
||||||
i2pforum.i2p,tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
|
|
||||||
i2pjump.i2p,2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
|
|
||||||
i2plugins.i2p,bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
|
|
||||||
i2pmetrics.i2p,v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
|
|
||||||
i2pnews.i2p,tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
|
|
||||||
i2podisy.i2p,3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
|
|
||||||
i2push.i2p,mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
|
|
||||||
i2pwiki.i2p,nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
|
|
||||||
iamevil.i2p,au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
|
|
||||||
icu812.i2p,bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
|
|
||||||
id3nt.i2p,ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
|
|
||||||
identiguy.i2p,3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
|
|
||||||
ilcosmista.i2p,6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
|
|
||||||
ilita.i2p,isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
|
|
||||||
illuminati.i2p,syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
|
|
||||||
imhotep.i2p,qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
|
|
||||||
in.i2p,r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
|
|
||||||
infosecurity.i2p,v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
|
|
||||||
infoserver.i2p,jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
|
|
||||||
inproxy.tino.i2p,ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
|
|
||||||
inr.i2p,joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
|
|
||||||
instantexchange.i2p,5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
|
|
||||||
investigaciones.i2p,n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
|
|
||||||
invisible-internet.i2p,jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
|
|
||||||
io.i2p,tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
|
|
||||||
irc.00.i2p,bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
|
|
||||||
irc.arcturus.i2p,5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
|
|
||||||
irc.baffled.i2p,5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
|
|
||||||
irc.carambar.i2p,hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
|
|
||||||
irc.cerapadus.i2p,e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
|
|
||||||
irc.dg.i2p,fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
|
|
||||||
irc.duck.i2p,chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
|
|
||||||
irc.echelon.i2p,ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
|
|
||||||
irc.freshcoffee.i2p,ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
|
|
||||||
irc.i2p,l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
|
|
||||||
irc.ilita.i2p,5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
|
|
||||||
irc.ircbnc.i2p,4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
|
|
||||||
irc.killyourtv.i2p,wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
|
|
||||||
irc.nickster.i2p,dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
|
|
||||||
irc.orz.i2p,7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
|
|
||||||
irc.postman.i2p,mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
|
|
||||||
irc.r4sas.i2p,hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
|
|
||||||
ircssl.cerapadus.i2p,4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
|
|
||||||
irongeeks.i2p,ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
|
|
||||||
iscofsi.i2p,enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
|
|
||||||
isotoxin.i2p,wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
|
|
||||||
itemname.i2p,o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
|
|
||||||
ivorytower.i2p,fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
|
|
||||||
j.i2p,kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
|
|
||||||
jabber-2.i2p,pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
|
|
||||||
jabber.duck.i2p,rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
|
|
||||||
jake.i2p,v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
|
|
||||||
jar.i2p,2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
|
|
||||||
jazzy.i2p,ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
|
|
||||||
jdot.i2p,kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
|
|
||||||
jhor.i2p,c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
|
|
||||||
jikx.i2p,aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
|
|
||||||
jisko.i2p,jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
|
|
||||||
jmg.i2p,oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
|
|
||||||
jnymo.i2p,nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
|
|
||||||
jrandom.dev.i2p,htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
|
|
||||||
jrandom.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
|
|
||||||
jrrecology.i2p,qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
|
|
||||||
jwebcache.i2p,xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
|
|
||||||
k1773r.i2p,zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
|
|
||||||
kaji.i2p,z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
|
|
||||||
kaji2.i2p,4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
|
|
||||||
keys.echelon.i2p,mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
|
|
||||||
keys.i2p,6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
|
|
||||||
keyserver.sigterm.i2p,isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
|
|
||||||
killyourtv.i2p,aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
|
|
||||||
knijka.i2p,knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
|
|
||||||
knotwork.i2p,2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
|
|
||||||
kohaar.i2p,qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
|
|
||||||
krabs.i2p,3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
|
|
||||||
kuroneko.i2p,wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
|
|
||||||
kycklingar.i2p,gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
|
|
||||||
lazyguy.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
|
|
||||||
legion.i2p,5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
|
|
||||||
legwork.i2p,cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
|
|
||||||
lenta.i2p,nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
|
|
||||||
libertor.i2p,7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
|
|
||||||
library.i2p,brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
|
|
||||||
lifebox.i2p,pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
|
|
||||||
linuxagent.i2p,ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
|
|
||||||
lists.i2p2.i2p,vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
|
|
||||||
lm.i2p,yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
|
|
||||||
lodikon.i2p,u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
|
|
||||||
lolicatgirls.i2p,a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
|
|
||||||
lolifox.i2p,7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
|
|
||||||
longhorn.i2p,pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
|
|
||||||
lp.i2p,jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
|
|
||||||
lucky.i2p,wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
|
|
||||||
luckypunk.i2p,y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
|
|
||||||
lunokhod.i2p,3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
|
|
||||||
m16.i2p,ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
|
|
||||||
mac7.i2p,3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
|
|
||||||
madman2003.i2p,a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
|
|
||||||
magix.i2p,cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
|
|
||||||
magnets.i2p,snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
|
|
||||||
manas.i2p,6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
|
|
||||||
manveru.i2p,pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
|
|
||||||
marcos.i2p,vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
|
|
||||||
marshmallow.i2p,svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
|
|
||||||
marxists.i2p,lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
|
|
||||||
mattermost.i2p,x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
|
|
||||||
me.i2p,dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
|
|
||||||
meeh.i2p,4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
|
|
||||||
mesh.firerabbit.i2p,3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
|
|
||||||
messageinabottle.i2p,avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
|
|
||||||
metrics.i2p,z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
|
|
||||||
mhatta.i2p,o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
|
|
||||||
microbleu.i2p,mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
|
|
||||||
microsoft.i2p,hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
|
|
||||||
mindisl0st.i2p,u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
|
|
||||||
mindspore.i2p,uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
|
|
||||||
modulus.i2p,ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
|
|
||||||
monerotools.i2p,5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
|
|
||||||
monerujo.i2p,puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
|
|
||||||
morph.i2p,iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
|
|
||||||
mosbot.i2p,5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
|
|
||||||
mosfet.i2p,s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
|
|
||||||
moxonom.i2p,gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
|
|
||||||
mp3.aum.i2p,n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
|
|
||||||
mp3.tc.i2p,w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
|
|
||||||
mpaa.i2p,m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
|
|
||||||
mrbamboo.i2p,tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
|
|
||||||
mrflibble.i2p,u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
|
|
||||||
mrplod.i2p,fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
|
|
||||||
mtn.i2p,xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
|
|
||||||
mtn.i2p-projekt.i2p,f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
|
|
||||||
mtn.i2p2.i2p,l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
|
|
||||||
mtn.meeh.i2p,h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
|
|
||||||
mudgaard.i2p,yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
|
|
||||||
mush.zeit.i2p,dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
|
|
||||||
music.i2p,akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
|
|
||||||
mysterious.i2p,p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
|
|
||||||
mywastedlife.i2p,ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
|
|
||||||
nacl.i2p,bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
|
|
||||||
nano.i2p,ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
|
|
||||||
nassai.i2p,v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
|
|
||||||
neodome.i2p,5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
|
|
||||||
news-i2pn.i2p,wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
|
|
||||||
news.neodome.i2p,trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
|
|
||||||
news.underscore.i2p,rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
|
|
||||||
newsbyte.i2p,gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
|
|
||||||
nibble.i2p,jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
|
|
||||||
nic.i2p,vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
|
|
||||||
nickster.i2p,zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
|
|
||||||
nickster2.i2p,eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
|
|
||||||
nickyb.i2p,gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
|
|
||||||
nightblade.i2p,p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
|
|
||||||
ninja.i2p,q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
|
|
||||||
nm.i2p,3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
|
|
||||||
nntp.baffled.i2p,kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
|
|
||||||
nntp.duck.i2p,gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
|
|
||||||
nntp.fr.i2p,npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
|
|
||||||
nntp.i2p,wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
|
|
||||||
no.i2p,lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
|
|
||||||
noname56.i2p,oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
|
|
||||||
nop.i2p,ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
|
|
||||||
normal.i2p,j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
|
|
||||||
normanabcd.i2p,si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
|
|
||||||
nothingburger.i2p,tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
|
|
||||||
nothingspecial.i2p,wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
|
|
||||||
novospice.i2p,ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
|
|
||||||
nsa.i2p,nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
|
|
||||||
nvspc.i2p,anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
|
|
||||||
nxt-wallet.i2p,33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
|
|
||||||
obmen.i2p,vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
|
|
||||||
obscuratus.i2p,i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
|
|
||||||
ogg.aum.i2p,wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
|
|
||||||
ogg.baffled.i2p,tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
|
|
||||||
ol.i2p,bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
|
|
||||||
onboard.i2p,qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
|
|
||||||
onelon.i2p,irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
|
|
||||||
onhere.i2p,vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
|
|
||||||
oniichan.i2p,nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
|
|
||||||
onionforum.i2p,yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
|
|
||||||
ooo.i2p,iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
|
|
||||||
opal.i2p,li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
|
|
||||||
open4you.i2p,ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
|
|
||||||
opendiftracker.i2p,bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
|
|
||||||
openforums.i2p,lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
|
|
||||||
opentracker.dg2.i2p,w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
|
|
||||||
orion.i2p,5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
|
|
||||||
orz.i2p,oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
|
|
||||||
os3.i2p,s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
|
|
||||||
osiristomb.i2p,t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
|
|
||||||
ot.knotwork.i2p,cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
|
|
||||||
outproxy-tor.meeh.i2p,77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
|
|
||||||
outproxy.h2ik.i2p,nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
|
|
||||||
outproxyng.h2ik.i2p,v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
|
|
||||||
overchan.oniichan.i2p,g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
|
|
||||||
p4bl0.i2p,lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
|
|
||||||
pants.i2p,xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
|
|
||||||
papel.i2p,mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
|
|
||||||
pasta-nojs.i2p,dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
|
|
||||||
paste.crypthost.i2p,2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
|
|
||||||
paste.i2p2.i2p,b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
|
|
||||||
paste.r4sas.i2p,csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
|
|
||||||
pastebin.i2p,mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
|
|
||||||
pastethis.i2p,erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
|
|
||||||
pdforge.i2p,wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
|
|
||||||
perv.i2p,f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
|
|
||||||
pgp.duck.i2p,wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
|
|
||||||
pharos.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
|
|
||||||
pharoz.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
|
|
||||||
phonebooth.i2p,noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
|
|
||||||
photo.i2p,fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
|
|
||||||
piespy.i2p,vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
|
|
||||||
pisekot.i2p,7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
|
|
||||||
pizdabol.i2p,5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
|
|
||||||
planet.i2p,y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
|
|
||||||
plugins.i2p,wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
|
|
||||||
polecat.i2p,het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
|
|
||||||
politguy.i2p,6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
|
|
||||||
pomoyka.i2p,omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
|
|
||||||
pool.gostcoin.i2p,m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
|
|
||||||
pop.mail.i2p,bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
|
|
||||||
pop.postman.i2p,ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
|
|
||||||
pravtor.i2p,2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
|
|
||||||
pris.i2p,ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
|
|
||||||
project-future.i2p,ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
|
|
||||||
projectmayhem2012-086.i2p,ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
|
|
||||||
protokol.i2p,f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
|
|
||||||
proxynet.i2p,7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
|
|
||||||
psi.i2p,avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
|
|
||||||
psy.i2p,s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
|
|
||||||
psyco.i2p,eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
|
|
||||||
pt.hiddenanswers.i2p,o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
|
|
||||||
ptm.i2p,7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
|
|
||||||
ptt.i2p,q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
|
|
||||||
pull.git.repo.i2p,3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
|
|
||||||
push.git.repo.i2p,jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
|
|
||||||
pycache.awup.i2p,w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
|
|
||||||
r4sas.i2p,2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
|
|
||||||
radio.r4sas.i2p,cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
|
|
||||||
ragnarok.i2p,jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
|
|
||||||
ransack.i2p,mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
|
|
||||||
rasputin-sucks.i2p,fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
|
|
||||||
rebel.i2p,nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
|
|
||||||
red.i2p,fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
|
|
||||||
redpanda.i2p,3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
|
|
||||||
redzara.i2p,ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
|
|
||||||
reefer.i2p,4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
|
|
||||||
relatelist.i2p,utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
|
|
||||||
repo.i2p,uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
|
|
||||||
repo.r4sas.i2p,ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
|
|
||||||
reseed.i2p,j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
|
|
||||||
retrobbs-nntp.i2p,fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
|
|
||||||
retrobbs.i2p,mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
|
|
||||||
retrobbs2.i2p,ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
|
|
||||||
revo-ua.i2p,hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
|
|
||||||
riaa.i2p,lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
|
|
||||||
rideronthestorm.i2p,xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
|
|
||||||
romster.i2p,eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
|
|
||||||
rootd.i2p,mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
|
|
||||||
rospravosudie.i2p,z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
|
|
||||||
rotten.i2p,j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
|
|
||||||
rpi.i2p,56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
|
|
||||||
rslight.i2p,bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
|
|
||||||
rsync.thetower.i2p,w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
|
|
||||||
ru.hiddenanswers.i2p,o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
|
|
||||||
ru.i2p,m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
|
|
||||||
rufurus.i2p,7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
|
|
||||||
rus.i2p,gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
|
|
||||||
ruslibgen.i2p,kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
|
|
||||||
rutor.i2p,tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
|
|
||||||
salt.i2p,6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
|
|
||||||
sasquotch.i2p,p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
|
|
||||||
schwarzwald.i2p,4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
|
|
||||||
sciencebooks.i2p,ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
|
|
||||||
scp.duck.i2p,ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
|
|
||||||
search.i2p,nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
|
|
||||||
secretchat.i2p,cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
|
|
||||||
secure.thetinhat.i2p,4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
|
|
||||||
seeker.i2p,ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
|
|
||||||
seomon.i2p,5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
|
|
||||||
septu.i2p,5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
|
|
||||||
serien.i2p,3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
|
|
||||||
ses.i2p,5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
|
|
||||||
shiftfox.i2p,wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
|
|
||||||
shoieq3.i2p,3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
|
|
||||||
shoronil.i2p,7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
|
|
||||||
short.i2p,z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
|
|
||||||
sion.i2p,lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
|
|
||||||
sirup.i2p,aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
|
|
||||||
site.games.i2p,zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
|
|
||||||
skank.i2p,qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
|
|
||||||
slack.i2p,gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
|
|
||||||
slacker.i2p,wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
|
|
||||||
smeghead.i2p,ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
|
|
||||||
smtp.mail.i2p,kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
|
|
||||||
smtp.postman.i2p,jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
|
|
||||||
socks1.tor.i2p,sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
|
|
||||||
sonax.i2p,jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
|
|
||||||
sponge.i2p,o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
|
|
||||||
squid.i2p,r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
|
|
||||||
squid2.i2p,hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
|
|
||||||
sqz.i2p,3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
|
|
||||||
ssh.i2p,xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
|
|
||||||
stasher.i2p,6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
|
|
||||||
stats.i2p,7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
|
|
||||||
status.str4d.i2p,ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
|
|
||||||
sto-man.i2p,rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
|
|
||||||
str4d.i2p,wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
|
|
||||||
stream.i2p,prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
|
|
||||||
streams.darkrealm.i2p,ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
|
|
||||||
striker.i2p,4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
|
|
||||||
subrosa.i2p,g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
|
|
||||||
subterra.i2p,vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
|
|
||||||
sugadude.i2p,yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
|
|
||||||
suicidal.i2p,yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
|
|
||||||
sungo.i2p,h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
|
|
||||||
surrender.adab.i2p,jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
|
|
||||||
susi.i2p,qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
|
|
||||||
syncline.i2p,5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
|
|
||||||
syndie-project.i2p,xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
|
|
||||||
syndie.echelon.i2p,vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
|
|
||||||
syndie.i2p,7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
|
|
||||||
syndiemedia.i2p,4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
|
|
||||||
tabak.i2p,y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
|
|
||||||
tahoeserve.i2p,yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
|
|
||||||
tc.i2p,qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
|
|
||||||
telegram.i2p,i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
|
|
||||||
templar.i2p,zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
|
|
||||||
terror.i2p,wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
|
|
||||||
thebland.i2p,oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
|
|
||||||
thebreton.i2p,woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
|
|
||||||
thedarkside.i2p,fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
|
|
||||||
theland.i2p,26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
|
|
||||||
thetower.i2p,3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
|
|
||||||
thornworld.i2p,vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
|
|
||||||
tino.i2p,e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
|
|
||||||
tinyurl.i2p,mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
|
|
||||||
tome.i2p,qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
|
|
||||||
tor-gw.meeh.i2p,ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
|
|
||||||
tor-www-proxy.i2p,xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
|
|
||||||
torapa.i2p,eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
|
|
||||||
torrentfinder.i2p,mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
|
|
||||||
torrfreedom.i2p,nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
|
|
||||||
trac.i2p,kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
|
|
||||||
trac.i2p2.i2p,i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
|
|
||||||
tracker-fr.i2p,qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
|
|
||||||
tracker.awup.i2p,dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
|
|
||||||
tracker.crypthost.i2p,ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
|
|
||||||
tracker.fr.i2p,rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
|
|
||||||
tracker.i2p,lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
|
|
||||||
tracker.lodikon.i2p,q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
|
|
||||||
tracker.mastertracker.i2p,tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
|
|
||||||
tracker.postman.i2p,jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
|
|
||||||
tracker.psi.i2p,vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
|
|
||||||
tracker.thebland.i2p,s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
|
|
||||||
tracker.welterde.i2p,cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
|
|
||||||
tracker2.postman.i2p,ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
|
|
||||||
traditio.i2p,wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
|
|
||||||
trevorreznik.i2p,wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
|
|
||||||
true.i2p,pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
|
|
||||||
trwcln.i2p,evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
|
|
||||||
trypanom.i2p,tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
|
|
||||||
ts.i2p,nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
|
|
||||||
ttc.i2p,wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
|
|
||||||
ttp.i2p,uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
|
|
||||||
tumbach.i2p,u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
|
|
||||||
tutorials.i2p,zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
|
|
||||||
ugha.i2p,z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
|
|
||||||
uk.i2p,vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
|
|
||||||
underground.i2p,dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
|
|
||||||
underscore.i2p,3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
|
|
||||||
unqueued.i2p,3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
|
|
||||||
up.i2p,25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
|
|
||||||
update.dg.i2p,iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
|
|
||||||
update.killyourtv.i2p,gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
|
|
||||||
update.postman.i2p,u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
|
|
||||||
utansans.i2p,u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
|
|
||||||
v2mail.i2p,4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
|
|
||||||
vadino.i2p,aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
|
|
||||||
visibility.i2p,pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
|
|
||||||
volatile.i2p,q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
|
|
||||||
vpnbest.i2p,ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
|
|
||||||
vudu.i2p,3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
|
|
||||||
w.i2p,j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
|
|
||||||
wa11ed.city.i2p,7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
|
|
||||||
wahoo.i2p,vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
|
|
||||||
wallet.gostcoin.i2p,reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
|
|
||||||
wallsgetbombed.i2p,tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
|
|
||||||
web.telegram.i2p,re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
|
|
||||||
wiht.i2p,yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
|
|
||||||
wiki.fr.i2p,lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
|
|
||||||
wiki.ilita.i2p,r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
|
|
||||||
wintermute.i2p,4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
|
|
||||||
wspucktracker.i2p,ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
|
|
||||||
www.aum.i2p,3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
|
|
||||||
www.baffled.i2p,lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
|
|
||||||
www.fr.i2p,rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
|
|
||||||
www.i2p,ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
|
|
||||||
www.i2p2.i2p,rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
|
|
||||||
www.imule.i2p,657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
|
|
||||||
www.infoserver.i2p,fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
|
|
||||||
www.janonymous.i2p,vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
|
|
||||||
www.mail.i2p,nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
|
|
||||||
www.nntp.i2p,kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
|
|
||||||
www.postman.i2p,rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
|
|
||||||
www.syndie.i2p,vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
|
|
||||||
www1.squid.i2p,vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
|
|
||||||
xc.i2p,mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
|
|
||||||
xeha.i2p,oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
|
|
||||||
xilog.i2p,eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
|
|
||||||
xmpp.crypthost.i2p,ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
|
|
||||||
xmpp.rpi.i2p,3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
|
|
||||||
xn--l2bl5aw.i2p,d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
|
|
||||||
xolotl.i2p,rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
|
|
||||||
xotc.i2p,gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
|
|
||||||
z-lab.i2p,s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
|
|
||||||
zab.i2p,n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
|
|
||||||
zcash.i2p,zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
|
|
||||||
zener.i2p,mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
|
|
||||||
zerobin.i2p,3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
|
|
||||||
zeroman.i2p,gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
|
|
||||||
zeronet.i2p,fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
|
|
||||||
znc.i2p,uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
|
|
||||||
znc.str4d.i2p,ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
|
|
||||||
zzz.i2p,ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq
|
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
../../contrib/certificates
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
## Configuration file for a typical i2pd user
|
|
||||||
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
|
|
||||||
## for more options you can use in this file.
|
|
||||||
|
|
||||||
#logfile = /sdcard/i2pd/i2pd.log
|
|
||||||
loglevel = none
|
|
||||||
#tunnelsdir = /sdcard/i2pd/tunnels.d
|
|
||||||
|
|
||||||
# host = 1.2.3.4
|
|
||||||
# port = 4567
|
|
||||||
|
|
||||||
ipv4 = true
|
|
||||||
ipv6 = false
|
|
||||||
|
|
||||||
# ntcp = true
|
|
||||||
# ntcpproxy = http://127.0.0.1:8118
|
|
||||||
# ssu = true
|
|
||||||
|
|
||||||
bandwidth = L
|
|
||||||
# share = 100
|
|
||||||
|
|
||||||
# notransit = true
|
|
||||||
# floodfill = true
|
|
||||||
|
|
||||||
[ntcp2]
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
[http]
|
|
||||||
enabled = true
|
|
||||||
address = 127.0.0.1
|
|
||||||
port = 7070
|
|
||||||
# auth = true
|
|
||||||
# user = i2pd
|
|
||||||
# pass = changeme
|
|
||||||
|
|
||||||
[httpproxy]
|
|
||||||
enabled = true
|
|
||||||
address = 127.0.0.1
|
|
||||||
port = 4444
|
|
||||||
inbound.length = 1
|
|
||||||
inbound.quantity = 5
|
|
||||||
outbound.length = 1
|
|
||||||
outbound.quantity = 5
|
|
||||||
signaturetype=7
|
|
||||||
i2cp.leaseSetType=3
|
|
||||||
i2cp.leaseSetEncType=0,4
|
|
||||||
keys = proxy-keys.dat
|
|
||||||
# addresshelper = true
|
|
||||||
# outproxy = http://false.i2p
|
|
||||||
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
|
|
||||||
|
|
||||||
[socksproxy]
|
|
||||||
enabled = true
|
|
||||||
address = 127.0.0.1
|
|
||||||
port = 4447
|
|
||||||
keys = proxy-keys.dat
|
|
||||||
# outproxy.enabled = false
|
|
||||||
# outproxy = 127.0.0.1
|
|
||||||
# outproxyport = 9050
|
|
||||||
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
|
|
||||||
|
|
||||||
[sam]
|
|
||||||
enabled = false
|
|
||||||
# address = 127.0.0.1
|
|
||||||
# port = 7656
|
|
||||||
|
|
||||||
[precomputation]
|
|
||||||
elgamal = true
|
|
||||||
|
|
||||||
[upnp]
|
|
||||||
enabled = true
|
|
||||||
# name = I2Pd
|
|
||||||
|
|
||||||
[reseed]
|
|
||||||
verify = true
|
|
||||||
## Path to local reseed data file (.su3) for manual reseeding
|
|
||||||
# file = /path/to/i2pseeds.su3
|
|
||||||
## or HTTPS URL to reseed from
|
|
||||||
# file = https://legit-website.com/i2pseeds.su3
|
|
||||||
## Path to local ZIP file or HTTPS URL to reseed from
|
|
||||||
# zipfile = /path/to/netDb.zip
|
|
||||||
## If you run i2pd behind a proxy server, set proxy server for reseeding here
|
|
||||||
## Should be http://address:port or socks://address:port
|
|
||||||
# proxy = http://127.0.0.1:8118
|
|
||||||
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
|
|
||||||
# threshold = 25
|
|
||||||
|
|
||||||
[limits]
|
|
||||||
transittunnels = 50
|
|
||||||
|
|
||||||
[persist]
|
|
||||||
profiles = false
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
http://inr.i2p/export/alive-hosts.txt
|
|
||||||
http://stats.i2p/cgi-bin/newhosts.txt
|
|
||||||
http://i2p-projekt.i2p/hosts.txt
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
[IRC-IRC2P]
|
|
||||||
#type = client
|
|
||||||
#address = 127.0.0.1
|
|
||||||
#port = 6668
|
|
||||||
#destination = irc.postman.i2p
|
|
||||||
#destinationport = 6667
|
|
||||||
#keys = irc-keys.dat
|
|
||||||
|
|
||||||
#[IRC-ILITA]
|
|
||||||
#type = client
|
|
||||||
#address = 127.0.0.1
|
|
||||||
#port = 6669
|
|
||||||
#destination = irc.ilita.i2p
|
|
||||||
#destinationport = 6667
|
|
||||||
#keys = irc-keys.dat
|
|
||||||
|
|
||||||
#[SMTP]
|
|
||||||
#type = client
|
|
||||||
#address = 127.0.0.1
|
|
||||||
#port = 7659
|
|
||||||
#destination = smtp.postman.i2p
|
|
||||||
#destinationport = 25
|
|
||||||
#keys = smtp-keys.dat
|
|
||||||
|
|
||||||
#[POP3]
|
|
||||||
#type = client
|
|
||||||
#address = 127.0.0.1
|
|
||||||
#port = 7660
|
|
||||||
#destination = pop.postman.i2p
|
|
||||||
#destinationport = 110
|
|
||||||
#keys = pop3-keys.dat
|
|
||||||
|
|
||||||
# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../contrib/tunnels.d
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
url 'https://maven.google.com'
|
|
||||||
}
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'androidx.core:core:1.0.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion 29
|
|
||||||
buildToolsVersion "28.0.3"
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "org.purplei2p.i2pd"
|
|
||||||
targetSdkVersion 29
|
|
||||||
minSdkVersion 14
|
|
||||||
versionCode 2321
|
|
||||||
versionName "2.32.1"
|
|
||||||
setProperty("archivesBaseName", archivesBaseName + "-" + versionName)
|
|
||||||
ndk {
|
|
||||||
abiFilters 'armeabi-v7a'
|
|
||||||
abiFilters 'x86'
|
|
||||||
//abiFilters 'arm64-v8a'
|
|
||||||
//abiFilters 'x86_64'
|
|
||||||
}
|
|
||||||
externalNativeBuild {
|
|
||||||
ndkBuild {
|
|
||||||
arguments "-j3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
|
||||||
java.srcDirs = ['src']
|
|
||||||
res.srcDirs = ['res']
|
|
||||||
jniLibs.srcDirs = ['libs']
|
|
||||||
assets.srcDirs = ['assets']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
splits {
|
|
||||||
abi {
|
|
||||||
// change that to true if you need splitted apk
|
|
||||||
enable true
|
|
||||||
reset()
|
|
||||||
//include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
|
||||||
include "armeabi-v7a", "x86"
|
|
||||||
universalApk true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signingConfigs {
|
|
||||||
orignal {
|
|
||||||
storeFile file("i2pdapk.jks")
|
|
||||||
storePassword "android"
|
|
||||||
keyAlias "i2pdapk"
|
|
||||||
keyPassword "android"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled false
|
|
||||||
signingConfig signingConfigs.orignal
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
externalNativeBuild {
|
|
||||||
ndkBuild {
|
|
||||||
path './jni/Android.mk'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = '1.8'
|
|
||||||
targetCompatibility = '1.8'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.abiCodes = ['armeabi-v7a':1, 'x86':2, 'arm64-v8a':3, 'x86_64':4]
|
|
||||||
import com.android.build.OutputFile
|
|
||||||
|
|
||||||
android.applicationVariants.all { variant ->
|
|
||||||
variant.outputs.each { output ->
|
|
||||||
def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
|
|
||||||
|
|
||||||
if (baseAbiVersionCode != null) {
|
|
||||||
output.versionCodeOverride = baseAbiVersionCode + variant.versionCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="i2pd" default="help">
|
|
||||||
|
|
||||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
|
||||||
It contains the path to the SDK. It should *NOT* be checked into
|
|
||||||
Version Control Systems. -->
|
|
||||||
<property file="local.properties" />
|
|
||||||
|
|
||||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
|
||||||
'android' tool to add properties to it.
|
|
||||||
This is the place to change some Ant specific build properties.
|
|
||||||
Here are some properties you may want to change/update:
|
|
||||||
|
|
||||||
source.dir
|
|
||||||
The name of the source directory. Default is 'src'.
|
|
||||||
out.dir
|
|
||||||
The name of the output directory. Default is 'bin'.
|
|
||||||
|
|
||||||
For other overridable properties, look at the beginning of the rules
|
|
||||||
files in the SDK, at tools/ant/build.xml
|
|
||||||
|
|
||||||
Properties related to the SDK location or the project target should
|
|
||||||
be updated using the 'android' tool with the 'update' action.
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property file="ant.properties" />
|
|
||||||
|
|
||||||
<!-- if sdk.dir was not set from one of the property file, then
|
|
||||||
get it from the ANDROID_HOME env var.
|
|
||||||
This must be done before we load project.properties since
|
|
||||||
the proguard config can use sdk.dir -->
|
|
||||||
<property environment="env" />
|
|
||||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
|
||||||
<isset property="env.ANDROID_HOME" />
|
|
||||||
</condition>
|
|
||||||
|
|
||||||
<!-- The project.properties file is created and updated by the 'android'
|
|
||||||
tool, as well as ADT.
|
|
||||||
|
|
||||||
This contains project specific properties such as project target, and library
|
|
||||||
dependencies. Lower level build properties are stored in ant.properties
|
|
||||||
(or in .classpath for Eclipse projects).
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems. -->
|
|
||||||
<loadproperties srcFile="project.properties" />
|
|
||||||
|
|
||||||
<!-- quick check on sdk.dir -->
|
|
||||||
<fail
|
|
||||||
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
|
||||||
unless="sdk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<fail
|
|
||||||
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'."
|
|
||||||
unless="ndk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Import per project custom build rules if present at the root of the project.
|
|
||||||
This is the place to put custom intermediary targets such as:
|
|
||||||
-pre-build
|
|
||||||
-pre-compile
|
|
||||||
-post-compile (This is typically used for code obfuscation.
|
|
||||||
Compiled code location: ${out.classes.absolute.dir}
|
|
||||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
|
||||||
-post-package
|
|
||||||
-post-build
|
|
||||||
-pre-clean
|
|
||||||
-->
|
|
||||||
<import file="custom_rules.xml" optional="true" />
|
|
||||||
|
|
||||||
<!-- Import the actual build file.
|
|
||||||
|
|
||||||
To customize existing targets, there are two options:
|
|
||||||
- Customize only one target:
|
|
||||||
- copy/paste the target into this file, *before* the
|
|
||||||
<import> task.
|
|
||||||
- customize it to your needs.
|
|
||||||
- Customize the whole content of build.xml
|
|
||||||
- copy/paste the content of the rules files (minus the top node)
|
|
||||||
into this file, replacing the <import> task.
|
|
||||||
- customize to your needs.
|
|
||||||
|
|
||||||
***********************
|
|
||||||
****** IMPORTANT ******
|
|
||||||
***********************
|
|
||||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
|
||||||
in order to avoid having your file be overridden by tools such as "android update project"
|
|
||||||
-->
|
|
||||||
<!-- version-tag: 1 -->
|
|
||||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
|
||||||
</project>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
android.enableJetifier=true
|
|
||||||
android.useAndroidX=true
|
|
||||||
org.gradle.parallel=true
|
|
||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,6 +0,0 @@
|
|||||||
#Tue Aug 20 14:39:08 MSK 2019
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
|
||||||
172
android/gradlew
vendored
172
android/gradlew
vendored
@@ -1,172 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
##
|
|
||||||
## Gradle start up script for UN*X
|
|
||||||
##
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=`basename "$0"`
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS=""
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD="maximum"
|
|
||||||
|
|
||||||
warn () {
|
|
||||||
echo "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die () {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
nonstop=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN* )
|
|
||||||
cygwin=true
|
|
||||||
;;
|
|
||||||
Darwin* )
|
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="java"
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
ulimit -n $MAX_FD
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
|
||||||
if $cygwin ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Escape application args
|
|
||||||
save () {
|
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
|
||||||
echo " "
|
|
||||||
}
|
|
||||||
APP_ARGS=$(save "$@")
|
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
|
||||||
84
android/gradlew.bat
vendored
84
android/gradlew.bat
vendored
@@ -1,84 +0,0 @@
|
|||||||
@if "%DEBUG%" == "" @echo off
|
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
|
||||||
@rem Gradle startup script for Windows
|
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
|
||||||
set APP_BASE_NAME=%~n0
|
|
||||||
set APP_HOME=%DIRNAME%
|
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS=
|
|
||||||
|
|
||||||
@rem Find java.exe
|
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
|
||||||
@rem Setup the command line
|
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
|
||||||
|
|
||||||
:end
|
|
||||||
@rem End local scope for the variables with windows NT shell
|
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
||||||
@@ -1,73 +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 := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \
|
|
||||||
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
|
|
||||||
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
|
|
||||||
$(DAEMON_SRC_PATH)/Daemon.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/UPnP.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
|
|
||||||
$(DAEMON_SRC_PATH)/I2PControl.cpp
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
|
||||||
|
|
||||||
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,36 +0,0 @@
|
|||||||
#APP_ABI := armeabi-v7a x86
|
|
||||||
#APP_PLATFORM := android-14
|
|
||||||
|
|
||||||
# ABI arm64-v8a and x86_64 supported only from platform-21
|
|
||||||
#APP_ABI := arm64-v8a x86_64
|
|
||||||
#APP_PLATFORM := android-21
|
|
||||||
|
|
||||||
NDK_TOOLCHAIN_VERSION := clang
|
|
||||||
#APP_STL := c++_shared
|
|
||||||
APP_STL := c++_static
|
|
||||||
|
|
||||||
# Enable c++17 extensions in source code
|
|
||||||
APP_CPPFLAGS += -std=c++17 -fexceptions -frtti
|
|
||||||
|
|
||||||
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
|
||||||
APP_CPPFLAGS += -DANDROID_ARM7A
|
|
||||||
endif
|
|
||||||
|
|
||||||
# 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
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include <exception>
|
|
||||||
#include <boost/exception/diagnostic_information.hpp>
|
|
||||||
#include <boost/exception_ptr.hpp>
|
|
||||||
//#include "mainwindow.h"
|
|
||||||
#include "FS.h"
|
|
||||||
#include "DaemonAndroid.h"
|
|
||||||
#include "Daemon.h"
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace android
|
|
||||||
{
|
|
||||||
/* Worker::Worker (DaemonAndroidImpl& daemon):
|
|
||||||
m_Daemon (daemon)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::startDaemon()
|
|
||||||
{
|
|
||||||
Log.d(TAG"Performing daemon start...");
|
|
||||||
m_Daemon.start();
|
|
||||||
Log.d(TAG"Daemon started.");
|
|
||||||
emit resultReady();
|
|
||||||
}
|
|
||||||
void Worker::restartDaemon()
|
|
||||||
{
|
|
||||||
Log.d(TAG"Performing daemon restart...");
|
|
||||||
m_Daemon.restart();
|
|
||||||
Log.d(TAG"Daemon restarted.");
|
|
||||||
emit resultReady();
|
|
||||||
}
|
|
||||||
void Worker::stopDaemon() {
|
|
||||||
Log.d(TAG"Performing daemon stop...");
|
|
||||||
m_Daemon.stop();
|
|
||||||
Log.d(TAG"Daemon stopped.");
|
|
||||||
emit resultReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller::Controller(DaemonAndroidImpl& daemon):
|
|
||||||
m_Daemon (daemon)
|
|
||||||
{
|
|
||||||
Worker *worker = new Worker (m_Daemon);
|
|
||||||
worker->moveToThread(&workerThread);
|
|
||||||
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
|
|
||||||
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
|
|
||||||
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
|
|
||||||
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
|
|
||||||
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
|
|
||||||
workerThread.start();
|
|
||||||
}
|
|
||||||
Controller::~Controller()
|
|
||||||
{
|
|
||||||
Log.d(TAG"Closing and waiting for daemon worker thread...");
|
|
||||||
workerThread.quit();
|
|
||||||
workerThread.wait();
|
|
||||||
Log.d(TAG"Waiting for daemon worker thread finished.");
|
|
||||||
if(m_Daemon.isRunning())
|
|
||||||
{
|
|
||||||
Log.d(TAG"Stopping the daemon...");
|
|
||||||
m_Daemon.stop();
|
|
||||||
Log.d(TAG"Stopped the daemon.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
std::string dataDir = "";
|
|
||||||
|
|
||||||
DaemonAndroidImpl::DaemonAndroidImpl ()
|
|
||||||
//:
|
|
||||||
/*mutex(nullptr), */
|
|
||||||
//m_IsRunning(false),
|
|
||||||
//m_RunningChangedCallback(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DaemonAndroidImpl::~DaemonAndroidImpl ()
|
|
||||||
{
|
|
||||||
//delete mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DaemonAndroidImpl::init(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
//mutex=new QMutex(QMutex::Recursive);
|
|
||||||
//setRunningCallback(0);
|
|
||||||
//m_IsRunning=false;
|
|
||||||
|
|
||||||
// make sure assets are ready before proceed
|
|
||||||
i2p::fs::DetectDataDir(dataDir, false);
|
|
||||||
int numAttempts = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
|
|
||||||
numAttempts++;
|
|
||||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
|
|
||||||
}
|
|
||||||
while (numAttempts <= 10); // 10 seconds max
|
|
||||||
return Daemon.init(argc,argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonAndroidImpl::start()
|
|
||||||
{
|
|
||||||
//QMutexLocker locker(mutex);
|
|
||||||
//setRunning(true);
|
|
||||||
Daemon.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonAndroidImpl::stop()
|
|
||||||
{
|
|
||||||
//QMutexLocker locker(mutex);
|
|
||||||
Daemon.stop();
|
|
||||||
//setRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonAndroidImpl::restart()
|
|
||||||
{
|
|
||||||
//QMutexLocker locker(mutex);
|
|
||||||
stop();
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb)
|
|
||||||
{
|
|
||||||
m_RunningChangedCallback = cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DaemonAndroidImpl::isRunning()
|
|
||||||
{
|
|
||||||
return m_IsRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonAndroidImpl::setRunning(bool newValue)
|
|
||||||
{
|
|
||||||
bool oldValue = m_IsRunning;
|
|
||||||
if(oldValue!=newValue)
|
|
||||||
{
|
|
||||||
m_IsRunning = newValue;
|
|
||||||
if(m_RunningChangedCallback)
|
|
||||||
m_RunningChangedCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
static DaemonAndroidImpl daemon;
|
|
||||||
static char* argv[1]={strdup("tmp")};
|
|
||||||
/**
|
|
||||||
* returns error details if failed
|
|
||||||
* returns "ok" if daemon initialized and started okay
|
|
||||||
*/
|
|
||||||
std::string start(/*int argc, char* argv[]*/)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//int result;
|
|
||||||
|
|
||||||
{
|
|
||||||
//Log.d(TAG"Initialising the daemon...");
|
|
||||||
bool daemonInitSuccess = daemon.init(1,argv);
|
|
||||||
if(!daemonInitSuccess)
|
|
||||||
{
|
|
||||||
//QMessageBox::critical(0, "Error", "Daemon init failed");
|
|
||||||
return "Daemon init failed";
|
|
||||||
}
|
|
||||||
//Log.d(TAG"Initialised, creating the main window...");
|
|
||||||
//MainWindow w;
|
|
||||||
//Log.d(TAG"Before main window.show()...");
|
|
||||||
//w.show ();
|
|
||||||
|
|
||||||
{
|
|
||||||
//i2p::qt::Controller daemonQtController(daemon);
|
|
||||||
//Log.d(TAG"Starting the daemon...");
|
|
||||||
//emit daemonQtController.startDaemon();
|
|
||||||
//daemon.start ();
|
|
||||||
//Log.d(TAG"Starting GUI event loop...");
|
|
||||||
//result = app.exec();
|
|
||||||
//daemon.stop ();
|
|
||||||
daemon.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//QMessageBox::information(&w, "Debug", "demon stopped");
|
|
||||||
//Log.d(TAG"Exiting the application");
|
|
||||||
//return result;
|
|
||||||
}
|
|
||||||
catch (boost::exception& ex)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << boost::diagnostic_information(ex);
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << ex.what();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
return "unknown exception";
|
|
||||||
}
|
|
||||||
return "ok";
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop()
|
|
||||||
{
|
|
||||||
daemon.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDataDir(std::string jdataDir)
|
|
||||||
{
|
|
||||||
dataDir = jdataDir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DAEMON_ANDROID_H
|
|
||||||
#define DAEMON_ANDROID_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace android
|
|
||||||
{
|
|
||||||
class DaemonAndroidImpl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DaemonAndroidImpl ();
|
|
||||||
~DaemonAndroidImpl ();
|
|
||||||
|
|
||||||
//typedef void (*runningChangedCallback)();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return success
|
|
||||||
*/
|
|
||||||
bool init(int argc, char* argv[]);
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
void restart();
|
|
||||||
//void setRunningCallback(runningChangedCallback cb);
|
|
||||||
//bool isRunning();
|
|
||||||
private:
|
|
||||||
//void setRunning(bool running);
|
|
||||||
private:
|
|
||||||
//QMutex* mutex;
|
|
||||||
//bool m_IsRunning;
|
|
||||||
//runningChangedCallback m_RunningChangedCallback;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns "ok" if daemon init failed
|
|
||||||
* returns errinfo if daemon initialized and started okay
|
|
||||||
*/
|
|
||||||
std::string start();
|
|
||||||
|
|
||||||
// stops the daemon
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
// set datadir received from jni
|
|
||||||
void SetDataDir(std::string jdataDir);
|
|
||||||
/*
|
|
||||||
class Worker : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
|
|
||||||
Worker (DaemonAndroidImpl& daemon);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DaemonAndroidImpl& m_Daemon;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void startDaemon();
|
|
||||||
void restartDaemon();
|
|
||||||
void stopDaemon();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void resultReady();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Controller : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QThread workerThread;
|
|
||||||
public:
|
|
||||||
Controller(DaemonAndroidImpl& daemon);
|
|
||||||
~Controller();
|
|
||||||
private:
|
|
||||||
DaemonAndroidImpl& m_Daemon;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void handleResults(){}
|
|
||||||
signals:
|
|
||||||
void startDaemon();
|
|
||||||
void stopDaemon();
|
|
||||||
void restartDaemon();
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DAEMON_ANDROID_H
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include "org_purplei2p_i2pd_I2PD_JNI.h"
|
|
||||||
#include "DaemonAndroid.h"
|
|
||||||
#include "RouterContext.h"
|
|
||||||
#include "ClientContext.h"
|
|
||||||
#include "Transports.h"
|
|
||||||
#include "Tunnel.h"
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
#if defined(__arm__)
|
|
||||||
#if defined(__ARM_ARCH_7A__)
|
|
||||||
#if defined(__ARM_NEON__)
|
|
||||||
#if defined(__ARM_PCS_VFP)
|
|
||||||
#define ABI "armeabi-v7a/NEON (hard-float)"
|
|
||||||
#else
|
|
||||||
#define ABI "armeabi-v7a/NEON"
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#if defined(__ARM_PCS_VFP)
|
|
||||||
#define ABI "armeabi-v7a (hard-float)"
|
|
||||||
#else
|
|
||||||
#define ABI "armeabi-v7a"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define ABI "armeabi"
|
|
||||||
#endif
|
|
||||||
#elif defined(__i386__)
|
|
||||||
#define ABI "x86"
|
|
||||||
#elif defined(__x86_64__)
|
|
||||||
#define ABI "x86_64"
|
|
||||||
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
|
|
||||||
#define ABI "mips64"
|
|
||||||
#elif defined(__mips__)
|
|
||||||
#define ABI "mips"
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
#define ABI "arm64-v8a"
|
|
||||||
#else
|
|
||||||
#define ABI "unknown"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return env->NewStringUTF(ABI);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
return env->NewStringUTF(i2p::android::start().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
i2p::android::stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
i2p::context.SetAcceptsTunnels (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
i2p::client::context.ReloadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
|
||||||
(JNIEnv *env, jclass clazz, jboolean isConnected) {
|
|
||||||
bool isConnectedBool = (bool) isConnected;
|
|
||||||
i2p::transport::transports.SetOnline (isConnectedBool);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
|
|
||||||
(JNIEnv *env, jclass clazz, jstring jdataDir) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336)
|
|
||||||
const jclass stringClass = env->GetObjectClass(jdataDir);
|
|
||||||
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
|
|
||||||
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8"));
|
|
||||||
|
|
||||||
size_t length = (size_t) env->GetArrayLength(stringJbytes);
|
|
||||||
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
|
|
||||||
|
|
||||||
std::string dataDir = std::string((char *)pBytes, length);
|
|
||||||
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
|
|
||||||
|
|
||||||
env->DeleteLocalRef(stringJbytes);
|
|
||||||
env->DeleteLocalRef(stringClass); */
|
|
||||||
|
|
||||||
// Method 2: get string chars and make char array.
|
|
||||||
auto dataDir = env->GetStringUTFChars(jdataDir, NULL);
|
|
||||||
env->ReleaseStringUTFChars(jdataDir, dataDir);
|
|
||||||
|
|
||||||
// Set DataDir
|
|
||||||
i2p::android::SetDataDir(dataDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount
|
|
||||||
(JNIEnv *env, jclass clazz) {
|
|
||||||
return i2p::tunnel::tunnels.CountTransitTunnels();
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
|
||||||
#include <jni.h>
|
|
||||||
/* Header for class org_purplei2p_i2pd_I2PD_JNI */
|
|
||||||
|
|
||||||
#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI
|
|
||||||
#define _Included_org_purplei2p_i2pd_I2PD_JNI
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Class: org_purplei2p_i2pd_I2PD_JNI
|
|
||||||
* Method: stringFromJNI
|
|
||||||
* Signature: ()Ljava/lang/String;
|
|
||||||
*/
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
|
||||||
(JNIEnv * env, jclass clazz, jboolean isConnected);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
|
|
||||||
(JNIEnv *env, jclass clazz, jstring jdataDir);
|
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount
|
|
||||||
(JNIEnv *, jclass);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# To enable ProGuard in your project, edit project.properties
|
|
||||||
# to define the proguard.config property as described in that file.
|
|
||||||
#
|
|
||||||
# Add project specific ProGuard rules here.
|
|
||||||
# By default, the flags in this file are appended to flags specified
|
|
||||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
|
||||||
# You can edit the include path and order by changing the ProGuard
|
|
||||||
# include property in project.properties.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# Add any project specific keep options here:
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# This file is automatically generated by Android Tools.
|
|
||||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
|
||||||
#
|
|
||||||
# This file must be checked in Version Control Systems.
|
|
||||||
#
|
|
||||||
# To customize properties used by the Ant build system edit
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
#
|
|
||||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
|
||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
|
||||||
|
|
||||||
# Project target.
|
|
||||||
target=android-29
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -1,26 +0,0 @@
|
|||||||
<LinearLayout android:id="@+id/main_layout"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/vertical_page_margin"
|
|
||||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingRight="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingTop="@dimen/vertical_page_margin"
|
|
||||||
tools:context=".I2PDPermsAskerActivity">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_retry"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_request_write_ext_storage_perms"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/retryPermRequest"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<LinearLayout android:id="@+id/layout_prompt"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/vertical_page_margin"
|
|
||||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingRight="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingTop="@dimen/vertical_page_margin"
|
|
||||||
tools:context=".I2PDPermsAskerActivity">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_explanation"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
|
||||||
android:text="@string/permRequired" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_ok"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/ok" />
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<LinearLayout android:id="@+id/layout_prompt"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
tools:context=".I2PDActivity">
|
|
||||||
|
|
||||||
<WebView
|
|
||||||
android:id="@+id/webview1"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent" />
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<menu
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:context=".I2PDActivity">
|
|
||||||
|
|
||||||
<group android:id="@+id/group_various">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_battery_otimizations"
|
|
||||||
android:title="@string/menu_item_battery_optimizations_str" />
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<group android:id="@+id/group_i2pd_control">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_start_webview"
|
|
||||||
android:orderInCategory="96"
|
|
||||||
android:title="@string/action_start_webview" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_reload_tunnels_config"
|
|
||||||
android:orderInCategory="97"
|
|
||||||
android:title="@string/action_reload_tunnels_config" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_graceful_stop"
|
|
||||||
android:orderInCategory="98"
|
|
||||||
android:title="@string/action_graceful_stop" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_stop"
|
|
||||||
android:orderInCategory="99"
|
|
||||||
android:title="@string/action_stop" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">i2pd</string>
|
|
||||||
|
|
||||||
<string name="action_stop">Остановить</string>
|
|
||||||
<string name="action_graceful_stop">Корректная остановка</string>
|
|
||||||
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
|
|
||||||
<string name="action_reload_tunnels_config">Перезагрузить туннели</string>
|
|
||||||
<string name="action_start_webview">Открыть Веб Консоль</string>
|
|
||||||
|
|
||||||
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
|
|
||||||
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
|
|
||||||
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string>
|
|
||||||
|
|
||||||
<string name="already_stopped">Уже остановлено</string>
|
|
||||||
<string name="uninitialized">Приложение инициализируется</string>
|
|
||||||
<string name="starting">Приложение запускается</string>
|
|
||||||
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string>
|
|
||||||
<string name="startedOkay">Приложение запущено</string>
|
|
||||||
<string name="startFailed">Запуск не удался</string>
|
|
||||||
<string name="stopped">Приложение было остановлено</string>
|
|
||||||
<string name="remaining">осталось</string>
|
|
||||||
|
|
||||||
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string>
|
|
||||||
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string>
|
|
||||||
<string name="permRequired">Права на запись на SD карту необходимы для записи ключей и других файлов в папку I2PD на внутренней памяти.</string>
|
|
||||||
<string name="retryPermRequest">Повторить запрос прав на запись на SD карту</string>
|
|
||||||
|
|
||||||
<string name="menu_item_battery_optimizations_str">Оптимизации аккумулятора</string>
|
|
||||||
<string name="battery_optimizations_enabled">Оптимизации аккумулятора включены</string>
|
|
||||||
<string name="battery_optimizations_enabled_explained">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации.</string>
|
|
||||||
<string name="battery_optimizations_enabled_dialog">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций.</string>
|
|
||||||
<string name="continue_str">Продолжить</string>
|
|
||||||
<string name="device_does_not_support_disabling_battery_optimizations">Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора</string>
|
|
||||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений.</string>
|
|
||||||
|
|
||||||
<string name="shutdown_canceled">Плановая остановка отменена</string>
|
|
||||||
|
|
||||||
<string name="tunnels_reloading">Перезагрузка конфигурации туннелей...</string>
|
|
||||||
</resources>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
|
||||||
<string name="app_name">i2pd</string>
|
|
||||||
|
|
||||||
<string name="action_stop">Stop</string>
|
|
||||||
<string name="action_graceful_stop">Graceful Stop</string>
|
|
||||||
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
|
|
||||||
<string name="action_reload_tunnels_config">Reload tunnels</string>
|
|
||||||
<string name="action_start_webview">Open Web Console</string>
|
|
||||||
|
|
||||||
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
|
|
||||||
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
|
|
||||||
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string>
|
|
||||||
|
|
||||||
<string name="already_stopped">Already stopped</string>
|
|
||||||
<string name="uninitialized">Application initializing</string>
|
|
||||||
<string name="starting">Application starting</string>
|
|
||||||
<string name="jniLibraryLoaded">Loaded JNI libraries</string>
|
|
||||||
<string name="startedOkay">Application Started</string>
|
|
||||||
<string name="startFailed">Start failed</string>
|
|
||||||
<string name="stopped">Application stopped</string>
|
|
||||||
<string name="remaining">remaining</string>
|
|
||||||
<string name="ok">OK</string>
|
|
||||||
|
|
||||||
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
|
|
||||||
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string>
|
|
||||||
<string name="permRequired">SD card write access is required to write the keys and other files to the I2PD folder on SD card.</string>
|
|
||||||
<string name="retryPermRequest">Retry requesting the SD card write permissions</string>
|
|
||||||
|
|
||||||
<string name="menu_item_battery_optimizations_str">Battery Optimizations</string>
|
|
||||||
<string name="battery_optimizations_enabled">Battery optimizations enabled</string>
|
|
||||||
<string name="battery_optimizations_enabled_explained">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations.</string>
|
|
||||||
<string name="battery_optimizations_enabled_dialog">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those.</string>
|
|
||||||
<string name="continue_str">Continue</string>
|
|
||||||
<string name="device_does_not_support_disabling_battery_optimizations">Your Android version does not support opting out of battery optimizations</string>
|
|
||||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Your Android OS version does not support showing the dialog for battery optimizations for applications.</string>
|
|
||||||
|
|
||||||
<string name="shutdown_canceled">Planned shutdown canceled</string>
|
|
||||||
|
|
||||||
<string name="tunnels_reloading">Reloading tunnels config...</string>
|
|
||||||
</resources>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
|
|
||||||
|
|
||||||
<dimen name="margin_tiny">4dp</dimen>
|
|
||||||
<dimen name="margin_small">8dp</dimen>
|
|
||||||
<dimen name="margin_medium">16dp</dimen>
|
|
||||||
<dimen name="margin_large">32dp</dimen>
|
|
||||||
<dimen name="margin_huge">64dp</dimen>
|
|
||||||
|
|
||||||
<!-- Semantic definitions -->
|
|
||||||
|
|
||||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
|
|
||||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
rootProject.name = "i2pd"
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.purplei2p.i2pd.R;
|
|
||||||
|
|
||||||
public class DaemonSingleton {
|
|
||||||
private static final String TAG = "i2pd";
|
|
||||||
private static final DaemonSingleton instance = new DaemonSingleton();
|
|
||||||
|
|
||||||
public interface StateUpdateListener {
|
|
||||||
void daemonStateUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
|
||||||
|
|
||||||
public static DaemonSingleton getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void addStateChangeListener(StateUpdateListener listener) {
|
|
||||||
stateUpdateListeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) {
|
|
||||||
stateUpdateListeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void setState(State newState) {
|
|
||||||
if (newState == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
|
|
||||||
State oldState = state;
|
|
||||||
|
|
||||||
if (oldState == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
|
|
||||||
if (oldState.equals(newState))
|
|
||||||
return;
|
|
||||||
|
|
||||||
state = newState;
|
|
||||||
fireStateUpdate1();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stopAcceptingTunnels() {
|
|
||||||
if (isStartedOkay()) {
|
|
||||||
setState(State.gracefulShutdownInProgress);
|
|
||||||
I2PD_JNI.stopAcceptingTunnels();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void startAcceptingTunnels() {
|
|
||||||
if (isStartedOkay()) {
|
|
||||||
setState(State.startedOkay);
|
|
||||||
I2PD_JNI.startAcceptingTunnels();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reloadTunnelsConfigs() {
|
|
||||||
if (isStartedOkay()) {
|
|
||||||
I2PD_JNI.reloadTunnelsConfigs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int GetTransitTunnelsCount() {
|
|
||||||
return I2PD_JNI.GetTransitTunnelsCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
private volatile boolean startedOkay;
|
|
||||||
|
|
||||||
public enum State {
|
|
||||||
uninitialized(R.string.uninitialized),
|
|
||||||
starting(R.string.starting),
|
|
||||||
jniLibraryLoaded(R.string.jniLibraryLoaded),
|
|
||||||
startedOkay(R.string.startedOkay),
|
|
||||||
startFailed(R.string.startFailed),
|
|
||||||
gracefulShutdownInProgress(R.string.gracefulShutdownInProgress),
|
|
||||||
stopped(R.string.stopped);
|
|
||||||
|
|
||||||
State(int statusStringResourceId) {
|
|
||||||
this.statusStringResourceId = statusStringResourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int statusStringResourceId;
|
|
||||||
|
|
||||||
public int getStatusStringResourceId() {
|
|
||||||
return statusStringResourceId;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private volatile State state = State.uninitialized;
|
|
||||||
|
|
||||||
public State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
setState(State.starting);
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
I2PD_JNI.loadLibraries();
|
|
||||||
setState(State.jniLibraryLoaded);
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
lastThrowable = tr;
|
|
||||||
setState(State.startFailed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
synchronized (DaemonSingleton.this) {
|
|
||||||
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
|
|
||||||
daemonStartResult = I2PD_JNI.startDaemon();
|
|
||||||
if ("ok".equals(daemonStartResult)) {
|
|
||||||
setState(State.startedOkay);
|
|
||||||
setStartedOkay(true);
|
|
||||||
} else
|
|
||||||
setState(State.startFailed);
|
|
||||||
}
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
lastThrowable = tr;
|
|
||||||
setState(State.startFailed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, "i2pdDaemonStart").start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Throwable lastThrowable;
|
|
||||||
private String daemonStartResult = "N/A";
|
|
||||||
|
|
||||||
private void fireStateUpdate1() {
|
|
||||||
Log.i(TAG, "daemon state change: " + state);
|
|
||||||
for (StateUpdateListener listener : stateUpdateListeners) {
|
|
||||||
try {
|
|
||||||
listener.daemonStateUpdate();
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "exception in listener ignored", tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable getLastThrowable() {
|
|
||||||
return lastThrowable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDaemonStartResult() {
|
|
||||||
return daemonStartResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Object startedOkayLock = new Object();
|
|
||||||
|
|
||||||
public boolean isStartedOkay() {
|
|
||||||
synchronized (startedOkayLock) {
|
|
||||||
return startedOkay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setStartedOkay(boolean startedOkay) {
|
|
||||||
synchronized (startedOkayLock) {
|
|
||||||
this.startedOkay = startedOkay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stopDaemon() {
|
|
||||||
if (isStartedOkay()) {
|
|
||||||
try {
|
|
||||||
I2PD_JNI.stopDaemon();
|
|
||||||
} catch(Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
setStartedOkay(false);
|
|
||||||
setState(State.stopped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class ForegroundService extends Service {
|
|
||||||
private static final String TAG="FgService";
|
|
||||||
|
|
||||||
private volatile boolean shown;
|
|
||||||
|
|
||||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
|
||||||
new DaemonSingleton.StateUpdateListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void daemonStateUpdate() {
|
|
||||||
try {
|
|
||||||
synchronized (ForegroundService.this) {
|
|
||||||
if (shown) cancelNotification();
|
|
||||||
showNotification();
|
|
||||||
}
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG,"error ignored",tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
|
||||||
|
|
||||||
// Unique Identification Number for the Notification.
|
|
||||||
// We use it on Notification start, and to cancel it.
|
|
||||||
private int NOTIFICATION = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for clients to access. Because we know this service always
|
|
||||||
* runs in the same process as its clients, we don't need to deal with
|
|
||||||
* IPC.
|
|
||||||
*/
|
|
||||||
public class LocalBinder extends Binder {
|
|
||||||
ForegroundService getService() {
|
|
||||||
return ForegroundService.this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
|
||||||
if (!shown) daemonStateUpdatedListener.daemonStateUpdate();
|
|
||||||
}
|
|
||||||
// Tell the user we started.
|
|
||||||
// Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener);
|
|
||||||
cancelNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void cancelNotification() {
|
|
||||||
// Cancel the persistent notification.
|
|
||||||
notificationManager.cancel(NOTIFICATION);
|
|
||||||
|
|
||||||
stopForeground(true);
|
|
||||||
|
|
||||||
// Tell the user we stopped.
|
|
||||||
//Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
|
||||||
shown=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
return mBinder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the object that receives interactions from clients. See
|
|
||||||
// RemoteService for a more complete example.
|
|
||||||
private final IBinder mBinder = new LocalBinder();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a notification while this service is running.
|
|
||||||
*/
|
|
||||||
private synchronized void showNotification() {
|
|
||||||
// In this sample, we'll use the same text for the ticker and the expanded notification
|
|
||||||
CharSequence text = getText(DaemonSingleton.getInstance().getState().getStatusStringResourceId());
|
|
||||||
|
|
||||||
// The PendingIntent to launch our activity if the user selects this notification
|
|
||||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
|
|
||||||
new Intent(this, I2PDActivity.class), 0);
|
|
||||||
|
|
||||||
// If earlier version channel ID is not used
|
|
||||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
|
||||||
String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : "";
|
|
||||||
|
|
||||||
// Set the info for the views that show in the notification panel.
|
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
|
|
||||||
.setOngoing(true)
|
|
||||||
.setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon
|
|
||||||
if(Build.VERSION.SDK_INT >= 16) builder = builder.setPriority(Notification.PRIORITY_DEFAULT);
|
|
||||||
if(Build.VERSION.SDK_INT >= 21) builder = builder.setCategory(Notification.CATEGORY_SERVICE);
|
|
||||||
Notification notification = builder
|
|
||||||
.setTicker(text) // the status text
|
|
||||||
.setWhen(System.currentTimeMillis()) // the time stamp
|
|
||||||
.setContentTitle(getText(R.string.app_name)) // the label of the entry
|
|
||||||
.setContentText(text) // the contents of the entry
|
|
||||||
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Send the notification.
|
|
||||||
//mNM.notify(NOTIFICATION, notification);
|
|
||||||
startForeground(NOTIFICATION, notification);
|
|
||||||
shown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
private synchronized String createNotificationChannel() {
|
|
||||||
String channelId = getString(R.string.app_name);
|
|
||||||
CharSequence channelName = "I2Pd service";
|
|
||||||
NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
|
|
||||||
//chan.setLightColor(Color.PURPLE);
|
|
||||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
|
||||||
NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
if(service!=null)service.createNotificationChannel(chan);
|
|
||||||
else Log.e(TAG, "error: NOTIFICATION_SERVICE is null");
|
|
||||||
return channelId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
|
||||||
}
|
|
||||||
@@ -1,654 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.PowerManager;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
// For future package update checking
|
|
||||||
|
|
||||||
import android.webkit.WebSettings;
|
|
||||||
import android.webkit.WebView;
|
|
||||||
import android.webkit.WebViewClient;
|
|
||||||
|
|
||||||
|
|
||||||
import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS;
|
|
||||||
|
|
||||||
public class I2PDActivity extends Activity {
|
|
||||||
private WebView webView;
|
|
||||||
|
|
||||||
private static final String TAG = "i2pdActvt";
|
|
||||||
private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
|
|
||||||
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
|
|
||||||
public static final String PACKAGE_URI_SCHEME = "package:";
|
|
||||||
|
|
||||||
private TextView textView;
|
|
||||||
private boolean assetsCopied;
|
|
||||||
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
|
|
||||||
//private ConfigParser parser = new ConfigParser(i2pdpath); // TODO:
|
|
||||||
|
|
||||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
|
||||||
|
|
||||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = new DaemonSingleton.StateUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void daemonStateUpdate() {
|
|
||||||
processAssets();
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
try {
|
|
||||||
if (textView == null)
|
|
||||||
return;
|
|
||||||
Throwable tr = daemon.getLastThrowable();
|
|
||||||
if (tr!=null) {
|
|
||||||
textView.setText(throwableToString(tr));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DaemonSingleton.State state = daemon.getState();
|
|
||||||
String startResultStr = DaemonSingleton.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
|
|
||||||
String graceStr = DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
|
|
||||||
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG,"error ignored",tr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private static volatile long graceStartedMillis;
|
|
||||||
private static final Object graceStartedMillis_LOCK = new Object();
|
|
||||||
private Menu optionsMenu;
|
|
||||||
|
|
||||||
private static String formatGraceTimeRemaining() {
|
|
||||||
long remainingSeconds;
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
remainingSeconds = Math.round(Math.max(0, graceStartedMillis + GRACEFUL_DELAY_MILLIS - System.currentTimeMillis()) / 1000.0D);
|
|
||||||
}
|
|
||||||
long remainingMinutes = (long)Math.floor(remainingSeconds / 60.0D);
|
|
||||||
long remSec = remainingSeconds - remainingMinutes * 60;
|
|
||||||
return remainingMinutes + ":" + (remSec / 10) + remSec % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log.i(TAG, "onCreate");
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
textView = new TextView(this);
|
|
||||||
setContentView(textView);
|
|
||||||
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
|
||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
|
||||||
|
|
||||||
// request permissions
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
ActivityCompat.requestPermissions(this,
|
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the app be foreground
|
|
||||||
doBindService();
|
|
||||||
|
|
||||||
final Timer gracefulQuitTimer = getGracefulQuitTimer();
|
|
||||||
if (gracefulQuitTimer != null) {
|
|
||||||
long gracefulStopAtMillis;
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
|
||||||
}
|
|
||||||
rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis);
|
|
||||||
}
|
|
||||||
|
|
||||||
openBatteryOptimizationDialogIfNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
textView = null;
|
|
||||||
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
|
||||||
//cancelGracefulStop0();
|
|
||||||
try {
|
|
||||||
doUnbindService();
|
|
||||||
} catch(Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
|
||||||
{
|
|
||||||
if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
|
|
||||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
|
||||||
Log.e(TAG, "WR_EXT_STORAGE perm granted");
|
|
||||||
else {
|
|
||||||
Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd");
|
|
||||||
i2pdStop();
|
|
||||||
//TODO must work w/o this perm, ask orignal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelGracefulStop0() {
|
|
||||||
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
|
||||||
if (gracefulQuitTimer != null) {
|
|
||||||
gracefulQuitTimer.cancel();
|
|
||||||
setGracefulQuitTimer(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CharSequence throwableToString(Throwable tr) {
|
|
||||||
StringWriter sw = new StringWriter(8192);
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
tr.printStackTrace(pw);
|
|
||||||
pw.close();
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// private LocalService mBoundService;
|
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
|
||||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
|
||||||
// This is called when the connection with the service has been
|
|
||||||
// established, giving us the service object we can use to
|
|
||||||
// interact with the service. Because we have bound to a explicit
|
|
||||||
// service that we know is running in our own process, we can
|
|
||||||
// cast its IBinder to a concrete class and directly access it.
|
|
||||||
// mBoundService = ((LocalService.LocalBinder)service).getService();
|
|
||||||
|
|
||||||
// Tell the user about this for our demo.
|
|
||||||
// Toast.makeText(Binding.this, R.string.local_service_connected,
|
|
||||||
// Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName className) {
|
|
||||||
// This is called when the connection with the service has been
|
|
||||||
// unexpectedly disconnected -- that is, its process crashed.
|
|
||||||
// Because it is running in our same process, we should never
|
|
||||||
// see this happen.
|
|
||||||
// mBoundService = null;
|
|
||||||
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
|
|
||||||
// Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static volatile boolean mIsBound;
|
|
||||||
|
|
||||||
private void doBindService() {
|
|
||||||
synchronized (I2PDActivity.class) {
|
|
||||||
if (mIsBound)
|
|
||||||
return;
|
|
||||||
// Establish a connection with the service. We use an explicit
|
|
||||||
// class name because we want a specific service implementation that
|
|
||||||
// we know will be running in our own process (and thus won't be
|
|
||||||
// supporting component replacement by other applications).
|
|
||||||
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
mIsBound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doUnbindService() {
|
|
||||||
synchronized (I2PDActivity.class) {
|
|
||||||
if (mIsBound) {
|
|
||||||
// Detach our existing connection.
|
|
||||||
unbindService(mConnection);
|
|
||||||
mIsBound = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
|
||||||
getMenuInflater().inflate(R.menu.options_main, menu);
|
|
||||||
menu.findItem(R.id.action_battery_otimizations).setVisible(isBatteryOptimizationsOpenOsDialogApiAvailable());
|
|
||||||
this.optionsMenu = menu;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() {
|
|
||||||
return android.os.Build.VERSION.SDK_INT >= 23;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
|
||||||
// Handle action bar item clicks here. The action bar will
|
|
||||||
// automatically handle clicks on the Home/Up button, so long
|
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
switch(id) {
|
|
||||||
case R.id.action_stop:
|
|
||||||
i2pdStop();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.action_graceful_stop:
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
if (getGracefulQuitTimer() != null)
|
|
||||||
cancelGracefulStop();
|
|
||||||
else
|
|
||||||
i2pdGracefulStop();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.action_battery_otimizations:
|
|
||||||
onActionBatteryOptimizations();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.action_reload_tunnels_config:
|
|
||||||
onReloadTunnelsConfig();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.action_start_webview:
|
|
||||||
setContentView(R.layout.webview);
|
|
||||||
this.webView = (WebView) findViewById(R.id.webview1);
|
|
||||||
this.webView.setWebViewClient(new WebViewClient());
|
|
||||||
|
|
||||||
WebSettings webSettings = this.webView.getSettings();
|
|
||||||
webSettings.setBuiltInZoomControls(true);
|
|
||||||
webSettings.setJavaScriptEnabled(false);
|
|
||||||
this.webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onActionBatteryOptimizations() {
|
|
||||||
if (isBatteryOptimizationsOpenOsDialogApiAvailable()) {
|
|
||||||
try {
|
|
||||||
startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Log.e(TAG, "BATT_OPTIM_DIALOG_ActvtNotFound", e);
|
|
||||||
Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onReloadTunnelsConfig() {
|
|
||||||
Log.d(TAG, "reloading tunnels");
|
|
||||||
daemon.reloadTunnelsConfigs();
|
|
||||||
Toast.makeText(this, R.string.tunnels_reloading, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void i2pdStop() {
|
|
||||||
cancelGracefulStop0();
|
|
||||||
new Thread(() -> {
|
|
||||||
Log.d(TAG, "stopping");
|
|
||||||
try {
|
|
||||||
daemon.stopDaemon();
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd.
|
|
||||||
}, "stop").start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static volatile Timer gracefulQuitTimer;
|
|
||||||
|
|
||||||
private void i2pdGracefulStop() {
|
|
||||||
if (daemon.getState() == DaemonSingleton.State.stopped) {
|
|
||||||
Toast.makeText(this, R.string.already_stopped, Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (getGracefulQuitTimer() != null) {
|
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress, Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_in_progress, Toast.LENGTH_SHORT).show();
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "graceful stopping");
|
|
||||||
if (daemon.isStartedOkay()) {
|
|
||||||
daemon.stopAcceptingTunnels();
|
|
||||||
long gracefulStopAtMillis;
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
graceStartedMillis = System.currentTimeMillis();
|
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
|
||||||
}
|
|
||||||
rescheduleGraceStop(null, gracefulStopAtMillis);
|
|
||||||
} else
|
|
||||||
i2pdStop();
|
|
||||||
} catch(Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
}, "gracInit").start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelGracefulStop()
|
|
||||||
{
|
|
||||||
cancelGracefulStop0();
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "canceling graceful stop");
|
|
||||||
if (daemon.isStartedOkay()) {
|
|
||||||
daemon.startAcceptingTunnels();
|
|
||||||
runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show());
|
|
||||||
} else
|
|
||||||
i2pdStop();
|
|
||||||
} catch(Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
}, "gracCancel").start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
|
|
||||||
if (gracefulQuitTimerOld != null)
|
|
||||||
gracefulQuitTimerOld.cancel();
|
|
||||||
|
|
||||||
if(daemon.GetTransitTunnelsCount() <= 0) { // no tunnels left
|
|
||||||
Log.d(TAG, "no transit tunnels left, stopping");
|
|
||||||
i2pdStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Timer gracefulQuitTimer = new Timer(true);
|
|
||||||
setGracefulQuitTimer(gracefulQuitTimer);
|
|
||||||
gracefulQuitTimer.schedule(new TimerTask() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
i2pdStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}, Math.max(0, gracefulStopAtMillis - System.currentTimeMillis()));
|
|
||||||
final TimerTask tickerTask = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
gracefulQuitTimer.scheduleAtFixedRate(tickerTask, 0/*start delay*/, 1000/*millis period*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Timer getGracefulQuitTimer() {
|
|
||||||
return gracefulQuitTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setGracefulQuitTimer(Timer gracefulQuitTimer) {
|
|
||||||
I2PDActivity.gracefulQuitTimer = gracefulQuitTimer;
|
|
||||||
runOnUiThread(()-> {
|
|
||||||
Menu menu = optionsMenu;
|
|
||||||
if (menu != null) {
|
|
||||||
MenuItem item = menu.findItem(R.id.action_graceful_stop);
|
|
||||||
if (item != null) {
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
item.setTitle(getGracefulQuitTimer() != null ? R.string.action_cancel_graceful_stop : R.string.action_graceful_stop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the asset at the specified path to this app's data directory. If the
|
|
||||||
* asset is a directory, its contents are also copied.
|
|
||||||
*
|
|
||||||
* @param path
|
|
||||||
* Path to asset, relative to app's assets directory.
|
|
||||||
*/
|
|
||||||
private void copyAsset(String path) {
|
|
||||||
AssetManager manager = getAssets();
|
|
||||||
|
|
||||||
// If we have a directory, we make it and recurse. If a file, we copy its
|
|
||||||
// contents.
|
|
||||||
try {
|
|
||||||
String[] contents = manager.list(path);
|
|
||||||
|
|
||||||
// The documentation suggests that list throws an IOException, but doesn't
|
|
||||||
// say under what conditions. It'd be nice if it did so when the path was
|
|
||||||
// to a file. That doesn't appear to be the case. If the returned array is
|
|
||||||
// null or has 0 length, we assume the path is to a file. This means empty
|
|
||||||
// directories will get turned into files.
|
|
||||||
if (contents == null || contents.length == 0) {
|
|
||||||
copyFileAsset(path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the directory.
|
|
||||||
File dir = new File(i2pdpath, path);
|
|
||||||
boolean result = dir.mkdirs();
|
|
||||||
Log.d(TAG, "dir.mkdirs() returned " + result);
|
|
||||||
|
|
||||||
// Recurse on the contents.
|
|
||||||
for (String entry : contents) {
|
|
||||||
copyAsset(path + '/' + entry);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "ex ignored for path='" + path + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the asset file specified by path to app's data directory. Assumes
|
|
||||||
* parent directories have already been created.
|
|
||||||
*
|
|
||||||
* @param path
|
|
||||||
* Path to asset, relative to app's assets directory.
|
|
||||||
*/
|
|
||||||
private void copyFileAsset(String path) {
|
|
||||||
File file = new File(i2pdpath, path);
|
|
||||||
if (!file.exists()) {
|
|
||||||
try {
|
|
||||||
try (InputStream in = getAssets().open(path)) {
|
|
||||||
try (OutputStream out = new FileOutputStream(file)) {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int read = in.read(buffer);
|
|
||||||
while (read != -1) {
|
|
||||||
out.write(buffer, 0, read);
|
|
||||||
read = in.read(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteRecursive(File fileOrDirectory) {
|
|
||||||
if (fileOrDirectory.isDirectory()) {
|
|
||||||
File[] files = fileOrDirectory.listFiles();
|
|
||||||
if (files != null) {
|
|
||||||
for (File child : files) {
|
|
||||||
deleteRecursive(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean deleteResult = fileOrDirectory.delete();
|
|
||||||
if (!deleteResult)
|
|
||||||
Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processAssets() {
|
|
||||||
if (!assetsCopied) {
|
|
||||||
try {
|
|
||||||
assetsCopied = true; // prevent from running on every state update
|
|
||||||
|
|
||||||
File holderFile = new File(i2pdpath, "assets.ready");
|
|
||||||
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
|
|
||||||
StringBuilder text = new StringBuilder();
|
|
||||||
|
|
||||||
if (holderFile.exists()) {
|
|
||||||
try { // if holder file exists, read assets version string
|
|
||||||
FileReader fileReader = new FileReader(holderFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
BufferedReader br = new BufferedReader(fileReader);
|
|
||||||
|
|
||||||
try {
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
text.append(line);
|
|
||||||
}
|
|
||||||
}finally {
|
|
||||||
try {
|
|
||||||
br.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
fileReader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if version differs from current app version or null, try to delete certificates folder
|
|
||||||
if (!text.toString().contains(versionName))
|
|
||||||
try {
|
|
||||||
boolean deleteResult = holderFile.delete();
|
|
||||||
if (!deleteResult)
|
|
||||||
Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'");
|
|
||||||
File certPath = new File(i2pdpath, "certificates");
|
|
||||||
deleteRecursive(certPath);
|
|
||||||
}
|
|
||||||
catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy assets. If processed file exists, it won't be overwritten
|
|
||||||
copyAsset("addressbook");
|
|
||||||
copyAsset("certificates");
|
|
||||||
copyAsset("tunnels.d");
|
|
||||||
copyAsset("i2pd.conf");
|
|
||||||
copyAsset("subscriptions.txt");
|
|
||||||
copyAsset("tunnels.conf");
|
|
||||||
|
|
||||||
// update holder file about successful copying
|
|
||||||
FileWriter writer = new FileWriter(holderFile);
|
|
||||||
try {
|
|
||||||
writer.append(versionName);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG,"on writer close", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable tr)
|
|
||||||
{
|
|
||||||
Log.e(TAG,"on assets copying", tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("BatteryLife")
|
|
||||||
private void openBatteryOptimizationDialogIfNeeded() {
|
|
||||||
boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true);
|
|
||||||
Log.i(TAG, "BATT_OPTIM_questionEnabled==" + questionEnabled);
|
|
||||||
if (!isKnownIgnoringBatteryOptimizations()
|
|
||||||
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
|
|
||||||
&& questionEnabled) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.battery_optimizations_enabled);
|
|
||||||
builder.setMessage(R.string.battery_optimizations_enabled_dialog);
|
|
||||||
builder.setPositiveButton(R.string.continue_str, (dialog, which) -> {
|
|
||||||
try {
|
|
||||||
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName())));
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Log.e(TAG, "BATT_OPTIM_ActvtNotFound", e);
|
|
||||||
Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain());
|
|
||||||
final AlertDialog dialog = builder.create();
|
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setNeverAskForBatteryOptimizationsAgain() {
|
|
||||||
getPreferences().edit().putBoolean(getBatteryOptimizationPreferenceKey(), false).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isKnownIgnoringBatteryOptimizations() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
|
||||||
if (pm == null) {
|
|
||||||
Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName());
|
|
||||||
Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring);
|
|
||||||
return ignoring;
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "BATT_OPTIM: old sdk version==" + Build.VERSION.SDK_INT);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SharedPreferences getPreferences() {
|
|
||||||
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getBatteryOptimizationPreferenceKey() {
|
|
||||||
@SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
|
|
||||||
return "show_battery_optimization" + (device == null ? "" : device);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void quit() {
|
|
||||||
try {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
finishAndRemoveTask();
|
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
finishAffinity();
|
|
||||||
} else {
|
|
||||||
//moveTaskToBack(true);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
daemon.stopDaemon();
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
//dangerous perms, per https://developer.android.com/guide/topics/permissions/normal-permissions.html :
|
|
||||||
//android.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
public class I2PDPermsAskerActivity extends Activity {
|
|
||||||
|
|
||||||
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
|
|
||||||
|
|
||||||
private Button button_request_write_ext_storage_perms;
|
|
||||||
private TextView textview_retry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
//if less than Android 6, no runtime perms req system present
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 23) {
|
|
||||||
startMainActivity();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_perms_asker);
|
|
||||||
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
|
|
||||||
textview_retry = (TextView) findViewById(R.id.textview_retry);
|
|
||||||
|
|
||||||
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
request_write_ext_storage_perms();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request_write_ext_storage_perms();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void request_write_ext_storage_perms() {
|
|
||||||
|
|
||||||
textview_retry.setVisibility(TextView.GONE);
|
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
|
|
||||||
|
|
||||||
Method methodCheckPermission;
|
|
||||||
Method method_shouldShowRequestPermissionRationale;
|
|
||||||
Method method_requestPermissions;
|
|
||||||
try {
|
|
||||||
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
|
|
||||||
method_shouldShowRequestPermissionRationale =
|
|
||||||
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
|
|
||||||
method_requestPermissions =
|
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
Integer resultObj;
|
|
||||||
try {
|
|
||||||
resultObj = (Integer) methodCheckPermission.invoke(
|
|
||||||
this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultObj != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
// Should we show an explanation?
|
|
||||||
Boolean aBoolean;
|
|
||||||
try {
|
|
||||||
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
if (aBoolean) {
|
|
||||||
|
|
||||||
// Show an explanation to the user *asynchronously* -- don't block
|
|
||||||
// this thread waiting for the user's response! After the user
|
|
||||||
// sees the explanation, try again to request the permission.
|
|
||||||
|
|
||||||
showExplanation();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// No explanation needed, we can request the permission.
|
|
||||||
|
|
||||||
try {
|
|
||||||
method_requestPermissions.invoke(this,
|
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else startMainActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
|
||||||
String permissions[], int[] grantResults) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
|
|
||||||
// If request is cancelled, the result arrays are empty.
|
|
||||||
if (grantResults.length > 0
|
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
// permission was granted, yay! Do the
|
|
||||||
// contacts-related task you need to do.
|
|
||||||
|
|
||||||
startMainActivity();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// permission denied, boo! Disable the
|
|
||||||
// functionality that depends on this permission.
|
|
||||||
textview_retry.setText(R.string.permDenied);
|
|
||||||
textview_retry.setVisibility(TextView.VISIBLE);
|
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// other 'case' lines to check for other
|
|
||||||
// permissions this app might request.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startMainActivity() {
|
|
||||||
startActivity(new Intent(this, I2PDActivity.class));
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
|
||||||
private void showExplanation() {
|
|
||||||
Intent intent = new Intent(this, I2PDPermsExplanationActivity.class);
|
|
||||||
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
// Check which request we're responding to
|
|
||||||
if (requestCode == SHOW_EXPLANATION_REQUEST) {
|
|
||||||
// Make sure the request was successful
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
// Request the permission
|
|
||||||
Method method_requestPermissions;
|
|
||||||
try {
|
|
||||||
method_requestPermissions =
|
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
method_requestPermissions.invoke(this,
|
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
finish(); //close the app
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import android.app.ActionBar;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
public class I2PDPermsExplanationActivity extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_perms_explanation);
|
|
||||||
ActionBar actionBar = getActionBar();
|
|
||||||
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
|
|
||||||
Button button_ok = (Button) findViewById(R.id.button_ok);
|
|
||||||
button_ok.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
returnFromActivity();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void returnFromActivity() {
|
|
||||||
Intent data = new Intent();
|
|
||||||
Activity parent = getParent();
|
|
||||||
if (parent == null) {
|
|
||||||
setResult(Activity.RESULT_OK, data);
|
|
||||||
} else {
|
|
||||||
parent.setResult(Activity.RESULT_OK, data);
|
|
||||||
}
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
public class I2PD_JNI {
|
|
||||||
public static native String getABICompiledWith();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns error info if failed
|
|
||||||
* returns "ok" if daemon initialized and started okay
|
|
||||||
*/
|
|
||||||
public static native String startDaemon();
|
|
||||||
|
|
||||||
//should only be called after startDaemon() success
|
|
||||||
public static native void stopDaemon();
|
|
||||||
|
|
||||||
public static native void stopAcceptingTunnels();
|
|
||||||
|
|
||||||
public static native void startAcceptingTunnels();
|
|
||||||
|
|
||||||
public static native void reloadTunnelsConfigs();
|
|
||||||
|
|
||||||
public static native void onNetworkStateChanged(boolean isConnected);
|
|
||||||
|
|
||||||
public static native void setDataDir(String jdataDir);
|
|
||||||
|
|
||||||
public static native int GetTransitTunnelsCount();
|
|
||||||
|
|
||||||
public static void loadLibraries() {
|
|
||||||
//System.loadLibrary("c++_shared");
|
|
||||||
System.loadLibrary("i2pd");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
|
|
||||||
public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
private static final String TAG = "i2pd";
|
|
||||||
|
|
||||||
//api level 1
|
|
||||||
@Override
|
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
|
||||||
Log.d(TAG,"Network state change");
|
|
||||||
try {
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
|
|
||||||
boolean isConnected = activeNetworkInfo!=null && activeNetworkInfo.isConnected();
|
|
||||||
// https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html?hl=ru
|
|
||||||
// boolean isWiFi = activeNetworkInfo!=null && (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
|
|
||||||
|
|
||||||
I2PD_JNI.onNetworkStateChanged(isConnected);
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.d(TAG,"",tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
41
appveyor.yml
41
appveyor.yml
@@ -1,4 +1,4 @@
|
|||||||
version: 2.32.1.{build}
|
version: 2.37.0.{build}
|
||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
branches:
|
branches:
|
||||||
@@ -9,32 +9,49 @@ os: Visual Studio 2015
|
|||||||
shallow_clone: true
|
shallow_clone: true
|
||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
|
|
||||||
|
# avoid building 32-bit if 64-bit failed already
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
APPVEYOR_SAVE_CACHE_ON_ERROR: true
|
||||||
MSYS2_PATH_TYPE: inherit
|
MSYS2_PATH_TYPE: inherit
|
||||||
CHERE_INVOKING: enabled_from_arguments
|
CHERE_INVOKING: enabled_from_arguments
|
||||||
matrix:
|
matrix:
|
||||||
- MSYSTEM: MINGW64
|
- MSYSTEM: MINGW64
|
||||||
MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc
|
|
||||||
MSYS_BITNESS: 64
|
|
||||||
- MSYSTEM: MINGW32
|
- MSYSTEM: MINGW32
|
||||||
MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc
|
|
||||||
MSYS_BITNESS: 32
|
cache:
|
||||||
|
- c:\msys64\var\cache\pacman\pkg\
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
# install new signing keyring
|
||||||
|
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
||||||
|
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
||||||
|
- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
||||||
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
||||||
|
# remove packages which can break build
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc"
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc"
|
||||||
# TODO: revert that change when appveyor's images will be updated
|
|
||||||
- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash"
|
|
||||||
# update runtime
|
# update runtime
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
||||||
|
# Kill bash before next try
|
||||||
|
- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0
|
||||||
# update packages and install required
|
# update packages and install required
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}"
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc"
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS%
|
- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3"
|
||||||
- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3"
|
# prepare archive for uploading
|
||||||
- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe
|
- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
||||||
|
- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt
|
||||||
|
- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST%
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc"
|
||||||
|
|
||||||
test: off
|
test: off
|
||||||
|
|
||||||
|
deploy: off
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: i2pd-mingw-win*.zip
|
- path: i2pd-*.zip
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ if(WIN32 OR MSVC OR MSYS OR MINGW)
|
|||||||
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
|
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# configurale options
|
# configurable options
|
||||||
option(WITH_AESNI "Use AES-NI instructions set" OFF)
|
option(WITH_AESNI "Use AES-NI instructions set" ON)
|
||||||
option(WITH_AVX "Use AVX instructions" OFF)
|
|
||||||
option(WITH_HARDENING "Use hardening compiler flags" OFF)
|
option(WITH_HARDENING "Use hardening compiler flags" OFF)
|
||||||
option(WITH_LIBRARY "Build library" ON)
|
option(WITH_LIBRARY "Build library" ON)
|
||||||
option(WITH_BINARY "Build binary" ON)
|
option(WITH_BINARY "Build binary" ON)
|
||||||
@@ -68,7 +67,6 @@ set(LIBI2PD_SRC
|
|||||||
"${LIBI2PD_SRC_DIR}/NetDb.cpp"
|
"${LIBI2PD_SRC_DIR}/NetDb.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/NetDbRequests.cpp"
|
"${LIBI2PD_SRC_DIR}/NetDbRequests.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
|
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/NTCPSession.cpp"
|
|
||||||
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
|
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Profiling.cpp"
|
"${LIBI2PD_SRC_DIR}/Profiling.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Reseed.cpp"
|
"${LIBI2PD_SRC_DIR}/Reseed.cpp"
|
||||||
@@ -86,6 +84,7 @@ set(LIBI2PD_SRC
|
|||||||
"${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp"
|
"${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/TunnelGateway.cpp"
|
"${LIBI2PD_SRC_DIR}/TunnelGateway.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/TunnelPool.cpp"
|
"${LIBI2PD_SRC_DIR}/TunnelPool.cpp"
|
||||||
|
"${LIBI2PD_SRC_DIR}/TunnelConfig.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/util.cpp"
|
"${LIBI2PD_SRC_DIR}/util.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -189,13 +188,11 @@ if(UNIX)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_AESNI)
|
# Note: AES-NI and AVX is available on x86-based CPU's.
|
||||||
|
# Here also ARM64 implementation, but currently we don't support it.
|
||||||
|
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||||
add_definitions(-DAESNI)
|
add_definitions(-D__AES__)
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_AVX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_ADDRSANITIZER)
|
if(WITH_ADDRSANITIZER)
|
||||||
@@ -309,7 +306,6 @@ message(STATUS "Architecture : ${ARCHITECTURE}")
|
|||||||
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
|
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
|
||||||
message(STATUS "Options:")
|
message(STATUS "Options:")
|
||||||
message(STATUS " AESNI : ${WITH_AESNI}")
|
message(STATUS " AESNI : ${WITH_AESNI}")
|
||||||
message(STATUS " AVX : ${WITH_AVX}")
|
|
||||||
message(STATUS " HARDENING : ${WITH_HARDENING}")
|
message(STATUS " HARDENING : ${WITH_HARDENING}")
|
||||||
message(STATUS " LIBRARY : ${WITH_LIBRARY}")
|
message(STATUS " LIBRARY : ${WITH_LIBRARY}")
|
||||||
message(STATUS " BINARY : ${WITH_BINARY}")
|
message(STATUS " BINARY : ${WITH_BINARY}")
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
set -e -x
|
|
||||||
|
|
||||||
base_url='http://repo.msys2.org/msys/x86_64/'
|
|
||||||
packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz"
|
|
||||||
for p in $packages
|
|
||||||
do
|
|
||||||
curl "${base_url}$p" -o "$p"
|
|
||||||
done
|
|
||||||
pacman -U --noconfirm $packages
|
|
||||||
rm -f $packages
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
setlocal enableextensions enabledelayedexpansion
|
setlocal enableextensions enabledelayedexpansion
|
||||||
title Building i2pd
|
title Building i2pd
|
||||||
|
|
||||||
REM Copyright (c) 2013-2017, The PurpleI2P Project
|
REM Copyright (c) 2013-2020, 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
|
||||||
|
|
||||||
@@ -23,17 +23,17 @@ set "xSH=%WD%bash -lc"
|
|||||||
|
|
||||||
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
||||||
|
|
||||||
REM detecting number of processors and subtract 1.
|
REM detecting number of processors
|
||||||
set /a threads=%NUMBER_OF_PROCESSORS%-1
|
set /a threads=%NUMBER_OF_PROCESSORS%
|
||||||
|
|
||||||
REM we must work in root of repo
|
REM we must work in root of repo
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
REM deleting old log files
|
REM deleting old log files
|
||||||
del /S build_*.log >> nul
|
del /S build_*.log >> nul 2>&1
|
||||||
|
|
||||||
echo Receiving latest commit and cleaning up...
|
echo Receiving latest commit and cleaning up...
|
||||||
%xSH% "git pull && make clean" > build/build_git.log 2>&1
|
%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM set to variable current commit hash
|
REM set to variable current commit hash
|
||||||
@@ -43,16 +43,17 @@ FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO (
|
|||||||
|
|
||||||
%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)
|
||||||
|
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" >> build\build.log 2>&1
|
||||||
|
|
||||||
REM starting building
|
REM starting building
|
||||||
set MSYSTEM=MINGW32
|
set MSYSTEM=MINGW32
|
||||||
set bitness=32
|
set bitness=32
|
||||||
call :BUILDING
|
call :BUILDING
|
||||||
echo.
|
|
||||||
|
|
||||||
set MSYSTEM=MINGW64
|
set MSYSTEM=MINGW64
|
||||||
set bitness=64
|
set bitness=64
|
||||||
call :BUILDING
|
call :BUILDING
|
||||||
echo.
|
|
||||||
|
|
||||||
REM building for WinXP
|
REM building for WinXP
|
||||||
set "WD=C:\msys64-xp\usr\bin\"
|
set "WD=C:\msys64-xp\usr\bin\"
|
||||||
@@ -62,7 +63,10 @@ set "xSH=%WD%bash -lc"
|
|||||||
call :BUILDING_XP
|
call :BUILDING_XP
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
del README.txt >> nul
|
REM compile installer
|
||||||
|
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%tag%.0" build\win_installer.iss >> build\build.log 2>&1
|
||||||
|
|
||||||
|
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
|
||||||
|
|
||||||
echo Build complete...
|
echo Build complete...
|
||||||
pause
|
pause
|
||||||
@@ -70,20 +74,13 @@ 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%
|
||||||
echo Build AVX+AESNI...
|
%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
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_aesni_%tag%.log 2>&1
|
|
||||||
echo Build AVX...
|
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_%tag%.log 2>&1
|
|
||||||
echo Build AESNI...
|
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1
|
|
||||||
echo Build without extensions...
|
|
||||||
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1
|
|
||||||
goto EOF
|
goto EOF
|
||||||
|
|
||||||
:BUILDING_XP
|
:BUILDING_XP
|
||||||
%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% && 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% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1
|
||||||
|
|
||||||
:EOF
|
:EOF
|
||||||
@@ -1,32 +1,46 @@
|
|||||||
#define I2Pd_AppName "i2pd"
|
#define I2Pd_AppName "i2pd"
|
||||||
#define I2Pd_ver "2.32.1"
|
|
||||||
#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}
|
||||||
AppVersion={#I2Pd_ver}
|
AppVersion={#I2Pd_TextVer}
|
||||||
AppPublisher={#I2Pd_Publisher}
|
AppPublisher={#I2Pd_Publisher}
|
||||||
|
|
||||||
DefaultDirName={pf}\I2Pd
|
DefaultDirName={pf}\I2Pd
|
||||||
DefaultGroupName=I2Pd
|
DefaultGroupName=I2Pd
|
||||||
UninstallDisplayIcon={app}\I2Pd.exe
|
UninstallDisplayIcon={app}\I2Pd.exe
|
||||||
OutputDir=.
|
OutputDir=.
|
||||||
LicenseFile=../LICENSE
|
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_TextVer}
|
||||||
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
|
|
||||||
SetupIconFile=mask.ico
|
LicenseFile=..\LICENSE
|
||||||
|
SetupIconFile=..\Win32\mask.ico
|
||||||
|
|
||||||
InternalCompressLevel=ultra64
|
InternalCompressLevel=ultra64
|
||||||
Compression=lzma/ultra64
|
Compression=lzma/ultra64
|
||||||
SolidCompression=true
|
SolidCompression=true
|
||||||
|
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
AppVerName={#I2Pd_AppName}
|
|
||||||
ExtraDiskSpaceRequired=15
|
ExtraDiskSpaceRequired=15
|
||||||
|
|
||||||
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
||||||
|
AppVerName={#I2Pd_AppName}
|
||||||
|
AppCopyright=Copyright (c) 2013-2020, 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
|
||||||
|
|
||||||
|
VersionInfoProductVersion={#I2Pd_Ver}
|
||||||
|
VersionInfoVersion={#I2Pd_Ver}
|
||||||
|
|
||||||
|
CloseApplications=yes
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64
|
Source: ..\i2pd_x32.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64; MinVersion: 6.0
|
||||||
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64
|
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; MinVersion: 6.0
|
||||||
|
Source: ..\i2pd_xp.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; OnlyBelowVersion: 6.0
|
||||||
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
|
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
|
||||||
Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||||
Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||||
0
android_binary_only/jni/Android.mk → contrib/android_binary_only/jni/Android.mk
Executable file → Normal file
0
android_binary_only/jni/Android.mk → contrib/android_binary_only/jni/Android.mk
Executable file → Normal file
2
android_binary_only/jni/Application.mk → contrib/android_binary_only/jni/Application.mk
Executable file → Normal file
2
android_binary_only/jni/Application.mk → contrib/android_binary_only/jni/Application.mk
Executable file → Normal file
@@ -33,7 +33,7 @@ MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
|
|||||||
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
|
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
|
||||||
|
|
||||||
# don't change me
|
# don't change me
|
||||||
I2PD_SRC_PATH = $(PWD)/..
|
I2PD_SRC_PATH = $(PWD)/../..
|
||||||
|
|
||||||
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
|
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
|
||||||
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
|
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2013-2017, The PurpleI2P Project
|
# Copyright (c) 2013-2020, 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
|
||||||
#
|
#
|
||||||
@@ -20,7 +20,7 @@ if [ -d archive ]; then
|
|||||||
rm -r archive
|
rm -r archive
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f i2pd_*_android_binary.zip ]; then
|
if [ -f ../i2pd_*_android_binary.zip ]; then
|
||||||
rm i2pd_*_android_binary.zip
|
rm i2pd_*_android_binary.zip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -28,13 +28,16 @@ fi
|
|||||||
mkdir archive
|
mkdir archive
|
||||||
|
|
||||||
for ABI in "${!ABILIST[@]}"; do
|
for ABI in "${!ABILIST[@]}"; do
|
||||||
if [ -f ../../android_binary_only/libs/${ABI}/i2pd ]; then
|
if [ -f ../android_binary_only/libs/${ABI}/i2pd ]; then
|
||||||
cp ../../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
|
cp ../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
cp i2pd archive/i2pd
|
cp i2pd archive/i2pd
|
||||||
cp -rH ../../android/assets/* archive/
|
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
|
# Compress files
|
||||||
cd archive
|
cd archive
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Copyright (c) 2013-2019, The PurpleI2P Project
|
# Copyright (c) 2013-2020, 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
|
||||||
#
|
#
|
||||||
@@ -21,13 +21,13 @@ arch=$(uname -m)
|
|||||||
|
|
||||||
screenfind=$(which screen)
|
screenfind=$(which screen)
|
||||||
if [ -z $screenfind ]; then
|
if [ -z $screenfind ]; then
|
||||||
echo "Can't find 'screen' installed. That script needs it!";
|
echo "Can't find 'screen' installed. That script needs it!";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z i2pd-$arch ]; then
|
if [ -z i2pd-$arch ]; then
|
||||||
echo "Can't find i2pd binary for your archtecture.";
|
echo "Can't find i2pd binary for your archtecture.";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR
|
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR
|
||||||
|
|||||||
@@ -4,34 +4,22 @@
|
|||||||
#
|
#
|
||||||
#include <tunables/global>
|
#include <tunables/global>
|
||||||
|
|
||||||
/usr/sbin/i2pd {
|
profile i2pd /{usr/,}sbin/i2pd {
|
||||||
#include <abstractions/base>
|
#include <abstractions/base>
|
||||||
|
#include <abstractions/openssl>
|
||||||
network inet dgram,
|
#include <abstractions/nameservice>
|
||||||
network inet stream,
|
|
||||||
network inet6 dgram,
|
|
||||||
network inet6 stream,
|
|
||||||
network netlink raw,
|
|
||||||
|
|
||||||
/etc/gai.conf r,
|
|
||||||
/etc/host.conf r,
|
|
||||||
/etc/hosts r,
|
|
||||||
/etc/nsswitch.conf r,
|
|
||||||
/etc/resolv.conf r,
|
|
||||||
/run/resolvconf/resolv.conf r,
|
|
||||||
/run/systemd/resolve/resolv.conf r,
|
|
||||||
/run/systemd/resolve/stub-resolv.conf r,
|
|
||||||
|
|
||||||
# path specific (feel free to modify if you have another paths)
|
# path specific (feel free to modify if you have another paths)
|
||||||
/etc/i2pd/** r,
|
/etc/i2pd/** r,
|
||||||
/run/i2pd/i2pd.pid rwk,
|
|
||||||
/var/lib/i2pd/** rw,
|
/var/lib/i2pd/** rw,
|
||||||
/var/log/i2pd/i2pd.log w,
|
/var/log/i2pd/i2pd.log w,
|
||||||
/var/run/i2pd/i2pd.pid rwk,
|
/{var/,}run/i2pd/i2pd.pid rwk,
|
||||||
/usr/sbin/i2pd mr,
|
/{usr/,}sbin/i2pd mr,
|
||||||
/usr/share/i2pd/** r,
|
@{system_share_dirs}/i2pd/** r,
|
||||||
|
|
||||||
# user homedir (if started not by init.d or systemd)
|
# user homedir (if started not by init.d or systemd)
|
||||||
owner @{HOME}/.i2pd/ rw,
|
owner @{HOME}/.i2pd/ rw,
|
||||||
owner @{HOME}/.i2pd/** rwk,
|
owner @{HOME}/.i2pd/** rwk,
|
||||||
|
|
||||||
|
#include if exists <local/usr.sbin.i2pd>
|
||||||
}
|
}
|
||||||
|
|||||||
32
contrib/certificates/reseed/acetone_at_mail.i2p.crt
Normal file
32
contrib/certificates/reseed/acetone_at_mail.i2p.crt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFfzCCA2egAwIBAgIEctG1gDANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY
|
||||||
|
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt
|
||||||
|
b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEZMBcGA1UEAwwQYWNldG9uZUBtYWls
|
||||||
|
LmkycDAeFw0yMTAxMjUxMDMyMjBaFw0zMTAxMjMxMDMyMjBaMHAxCzAJBgNVBAYT
|
||||||
|
AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u
|
||||||
|
eW1vdXMgTmV0d29yazEMMAoGA1UECwwDSTJQMRkwFwYDVQQDDBBhY2V0b25lQG1h
|
||||||
|
aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwqF/BRRmvZ54
|
||||||
|
5XArgxbytDi7m7MDjFE/whUADruHj/9jXGCxE8DDiiKTt3yhfakV0SNo5xk7AMD+
|
||||||
|
wqiSNC5JCHTm18gd2M4cQLIaOVRqucLLge4XVgk2WPX6OT98wfxh7mqA3wlSdEpj
|
||||||
|
dY3Txtkf7VfZLicG76/RBtLFW3aBdsn63hZaQqZE4x/5MJyPVZx59+lys5RmMi0o
|
||||||
|
LpXJy4HOu1/Gl1iKDJoI/ARFG3y7uP/B+ZtZBitJetTs0HcqycnNJq0tVZf2HiGF
|
||||||
|
JNy67AL4foxNYPXP6QsvXvp6LRpGANaBCkFCBlriSF+x1zO2H3uAkRnuLYXuKIfB
|
||||||
|
HudejTp4R57VgZGiHYoawHaF17FVAApue9G8O82XYECjhET35B9yFoOBHTvaMxLU
|
||||||
|
CKrmayH8KMQon95mfe1qpoO3/YDa8DCxkjAfjdtytat7nt2pGZMH6/cLJxcFiofh
|
||||||
|
RtRVvb+omv/X12j/6iCFrwP4NvBnAZsa736igbjpyee5n+CSyYxd9cJkRX1vQVk7
|
||||||
|
WFSqL58Pz+g6CKJmdMPvqNOfUQ6mieBeejmx35B4pLzLcoNxw8R3O1+I2l4dg042
|
||||||
|
dEydKRQNwdzOec4jYwnKR40iwIyZxpchXWGRbBdyF5RQCbIIo60QBJlfXMJ2svan
|
||||||
|
q5lYIeWeY3mlODXu4KH4K09y10KT8FsCAwEAAaMhMB8wHQYDVR0OBBYEFMh+DoIL
|
||||||
|
APNiu2o+6I9A49joNYQuMA0GCSqGSIb3DQEBDQUAA4ICAQBFeOJi0rmkqN5/E3IB
|
||||||
|
nE2x4mUeLI82tUcN2D3Yu8J81vy4DnH+oMRQFDtYEHW5pfirRmgSZ7MQwYQnqWLp
|
||||||
|
iTE7SyCxlqGrmVsYp7PzfS1pUT2QeWPtsNYUDdraG0Zr9BkIGB60VMhjMSa9WUrj
|
||||||
|
lbchzr6E/j/EsEOE7IK08JxIDKCDZM2LLwis4tAM6tmiylkMf2RlUBIRBs1TCO+q
|
||||||
|
x3yByttNE2P4nQyQVQpjc1qsaOMvJvbxun37dwo+oTQy+hwkA86BWTDRYdN3xwOk
|
||||||
|
OfAOtlX6zM/wCKMN0ZRnjZoh59ZCn4JXokt3IjZ4n8qJOuJFRKeKGmGeKA8uaGW8
|
||||||
|
ih5tdB99Gu5Z8LOT1FxAJKwQBn5My0JijPoMit4B0WKNC8hy2zc2YvNfflu1ZRj5
|
||||||
|
wF4E5ktbtT/LWFSoRPas/GFS8wSXk/kbSB0ArDcRRszb3JHqbALmSQxngz3rfwb3
|
||||||
|
SHwQIIg956gjMDueEX5CrGrMqigiK53b9fqtpghUrHDsqtEXqeImpAY65PX1asqo
|
||||||
|
metDNuETHF7XrAjP7TGJfnrYQyeK90iS7j1G68ScBGkKY2nsTnFoXkSk5s5D338E
|
||||||
|
SUzPaOlh91spmkVY6gQTVQ7BakADBHw+zBgDA1gBN/4JPvgN36hquj63+aG1cKy3
|
||||||
|
3ZUnv2ipo2fpr69NtuBnutK6gw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFezCCA2OgAwIBAgIEUQYyQjANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p
|
|
||||||
MnAwHhcNMTQxMTA2MDkxMTE0WhcNMjQxMTA1MDkxMTE0WjBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p
|
|
||||||
MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCrThOH0eSDT0VnCSBC
|
|
||||||
sqYmAydWH+O8eNttDXr2mSvZLhvAW+6/xHTkKhaWvkIvvS0Vh8hujMnD90Cgp4Fk
|
|
||||||
TKCxMj9K527o5xIZwWW05OevbjlBwIpVLO1PjmsfsoD1nIX14eEzJSEoAulKsv7V
|
|
||||||
jGUC/6hC11mmVvH9buQLSRv6sCjuAcMszmw3TAD+XYBIs+z57KuwYXtX3+OA543c
|
|
||||||
l1/ZKLYkkwY8cwzZqWDVWqTKP5TfVae58t40HhJk3bOsr21FZsaOjlmao3GO+d/3
|
|
||||||
exKuUGJRcolSqskL3sZ1ovFqko81obvvx0upI0YA0iMr/NRGl3VPuf/LJvRppYGc
|
|
||||||
LsJHgy9TIgtHvaXRi5Nt4CbKl9sZh/7WkkTTI5YGvevu00btlabAN+DSAZZqdsB3
|
|
||||||
wY8HhM1MHiA9SWsqwU65TwErcRrjNna2FiDHEu0xk5+/iAGl6CSKHZBmNcYKXSv8
|
|
||||||
cwShB0jjmciK0a05nC638RPgj0fng7KRrSglyzfjXRrljmZ40LSBL/GGMZMWpOM7
|
|
||||||
mEsBH5UZJ/2BEmjc9X9257zBdx8BK8y1TXpAligpNBsERcTw1WP1PJ35einZvlXW
|
|
||||||
qI3GwMf0sl26sn+evcK0gDl27jVDZ45MtNQEq64M4NV3Tn9zq0eg/39YvjVeqrI5
|
|
||||||
l7sxmYqYGR6BuSncwdc4x+t6swIDAQABoyEwHzAdBgNVHQ4EFgQU/REZ7NMbVZHr
|
|
||||||
Xkao6Q8Ccqv2kAMwDQYJKoZIhvcNAQENBQADggIBACc2YjLVNbl1kJUdg2klCLJt
|
|
||||||
5LjNTiIZa2Cha5GStlC/lyoRRge6+q/y9TN3tTptlzLPS9pI9EE1GfIQaE+HAk+e
|
|
||||||
/bC3KUOAHgVuETvsNAbfpaVsPCdWpFuXmp/4b9iDN7qZy4afTKUPA/Ir/cLfNp14
|
|
||||||
JULfP4z2yFOsCQZ5viNFAs1u99FrwobV2LBzUSIJQewsksuOwj96zIyau0Y629oJ
|
|
||||||
k+og88Tifd9EH3MVZNGhdpojQDDdwHQSITnCDgfRP5yER1WIA4jg6l+mM90QkvLY
|
|
||||||
5NjWTna5kJ3X6UizvgCk365yzT2sbN3R9UGXfCJa9GBcnnviJtJF3+/gC0abwY2f
|
|
||||||
NtVYp32Xky45NY/NdRhDg0bjHP3psxmX+Sc0M9NuQcDQ+fUR+CzM0IGeiszkzXOs
|
|
||||||
RG+bOou2cZ81G4oxWdAALHIRrn7VvLGlkFMxiIZyhYcTGQZzsTPT6n18dY99+DAV
|
|
||||||
yQWZfIRdm8DOnt0G+cwfeohc/9ZwDmj4jJAAi0aeTXdY6NEGIVydk6MAycEhg2Hx
|
|
||||||
9EV96kRwZNIW0AGY8CozECFL3Eyo2ClQVV4Q35SsBibsitDjM03usc2DJ/qjynXA
|
|
||||||
C8HoOSWgbddiBvqZueqK8GdhykOy3J3ysr+MNN/lbG48LqkQr1OWxev9rGGQ6RJT
|
|
||||||
wpBgPyAFAwouPy1whmnx
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFeTCCA2GgAwIBAgIEZZozujANBgkqhkiG9w0BAQ0FADBtMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwNbWVlaEBtYWlsLmky
|
|
||||||
cDAeFw0xNDA2MjgyMjQ5MDlaFw0yNDA2MjcyMjQ5MDlaMG0xCzAJBgNVBAYTAlhY
|
|
||||||
MQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1v
|
|
||||||
dXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1tZWVoQG1haWwuaTJw
|
|
||||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnVnmPE4uUvCky0yCnnVH
|
|
||||||
cJEDqzwDPupx0zr0YDlhZk5VOPPecx5haayJ/V6nXPc1aVVWn+CHfedcF2aBgN4K
|
|
||||||
5aBueS/l6l5WHcv02DofAqlTmyAws3oQeR1qoTuW24cKRtLR7h5bxv63f6bgp6e+
|
|
||||||
RihFNez6UxErnRPuJOJEO2Im6EgVp6fz7tQ7R35zxAUeES2YILPySvzy2vYm/EEG
|
|
||||||
jXX7Ap2A5svVo90xCMOeUZ/55vLsjyIshN+tV87U4xwvAkUmwsmWVHm3BQpHkI6z
|
|
||||||
zMJie6epB8Bqm0GYm0EcElJH4OCxGTvDLoghpswbuUO7iy3JSfoL7ZCnoiQdK9K4
|
|
||||||
yVVChj8lG+r7KaTowK96iZep+sZefjOt5VFGuW2Fi/WBv3ldiLlJAo/ZfrUM4+vG
|
|
||||||
fyNBXbl6bX87uTCGOT1p3dazo+zJMsAZ+Y93DlM/mDEWFa1kKNrs74syzaWEqF4L
|
|
||||||
KQE6VoYn80OOzafSigTVQgSwUtQtB0XGhMzJhyxU2XHWe1LFIy7Pta0B+lDiZj7c
|
|
||||||
I8nXxYjsDfEu/Elj/Ra9N6bH0awmgB5JDa+Tbir+oEM5SyDfpSaCGuatdGxjweGI
|
|
||||||
kVmFU0SqCZV/8TXbIu6MUVzTZMZVT94edifFSRad4fqw7eZbSXlPu++3d1/btn6h
|
|
||||||
ibM04nkv0mm+FxCKB/wdAkECAwEAAaMhMB8wHQYDVR0OBBYEFO7jIkSRkoXyJcho
|
|
||||||
9/Q0gDOINa5EMA0GCSqGSIb3DQEBDQUAA4ICAQBzfWO7+8HWOKLaYWToJ6XZbpNF
|
|
||||||
3wXv1yC4W/HRR80m4JSsq9r0d7838Nvd7vLVP6MY6MaVb/JnV76FdQ5WQ6ticD0Y
|
|
||||||
o3zmpqqbKVSspN0lrkig4surT88AjfVQz/vEIzKNQEbpzc3hC2LCiE2u+cK/ix4j
|
|
||||||
b9RohnaPvwLnew5RNQRpcmk+XejaNITISr2yQIwXL7TEYy8HdGCfzFSSFhKe9vkb
|
|
||||||
GsWS5ASrUzRoprswmlgRe8gEHI+d51Z7mWgna0/5mBz9bH/3QXtpxlLWm3bVV+kt
|
|
||||||
pZjQDTHE0GqG2YsD1Gmp4LU/JFhCojMTtiPCXmr9KFtpiVlx06DuKm5PC8Ak+5w+
|
|
||||||
m/DQYYfv9z+AA5Y430bjnzwg67bhqVyyek4wcDQinFswv3h4bIB7CJujDcEqXXza
|
|
||||||
lhG1ufPPCUTMrVjh7AShohZraqlSlyQPY9vEppLwD4W1d+MqDHM7ljOH7gQYaUPi
|
|
||||||
wE30AdXEOxLZcT3aRKxkKf2esNofSuUC/+NXQvPjpuI4UJKO3eegi+M9dbnKoNWs
|
|
||||||
MPPLPpycecWPheFYM5K6Ao63cjlUY2wYwCfDTFgjA5q8i/Rp7i6Z6fLE3YWJ4VdR
|
|
||||||
WOFB7hlluQ//jMW6M1qz6IYXmlUjcXl81VEvlOH/QBNrPvX3I3SYXYgVRnVGUudB
|
|
||||||
o3eNsanvTU+TIFBh2Q==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
34
contrib/certificates/reseed/reseed_at_diva.exchange.crt
Normal file
34
contrib/certificates/reseed/reseed_at_diva.exchange.crt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF0zCCA7ugAwIBAgIQWjHyC+NRh3emuuAwcEnKSjANBgkqhkiG9w0BAQsFADB0
|
||||||
|
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
||||||
|
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsGA1UEAwwU
|
||||||
|
cmVzZWVkQGRpdmEuZXhjaGFuZ2UwHhcNMjAwNjA5MDUzNjQ1WhcNMzAwNjA5MDUz
|
||||||
|
NjQ1WjB0MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4w
|
||||||
|
HAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsG
|
||||||
|
A1UEAwwUcmVzZWVkQGRpdmEuZXhjaGFuZ2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
|
||||||
|
DwAwggIKAoICAQC6BJGeMEgoXk9dlzKVfmwHrT2VpwTT+wRJvh3eAM746u4uDT2y
|
||||||
|
NPHXhdGcQ9dRRZ63T98IshWCwOmWSlm1kdWkmKkVVb93GUoMQ3gziCi0apLJMAau
|
||||||
|
gEu/sPCbORS2dPsQeAPW2eIsJO7dSjTRiQAuquW//NcIXG4gnxDA52lgke1BvpKr
|
||||||
|
83SJlCrqECAy6OKtZ49yn75CqmPPWFn0b/E8bxruN5ffeipTTospvdEtT41gXUqk
|
||||||
|
hOz3k8ang+QTWiP//jOjk31KXZ2dbh0LOlNJOvRxCqQmBZafNxxCR4DH8RewfPlL
|
||||||
|
qOiOJVzbLSP9RjqPLwnny5BOjbLWXcaybN5Qv2Pyd4mKtN3EpqBwRu7VnzXpsuuG
|
||||||
|
gRbxNmfKJ/vBEGrZAHAxi0NkHHEEne3B7pPDc2dVZHOfTfCu31m9uDHZ4eHEsNOJ
|
||||||
|
SJRiGjq74l0chCSlBGLrD1Y9LPyqadjdwuB9bzM0tMFC1wPflanQCflhhnEzAfbN
|
||||||
|
BaU2GRXo/I1UCDW/dH1FIkqEe61eMW1Lwqr5tdlrUpdr5VIddTyNJRBJogbZ+HZE
|
||||||
|
8mcoJW2lXRAkYi7KEm4b4EQNe7sbRNTF0j+fAJ+3ZOZ3O3SMHss6ignlSa+giVim
|
||||||
|
VvL+Joc6wpSzxpeNPf6m82cEO/UvifFYeOC9TpiRriSt+vvgQVzQtfQ+fQIDAQAB
|
||||||
|
o2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF
|
||||||
|
BwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHJlc2VlZEBkaXZhLmV4Y2hh
|
||||||
|
bmdlMA0GCSqGSIb3DQEBCwUAA4ICAQCFGOb1dHlwjmgFHEER6oMiGWl1mI3Hb7GX
|
||||||
|
NNI6QUhZQ+iEWGYtsOTk3Q8xejL8t6AG/ZLXfZviLIJXZc5XZfPXk0ezDSC2cYxQ
|
||||||
|
ZAyYPw2dRP14brI86sCSqNAFIax/U5SM3zXhCbBiTfaEoBPfDpvKjx+VliaITUnc
|
||||||
|
sHTRn+C5ID5M8cZIqUSGECPEMU/bDtuRNJLTKYaJ98yXtYuS2CWsMEM4o0GGcnYQ
|
||||||
|
5HOZT/lbbwfq1Ks7IyJpeIpRaS5qckGcfgkxFY4eGujDuaFeWC+HCIh9RzBJrqZR
|
||||||
|
73Aly4Pyu7Jjg8xCCf9MswDjtqAjEHgWCmRLWL7p3H6cPipFKNMY6yomYZl5urE7
|
||||||
|
q6DUAZFKwPqlZpyeaY4/SVvaHTxuPp7484s3db4kPhdmuQS/DOB/7d+cn/S580Vy
|
||||||
|
ALqlFQjtjLEaT16upceAV0gYktDInE6Rtym/OsqilrtYks/Sc0GROSz8lJhDDWbr
|
||||||
|
W3t92muSXDh0rYrEUYWl+xl1gSTpbIP75zzU+cUr1E/qlRY9qZn66FsJpOuN0I0q
|
||||||
|
UXsQS/bPDcA+IW48Hd9LfO9gtTWZslwFTimjEvQ2nJAnUlUQP6OfuPUKHoYX/CwY
|
||||||
|
2LCN8+pv2bKPDVHvp0lf6xrbbZNvFtzfR0G3AprZjYpuu2XgjVB5nJnwmbH74b9w
|
||||||
|
LD8d2z2Lgg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -11,6 +11,7 @@ ENV REPO_URL=${REPO_URL}
|
|||||||
|
|
||||||
ENV I2PD_HOME="/home/i2pd"
|
ENV I2PD_HOME="/home/i2pd"
|
||||||
ENV DATA_DIR="${I2PD_HOME}/data"
|
ENV DATA_DIR="${I2PD_HOME}/data"
|
||||||
|
ENV DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0"
|
||||||
|
|
||||||
RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
|
RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
|
||||||
&& adduser -S -h "$I2PD_HOME" i2pd \
|
&& adduser -S -h "$I2PD_HOME" i2pd \
|
||||||
@@ -36,7 +37,7 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib
|
|||||||
&& cd /usr/local/bin \
|
&& cd /usr/local/bin \
|
||||||
&& strip i2pd \
|
&& strip i2pd \
|
||||||
&& rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
|
&& rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
|
||||||
boost-python3 python3 gdbm boost-unit_test_framework boost-python2 linux-headers boost-prg_exec_monitor \
|
boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \
|
||||||
boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \
|
boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \
|
||||||
libtool g++ gcc
|
libtool g++ gcc
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
COMMAND=/usr/local/bin/i2pd
|
COMMAND=/usr/local/bin/i2pd
|
||||||
# To make ports exposeable
|
# To make ports exposeable
|
||||||
# Note: $DATA_DIR is defined in /etc/profile
|
# Note: $DATA_DIR is defined in /etc/profile
|
||||||
DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0"
|
|
||||||
|
|
||||||
if [ "$1" = "--help" ]; then
|
if [ "$1" = "--help" ]; then
|
||||||
set -- $COMMAND --help
|
set -- $COMMAND --help
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ verify = true
|
|||||||
|
|
||||||
[addressbook]
|
[addressbook]
|
||||||
## AddressBook subscription URL for initial setup
|
## AddressBook subscription URL for initial setup
|
||||||
## Default: inr.i2p at "mainline" I2P Network
|
## Default: reg.i2p at "mainline" I2P Network
|
||||||
# defaulturl = http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt
|
# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
|
||||||
## Optional subscriptions URLs, separated by comma
|
## Optional subscriptions URLs, separated by comma
|
||||||
# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
|
# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
|
||||||
|
|
||||||
@@ -229,3 +229,12 @@ verify = true
|
|||||||
[persist]
|
[persist]
|
||||||
## Save peer profiles on disk (default: true)
|
## Save peer profiles on disk (default: true)
|
||||||
# profiles = true
|
# profiles = true
|
||||||
|
|
||||||
|
[cpuext]
|
||||||
|
## Use CPU AES-NI instructions set when work with cryptography when available (default: true)
|
||||||
|
# aesni = true
|
||||||
|
## Use CPU AVX instructions set when work with cryptography when available (default: true)
|
||||||
|
# avx = true
|
||||||
|
## Force usage of CPU instructions set, even if they not found
|
||||||
|
## DO NOT TOUCH that option if you really don't know what are you doing!
|
||||||
|
# force = false
|
||||||
|
|||||||
@@ -17,7 +17,12 @@ PIDFile=/run/i2pd/i2pd.pid
|
|||||||
### Uncomment, if auto restart needed
|
### Uncomment, if auto restart needed
|
||||||
#Restart=on-failure
|
#Restart=on-failure
|
||||||
|
|
||||||
KillSignal=SIGQUIT
|
# Use SIGTERM to stop i2pd immediately.
|
||||||
|
# Some cleanup processes can delay stopping, so we set 30 seconds timeout and then SIGKILL i2pd.
|
||||||
|
KillSignal=SIGTERM
|
||||||
|
TimeoutStopSec=30s
|
||||||
|
SendSIGKILL=yes
|
||||||
|
|
||||||
# If you have the patience waiting 10 min on restarting/stopping it, uncomment this.
|
# If you have the patience waiting 10 min on restarting/stopping it, uncomment this.
|
||||||
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
|
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
|
||||||
#KillSignal=SIGINT
|
#KillSignal=SIGINT
|
||||||
|
|||||||
@@ -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.32.1
|
Version: 2.37.0
|
||||||
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
|
||||||
@@ -56,18 +56,31 @@ cd build
|
|||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia} > 7
|
%if 0%{?fedora} >= 33
|
||||||
pushd build
|
pushd %{_target_platform}
|
||||||
make %{?_smp_mflags}
|
|
||||||
popd
|
|
||||||
%else
|
|
||||||
make %{?_smp_mflags}
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?mageia} > 7
|
||||||
|
pushd build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?mageia} > 7
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
|
||||||
%install
|
%install
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
pushd %{_target_platform}
|
||||||
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia}
|
%if 0%{?mageia}
|
||||||
pushd build
|
pushd build
|
||||||
%endif
|
%endif
|
||||||
@@ -124,6 +137,21 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 15 2021 orignal <i2porignal@yandex.ru> - 2.37.0
|
||||||
|
- update to 2.37.0
|
||||||
|
|
||||||
|
* Mon Feb 15 2021 orignal <i2porignal@yandex.ru> - 2.36.0
|
||||||
|
- update to 2.36.0
|
||||||
|
|
||||||
|
* Mon Nov 30 2020 orignal <i2porignal@yandex.ru> - 2.35.0
|
||||||
|
- update to 2.35.0
|
||||||
|
|
||||||
|
* Tue Oct 27 2020 orignal <i2porignal@yandex.ru> - 2.34.0
|
||||||
|
- update to 2.34.0
|
||||||
|
|
||||||
|
* Mon Aug 24 2020 orignal <i2porignal@yandex.ru> - 2.33.0
|
||||||
|
- update to 2.33.0
|
||||||
|
|
||||||
* Tue Jun 02 2020 r4sas <r4sas@i2pmail.org> - 2.32.1
|
* Tue Jun 02 2020 r4sas <r4sas@i2pmail.org> - 2.32.1
|
||||||
- update to 2.32.1
|
- update to 2.32.1
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.32.1
|
Version: 2.37.0
|
||||||
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,18 +54,31 @@ cd build
|
|||||||
%endif
|
%endif
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia} > 7
|
%if 0%{?fedora} >= 33
|
||||||
pushd build
|
pushd %{_target_platform}
|
||||||
make %{?_smp_mflags}
|
|
||||||
popd
|
|
||||||
%else
|
|
||||||
make %{?_smp_mflags}
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?mageia} > 7
|
||||||
|
pushd build
|
||||||
|
%endif
|
||||||
|
|
||||||
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%if 0%{?mageia} > 7
|
||||||
|
popd
|
||||||
|
%endif
|
||||||
|
|
||||||
%install
|
%install
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
|
%if 0%{?fedora} >= 33
|
||||||
|
pushd %{_target_platform}
|
||||||
|
%endif
|
||||||
|
|
||||||
%if 0%{?mageia}
|
%if 0%{?mageia}
|
||||||
pushd build
|
pushd build
|
||||||
%endif
|
%endif
|
||||||
@@ -122,6 +135,21 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 15 2021 orignal <i2porignal@yandex.ru> - 2.37.0
|
||||||
|
- update to 2.37.0
|
||||||
|
|
||||||
|
* Mon Feb 15 2021 orignal <i2porignal@yandex.ru> - 2.36.0
|
||||||
|
- update to 2.36.0
|
||||||
|
|
||||||
|
* Mon Nov 30 2020 orignal <i2porignal@yandex.ru> - 2.35.0
|
||||||
|
- update to 2.35.0
|
||||||
|
|
||||||
|
* Tue Oct 27 2020 orignal <i2porignal@yandex.ru> - 2.34.0
|
||||||
|
- update to 2.34.0
|
||||||
|
|
||||||
|
* Mon Aug 24 2020 orignal <i2porignal@yandex.ru> - 2.33.0
|
||||||
|
- update to 2.33.0
|
||||||
|
|
||||||
* Tue Jun 02 2020 r4sas <r4sas@i2pmail.org> - 2.32.1
|
* Tue Jun 02 2020 r4sas <r4sas@i2pmail.org> - 2.32.1
|
||||||
- update to 2.32.1
|
- update to 2.32.1
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
http://inr.i2p/export/alive-hosts.txt
|
http://reg.i2p/hosts.txt
|
||||||
|
http://identiguy.i2p/hosts.txt
|
||||||
http://stats.i2p/cgi-bin/newhosts.txt
|
http://stats.i2p/cgi-bin/newhosts.txt
|
||||||
http://i2p-projekt.i2p/hosts.txt
|
http://i2p-projekt.i2p/hosts.txt
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "NTCPSession.h"
|
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
@@ -36,375 +35,440 @@
|
|||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
|
{
|
||||||
|
class Daemon_Singleton::Daemon_Singleton_Private
|
||||||
{
|
{
|
||||||
class Daemon_Singleton::Daemon_Singleton_Private
|
public:
|
||||||
{
|
Daemon_Singleton_Private() {};
|
||||||
public:
|
~Daemon_Singleton_Private() {};
|
||||||
Daemon_Singleton_Private() {};
|
|
||||||
~Daemon_Singleton_Private() {};
|
|
||||||
|
|
||||||
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
||||||
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
||||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||||
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
|
Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
|
||||||
Daemon_Singleton::~Daemon_Singleton() {
|
Daemon_Singleton::~Daemon_Singleton() {
|
||||||
delete &d;
|
delete &d;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::IsService () const
|
bool Daemon_Singleton::IsService () const
|
||||||
{
|
{
|
||||||
bool service = false;
|
bool service = false;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
i2p::config::GetOption("service", service);
|
i2p::config::GetOption("service", service);
|
||||||
#endif
|
#endif
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
|
bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
|
||||||
|
{
|
||||||
|
i2p::config::Init();
|
||||||
|
i2p::config::ParseCmdline(argc, argv);
|
||||||
|
|
||||||
|
std::string config; i2p::config::GetOption("conf", config);
|
||||||
|
std::string datadir; i2p::config::GetOption("datadir", datadir);
|
||||||
|
i2p::fs::DetectDataDir(datadir, IsService());
|
||||||
|
i2p::fs::Init();
|
||||||
|
|
||||||
|
datadir = i2p::fs::GetDataDir();
|
||||||
|
|
||||||
|
if (config == "")
|
||||||
{
|
{
|
||||||
i2p::config::Init();
|
config = i2p::fs::DataDirPath("i2pd.conf");
|
||||||
i2p::config::ParseCmdline(argc, argv);
|
if (!i2p::fs::Exists (config)) {
|
||||||
|
// use i2pd.conf only if exists
|
||||||
std::string config; i2p::config::GetOption("conf", config);
|
config = ""; /* reset */
|
||||||
std::string datadir; i2p::config::GetOption("datadir", datadir);
|
|
||||||
i2p::fs::DetectDataDir(datadir, IsService());
|
|
||||||
i2p::fs::Init();
|
|
||||||
|
|
||||||
datadir = i2p::fs::GetDataDir();
|
|
||||||
|
|
||||||
if (config == "")
|
|
||||||
{
|
|
||||||
config = i2p::fs::DataDirPath("i2pd.conf");
|
|
||||||
if (!i2p::fs::Exists (config)) {
|
|
||||||
// use i2pd.conf only if exists
|
|
||||||
config = ""; /* reset */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i2p::config::ParseConfig(config);
|
i2p::config::ParseConfig(config);
|
||||||
i2p::config::Finalize();
|
i2p::config::Finalize();
|
||||||
|
|
||||||
i2p::config::GetOption("daemon", isDaemon);
|
i2p::config::GetOption("daemon", isDaemon);
|
||||||
|
|
||||||
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 */
|
||||||
if (logclftime)
|
if (logclftime)
|
||||||
i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
|
i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
|
||||||
|
|
||||||
if (isDaemon && (logs == "" || logs == "stdout"))
|
#ifdef WIN32_APP
|
||||||
logs = "file";
|
// Win32 app with GUI supports only logging to file
|
||||||
|
logs = "file";
|
||||||
i2p::log::Logger().SetLogLevel(loglevel);
|
#else
|
||||||
if (logstream) {
|
if (isDaemon && (logs == "" || logs == "stdout"))
|
||||||
LogPrint(eLogInfo, "Log: will send messages to std::ostream");
|
logs = "file";
|
||||||
i2p::log::Logger().SendTo (logstream);
|
|
||||||
} else if (logs == "file") {
|
|
||||||
if (logfile == "")
|
|
||||||
logfile = i2p::fs::DataDirPath("i2pd.log");
|
|
||||||
LogPrint(eLogInfo, "Log: will send messages to ", logfile);
|
|
||||||
i2p::log::Logger().SendTo (logfile);
|
|
||||||
#ifndef _WIN32
|
|
||||||
} else if (logs == "syslog") {
|
|
||||||
LogPrint(eLogInfo, "Log: will send messages to syslog");
|
|
||||||
i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
// use stdout -- default
|
|
||||||
}
|
|
||||||
|
|
||||||
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
i2p::log::Logger().SetLogLevel(loglevel);
|
||||||
LogPrint(eLogDebug, "FS: main config file: ", config);
|
if (logstream) {
|
||||||
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
LogPrint(eLogInfo, "Log: will send messages to std::ostream");
|
||||||
|
i2p::log::Logger().SendTo (logstream);
|
||||||
|
} else if (logs == "file") {
|
||||||
|
if (logfile == "")
|
||||||
|
logfile = i2p::fs::DataDirPath("i2pd.log");
|
||||||
|
LogPrint(eLogInfo, "Log: will send messages to ", logfile);
|
||||||
|
i2p::log::Logger().SendTo (logfile);
|
||||||
|
#ifndef _WIN32
|
||||||
|
} else if (logs == "syslog") {
|
||||||
|
LogPrint(eLogInfo, "Log: will send messages to syslog");
|
||||||
|
i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// use stdout -- default
|
||||||
|
}
|
||||||
|
|
||||||
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
LogPrint(eLogNone, "i2pd v", VERSION, " starting");
|
||||||
i2p::crypto::InitCrypto (precomputation);
|
LogPrint(eLogDebug, "FS: main config file: ", config);
|
||||||
|
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
||||||
|
|
||||||
int netID; i2p::config::GetOption("netid", netID);
|
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
||||||
i2p::context.SetNetID (netID);
|
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
|
||||||
i2p::context.Init ();
|
bool avx; i2p::config::GetOption("cpuext.avx", avx);
|
||||||
|
bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
|
||||||
|
i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
|
||||||
|
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
int netID; i2p::config::GetOption("netid", netID);
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
i2p::context.SetNetID (netID);
|
||||||
|
i2p::context.Init ();
|
||||||
|
|
||||||
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
#ifdef MESHNET
|
#ifdef MESHNET
|
||||||
// manual override for meshnet
|
// manual override for meshnet
|
||||||
ipv4 = false;
|
ipv4 = false;
|
||||||
ipv6 = true;
|
ipv6 = true;
|
||||||
#endif
|
#endif
|
||||||
uint16_t port; i2p::config::GetOption("port", port);
|
// ifname -> address
|
||||||
if (!i2p::config::IsDefault("port"))
|
std::string ifname; i2p::config::GetOption("ifname", ifname);
|
||||||
|
if (ipv4 && i2p::config::IsDefault ("address4"))
|
||||||
|
{
|
||||||
|
std::string ifname4; i2p::config::GetOption("ifname4", ifname4);
|
||||||
|
if (!ifname4.empty ())
|
||||||
|
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname4, false).to_string ()); // v4
|
||||||
|
else if (!ifname.empty ())
|
||||||
|
i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4
|
||||||
|
}
|
||||||
|
if (ipv6 && i2p::config::IsDefault ("address6"))
|
||||||
|
{
|
||||||
|
std::string ifname6; i2p::config::GetOption("ifname6", ifname6);
|
||||||
|
if (!ifname6.empty ())
|
||||||
|
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname6, true).to_string ()); // v6
|
||||||
|
else if (!ifname.empty ())
|
||||||
|
i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname, true).to_string ()); // v6
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
||||||
|
boost::asio::ip::address_v6 yggaddr;
|
||||||
|
if (ygg)
|
||||||
|
{
|
||||||
|
std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
|
||||||
|
if (!yggaddress.empty ())
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
|
yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
|
||||||
i2p::context.UpdatePort (port);
|
if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) ||
|
||||||
}
|
!i2p::util::net::IsLocalAddress (yggaddr))
|
||||||
i2p::context.SetSupportsV6 (ipv6);
|
|
||||||
i2p::context.SetSupportsV4 (ipv4);
|
|
||||||
|
|
||||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
|
||||||
i2p::context.PublishNTCPAddress (ntcp, !ipv6);
|
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
|
||||||
if (ntcp2)
|
|
||||||
{
|
|
||||||
bool published; i2p::config::GetOption("ntcp2.published", published);
|
|
||||||
if (published)
|
|
||||||
{
|
{
|
||||||
uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
|
LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress);
|
||||||
if (!ntcp && !ntcp2port) ntcp2port = port; // use standard port
|
ygg = false;
|
||||||
i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
|
|
||||||
if (ipv6)
|
|
||||||
{
|
|
||||||
std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
|
|
||||||
auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
|
|
||||||
if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
|
|
||||||
i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
i2p::context.PublishNTCP2Address (port, false); // unpublish
|
|
||||||
}
|
|
||||||
|
|
||||||
bool transit; i2p::config::GetOption("notransit", transit);
|
|
||||||
i2p::context.SetAcceptsTunnels (!transit);
|
|
||||||
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
|
||||||
SetMaxNumTransitTunnels (transitTunnels);
|
|
||||||
|
|
||||||
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
|
||||||
if (isFloodfill)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
|
||||||
i2p::context.SetFloodfill (true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i2p::context.SetFloodfill (false);
|
yggaddr = i2p::util::net::GetYggdrasilAddress ();
|
||||||
}
|
if (yggaddr.is_unspecified ())
|
||||||
|
|
||||||
/* this section also honors 'floodfill' flag, if set above */
|
|
||||||
std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
|
|
||||||
if (bandwidth.length () > 0)
|
|
||||||
{
|
|
||||||
if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X')
|
|
||||||
{
|
{
|
||||||
i2p::context.SetBandwidth (bandwidth[0]);
|
LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled");
|
||||||
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
|
ygg = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t port; i2p::config::GetOption("port", port);
|
||||||
|
if (!i2p::config::IsDefault("port"))
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
|
||||||
|
i2p::context.UpdatePort (port);
|
||||||
|
}
|
||||||
|
i2p::context.SetSupportsV6 (ipv6);
|
||||||
|
i2p::context.SetSupportsV4 (ipv4);
|
||||||
|
i2p::context.SetSupportsMesh (ygg, yggaddr);
|
||||||
|
|
||||||
|
i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later
|
||||||
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
|
if (ntcp2)
|
||||||
|
{
|
||||||
|
bool published; i2p::config::GetOption("ntcp2.published", published);
|
||||||
|
if (published)
|
||||||
|
{
|
||||||
|
std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
|
||||||
|
if (!ntcp2proxy.empty ()) published = false;
|
||||||
|
}
|
||||||
|
if (published)
|
||||||
|
{
|
||||||
|
uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
|
||||||
|
if (!ntcp2port) ntcp2port = port; // use standard port
|
||||||
|
i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
|
||||||
|
if (ipv6)
|
||||||
|
{
|
||||||
|
std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
|
||||||
|
auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
|
||||||
|
if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
|
||||||
|
i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i2p::context.PublishNTCP2Address (port, false); // unpublish
|
||||||
|
}
|
||||||
|
if (ygg)
|
||||||
|
{
|
||||||
|
if (!ntcp2)
|
||||||
|
i2p::context.PublishNTCP2Address (port, true);
|
||||||
|
i2p::context.UpdateNTCP2V6Address (yggaddr);
|
||||||
|
if (!ipv4 && !ipv6)
|
||||||
|
i2p::context.SetStatus (eRouterStatusMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool transit; i2p::config::GetOption("notransit", transit);
|
||||||
|
i2p::context.SetAcceptsTunnels (!transit);
|
||||||
|
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
||||||
|
SetMaxNumTransitTunnels (transitTunnels);
|
||||||
|
|
||||||
|
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
||||||
|
if (isFloodfill) {
|
||||||
|
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
||||||
|
i2p::context.SetFloodfill (true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i2p::context.SetFloodfill (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this section also honors 'floodfill' flag, if set above */
|
||||||
|
std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
|
||||||
|
if (bandwidth.length () > 0)
|
||||||
|
{
|
||||||
|
if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X')
|
||||||
|
{
|
||||||
|
i2p::context.SetBandwidth (bandwidth[0]);
|
||||||
|
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto value = std::atoi(bandwidth.c_str());
|
||||||
|
if (value > 0)
|
||||||
|
{
|
||||||
|
i2p::context.SetBandwidth (value);
|
||||||
|
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto value = std::atoi(bandwidth.c_str());
|
LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
|
||||||
if (value > 0)
|
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
|
||||||
{
|
|
||||||
i2p::context.SetBandwidth (value);
|
|
||||||
LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
|
|
||||||
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isFloodfill)
|
}
|
||||||
{
|
else if (isFloodfill)
|
||||||
LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
|
{
|
||||||
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
|
LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
|
||||||
}
|
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
|
{
|
||||||
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
|
LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
|
||||||
}
|
i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
|
||||||
|
|
||||||
int shareRatio; i2p::config::GetOption("share", shareRatio);
|
|
||||||
i2p::context.SetShareRatio (shareRatio);
|
|
||||||
|
|
||||||
std::string family; i2p::config::GetOption("family", family);
|
|
||||||
i2p::context.SetFamily (family);
|
|
||||||
if (family.length () > 0)
|
|
||||||
LogPrint(eLogInfo, "Daemon: family set to ", family);
|
|
||||||
|
|
||||||
bool trust; i2p::config::GetOption("trust.enabled", trust);
|
|
||||||
if (trust)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Daemon: explicit trust enabled");
|
|
||||||
std::string fam; i2p::config::GetOption("trust.family", fam);
|
|
||||||
std::string routers; i2p::config::GetOption("trust.routers", routers);
|
|
||||||
bool restricted = false;
|
|
||||||
if (fam.length() > 0)
|
|
||||||
{
|
|
||||||
std::set<std::string> fams;
|
|
||||||
size_t pos = 0, comma;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
comma = fam.find (',', pos);
|
|
||||||
fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
|
|
||||||
pos = comma + 1;
|
|
||||||
}
|
|
||||||
while (comma != std::string::npos);
|
|
||||||
i2p::transport::transports.RestrictRoutesToFamilies(fams);
|
|
||||||
restricted = fams.size() > 0;
|
|
||||||
}
|
|
||||||
if (routers.length() > 0)
|
|
||||||
{
|
|
||||||
std::set<i2p::data::IdentHash> idents;
|
|
||||||
size_t pos = 0, comma;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
comma = routers.find (',', pos);
|
|
||||||
i2p::data::IdentHash ident;
|
|
||||||
ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
|
|
||||||
idents.insert (ident);
|
|
||||||
pos = comma + 1;
|
|
||||||
}
|
|
||||||
while (comma != std::string::npos);
|
|
||||||
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers");
|
|
||||||
i2p::transport::transports.RestrictRoutesToRouters(idents);
|
|
||||||
restricted = idents.size() > 0;
|
|
||||||
}
|
|
||||||
if(!restricted)
|
|
||||||
LogPrint(eLogError, "Daemon: no trusted routers of families specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hidden; i2p::config::GetOption("trust.hidden", hidden);
|
|
||||||
if (hidden)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
|
||||||
i2p::data::netdb.SetHidden(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::start()
|
int shareRatio; i2p::config::GetOption("share", shareRatio);
|
||||||
|
i2p::context.SetShareRatio (shareRatio);
|
||||||
|
|
||||||
|
std::string family; i2p::config::GetOption("family", family);
|
||||||
|
i2p::context.SetFamily (family);
|
||||||
|
if (family.length () > 0)
|
||||||
|
LogPrint(eLogInfo, "Daemon: family set to ", family);
|
||||||
|
|
||||||
|
bool trust; i2p::config::GetOption("trust.enabled", trust);
|
||||||
|
if (trust)
|
||||||
{
|
{
|
||||||
i2p::log::Logger().Start();
|
LogPrint(eLogInfo, "Daemon: explicit trust enabled");
|
||||||
LogPrint(eLogInfo, "Daemon: starting NetDB");
|
std::string fam; i2p::config::GetOption("trust.family", fam);
|
||||||
i2p::data::netdb.Start();
|
std::string routers; i2p::config::GetOption("trust.routers", routers);
|
||||||
|
bool restricted = false;
|
||||||
bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
|
if (fam.length() > 0)
|
||||||
if (upnp)
|
|
||||||
{
|
{
|
||||||
d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
|
std::set<std::string> fams;
|
||||||
d.UPnP->Start ();
|
size_t pos = 0, comma;
|
||||||
}
|
do
|
||||||
|
|
||||||
bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
|
|
||||||
if (nettime)
|
|
||||||
{
|
|
||||||
d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
|
|
||||||
d.m_NTPSync->Start ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting Transports");
|
|
||||||
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
|
|
||||||
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
|
||||||
|
|
||||||
i2p::transport::transports.Start(ntcp, ssu);
|
|
||||||
if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
|
|
||||||
LogPrint(eLogInfo, "Daemon: Transports started");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Daemon: failed to start Transports");
|
|
||||||
/** shut down netdb right away */
|
|
||||||
i2p::transport::transports.Stop();
|
|
||||||
i2p::data::netdb.Stop();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool http; i2p::config::GetOption("http.enabled", http);
|
|
||||||
if (http)
|
|
||||||
{
|
|
||||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
|
||||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
comma = fam.find (',', pos);
|
||||||
d.httpServer->Start();
|
fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
|
||||||
}
|
pos = comma + 1;
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
|
|
||||||
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
|
|
||||||
}
|
}
|
||||||
|
while (comma != std::string::npos);
|
||||||
|
i2p::transport::transports.RestrictRoutesToFamilies(fams);
|
||||||
|
restricted = fams.size() > 0;
|
||||||
}
|
}
|
||||||
|
if (routers.length() > 0) {
|
||||||
LogPrint(eLogInfo, "Daemon: starting Tunnels");
|
std::set<i2p::data::IdentHash> idents;
|
||||||
i2p::tunnel::tunnels.Start();
|
size_t pos = 0, comma;
|
||||||
|
do
|
||||||
LogPrint(eLogInfo, "Daemon: starting Client");
|
|
||||||
i2p::client::context.Start ();
|
|
||||||
|
|
||||||
// I2P Control Protocol
|
|
||||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
|
||||||
if (i2pcontrol) {
|
|
||||||
std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
|
|
||||||
uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort);
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
comma = routers.find (',', pos);
|
||||||
d.m_I2PControlService->Start ();
|
i2p::data::IdentHash ident;
|
||||||
}
|
ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
|
||||||
catch (std::exception& ex)
|
idents.insert (ident);
|
||||||
{
|
pos = comma + 1;
|
||||||
LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ());
|
|
||||||
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
|
|
||||||
}
|
}
|
||||||
|
while (comma != std::string::npos);
|
||||||
|
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers");
|
||||||
|
i2p::transport::transports.RestrictRoutesToRouters(idents);
|
||||||
|
restricted = idents.size() > 0;
|
||||||
}
|
}
|
||||||
return true;
|
if(!restricted)
|
||||||
|
LogPrint(eLogError, "Daemon: no trusted routers of families specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::stop()
|
bool hidden; i2p::config::GetOption("trust.hidden", hidden);
|
||||||
|
if (hidden)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Daemon: shutting down");
|
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Client");
|
i2p::data::netdb.SetHidden(true);
|
||||||
i2p::client::context.Stop();
|
}
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Tunnels");
|
return true;
|
||||||
i2p::tunnel::tunnels.Stop();
|
}
|
||||||
|
|
||||||
if (d.UPnP)
|
bool Daemon_Singleton::start()
|
||||||
{
|
{
|
||||||
d.UPnP->Stop ();
|
i2p::log::Logger().Start();
|
||||||
d.UPnP = nullptr;
|
LogPrint(eLogInfo, "Daemon: starting NetDB");
|
||||||
}
|
i2p::data::netdb.Start();
|
||||||
|
|
||||||
if (d.m_NTPSync)
|
bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
|
||||||
{
|
if (upnp) {
|
||||||
d.m_NTPSync->Stop ();
|
d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
|
||||||
d.m_NTPSync = nullptr;
|
d.UPnP->Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Transports");
|
bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
|
||||||
|
if (nettime)
|
||||||
|
{
|
||||||
|
d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
|
||||||
|
d.m_NTPSync->Start ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
|
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting Transports");
|
||||||
|
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
|
||||||
|
if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
|
||||||
|
|
||||||
|
i2p::transport::transports.SetCheckReserved(checkInReserved);
|
||||||
|
i2p::transport::transports.Start(ntcp2, ssu);
|
||||||
|
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
|
||||||
|
LogPrint(eLogInfo, "Daemon: Transports started");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Daemon: failed to start Transports");
|
||||||
|
/** shut down netdb right away */
|
||||||
i2p::transport::transports.Stop();
|
i2p::transport::transports.Stop();
|
||||||
LogPrint(eLogInfo, "Daemon: stopping NetDB");
|
|
||||||
i2p::data::netdb.Stop();
|
i2p::data::netdb.Stop();
|
||||||
if (d.httpServer) {
|
return false;
|
||||||
LogPrint(eLogInfo, "Daemon: stopping HTTP Server");
|
|
||||||
d.httpServer->Stop();
|
|
||||||
d.httpServer = nullptr;
|
|
||||||
}
|
|
||||||
if (d.m_I2PControlService)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "Daemon: stopping I2PControl");
|
|
||||||
d.m_I2PControlService->Stop ();
|
|
||||||
d.m_I2PControlService = nullptr;
|
|
||||||
}
|
|
||||||
i2p::crypto::TerminateCrypto ();
|
|
||||||
i2p::log::Logger().Stop();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool http; i2p::config::GetOption("http.enabled", http);
|
||||||
|
if (http) {
|
||||||
|
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||||
|
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
||||||
|
d.httpServer->Start();
|
||||||
|
}
|
||||||
|
catch (std::exception& ex)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
|
||||||
|
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting Tunnels");
|
||||||
|
i2p::tunnel::tunnels.Start();
|
||||||
|
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting Client");
|
||||||
|
i2p::client::context.Start ();
|
||||||
|
|
||||||
|
// I2P Control Protocol
|
||||||
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
|
if (i2pcontrol) {
|
||||||
|
std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
|
||||||
|
uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort);
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
||||||
|
d.m_I2PControlService->Start ();
|
||||||
|
}
|
||||||
|
catch (std::exception& ex)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ());
|
||||||
|
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Daemon_Singleton::stop()
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "Daemon: shutting down");
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping Client");
|
||||||
|
i2p::client::context.Stop();
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping Tunnels");
|
||||||
|
i2p::tunnel::tunnels.Stop();
|
||||||
|
|
||||||
|
if (d.UPnP)
|
||||||
|
{
|
||||||
|
d.UPnP->Stop ();
|
||||||
|
d.UPnP = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.m_NTPSync)
|
||||||
|
{
|
||||||
|
d.m_NTPSync->Stop ();
|
||||||
|
d.m_NTPSync = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping Transports");
|
||||||
|
i2p::transport::transports.Stop();
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping NetDB");
|
||||||
|
i2p::data::netdb.Stop();
|
||||||
|
if (d.httpServer) {
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping HTTP Server");
|
||||||
|
d.httpServer->Stop();
|
||||||
|
d.httpServer = nullptr;
|
||||||
|
}
|
||||||
|
if (d.m_I2PControlService)
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "Daemon: stopping I2PControl");
|
||||||
|
d.m_I2PControlService->Stop ();
|
||||||
|
d.m_I2PControlService = nullptr;
|
||||||
|
}
|
||||||
|
i2p::crypto::TerminateCrypto ();
|
||||||
|
i2p::log::Logger().Stop();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
@@ -31,8 +30,9 @@
|
|||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ECIESX25519AEADRatchetSession.h"
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
|
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include "Win32/Win32App.h"
|
#include "Win32App.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For image and info
|
// For image and info
|
||||||
@@ -63,23 +63,43 @@ namespace http {
|
|||||||
" body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
|
" body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
|
||||||
" a, .slide label { text-decoration: none; color: #894C84; }\r\n"
|
" a, .slide label { text-decoration: none; color: #894C84; }\r\n"
|
||||||
" a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n"
|
" a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n"
|
||||||
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial; padding: 0 5px; }\r\n"
|
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
" .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n"
|
" color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
|
||||||
" .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n"
|
" .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
|
||||||
" .left { float: left; position: absolute; }\r\n"
|
" .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n"
|
||||||
" .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\r\n"
|
" .menu { float: left; } .menu a, .commands a { display: block; }\r\n"
|
||||||
" .tunnel.established { color: #56B734; }\r\n"
|
" .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
" .tunnel.expiring { color: #D3AE3F; }\r\n"
|
" .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
" .tunnel.failed { color: #D33F3F; }\r\n"
|
" .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n"
|
||||||
" .tunnel.building { color: #434343; }\r\n"
|
" .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||||
|
" .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
|
||||||
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
||||||
" table { display: table; border-collapse: collapse; text-align: center; }\r\n"
|
" table { display: table; border-collapse: collapse; text-align: center; }\r\n"
|
||||||
" table.extaddr { text-align: left; }\r\n table.services { width: 100%; }"
|
" table.extaddr { text-align: left; } table.services { width: 100%; }\r\n"
|
||||||
|
" textarea { word-break: break-all; }\r\n"
|
||||||
" .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n"
|
" .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n"
|
||||||
" .slide div.content, .slide [type='checkbox'] { display: none; }\r\n"
|
" .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n"
|
||||||
" .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n"
|
" .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
|
||||||
" .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n"
|
" .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n"
|
||||||
" .enabled:after { color: #56B734; content: \"Enabled\" }\r\n"
|
" .enabled:after { color: #56B734; content: \"Enabled\" }\r\n"
|
||||||
|
" @media screen and (max-width: 980px) {\r\n" /* adaptive style */
|
||||||
|
" body { padding: 1.5em 0 0 0; }\r\n"
|
||||||
|
" .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n"
|
||||||
|
" text-align: center; }\r\n"
|
||||||
|
" .menu a, .commands a { padding: 2px; }\r\n"
|
||||||
|
" .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
|
||||||
|
" text-align: center; }\r\n"
|
||||||
|
" a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
|
||||||
|
" .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
|
||||||
|
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
|
" color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
|
||||||
|
" input { width: 35%; text-align: center; padding: 5px;\r\n"
|
||||||
|
" border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
|
||||||
|
" textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
|
||||||
|
" -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
|
||||||
|
" button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
|
||||||
|
" -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
||||||
|
" }\r\n" /* adaptive style */
|
||||||
"</style>\r\n";
|
"</style>\r\n";
|
||||||
|
|
||||||
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
||||||
@@ -103,6 +123,7 @@ namespace http {
|
|||||||
const char HTTP_COMMAND_LOGLEVEL[] = "set_loglevel";
|
const char HTTP_COMMAND_LOGLEVEL[] = "set_loglevel";
|
||||||
const char HTTP_COMMAND_KILLSTREAM[] = "closestream";
|
const char HTTP_COMMAND_KILLSTREAM[] = "closestream";
|
||||||
const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit";
|
const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit";
|
||||||
|
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
|
||||||
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
||||||
const char HTTP_PARAM_ADDRESS[] = "address";
|
const char HTTP_PARAM_ADDRESS[] = "address";
|
||||||
|
|
||||||
@@ -154,7 +175,7 @@ namespace http {
|
|||||||
default: state = "unknown"; break;
|
default: state = "unknown"; break;
|
||||||
}
|
}
|
||||||
s << "<span class=\"tunnel " << state << "\"> " << state << ((explr) ? " (exploratory)" : "") << "</span>, ";
|
s << "<span class=\"tunnel " << state << "\"> " << state << ((explr) ? " (exploratory)" : "") << "</span>, ";
|
||||||
s << " " << (int) (bytes / 1024) << " KiB<br>\r\n";
|
s << " " << (int) (bytes / 1024) << " KiB\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetLogLevel (const std::string& level)
|
static void SetLogLevel (const std::string& level)
|
||||||
@@ -181,36 +202,37 @@ namespace http {
|
|||||||
#else
|
#else
|
||||||
" <meta charset=\"windows-1251\">\r\n"
|
" <meta charset=\"windows-1251\">\r\n"
|
||||||
#endif
|
#endif
|
||||||
|
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
|
||||||
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
||||||
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
||||||
<< cssStyles <<
|
<< cssStyles <<
|
||||||
"</head>\r\n";
|
"</head>\r\n";
|
||||||
s <<
|
s <<
|
||||||
"<body>\r\n"
|
"<body>\r\n"
|
||||||
"<div class=header><b>i2pd</b> webconsole</div>\r\n"
|
"<div class=\"header\"><b>i2pd</b> webconsole</div>\r\n"
|
||||||
"<div class=wrapper>\r\n"
|
"<div class=\"wrapper\">\r\n"
|
||||||
"<div class=left>\r\n"
|
"<div class=\"menu\">\r\n"
|
||||||
" <a href=\"" << webroot << "\">Main page</a><br>\r\n<br>\r\n"
|
" <a href=\"" << webroot << "\">Main page</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a>\r\n";
|
||||||
if (i2p::context.IsFloodfill ())
|
if (i2p::context.IsFloodfill ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a>\r\n";
|
||||||
s <<
|
s <<
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a>\r\n";
|
||||||
if (i2p::client::context.GetSAMBridge ())
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a>\r\n";
|
||||||
s <<
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=right>";
|
"<div class=\"content\">";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowPageTail (std::stringstream& s)
|
static void ShowPageTail (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s <<
|
s <<
|
||||||
"</div></div>\r\n"
|
"</div>\r\n</div>\r\n"
|
||||||
"</body>\r\n"
|
"</body>\r\n"
|
||||||
"</html>\r\n";
|
"</html>\r\n";
|
||||||
}
|
}
|
||||||
@@ -231,14 +253,23 @@ namespace http {
|
|||||||
case eRouterStatusOK: s << "OK"; break;
|
case eRouterStatusOK: s << "OK"; break;
|
||||||
case eRouterStatusTesting: s << "Testing"; break;
|
case eRouterStatusTesting: s << "Testing"; break;
|
||||||
case eRouterStatusFirewalled: s << "Firewalled"; break;
|
case eRouterStatusFirewalled: s << "Firewalled"; break;
|
||||||
|
case eRouterStatusUnknown: s << "Unknown"; break;
|
||||||
|
case eRouterStatusProxy: s << "Proxy"; break;
|
||||||
|
case eRouterStatusMesh: s << "Mesh"; break;
|
||||||
case eRouterStatusError:
|
case eRouterStatusError:
|
||||||
{
|
{
|
||||||
s << "Error";
|
s << "Error";
|
||||||
switch (i2p::context.GetError ())
|
switch (i2p::context.GetError ())
|
||||||
{
|
{
|
||||||
case eRouterErrorClockSkew:
|
case eRouterErrorClockSkew:
|
||||||
s << "<br>Clock skew";
|
s << " - Clock skew";
|
||||||
break;
|
break;
|
||||||
|
case eRouterErrorOffline:
|
||||||
|
s << " - Offline";
|
||||||
|
break;
|
||||||
|
case eRouterErrorSymmetricNAT:
|
||||||
|
s << " - Symmetric NAT";
|
||||||
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -247,8 +278,18 @@ namespace http {
|
|||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (auto remains = Daemon.gracefulShutdownInterval)
|
if (auto remains = Daemon.gracefulShutdownInterval) {
|
||||||
s << "<b>Stopping in:</b> " << remains << " seconds<br>\r\n";
|
s << "<b>Stopping in:</b> ";
|
||||||
|
ShowUptime(s, remains);
|
||||||
|
s << "<br>\r\n";
|
||||||
|
}
|
||||||
|
#elif defined(WIN32_APP)
|
||||||
|
if (i2p::win32::g_GracefulShutdownEndtime != 0) {
|
||||||
|
uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
||||||
|
s << "<b>Stopping in:</b> ";
|
||||||
|
ShowUptime(s, remains);
|
||||||
|
s << "<br>\r\n";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
auto family = i2p::context.GetFamily ();
|
auto family = i2p::context.GetFamily ();
|
||||||
if (family.length () > 0)
|
if (family.length () > 0)
|
||||||
@@ -266,7 +307,7 @@ namespace http {
|
|||||||
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
|
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
|
||||||
s << "<div class='slide'>";
|
s << "<div class='slide'>";
|
||||||
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
|
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
|
||||||
s << "<label for='slide-info'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide-info'/>\r\n<div class='content'>\r\n";
|
s << "<label for=\"slide-info\">Hidden content. Press on text to see.</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
|
||||||
}
|
}
|
||||||
if(includeHiddenContent) {
|
if(includeHiddenContent) {
|
||||||
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
||||||
@@ -340,18 +381,19 @@ namespace http {
|
|||||||
void ShowLocalDestinations (std::stringstream& s)
|
void ShowLocalDestinations (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";
|
s << "<b>Local Destinations:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: i2p::client::context.GetDestinations ())
|
for (auto& it: i2p::client::context.GetDestinations ())
|
||||||
{
|
{
|
||||||
auto ident = it.second->GetIdentHash ();
|
auto ident = it.second->GetIdentHash ();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
|
|
||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
||||||
{
|
{
|
||||||
s << "<br><b>I2CP Local Destinations:</b><br>\r\n<br>\r\n";
|
s << "<br><b>I2CP Local Destinations:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: i2cpServer->GetSessions ())
|
for (auto& it: i2cpServer->GetSessions ())
|
||||||
{
|
{
|
||||||
auto dest = it.second->GetDestination ();
|
auto dest = it.second->GetDestination ();
|
||||||
@@ -359,51 +401,71 @@ namespace http {
|
|||||||
{
|
{
|
||||||
auto ident = dest->GetIdentHash ();
|
auto ident = dest->GetIdentHash ();
|
||||||
auto& name = dest->GetNickname ();
|
auto& name = dest->GetNickname ();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
|
||||||
s << name << " ]</a> ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"<br>\r\n" << std::endl;
|
s << name << " ]</a> ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"</div>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest)
|
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
|
||||||
{
|
{
|
||||||
s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"11\" wrap=\"on\">";
|
s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"8\">";
|
||||||
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
|
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
|
||||||
if (dest->IsEncryptedLeaseSet ())
|
if (dest->IsEncryptedLeaseSet ())
|
||||||
{
|
{
|
||||||
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
|
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
|
||||||
s << "<div class='slide'><label for='slide-b33'><b>Encrypted B33 address:</b></label>\r\n<input type='checkbox' id='slide-b33'/>\r\n<div class='content'>\r\n";
|
s << "<div class='slide'><label for='slide-b33'><b>Encrypted B33 address:</b></label>\r\n<input type=\"checkbox\" id=\"slide-b33\" />\r\n<div class=\"slidecontent\">\r\n";
|
||||||
s << blinded.ToB33 () << ".b32.i2p<br>\r\n";
|
s << blinded.ToB33 () << ".b32.i2p<br>\r\n";
|
||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(dest->IsPublic())
|
||||||
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
|
auto base32 = dest->GetIdentHash ().ToBase32 ();
|
||||||
|
s << "<div class='slide'><label for='slide-regaddr'><b>Address registration line</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
|
||||||
|
"<form method=\"get\" action=\"" << webroot << "\">\r\n"
|
||||||
|
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
|
||||||
|
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
|
||||||
|
" <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
|
||||||
|
" <b>Domain:</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
|
||||||
|
" <button type=\"submit\">Generate</button>\r\n"
|
||||||
|
"</form>\r\n<small><b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(dest->GetNumRemoteLeaseSets())
|
if(dest->GetNumRemoteLeaseSets())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets ()
|
s << "<div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets ()
|
||||||
<< "</i></label>\r\n<input type='checkbox' id='slide-lease'/>\r\n<div class='content'>\r\n<table><thead><th>Address</th><th>Type</th><th>EncType</th></thead><tbody>";
|
<< "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n<table><thead><th>Address</th><th>Type</th><th>EncType</th></thead><tbody class=\"tableitem\">";
|
||||||
for(auto& it: dest->GetLeaseSets ())
|
for(auto& it: dest->GetLeaseSets ())
|
||||||
s << "<tr><td>" << it.first.ToBase32 () << "</td><td>" << (int)it.second->GetStoreType () << "</td><td>" << (int)it.second->GetEncryptionType () <<"</td></tr>\r\n";
|
s << "<tr><td>" << it.first.ToBase32 () << "</td><td>" << (int)it.second->GetStoreType () << "</td><td>" << (int)it.second->GetEncryptionType () <<"</td></tr>\r\n";
|
||||||
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n<br>\r\n";
|
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n<br>\r\n";
|
||||||
|
|
||||||
auto pool = dest->GetTunnelPool ();
|
auto pool = dest->GetTunnelPool ();
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
s << "<b>Inbound tunnels:</b><br>\r\n";
|
s << "<b>Inbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : pool->GetInboundTunnels ()) {
|
for (auto & it : pool->GetInboundTunnels ()) {
|
||||||
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << "ms )";
|
||||||
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Outbound tunnels:</b><br>\r\n";
|
s << "<b>Outbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : pool->GetOutboundTunnels ()) {
|
for (auto & it : pool->GetOutboundTunnels ()) {
|
||||||
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << "ms )";
|
||||||
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
|
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
@@ -415,8 +477,8 @@ namespace http {
|
|||||||
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
|
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
|
||||||
out_tags += it.second->GetNumOutgoingTags ();
|
out_tags += it.second->GetNumOutgoingTags ();
|
||||||
}
|
}
|
||||||
s << "<div class='slide'><label for='slide-tags'>Outgoing: <i>" << out_tags << "</i></label>\r\n<input type='checkbox' id='slide-tags'/>\r\n"
|
s << "<div class='slide'><label for='slide-tags'>Outgoing: <i>" << out_tags << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-tags\" />\r\n"
|
||||||
<< "<div class='content'>\r\n<table><tbody><thead><th>Destination</th><th>Amount</th></thead>\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>Destination</th><th>Amount</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "Outgoing: <i>0</i><br>\r\n";
|
s << "Outgoing: <i>0</i><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
@@ -431,8 +493,8 @@ namespace http {
|
|||||||
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
|
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
|
||||||
ecies_sessions++;
|
ecies_sessions++;
|
||||||
}
|
}
|
||||||
s << "<div class='slide'><label for='slide-ecies-sessions'>Tags sessions: <i>" << ecies_sessions << "</i></label>\r\n<input type='checkbox' id='slide-ecies-sessions'/>\r\n"
|
s << "<div class='slide'><label for='slide-ecies-sessions'>Tags sessions: <i>" << ecies_sessions << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-ecies-sessions\" />\r\n"
|
||||||
<< "<div class='content'>\r\n<table><tbody><thead><th>Destination</th><th>Status</th></thead>\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>Destination</th><th>Status</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "Tags sessions: <i>0</i><br>\r\n";
|
s << "Tags sessions: <i>0</i><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
@@ -448,7 +510,7 @@ namespace http {
|
|||||||
|
|
||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
ShowLeaseSetDestination (s, dest);
|
ShowLeaseSetDestination (s, dest, token);
|
||||||
// show streams
|
// show streams
|
||||||
s << "<table>\r\n<caption>Streams</caption>\r\n<thead>\r\n<tr>";
|
s << "<table>\r\n<caption>Streams</caption>\r\n<thead>\r\n<tr>";
|
||||||
s << "<th style=\"width:25px;\">StreamID</th>";
|
s << "<th style=\"width:25px;\">StreamID</th>";
|
||||||
@@ -462,11 +524,12 @@ namespace http {
|
|||||||
s << "<th>RTT</th>";
|
s << "<th>RTT</th>";
|
||||||
s << "<th>Window</th>";
|
s << "<th>Window</th>";
|
||||||
s << "<th>Status</th>";
|
s << "<th>Status</th>";
|
||||||
s << "</tr>\r\n</thead>\r\n<tbody>\r\n";
|
s << "</tr>\r\n</thead>\r\n<tbody class=\"tableitem\">\r\n";
|
||||||
|
|
||||||
for (const auto& it: dest->GetAllStreams ())
|
for (const auto& it: dest->GetAllStreams ())
|
||||||
{
|
{
|
||||||
auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ());
|
auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ());
|
||||||
|
std::string streamDestShort = streamDest.substr(0,12) + "….b32.i2p";
|
||||||
s << "<tr>";
|
s << "<tr>";
|
||||||
s << "<td>" << it->GetRecvStreamID () << "</td>";
|
s << "<td>" << it->GetRecvStreamID () << "</td>";
|
||||||
if (it->GetRecvStreamID ()) {
|
if (it->GetRecvStreamID ()) {
|
||||||
@@ -475,7 +538,7 @@ namespace http {
|
|||||||
} else {
|
} else {
|
||||||
s << "<td \\>";
|
s << "<td \\>";
|
||||||
}
|
}
|
||||||
s << "<td class=\"streamdest\" title=\"" << streamDest << "\">" << streamDest << "</td>";
|
s << "<td class=\"streamdest\" title=\"" << streamDest << "\">" << streamDestShort << "</td>";
|
||||||
s << "<td>" << it->GetNumSentBytes () << "</td>";
|
s << "<td>" << it->GetNumSentBytes () << "</td>";
|
||||||
s << "<td>" << it->GetNumReceivedBytes () << "</td>";
|
s << "<td>" << it->GetNumReceivedBytes () << "</td>";
|
||||||
s << "<td>" << it->GetSendQueueSize () << "</td>";
|
s << "<td>" << it->GetSendQueueSize () << "</td>";
|
||||||
@@ -490,7 +553,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
||||||
{
|
{
|
||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer)
|
if (i2cpServer)
|
||||||
@@ -498,7 +561,7 @@ namespace http {
|
|||||||
s << "<b>I2CP Local Destination:</b><br>\r\n<br>\r\n";
|
s << "<b>I2CP Local Destination:</b><br>\r\n<br>\r\n";
|
||||||
auto it = i2cpServer->GetSessions ().find (std::stoi (id));
|
auto it = i2cpServer->GetSessions ().find (std::stoi (id));
|
||||||
if (it != i2cpServer->GetSessions ().end ())
|
if (it != i2cpServer->GetSessions ().end ())
|
||||||
ShowLeaseSetDestination (s, it->second->GetDestination ());
|
ShowLeaseSetDestination (s, it->second->GetDestination (), 0);
|
||||||
else
|
else
|
||||||
ShowError(s, "I2CP session not found");
|
ShowError(s, "I2CP session not found");
|
||||||
}
|
}
|
||||||
@@ -510,7 +573,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
if (i2p::data::netdb.GetNumLeaseSets ())
|
if (i2p::data::netdb.GetNumLeaseSets ())
|
||||||
{
|
{
|
||||||
s << "<b>LeaseSets:</b><br>\r\n<br>\r\n";
|
s << "<b>LeaseSets:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
// for each lease set
|
// for each lease set
|
||||||
i2p::data::netdb.VisitLeaseSets(
|
i2p::data::netdb.VisitLeaseSets(
|
||||||
@@ -524,14 +587,14 @@ namespace http {
|
|||||||
else
|
else
|
||||||
ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
|
ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
|
||||||
if (!ls) return;
|
if (!ls) return;
|
||||||
s << "<div class='leaseset";
|
s << "<div class=\"leaseset listitem";
|
||||||
if (ls->IsExpired())
|
if (ls->IsExpired())
|
||||||
s << " expired"; // additional css class for expired
|
s << " expired"; // additional css class for expired
|
||||||
s << "'>\r\n";
|
s << "\">\r\n";
|
||||||
if (!ls->IsValid())
|
if (!ls->IsValid())
|
||||||
s << "<div class='invalid'>!! Invalid !! </div>\r\n";
|
s << "<div class=\"invalid\">!! Invalid !! </div>\r\n";
|
||||||
s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n";
|
s << "<div class=\"slide\"><label for=\"slide" << counter << "\">" << dest.ToBase32() << "</label>\r\n";
|
||||||
s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<div class='content'>\r\n";
|
s << "<input type=\"checkbox\" id=\"slide" << (counter++) << "\" />\r\n<div class=\"slidecontent\">\r\n";
|
||||||
s << "<b>Store type:</b> " << (int)storeType << "<br>\r\n";
|
s << "<b>Store type:</b> " << (int)storeType << "<br>\r\n";
|
||||||
s << "<b>Expires:</b> " << ConvertTime(ls->GetExpirationTime()) << "<br>\r\n";
|
s << "<b>Expires:</b> " << ConvertTime(ls->GetExpirationTime()) << "<br>\r\n";
|
||||||
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
||||||
@@ -563,54 +626,59 @@ namespace http {
|
|||||||
|
|
||||||
void ShowTunnels (std::stringstream& s)
|
void ShowTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Tunnels:</b><br>\r\n<br>\r\n";
|
s << "<b>Tunnels:</b><br>\r\n";
|
||||||
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n";
|
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
|
|
||||||
s << "<b>Inbound tunnels:</b><br>\r\n";
|
s << "<b>Inbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) {
|
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) {
|
||||||
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << "ms )";
|
||||||
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
|
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "</div>\r\n<br>\r\n";
|
||||||
s << "<b>Outbound tunnels:</b><br>\r\n";
|
s << "<b>Outbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) {
|
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) {
|
||||||
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << "ms )";
|
||||||
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
|
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
/* commands */
|
/* commands */
|
||||||
s << "<b>Router Commands</b><br>\r\n<br>\r\n";
|
s << "<b>Router Commands</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a>\r\n";
|
||||||
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">Decline transit tunnels</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">Decline transit tunnels</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">Accept transit tunnels</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">Accept transit tunnels</a>\r\n";
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (Daemon.gracefulShutdownInterval)
|
if (Daemon.gracefulShutdownInterval)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
||||||
#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a>\r\n";
|
||||||
#endif
|
#endif
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n<br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a>\r\n";
|
||||||
|
s << "</div>";
|
||||||
|
|
||||||
s << "<small><b>Note:</b> any action done here are not persistent and not changes your config files.</small>\r\n<br>\r\n";
|
s << "<br>\r\n<small><b>Note:</b> any action done here are not persistent and not changes your config files.</small>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<b>Logging level</b><br>\r\n";
|
s << "<b>Logging level</b><br>\r\n";
|
||||||
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
|
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
|
||||||
@@ -633,17 +701,19 @@ namespace http {
|
|||||||
{
|
{
|
||||||
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
||||||
{
|
{
|
||||||
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
|
s << "<b>Transit tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||||
{
|
{
|
||||||
|
s << "<div class=\"listitem\">\r\n";
|
||||||
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
||||||
s << it->GetTunnelID () << " ⇒ ";
|
s << it->GetTunnelID () << " ⇒ ";
|
||||||
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
|
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
|
||||||
s << " ⇒ " << it->GetTunnelID ();
|
s << " ⇒ " << it->GetTunnelID ();
|
||||||
else
|
else
|
||||||
s << " ⇒ " << it->GetTunnelID () << " ⇒ ";
|
s << " ⇒ " << it->GetTunnelID () << " ⇒ ";
|
||||||
s << " " << it->GetNumTransmittedBytes () << "<br>\r\n";
|
s << " " << it->GetNumTransmittedBytes () << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -657,52 +727,46 @@ namespace http {
|
|||||||
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
|
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
|
||||||
for (const auto& it: sessions )
|
for (const auto& it: sessions )
|
||||||
{
|
{
|
||||||
if (it.second && it.second->IsEstablished () && !it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
if (it.second && it.second->IsEstablished () && !it.second->GetRemoteEndpoint ().address ().is_v6 ())
|
||||||
{
|
{
|
||||||
// incoming connection doesn't have remote RI
|
tmp_s << "<div class=\"listitem\">\r\n";
|
||||||
if (it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
if (it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
||||||
tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
||||||
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
<< it.second->GetRemoteEndpoint ().address ().to_string ();
|
||||||
if (!it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
if (!it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
||||||
tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
tmp_s << "<br>\r\n" << std::endl;
|
tmp_s << "</div>\r\n" << std::endl;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
if (it.second && it.second->IsEstablished () && it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
if (it.second && it.second->IsEstablished () && it.second->GetRemoteEndpoint ().address ().is_v6 ())
|
||||||
{
|
{
|
||||||
|
tmp_s6 << "<div class=\"listitem\">\r\n";
|
||||||
if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
||||||
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
||||||
<< "[" << it.second->GetSocket ().remote_endpoint().address ().to_string () << "]";
|
<< "[" << it.second->GetRemoteEndpoint ().address ().to_string () << "]";
|
||||||
if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
||||||
tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
tmp_s6 << "<br>\r\n" << std::endl;
|
tmp_s6 << "</div>\r\n" << std::endl;
|
||||||
cnt6++;
|
cnt6++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!tmp_s.str ().empty ())
|
if (!tmp_s.str ().empty ())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "'><b>" << name
|
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "'><b>" << name
|
||||||
<< "</b> ( " << cnt << " )</label>\r\n<input type='checkbox' id='slide_" << boost::algorithm::to_lower_copy(name) << "'/>\r\n<div class='content'>"
|
<< "</b> ( " << cnt << " )</label>\r\n<input type=\"checkbox\" id=\"slide_" << boost::algorithm::to_lower_copy(name) << "\" />\r\n<div class=\"slidecontent list\">"
|
||||||
<< tmp_s.str () << "</div>\r\n</div>\r\n";
|
<< tmp_s.str () << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
if (!tmp_s6.str ().empty ())
|
if (!tmp_s6.str ().empty ())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "v6'><b>" << name
|
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "v6'><b>" << name
|
||||||
<< "v6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_" << boost::algorithm::to_lower_copy(name) << "v6'/>\r\n<div class='content'>"
|
<< "v6</b> ( " << cnt6 << " )</label>\r\n<input type=\"checkbox\" id=\"slide_" << boost::algorithm::to_lower_copy(name) << "v6\" />\r\n<div class=\"slidecontent list\">"
|
||||||
<< tmp_s6.str () << "</div>\r\n</div>\r\n";
|
<< tmp_s6.str () << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowTransports (std::stringstream& s)
|
void ShowTransports (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Transports:</b><br>\r\n<br>\r\n";
|
s << "<b>Transports:</b><br>\r\n";
|
||||||
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
|
|
||||||
if (ntcpServer)
|
|
||||||
{
|
|
||||||
auto sessions = ntcpServer->GetNTCPSessions ();
|
|
||||||
if (!sessions.empty ())
|
|
||||||
ShowNTCPTransports (s, sessions, "NTCP");
|
|
||||||
}
|
|
||||||
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
|
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
|
||||||
if (ntcp2Server)
|
if (ntcp2Server)
|
||||||
{
|
{
|
||||||
@@ -716,9 +780,10 @@ namespace http {
|
|||||||
auto sessions = ssuServer->GetSessions ();
|
auto sessions = ssuServer->GetSessions ();
|
||||||
if (!sessions.empty ())
|
if (!sessions.empty ())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide_ssu'><b>SSU</b> ( " << (int) sessions.size() << " )</label>\r\n<input type='checkbox' id='slide_ssu'/>\r\n<div class='content'>";
|
s << "<div class='slide'><label for='slide_ssu'><b>SSU</b> ( " << (int) sessions.size() << " )</label>\r\n<input type=\"checkbox\" id=\"slide_ssu\" />\r\n<div class=\"slidecontent list\">";
|
||||||
for (const auto& it: sessions)
|
for (const auto& it: sessions)
|
||||||
{
|
{
|
||||||
|
s << "<div class=\"listitem\">\r\n";
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
||||||
@@ -726,16 +791,17 @@ namespace http {
|
|||||||
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
if (it.second->GetRelayTag ())
|
if (it.second->GetRelayTag ())
|
||||||
s << " [itag:" << it.second->GetRelayTag () << "]";
|
s << " [itag:" << it.second->GetRelayTag () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "</div>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
auto sessions6 = ssuServer->GetSessionsV6 ();
|
auto sessions6 = ssuServer->GetSessionsV6 ();
|
||||||
if (!sessions6.empty ())
|
if (!sessions6.empty ())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssuv6'/>\r\n<div class='content'>";
|
s << "<div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type=\"checkbox\" id=\"slide_ssuv6\" />\r\n<div class=\"slidecontent list\">";
|
||||||
for (const auto& it: sessions6)
|
for (const auto& it: sessions6)
|
||||||
{
|
{
|
||||||
|
s << "<div class=\"listitem\">\r\n";
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << "[" << endpoint.address ().to_string () << "]:" << endpoint.port ();
|
s << "[" << endpoint.address ().to_string () << "]:" << endpoint.port ();
|
||||||
@@ -743,7 +809,7 @@ namespace http {
|
|||||||
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
if (it.second->GetRelayTag ())
|
if (it.second->GetRelayTag ())
|
||||||
s << " [itag:" << it.second->GetRelayTag () << "]";
|
s << " [itag:" << it.second->GetRelayTag () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "</div>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
@@ -762,129 +828,141 @@ namespace http {
|
|||||||
|
|
||||||
if(sam->GetSessions ().size ())
|
if(sam->GetSessions ().size ())
|
||||||
{
|
{
|
||||||
s << "<b>SAM Sessions:</b><br>\r\n<br>\r\n";
|
s << "<b>SAM Sessions:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: sam->GetSessions ())
|
for (auto& it: sam->GetSessions ())
|
||||||
{
|
{
|
||||||
auto& name = it.second->localDestination->GetNickname ();
|
auto& name = it.second->localDestination->GetNickname ();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
|
||||||
s << name << " (" << it.first << ")</a><br>\r\n" << std::endl;
|
s << name << " (" << it.first << ")</a></div>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>SAM Sessions:</b> no sessions currently running.<br>\r\n";
|
s << "<b>SAM Sessions:</b> no sessions currently running.<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowSAMSession (std::stringstream& s, const std::string& id)
|
void ShowSAMSession (std::stringstream& s, const std::string& id)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
|
||||||
s << "<b>SAM Session:</b><br>\r\n<br>\r\n";
|
|
||||||
auto sam = i2p::client::context.GetSAMBridge ();
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
if (!sam) {
|
if (!sam) {
|
||||||
ShowError(s, "SAM disabled");
|
ShowError(s, "SAM disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto session = sam->FindSession (id);
|
auto session = sam->FindSession (id);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
ShowError(s, "SAM session not found");
|
ShowError(s, "SAM session not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
|
s << "<b>SAM Session:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
auto& ident = session->localDestination->GetIdentHash();
|
auto& ident = session->localDestination->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Streams:</b><br>\r\n";
|
s << "<b>Streams:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (const auto& it: sam->ListSockets(id))
|
for (const auto& it: sam->ListSockets(id))
|
||||||
{
|
{
|
||||||
|
s << "<div class=\"listitem\">";
|
||||||
switch (it->GetSocketType ())
|
switch (it->GetSocketType ())
|
||||||
{
|
{
|
||||||
case i2p::client::eSAMSocketTypeSession : s << "session"; break;
|
case i2p::client::eSAMSocketTypeSession : s << "session"; break;
|
||||||
case i2p::client::eSAMSocketTypeStream : s << "stream"; break;
|
case i2p::client::eSAMSocketTypeStream : s << "stream"; break;
|
||||||
case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break;
|
case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break;
|
||||||
|
case i2p::client::eSAMSocketTypeForward : s << "forward"; break;
|
||||||
default: s << "unknown"; break;
|
default: s << "unknown"; break;
|
||||||
}
|
}
|
||||||
s << " [" << it->GetSocket ().remote_endpoint() << "]";
|
s << " [" << it->GetSocket ().remote_endpoint() << "]";
|
||||||
s << "<br>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowI2PTunnels (std::stringstream& s)
|
void ShowI2PTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n";
|
s << "<b>Client Tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: i2p::client::context.GetClientTunnels ())
|
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
auto httpProxy = i2p::client::context.GetHttpProxy ();
|
auto httpProxy = i2p::client::context.GetHttpProxy ();
|
||||||
if (httpProxy)
|
if (httpProxy)
|
||||||
{
|
{
|
||||||
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "HTTP Proxy" << "</a> ⇐ ";
|
s << "HTTP Proxy" << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
auto socksProxy = i2p::client::context.GetSocksProxy ();
|
auto socksProxy = i2p::client::context.GetSocksProxy ();
|
||||||
if (socksProxy)
|
if (socksProxy)
|
||||||
{
|
{
|
||||||
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "SOCKS Proxy" << "</a> ⇐ ";
|
s << "SOCKS Proxy" << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
|
|
||||||
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
||||||
if (!serverTunnels.empty ()) {
|
if (!serverTunnels.empty ()) {
|
||||||
s << "<br>\r\n<b>Server Tunnels:</b><br>\r\n<br>\r\n";
|
s << "<br>\r\n<b>Server Tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: serverTunnels)
|
for (auto& it: serverTunnels)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇒ ";
|
s << it.second->GetName () << "</a> ⇒ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << ":" << it.second->GetLocalPort ();
|
s << ":" << it.second->GetLocalPort ();
|
||||||
s << "</a><br>\r\n"<< std::endl;
|
s << "</a></div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& clientForwards = i2p::client::context.GetClientForwards ();
|
auto& clientForwards = i2p::client::context.GetClientForwards ();
|
||||||
if (!clientForwards.empty ())
|
if (!clientForwards.empty ())
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>Client Forwards:</b><br>\r\n<br>\r\n";
|
s << "<br>\r\n<b>Client Forwards:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: clientForwards)
|
for (auto& it: clientForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
auto& serverForwards = i2p::client::context.GetServerForwards ();
|
auto& serverForwards = i2p::client::context.GetServerForwards ();
|
||||||
if (!serverForwards.empty ())
|
if (!serverForwards.empty ())
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>Server Forwards:</b><br>\r\n<br>\r\n";
|
s << "<br>\r\n<b>Server Forwards:</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: serverForwards)
|
for (auto& it: serverForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ConvertTime (uint64_t time)
|
std::string ConvertTime (uint64_t time)
|
||||||
{
|
{
|
||||||
ldiv_t divTime = ldiv(time,1000);
|
lldiv_t divTime = lldiv(time, 1000);
|
||||||
time_t t = divTime.quot;
|
time_t t = divTime.quot;
|
||||||
struct tm *tm = localtime(&t);
|
struct tm *tm = localtime(&t);
|
||||||
char date[128];
|
char date[128];
|
||||||
snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03ld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem);
|
snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem);
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1148,15 +1226,15 @@ namespace http {
|
|||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
if(dest->DeleteStream (streamID))
|
if(dest->DeleteStream (streamID))
|
||||||
s << "<b>SUCCESS</b>: Stream closed<br><br>\r\n";
|
s << "<b>SUCCESS</b>: Stream closed<br>\r\n<br>\r\n";
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Stream not found or already was closed<br><br>\r\n";
|
s << "<b>ERROR</b>: Stream not found or already was closed<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Destination not found<br><br>\r\n";
|
s << "<b>ERROR</b>: Destination not found<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: StreamID can be null<br><br>\r\n";
|
s << "<b>ERROR</b>: StreamID can be null<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">Return to destination page</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">Return to destination page</a><br>\r\n";
|
||||||
s << "<p>You will be redirected back in 5 seconds</b>";
|
s << "<p>You will be redirected back in 5 seconds</b>";
|
||||||
@@ -1170,13 +1248,62 @@ namespace http {
|
|||||||
if (limit > 0 && limit <= 65535)
|
if (limit > 0 && limit <= 65535)
|
||||||
SetMaxNumTransitTunnels (limit);
|
SetMaxNumTransitTunnels (limit);
|
||||||
else {
|
else {
|
||||||
s << "<b>ERROR</b>: Transit tunnels count must not exceed 65535<br><br>\r\n";
|
s << "<b>ERROR</b>: Transit tunnels count must not exceed 65535\r\n<br>\r\n<br>\r\n";
|
||||||
s << "<a href=\"" << webroot << "?page=commands\">Back to commands list</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=commands\">Back to commands list</a>\r\n<br>\r\n";
|
||||||
s << "<p>You will be redirected back in 5 seconds</b>";
|
s << "<p>You will be redirected back in 5 seconds</b>";
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cmd == HTTP_COMMAND_GET_REG_STRING)
|
||||||
|
{
|
||||||
|
std::string b32 = params["b32"];
|
||||||
|
std::string name = params["name"];
|
||||||
|
|
||||||
|
i2p::data::IdentHash ident;
|
||||||
|
ident.FromBase32 (b32);
|
||||||
|
auto dest = i2p::client::context.FindLocalDestination (ident);
|
||||||
|
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
std::size_t pos;
|
||||||
|
pos = name.find (".i2p");
|
||||||
|
if (pos == (name.length () - 4))
|
||||||
|
{
|
||||||
|
pos = name.find (".b32.i2p");
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
{
|
||||||
|
auto signatureLen = dest->GetIdentity ()->GetSignatureLen ();
|
||||||
|
uint8_t * signature = new uint8_t[signatureLen];
|
||||||
|
char * sig = new char[signatureLen*2];
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
|
out << name << "=" << dest->GetIdentity ()->ToBase64 ();
|
||||||
|
dest->Sign ((uint8_t *)out.str ().c_str (), out.str ().length (), signature);
|
||||||
|
auto len = i2p::data::ByteStreamToBase64 (signature, signatureLen, sig, signatureLen*2);
|
||||||
|
sig[len] = 0;
|
||||||
|
out << "#!sig=" << sig;
|
||||||
|
s << "<b>SUCCESS</b>:<br>\r\n<form action=\"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/add\" method=\"post\" rel=\"noreferrer\" target=\"_blank\">\r\n"
|
||||||
|
"<textarea readonly name=\"record\" cols=\"80\" rows=\"10\">" << out.str () << "</textarea>\r\n<br>\r\n<br>\r\n"
|
||||||
|
"<b>Register at reg.i2p:</b>\r\n<br>\r\n"
|
||||||
|
"<b>Description:</b>\r\n<input type=\"text\" maxlength=\"64\" name=\"desc\" placeholder=\"A bit information about service on domain\">\r\n"
|
||||||
|
"<input type=\"submit\" value=\"Submit\">\r\n"
|
||||||
|
"</form>\r\n<br>\r\n";
|
||||||
|
delete[] signature;
|
||||||
|
delete[] sig;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s << "<b>ERROR</b>: Domain can't end with .b32.i2p\r\n<br>\r\n<br>\r\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s << "<b>ERROR</b>: Domain must end with .i2p\r\n<br>\r\n<br>\r\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s << "<b>ERROR</b>: Such destination is not found\r\n<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">Return to destination page</a>\r\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res.code = 400;
|
res.code = 400;
|
||||||
@@ -1255,6 +1382,8 @@ namespace http {
|
|||||||
|
|
||||||
void HTTPServer::Run ()
|
void HTTPServer::Run ()
|
||||||
{
|
{
|
||||||
|
i2p::util::SetThreadName("Webconsole");
|
||||||
|
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1271,8 +1400,8 @@ namespace http {
|
|||||||
void HTTPServer::Accept ()
|
void HTTPServer::Accept ()
|
||||||
{
|
{
|
||||||
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (m_Service);
|
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (m_Service);
|
||||||
m_Acceptor.async_accept (*newSocket, boost::bind (&HTTPServer::HandleAccept, this,
|
m_Acceptor.async_accept (*newSocket, std::bind (&HTTPServer::HandleAccept, this,
|
||||||
boost::asio::placeholders::error, newSocket));
|
std::placeholders::_1, newSocket));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPServer::HandleAccept(const boost::system::error_code& ecode,
|
void HTTPServer::HandleAccept(const boost::system::error_code& ecode,
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ namespace http
|
|||||||
void ShowSAMSessions (std::stringstream& s);
|
void ShowSAMSessions (std::stringstream& s);
|
||||||
void ShowI2PTunnels (std::stringstream& s);
|
void ShowI2PTunnels (std::stringstream& s);
|
||||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||||
|
void ShowSAMSession (std::stringstream& s, const std::string& id);
|
||||||
|
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
|
||||||
} // http
|
} // http
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
@@ -14,12 +6,7 @@
|
|||||||
#include <boost/date_time/local_time/local_time.hpp>
|
#include <boost/date_time/local_time/local_time.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
|
||||||
// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy
|
|
||||||
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
|
|
||||||
#if !GCC47_BOOST149
|
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
@@ -67,28 +54,29 @@ 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"] = &I2PControlService::TunnelsSuccessRateHandler;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
|
||||||
|
&I2PControlService::TunnelsSuccessRateHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||||
|
|
||||||
@@ -104,10 +92,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 ()
|
||||||
@@ -143,6 +131,8 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::Run ()
|
void I2PControlService::Run ()
|
||||||
{
|
{
|
||||||
|
i2p::util::SetThreadName("I2PC");
|
||||||
|
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -242,12 +232,6 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
#if GCC47_BOOST149
|
|
||||||
LogPrint (eLogError, "I2PControl: json_read is not supported due bug in boost 1.49 with gcc 4.7");
|
|
||||||
response << "{\"id\":null,\"error\":";
|
|
||||||
response << "{\"code\":-32603,\"message\":\"JSON requests is not supported with this version of boost\"},";
|
|
||||||
response << "\"jsonrpc\":\"2.0\"}";
|
|
||||||
#else
|
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
boost::property_tree::read_json (ss, pt);
|
boost::property_tree::read_json (ss, pt);
|
||||||
|
|
||||||
@@ -267,7 +251,6 @@ namespace client
|
|||||||
response << "{\"code\":-32601,\"message\":\"Method not found\"},";
|
response << "{\"code\":-32601,\"message\":\"Method not found\"},";
|
||||||
response << "\"jsonrpc\":\"2.0\"}";
|
response << "\"jsonrpc\":\"2.0\"}";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
SendResponse (socket, buf, response, isHtml);
|
SendResponse (socket, buf, response, isHtml);
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
@@ -408,8 +391,8 @@ namespace client
|
|||||||
auto it1 = m_RouterInfoHandlers.find (it->first);
|
auto it1 = m_RouterInfoHandlers.find (it->first);
|
||||||
if (it1 != m_RouterInfoHandlers.end ())
|
if (it1 != m_RouterInfoHandlers.end ())
|
||||||
{
|
{
|
||||||
if (!first) results << ",";
|
if (!first) results << ",";
|
||||||
else first = false;
|
else first = false;
|
||||||
(this->*(it1->second))(results);
|
(this->*(it1->second))(results);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -507,7 +490,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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -521,7 +504,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,18 +1,9 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef USE_UPNP
|
#ifdef USE_UPNP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@@ -69,6 +60,8 @@ namespace transport
|
|||||||
|
|
||||||
void UPnP::Run ()
|
void UPnP::Run ()
|
||||||
{
|
{
|
||||||
|
i2p::util::SetThreadName("UPnP");
|
||||||
|
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -100,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;
|
||||||
@@ -118,7 +111,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
||||||
m_upnpUrlsInitialized = err != 0;
|
m_upnpUrlsInitialized=err!=0;
|
||||||
if (err == UPNP_IGD_VALID_CONNECTED)
|
if (err == UPNP_IGD_VALID_CONNECTED)
|
||||||
{
|
{
|
||||||
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
||||||
@@ -232,7 +225,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
||||||
int err = UPNPCOMMAND_SUCCESS;
|
int err = UPNPCOMMAND_SUCCESS;
|
||||||
|
|
||||||
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
||||||
if (err == UPNPCOMMAND_SUCCESS)
|
if (err == UPNPCOMMAND_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|||||||
30
debian/changelog
vendored
30
debian/changelog
vendored
@@ -1,3 +1,33 @@
|
|||||||
|
i2pd (2.37.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.37.0
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 15 Mar 2021 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.36.0-1) unstable; urgency=high
|
||||||
|
|
||||||
|
* updated to version 2.36.0/0.9.49
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 15 Feb 2021 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.35.0-1) unstable; urgency=high
|
||||||
|
|
||||||
|
* updated to version 2.35.0/0.9.48
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 30 Nov 2020 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.34.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.34.0
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Tue, 27 Oct 2020 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.33.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.33.0/0.9.47
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 24 Aug 2020 16:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.32.1-1) unstable; urgency=high
|
i2pd (2.32.1-1) unstable; urgency=high
|
||||||
|
|
||||||
* updated to version 2.32.1
|
* updated to version 2.32.1
|
||||||
|
|||||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
|||||||
9
|
10
|
||||||
15
debian/patches/01-tune-build-opts.patch
vendored
15
debian/patches/01-tune-build-opts.patch
vendored
@@ -1,15 +0,0 @@
|
|||||||
Index: i2pd/Makefile
|
|
||||||
===================================================================
|
|
||||||
--- i2pd.orig/Makefile
|
|
||||||
+++ i2pd/Makefile
|
|
||||||
@@ -13,8 +13,8 @@ DAEMON_SRC_DIR := daemon
|
|
||||||
|
|
||||||
include filelist.mk
|
|
||||||
|
|
||||||
-USE_AESNI := yes
|
|
||||||
-USE_AVX := yes
|
|
||||||
+USE_AESNI := no
|
|
||||||
+USE_AVX := no
|
|
||||||
USE_STATIC := no
|
|
||||||
USE_MESHNET := no
|
|
||||||
USE_UPNP := no
|
|
||||||
17
debian/patches/02-upnp.patch
vendored
Normal file
17
debian/patches/02-upnp.patch
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Description: Enable UPnP usage in package
|
||||||
|
Author: r4sas <r4sas@i2pmail.org>
|
||||||
|
|
||||||
|
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||||
|
Last-Update: 2021-01-16
|
||||||
|
|
||||||
|
--- i2pd.orig/Makefile
|
||||||
|
+++ i2pd/Makefile
|
||||||
|
@@ -15,7 +15,7 @@ include filelist.mk
|
||||||
|
USE_AESNI := yes
|
||||||
|
USE_STATIC := no
|
||||||
|
USE_MESHNET := no
|
||||||
|
-USE_UPNP := no
|
||||||
|
+USE_UPNP := yes
|
||||||
|
DEBUG := yes
|
||||||
|
|
||||||
|
ifeq ($(DEBUG),yes)
|
||||||
4
debian/patches/series
vendored
4
debian/patches/series
vendored
@@ -1,2 +1,2 @@
|
|||||||
01-tune-build-opts.patch
|
01-fix-1210.patch
|
||||||
02-fix-1210.patch
|
02-upnp.patch
|
||||||
|
|||||||
@@ -27,37 +27,32 @@ namespace cpu
|
|||||||
bool aesni = false;
|
bool aesni = false;
|
||||||
bool avx = false;
|
bool avx = false;
|
||||||
|
|
||||||
void Detect()
|
void Detect(bool AesSwitch, bool AvxSwitch, bool force)
|
||||||
{
|
{
|
||||||
#if defined(__AES__) || defined(__AVX__)
|
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
int info[4];
|
int info[4];
|
||||||
__cpuid(0, info[0], info[1], info[2], info[3]);
|
__cpuid(0, info[0], info[1], info[2], info[3]);
|
||||||
if (info[0] >= 0x00000001) {
|
if (info[0] >= 0x00000001) {
|
||||||
__cpuid(0x00000001, info[0], info[1], info[2], info[3]);
|
__cpuid(0x00000001, info[0], info[1], info[2], info[3]);
|
||||||
#ifdef __AES__
|
#if defined (_WIN32) && (WINVER == 0x0501) // WinXP
|
||||||
aesni = info[2] & bit_AES; // AESNI
|
if (AesSwitch && force) { // only if forced
|
||||||
#endif // __AES__
|
#else
|
||||||
#ifdef __AVX__
|
if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) {
|
||||||
avx = info[2] & bit_AVX; // AVX
|
#endif
|
||||||
#endif // __AVX__
|
aesni = true;
|
||||||
|
}
|
||||||
|
#if defined (_WIN32) && (WINVER == 0x0501) // WinXP
|
||||||
|
if (AvxSwitch && force) { // only if forced
|
||||||
|
#else
|
||||||
|
if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) {
|
||||||
|
#endif
|
||||||
|
avx = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // defined(__x86_64__) || defined(__i386__)
|
#endif // defined(__x86_64__) || defined(__i386__)
|
||||||
|
|
||||||
#ifdef __AES__
|
LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled"));
|
||||||
if(aesni)
|
LogPrint(eLogInfo, "AVX ", (avx ? "enabled" : "disabled"));
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "AESNI enabled");
|
|
||||||
}
|
|
||||||
#endif // __AES__
|
|
||||||
#ifdef __AVX__
|
|
||||||
if(avx)
|
|
||||||
{
|
|
||||||
LogPrint(eLogInfo, "AVX enabled");
|
|
||||||
}
|
|
||||||
#endif // __AVX__
|
|
||||||
#endif // defined(__AES__) || defined(__AVX__)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace cpu
|
|||||||
extern bool aesni;
|
extern bool aesni;
|
||||||
extern bool avx;
|
extern bool avx;
|
||||||
|
|
||||||
void Detect();
|
void Detect(bool AesSwitch, bool AvxSwitch, bool force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
using namespace boost::program_options;
|
using namespace boost::program_options;
|
||||||
|
|
||||||
@@ -47,10 +48,13 @@ namespace config {
|
|||||||
("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
|
("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
|
||||||
("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
|
("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
|
||||||
("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
|
("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
|
||||||
("nat", value<bool>()->default_value(true), "Should we assume we are behind NAT? (default: enabled)")
|
("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)")
|
||||||
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
||||||
("ipv4", value<bool>()->default_value(true), "Enable communication through ipv4 (default: enabled)")
|
("ipv4", bool_switch()->default_value(true), "Enable communication through ipv4 (default: enabled)")
|
||||||
|
("address4", value<std::string>()->default_value(""), "Local address to bind ipv4 transport sockets to")
|
||||||
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
|
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
|
||||||
|
("address6", value<std::string>()->default_value(""), "Local address to bind ipv6 transport sockets to")
|
||||||
|
("reservedrange", bool_switch()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)")
|
||||||
("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
|
("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
|
||||||
("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
|
("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
|
||||||
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
|
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
|
||||||
@@ -58,11 +62,11 @@ namespace config {
|
|||||||
("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
|
("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
|
||||||
("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
|
("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
|
||||||
("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
|
("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
|
||||||
("ntcp", value<bool>()->default_value(false), "Enable NTCP transport (default: disabled)")
|
("ntcp", bool_switch()->default_value(false), "Ignored. Always false")
|
||||||
("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)")
|
("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)")
|
||||||
("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport")
|
("ntcpproxy", value<std::string>()->default_value(""), "Ignored")
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
|
("svcctl", value<std::string>()->default_value(""), "Ignored")
|
||||||
("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
|
("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
|
||||||
("close", value<std::string>()->default_value("ask"), "Action on close: minimize, exit, ask")
|
("close", value<std::string>()->default_value("ask"), "Action on close: minimize, exit, ask")
|
||||||
#endif
|
#endif
|
||||||
@@ -96,7 +100,7 @@ namespace config {
|
|||||||
("httpproxy.enabled", value<bool>()->default_value(true), "Enable or disable HTTP Proxy")
|
("httpproxy.enabled", value<bool>()->default_value(true), "Enable or disable HTTP Proxy")
|
||||||
("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address")
|
("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address")
|
||||||
("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port")
|
("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port")
|
||||||
("httpproxy.keys", value<std::string>()->default_value(""), "File to persist HTTP Proxy keys")
|
("httpproxy.keys", value<std::string>()->default_value("transient-proxy"), "File to persist HTTP Proxy keys. Transient by default")
|
||||||
("httpproxy.signaturetype", value<i2p::data::SigningKeyType>()->
|
("httpproxy.signaturetype", value<i2p::data::SigningKeyType>()->
|
||||||
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
|
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
|
||||||
("httpproxy.inbound.length", value<std::string>()->default_value("3"), "HTTP proxy inbound tunnel length")
|
("httpproxy.inbound.length", value<std::string>()->default_value("3"), "HTTP proxy inbound tunnel length")
|
||||||
@@ -107,8 +111,8 @@ namespace config {
|
|||||||
("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")
|
||||||
("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
|
("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
|
||||||
("httpproxy.i2cp.leaseSetType", value<std::string>()->default_value("1"), "Local destination's LeaseSet type")
|
("httpproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
|
||||||
("httpproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0"), "Local destination's LeaseSet encryption type")
|
("httpproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description socksproxy("SOCKS Proxy options");
|
options_description socksproxy("SOCKS Proxy options");
|
||||||
@@ -116,7 +120,7 @@ namespace config {
|
|||||||
("socksproxy.enabled", value<bool>()->default_value(true), "Enable or disable SOCKS Proxy")
|
("socksproxy.enabled", value<bool>()->default_value(true), "Enable or disable SOCKS Proxy")
|
||||||
("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address")
|
("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address")
|
||||||
("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port")
|
("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port")
|
||||||
("socksproxy.keys", value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys")
|
("socksproxy.keys", value<std::string>()->default_value("transient-proxy"), "File to persist SOCKS Proxy keys. Transient by default")
|
||||||
("socksproxy.signaturetype", value<i2p::data::SigningKeyType>()->
|
("socksproxy.signaturetype", value<i2p::data::SigningKeyType>()->
|
||||||
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
|
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
|
||||||
("socksproxy.inbound.length", value<std::string>()->default_value("3"), "SOCKS proxy inbound tunnel length")
|
("socksproxy.inbound.length", value<std::string>()->default_value("3"), "SOCKS proxy inbound tunnel length")
|
||||||
@@ -128,8 +132,8 @@ namespace config {
|
|||||||
("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")
|
||||||
("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
|
("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
|
||||||
("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
|
("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
|
||||||
("socksproxy.i2cp.leaseSetType", value<std::string>()->default_value("1"), "Local destination's LeaseSet type")
|
("socksproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
|
||||||
("socksproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0"), "Local destination's LeaseSet encryption type")
|
("socksproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description sam("SAM bridge options");
|
options_description sam("SAM bridge options");
|
||||||
@@ -152,6 +156,7 @@ namespace config {
|
|||||||
("i2cp.enabled", value<bool>()->default_value(false), "Enable or disable I2CP")
|
("i2cp.enabled", value<bool>()->default_value(false), "Enable or disable I2CP")
|
||||||
("i2cp.address", value<std::string>()->default_value("127.0.0.1"), "I2CP listen address")
|
("i2cp.address", value<std::string>()->default_value("127.0.0.1"), "I2CP listen address")
|
||||||
("i2cp.port", value<uint16_t>()->default_value(7654), "I2CP listen port")
|
("i2cp.port", value<uint16_t>()->default_value(7654), "I2CP listen port")
|
||||||
|
("i2cp.singlethread", value<bool>()->default_value(true), "Destinations run in the I2CP server's thread")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description i2pcontrol("I2PControl options");
|
options_description i2pcontrol("I2PControl options");
|
||||||
@@ -195,28 +200,31 @@ namespace config {
|
|||||||
("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://reseed.i2p-projekt.de/,"
|
||||||
"https://i2p.mooo.com/netDb/,"
|
"https://reseed.diva.exchange/,"
|
||||||
"https://reseed.i2p2.no/,"
|
|
||||||
"https://reseed-fr.i2pd.xyz/,"
|
"https://reseed-fr.i2pd.xyz/,"
|
||||||
"https://reseed.memcpy.io/,"
|
"https://reseed.memcpy.io/,"
|
||||||
"https://reseed.onion.im/,"
|
"https://reseed.onion.im/,"
|
||||||
"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/"
|
||||||
), "Reseed URLs, separated by comma")
|
), "Reseed URLs, separated by comma")
|
||||||
|
("reseed.yggurls", value<std::string>()->default_value(
|
||||||
|
"http://[324:9de3:fea4:f6ac::ace]:7070/"
|
||||||
|
), "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.defaulturl", value<std::string>()->default_value(
|
("addressbook.defaulturl", value<std::string>()->default_value(
|
||||||
"http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-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(""), "AddressBook subscriptions URLs, separated by comma");
|
("addressbook.subscriptions", value<std::string>()->default_value(""), "AddressBook subscriptions URLs, separated by comma")
|
||||||
|
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
|
||||||
|
|
||||||
options_description trust("Trust options");
|
options_description trust("Trust options");
|
||||||
trust.add_options()
|
trust.add_options()
|
||||||
("trust.enabled", value<bool>()->default_value(false), "Enable explicit trust options")
|
("trust.enabled", value<bool>()->default_value(false), "Enable explicit trust options")
|
||||||
("trust.family", value<std::string>()->default_value(""), "Router Familiy to trust for first hops")
|
("trust.family", value<std::string>()->default_value(""), "Router Family to trust for first hops")
|
||||||
("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
|
("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
|
||||||
("trust.hidden", value<bool>()->default_value(false), "Should we hide our router from other routers?")
|
("trust.hidden", value<bool>()->default_value(false), "Should we hide our router from other routers?")
|
||||||
;
|
;
|
||||||
@@ -242,7 +250,7 @@ namespace config {
|
|||||||
("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
|
("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
|
||||||
("ntcp2.published", value<bool>()->default_value(true), "Publish NTCP2 (default: enabled)")
|
("ntcp2.published", value<bool>()->default_value(true), "Publish NTCP2 (default: enabled)")
|
||||||
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
|
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
|
||||||
("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to bind NTCP2 on")
|
("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to publish NTCP2 with")
|
||||||
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
|
("ntcp2.proxy", value<std::string>()->default_value(""), "Proxy URL for NTCP2 transport")
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -264,6 +272,19 @@ namespace config {
|
|||||||
("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)")
|
("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
options_description cpuext("CPU encryption extensions options");
|
||||||
|
cpuext.add_options()
|
||||||
|
("cpuext.aesni", bool_switch()->default_value(true), "Use auto detection for AESNI CPU extensions. If false, AESNI will be not used")
|
||||||
|
("cpuext.avx", bool_switch()->default_value(true), "Use auto detection for AVX CPU extensions. If false, AVX will be not used")
|
||||||
|
("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description meshnets("Meshnet transports options");
|
||||||
|
meshnets.add_options()
|
||||||
|
("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)")
|
||||||
|
("meshnets.yggaddress", value<std::string>()->default_value(""), "Yggdrasil address to publish")
|
||||||
|
;
|
||||||
|
|
||||||
m_OptionsDesc
|
m_OptionsDesc
|
||||||
.add(general)
|
.add(general)
|
||||||
.add(limits)
|
.add(limits)
|
||||||
@@ -284,6 +305,8 @@ namespace config {
|
|||||||
.add(ntcp2)
|
.add(ntcp2)
|
||||||
.add(nettime)
|
.add(nettime)
|
||||||
.add(persist)
|
.add(persist)
|
||||||
|
.add(cpuext)
|
||||||
|
.add(meshnets)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +315,7 @@ namespace config {
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto style = boost::program_options::command_line_style::unix_style
|
auto style = boost::program_options::command_line_style::unix_style
|
||||||
| boost::program_options::command_line_style::allow_long_disguise;
|
| boost::program_options::command_line_style::allow_long_disguise;
|
||||||
style &= ~ boost::program_options::command_line_style::allow_guessing;
|
style &= ~ boost::program_options::command_line_style::allow_guessing;
|
||||||
if (ignoreUnknown)
|
if (ignoreUnknown)
|
||||||
store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options);
|
store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options);
|
||||||
@@ -301,6 +324,7 @@ namespace config {
|
|||||||
}
|
}
|
||||||
catch (boost::program_options::error& e)
|
catch (boost::program_options::error& e)
|
||||||
{
|
{
|
||||||
|
ThrowFatal ("Error while parsing arguments: ", e.what());
|
||||||
std::cerr << "args: " << e.what() << std::endl;
|
std::cerr << "args: " << e.what() << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -338,6 +362,7 @@ namespace config {
|
|||||||
|
|
||||||
if (!config.is_open())
|
if (!config.is_open())
|
||||||
{
|
{
|
||||||
|
ThrowFatal ("Missing or unreadable config file: ", path);
|
||||||
std::cerr << "missing/unreadable config file: " << path << std::endl;
|
std::cerr << "missing/unreadable config file: " << path << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -348,6 +373,7 @@ namespace config {
|
|||||||
}
|
}
|
||||||
catch (boost::program_options::error& e)
|
catch (boost::program_options::error& e)
|
||||||
{
|
{
|
||||||
|
ThrowFatal ("Error while parsing config file: ", e.what());
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ namespace crypto
|
|||||||
|
|
||||||
~CryptoConstants ()
|
~CryptoConstants ()
|
||||||
{
|
{
|
||||||
BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae);
|
BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -351,11 +351,13 @@ namespace crypto
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
|
bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
|
||||||
{
|
{
|
||||||
|
if (!pub || (pub[31] & 0x80)) return false; // not x25519 key
|
||||||
#if OPENSSL_X25519
|
#if OPENSSL_X25519
|
||||||
EVP_PKEY_derive_init (m_Ctx);
|
EVP_PKEY_derive_init (m_Ctx);
|
||||||
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
|
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
|
||||||
|
if (!pkey) return false;
|
||||||
EVP_PKEY_derive_set_peer (m_Ctx, pkey);
|
EVP_PKEY_derive_set_peer (m_Ctx, pkey);
|
||||||
size_t len = 32;
|
size_t len = 32;
|
||||||
EVP_PKEY_derive (m_Ctx, shared, &len);
|
EVP_PKEY_derive (m_Ctx, shared, &len);
|
||||||
@@ -363,6 +365,7 @@ namespace crypto
|
|||||||
#else
|
#else
|
||||||
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
|
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
||||||
@@ -375,15 +378,22 @@ namespace crypto
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519Keys::SetPrivateKey (const uint8_t * priv)
|
void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic)
|
||||||
{
|
{
|
||||||
#if OPENSSL_X25519
|
#if OPENSSL_X25519
|
||||||
if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx);
|
if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx);
|
||||||
if (m_Pkey) EVP_PKEY_free (m_Pkey);
|
if (m_Pkey) EVP_PKEY_free (m_Pkey);
|
||||||
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
|
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
|
||||||
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL);
|
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL);
|
||||||
|
if (calculatePublic)
|
||||||
|
{
|
||||||
|
size_t len = 32;
|
||||||
|
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
memcpy (m_PrivateKey, priv, 32);
|
memcpy (m_PrivateKey, priv, 32);
|
||||||
|
if (calculatePublic)
|
||||||
|
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +525,7 @@ namespace crypto
|
|||||||
bn2buf (y, encrypted + len, len);
|
bn2buf (y, encrypted + len, len);
|
||||||
RAND_bytes (encrypted + 2*len, 256 - 2*len);
|
RAND_bytes (encrypted + 2*len, 256 - 2*len);
|
||||||
}
|
}
|
||||||
// ecryption key and iv
|
// encryption key and iv
|
||||||
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
||||||
uint8_t keyBuf[64], iv[64], shared[32];
|
uint8_t keyBuf[64], iv[64], shared[32];
|
||||||
@@ -631,7 +641,7 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
uint64_t buf[256];
|
uint64_t buf[256];
|
||||||
uint64_t hash[12]; // 96 bytes
|
uint64_t hash[12]; // 96 bytes
|
||||||
#ifdef __AVX__
|
#if (defined(__x86_64__) || defined(__i386__)) && defined(__AVX__) // not all X86 targets supports AVX (like old Pentium, see #1600)
|
||||||
if(i2p::cpu::avx)
|
if(i2p::cpu::avx)
|
||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
@@ -650,7 +660,7 @@ namespace crypto
|
|||||||
:
|
:
|
||||||
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads),
|
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads),
|
||||||
[buf]"r"(buf), [hash]"r"(hash)
|
[buf]"r"(buf), [hash]"r"(hash)
|
||||||
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -681,7 +691,7 @@ namespace crypto
|
|||||||
// concatenate with msg
|
// concatenate with msg
|
||||||
memcpy (buf + 8, msg, len);
|
memcpy (buf + 8, msg, len);
|
||||||
// calculate first hash
|
// calculate first hash
|
||||||
MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
|
MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
|
||||||
|
|
||||||
// calculate digest
|
// calculate digest
|
||||||
MD5((uint8_t *)hash, 96, digest);
|
MD5((uint8_t *)hash, 96, digest);
|
||||||
@@ -689,35 +699,28 @@ namespace crypto
|
|||||||
|
|
||||||
// AES
|
// AES
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
#ifdef ARM64AES
|
|
||||||
void init_aesenc(void){
|
|
||||||
// TODO: Implementation
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KeyExpansion256(round0,round1) \
|
#define KeyExpansion256(round0,round1) \
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
||||||
"movaps %%xmm1, %%xmm4 \n" \
|
"movaps %%xmm1, %%xmm4 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
"pxor %%xmm4, %%xmm1 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
"pxor %%xmm4, %%xmm1 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
"pxor %%xmm4, %%xmm1 \n" \
|
||||||
"pxor %%xmm2, %%xmm1 \n" \
|
"pxor %%xmm2, %%xmm1 \n" \
|
||||||
"movaps %%xmm1, "#round0"(%[sched]) \n" \
|
"movaps %%xmm1, "#round0"(%[sched]) \n" \
|
||||||
"aeskeygenassist $0, %%xmm1, %%xmm4 \n" \
|
"aeskeygenassist $0, %%xmm1, %%xmm4 \n" \
|
||||||
"pshufd $0xaa, %%xmm4, %%xmm2 \n" \
|
"pshufd $0xaa, %%xmm4, %%xmm2 \n" \
|
||||||
"movaps %%xmm3, %%xmm4 \n" \
|
"movaps %%xmm3, %%xmm4 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
"pxor %%xmm4, %%xmm3 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
"pxor %%xmm4, %%xmm3 \n" \
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
"pxor %%xmm4, %%xmm3 \n" \
|
||||||
"pxor %%xmm2, %%xmm3 \n" \
|
"pxor %%xmm2, %%xmm3 \n" \
|
||||||
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
@@ -743,16 +746,16 @@ namespace crypto
|
|||||||
KeyExpansion256(192,208)
|
KeyExpansion256(192,208)
|
||||||
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
|
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
|
||||||
// key expansion final
|
// key expansion final
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
||||||
"movaps %%xmm1, %%xmm4 \n"
|
"movaps %%xmm1, %%xmm4 \n"
|
||||||
"pslldq $4, %%xmm4 \n"
|
"pslldq $4, %%xmm4 \n"
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
"pxor %%xmm4, %%xmm1 \n"
|
||||||
"pslldq $4, %%xmm4 \n"
|
"pslldq $4, %%xmm4 \n"
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
"pxor %%xmm4, %%xmm1 \n"
|
||||||
"pslldq $4, %%xmm4 \n"
|
"pslldq $4, %%xmm4 \n"
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
"pxor %%xmm4, %%xmm1 \n"
|
||||||
"pxor %%xmm2, %%xmm1 \n"
|
"pxor %%xmm2, %%xmm1 \n"
|
||||||
"movups %%xmm1, 224(%[sched]) \n"
|
"movups %%xmm1, 224(%[sched]) \n"
|
||||||
: // output
|
: // output
|
||||||
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
||||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
|
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
|
||||||
@@ -787,9 +790,9 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -826,9 +829,9 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -841,7 +844,7 @@ namespace crypto
|
|||||||
|
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
#define CallAESIMC(offset) \
|
#define CallAESIMC(offset) \
|
||||||
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
||||||
"aesimc %%xmm0, %%xmm0 \n" \
|
"aesimc %%xmm0, %%xmm0 \n" \
|
||||||
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
||||||
#endif
|
#endif
|
||||||
@@ -866,7 +869,7 @@ namespace crypto
|
|||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
ExpandKey (key); // expand encryption key first
|
ExpandKey (key); // expand encryption key first
|
||||||
// then invert it using aesimc
|
// then invert it using aesimc
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
CallAESIMC(16)
|
CallAESIMC(16)
|
||||||
@@ -899,18 +902,18 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
"movups %%xmm1, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
@@ -944,12 +947,12 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
"movups %%xmm0, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
@@ -968,19 +971,19 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
"movaps %%xmm0, %%xmm2 \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
"movaps %%xmm2, %%xmm1 \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
"movups %%xmm1, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
@@ -1014,12 +1017,12 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
"movups %%xmm0, (%[iv]) \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
@@ -1039,7 +1042,7 @@ namespace crypto
|
|||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
// encrypt IV
|
// encrypt IV
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
EncryptAES256(sched_iv)
|
EncryptAES256(sched_iv)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
// double IV encryption
|
// double IV encryption
|
||||||
@@ -1049,11 +1052,11 @@ namespace crypto
|
|||||||
"1: \n"
|
"1: \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched_l)
|
EncryptAES256(sched_l)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
:
|
:
|
||||||
@@ -1090,11 +1093,11 @@ namespace crypto
|
|||||||
"1: \n"
|
"1: \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
"movaps %%xmm0, %%xmm2 \n"
|
||||||
DecryptAES256(sched_l)
|
DecryptAES256(sched_l)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
"movaps %%xmm2, %%xmm1 \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
@@ -1316,9 +1319,79 @@ namespace crypto
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Noise
|
||||||
|
|
||||||
|
void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len)
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
SHA256_Init (&ctx);
|
||||||
|
SHA256_Update (&ctx, m_H, 32);
|
||||||
|
SHA256_Update (&ctx, buf, len);
|
||||||
|
SHA256_Final (m_H, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
|
||||||
|
{
|
||||||
|
HKDF (m_CK, sharedSecret, 32, "", m_CK);
|
||||||
|
// new ck is m_CK[0:31], key is m_CK[32:63]
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck,
|
||||||
|
const uint8_t * hh, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
// pub is Bob's public static key, hh = SHA256(h)
|
||||||
|
memcpy (state.m_CK, ck, 32);
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
SHA256_Init (&ctx);
|
||||||
|
SHA256_Update (&ctx, hh, 32);
|
||||||
|
SHA256_Update (&ctx, pub, 32);
|
||||||
|
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
|
||||||
|
static const uint8_t hh[32] =
|
||||||
|
{
|
||||||
|
0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1,
|
||||||
|
0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54
|
||||||
|
}; // hh = SHA256(protocol_name || 0)
|
||||||
|
InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
static const uint8_t protocolNameHash[] =
|
||||||
|
{
|
||||||
|
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
|
||||||
|
}; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256")
|
||||||
|
static const uint8_t hh[32] =
|
||||||
|
{
|
||||||
|
0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5,
|
||||||
|
0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e
|
||||||
|
}; // SHA256 (protocolNameHash)
|
||||||
|
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
static const uint8_t protocolNameHash[32] =
|
||||||
|
{
|
||||||
|
0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba,
|
||||||
|
0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c
|
||||||
|
}; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes
|
||||||
|
static const uint8_t hh[32] =
|
||||||
|
{
|
||||||
|
0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32,
|
||||||
|
0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c
|
||||||
|
}; // SHA256 (protocolNameHash)
|
||||||
|
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||||
|
}
|
||||||
|
|
||||||
// init and terminate
|
// init and terminate
|
||||||
|
|
||||||
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
||||||
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
||||||
{
|
{
|
||||||
if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ())
|
if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ())
|
||||||
@@ -1330,10 +1403,9 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
void InitCrypto (bool precomputation, bool aesni, bool avx, bool force)
|
||||||
void InitCrypto (bool precomputation)
|
|
||||||
{
|
{
|
||||||
i2p::cpu::Detect ();
|
i2p::cpu::Detect (aesni, avx, force);
|
||||||
#if LEGACY_OPENSSL
|
#if LEGACY_OPENSSL
|
||||||
SSL_library_init ();
|
SSL_library_init ();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -88,9 +88,12 @@ namespace crypto
|
|||||||
void GenerateKeys ();
|
void GenerateKeys ();
|
||||||
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
||||||
void GetPrivateKey (uint8_t * priv) const;
|
void GetPrivateKey (uint8_t * priv) const;
|
||||||
void SetPrivateKey (const uint8_t * priv); // wihout calculating public
|
void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false);
|
||||||
void Agree (const uint8_t * pub, uint8_t * shared);
|
bool Agree (const uint8_t * pub, uint8_t * shared);
|
||||||
|
|
||||||
|
bool IsElligatorIneligible () const { return m_IsElligatorIneligible; }
|
||||||
|
void SetElligatorIneligible () { m_IsElligatorIneligible = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_PublicKey[32];
|
uint8_t m_PublicKey[32];
|
||||||
@@ -101,6 +104,7 @@ namespace crypto
|
|||||||
BN_CTX * m_Ctx;
|
BN_CTX * m_Ctx;
|
||||||
uint8_t m_PrivateKey[32];
|
uint8_t m_PrivateKey[32];
|
||||||
#endif
|
#endif
|
||||||
|
bool m_IsElligatorIneligible = false; // true if definitly ineligible
|
||||||
};
|
};
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
@@ -165,9 +169,6 @@ namespace crypto
|
|||||||
|
|
||||||
|
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
#ifdef ARM64AES
|
|
||||||
void init_aesenc(void) __attribute__((constructor));
|
|
||||||
#endif
|
|
||||||
class ECBCryptoAESNI
|
class ECBCryptoAESNI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -307,8 +308,22 @@ namespace crypto
|
|||||||
|
|
||||||
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32
|
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32
|
||||||
|
|
||||||
|
// Noise
|
||||||
|
|
||||||
|
struct NoiseSymmetricState
|
||||||
|
{
|
||||||
|
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
|
||||||
|
|
||||||
|
void MixHash (const uint8_t * buf, size_t len);
|
||||||
|
void MixKey (const uint8_t * sharedSecret);
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router)
|
||||||
|
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2)
|
||||||
|
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets)
|
||||||
|
|
||||||
// init and terminate
|
// init and terminate
|
||||||
void InitCrypto (bool precomputation);
|
void InitCrypto (bool precomputation, bool aesni, bool avx, bool force);
|
||||||
void TerminateCrypto ();
|
void TerminateCrypto ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user