mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-20 16:06:36 +02:00
Compare commits
No commits in common. "openssl" and "2.35.0" have entirely different histories.
394 changed files with 29842 additions and 36146 deletions
|
@ -1,39 +0,0 @@
|
|||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# Unix style files
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile,Makefile.*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.cmd]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = crlf
|
||||
|
||||
[*.{h,cpp}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.rc]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{md,markdown}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.patch]
|
||||
trim_trailing_whitespace = false
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1 +0,0 @@
|
|||
/build/build_mingw.cmd eol=crlf
|
61
.github/workflows/build-deb.yml
vendored
61
.github/workflows/build-deb.yml
vendored
|
@ -1,61 +0,0 @@
|
|||
name: Build Debian packages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build-deb.yml
|
||||
- contrib/**
|
||||
- daemon/**
|
||||
- debian/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Makefile
|
||||
- Makefile.linux
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.dist }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
dist: ['buster', 'bullseye', 'bookworm']
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Commit Hash
|
||||
id: commit
|
||||
uses: prompt/actions-commit-hash@v3.0.0
|
||||
|
||||
- name: Build package
|
||||
uses: jtdor/build-deb-action@v1
|
||||
with:
|
||||
docker-image: debian:${{ matrix.dist }}-slim
|
||||
buildpackage-opts: --build=binary --no-sign
|
||||
before-build-hook: debchange --controlmaint --local "+${{ steps.commit.outputs.short }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build"
|
||||
extra-build-deps: devscripts git
|
||||
|
||||
- name: Upload package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd_${{ matrix.dist }}
|
||||
path: debian/artifacts/i2pd_*.deb
|
||||
|
||||
- name: Upload debugging symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-dbgsym_${{ matrix.dist }}
|
||||
path: debian/artifacts/i2pd-dbgsym_*.deb
|
50
.github/workflows/build-freebsd.yml
vendored
50
.github/workflows/build-freebsd.yml
vendored
|
@ -1,50 +0,0 @@
|
|||
name: Build on FreeBSD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build-freebsd.yml
|
||||
- build/CMakeLists.txt
|
||||
- build/cmake_modules/**
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Makefile
|
||||
- Makefile.bsd
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: with UPnP
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Test in FreeBSD
|
||||
id: test
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
mem: 2048
|
||||
sync: rsync
|
||||
copyback: 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
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-freebsd
|
||||
path: build/i2pd
|
33
.github/workflows/build-osx.yml
vendored
33
.github/workflows/build-osx.yml
vendored
|
@ -1,45 +1,20 @@
|
|||
name: Build on OSX
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build-osx.yml
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Makefile
|
||||
- Makefile.homebrew
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
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:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install required formulae
|
||||
- uses: actions/checkout@v2
|
||||
- name: install packages
|
||||
run: |
|
||||
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
|
||||
brew update
|
||||
brew install boost miniupnpc openssl@1.1
|
||||
|
||||
- name: List installed formulae
|
||||
run: brew list
|
||||
|
||||
- name: Build application
|
||||
- name: build application
|
||||
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
name: Build on Windows with MSVC
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build-windows-msvc.yml
|
||||
- build/CMakeLists.txt
|
||||
- build/cmake_modules/**
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Win32/**
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
boost_path: ${{ github.workspace }}\boost_1_83_0
|
||||
openssl_path: ${{ github.workspace }}\openssl_3_2_1
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build and install zlib
|
||||
run: |
|
||||
powershell -Command "(Invoke-WebRequest -Uri https://raw.githubusercontent.com/r4sas/zlib.install/master/install.bat -OutFile install_zlib.bat)"
|
||||
powershell -Command "(Get-Content install_zlib.bat) | Set-Content install_zlib.bat" # fixing line endings
|
||||
set BUILD_TYPE=Debug
|
||||
./install_zlib.bat
|
||||
set BUILD_TYPE=Release
|
||||
./install_zlib.bat
|
||||
del install_zlib.bat
|
||||
|
||||
- name: Install Boost
|
||||
run: |
|
||||
powershell -Command "(Start-BitsTransfer -Source https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe/download -Destination boost_1_83_0-msvc-14.3-64.exe)"
|
||||
./boost_1_83_0-msvc-14.3-64.exe /DIR="${{env.boost_path}}" /VERYSILENT /SUPPRESSMSGBOXES /SP-
|
||||
|
||||
- name: Install OpenSSL
|
||||
run: |
|
||||
powershell -Command "(Start-BitsTransfer -Source https://slproweb.com/download/Win64OpenSSL-3_2_1.exe -Destination Win64OpenSSL-3_2_1.exe)"
|
||||
./Win64OpenSSL-3_2_1.exe /DIR="${{env.openssl_path}}" /TASKS="copytobin" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
|
||||
|
||||
- name: Make copy of the OpenSSL libraries for CMake
|
||||
run: |
|
||||
dir ${{ github.workspace }}
|
||||
dir ${{env.openssl_path}}\lib\VC
|
||||
dir ${{env.openssl_path}}\lib\VC\x64\
|
||||
dir ${{env.openssl_path}}\lib\VC\x64\MTd\
|
||||
xcopy /s /y "${{env.openssl_path}}\lib\VC\x64\MTd" "${{env.openssl_path}}\lib"
|
||||
|
||||
- name: Configure
|
||||
working-directory: build
|
||||
run: cmake -DBoost_ROOT="${{env.boost_path}}" -DOPENSSL_ROOT_DIR="${{env.openssl_path}}" -DWITH_STATIC=ON .
|
||||
|
||||
- name: Build
|
||||
working-directory: build
|
||||
run: cmake --build . --config Debug -- -m
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-msvc
|
||||
path: build/Debug/i2pd.*
|
||||
|
237
.github/workflows/build-windows.yml
vendored
237
.github/workflows/build-windows.yml
vendored
|
@ -1,25 +1,6 @@
|
|||
name: Build on Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build-windows.yml
|
||||
- build/CMakeLists.txt
|
||||
- build/cmake_modules/**
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Win32/**
|
||||
- Makefile
|
||||
- Makefile.mingw
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
on: [push, pull_request]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
|
@ -27,224 +8,24 @@ defaults:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.arch }}
|
||||
name: Building for ${{ matrix.arch }}
|
||||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
fail-fast: true
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
|
||||
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
|
||||
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
|
||||
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
|
||||
{ msystem: MINGW64, arch: x86_64 },
|
||||
{ msystem: MINGW32, arch: i686 }
|
||||
]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: base-devel git mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
|
||||
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: Install additional clang packages
|
||||
if: ${{ matrix.msystem == 'CLANG64' }}
|
||||
run: pacman --noconfirm -S mingw-w64-${{ matrix.arch }}-gcc-compat
|
||||
|
||||
- name: Build application
|
||||
- name: build application
|
||||
run: |
|
||||
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
|
||||
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-${{ matrix.arch_short }}.exe
|
||||
path: i2pd.exe
|
||||
|
||||
build-cmake:
|
||||
name: CMake ${{ matrix.arch }}
|
||||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
|
||||
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
|
||||
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
|
||||
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
|
||||
]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: base-devel git mingw-w64-${{ matrix.arch }}-cmake mingw-w64-${{ matrix.arch }}-ninja mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
|
||||
update: true
|
||||
|
||||
- name: Build application
|
||||
run: |
|
||||
cd build
|
||||
cmake -DWITH_GIT_VERSION=ON -DWITH_STATIC=ON -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
|
||||
cmake --build . -- -j3
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-cmake-${{ matrix.arch_short }}.exe
|
||||
path: build/i2pd.exe
|
||||
|
||||
build-xp:
|
||||
name: XP
|
||||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW32
|
||||
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
|
||||
cache: true
|
||||
update: true
|
||||
|
||||
- name: Clone MinGW packages repository and revert boost to 1.85.0
|
||||
run: |
|
||||
git clone https://github.com/msys2/MINGW-packages
|
||||
cd MINGW-packages
|
||||
git checkout 4cbb366edf2f268ac3146174b40ce38604646fc5 mingw-w64-boost
|
||||
cd mingw-w64-boost
|
||||
sed -i 's/boostorg.jfrog.io\/artifactory\/main/archives.boost.io/' PKGBUILD
|
||||
|
||||
# headers
|
||||
- name: Get headers package version
|
||||
id: version-headers
|
||||
run: |
|
||||
echo "version=$(pacman -Si mingw-w64-i686-headers-git | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT
|
||||
- name: Cache headers package
|
||||
uses: actions/cache@v4
|
||||
id: cache-headers
|
||||
with:
|
||||
path: MINGW-packages/mingw-w64-headers-git/*.zst
|
||||
key: winxp-headers-${{ steps.version-headers.outputs.version }}
|
||||
- name: Build WinXP-capable headers package
|
||||
if: steps.cache-headers.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd MINGW-packages/mingw-w64-headers-git
|
||||
sed -i 's/0x601/0x501/' PKGBUILD
|
||||
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck
|
||||
- name: Install headers package
|
||||
run: pacman --noconfirm -U MINGW-packages/mingw-w64-headers-git/mingw-w64-i686-*-any.pkg.tar.zst
|
||||
|
||||
# CRT
|
||||
- name: Get crt package version
|
||||
id: version-crt
|
||||
run: |
|
||||
echo "version=$(pacman -Si mingw-w64-i686-crt-git | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT
|
||||
- name: Cache crt package
|
||||
uses: actions/cache@v4
|
||||
id: cache-crt
|
||||
with:
|
||||
path: MINGW-packages/mingw-w64-crt-git/*.zst
|
||||
key: winxp-crt-${{ steps.version-crt.outputs.version }}
|
||||
- name: Build WinXP-capable crt package
|
||||
if: steps.cache-crt.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd MINGW-packages/mingw-w64-crt-git
|
||||
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck
|
||||
- name: Install crt package
|
||||
run: pacman --noconfirm -U MINGW-packages/mingw-w64-crt-git/mingw-w64-i686-*-any.pkg.tar.zst
|
||||
|
||||
# winpthreads
|
||||
- name: Get winpthreads package version
|
||||
id: version-winpthreads
|
||||
run: |
|
||||
echo "version=$(pacman -Si mingw-w64-i686-winpthreads-git | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT
|
||||
- name: Cache winpthreads package
|
||||
uses: actions/cache@v4
|
||||
id: cache-winpthreads
|
||||
with:
|
||||
path: MINGW-packages/mingw-w64-winpthreads-git/*.zst
|
||||
key: winxp-winpthreads-${{ steps.version-winpthreads.outputs.version }}
|
||||
- name: Build WinXP-capable winpthreads package
|
||||
if: steps.cache-winpthreads.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd MINGW-packages/mingw-w64-winpthreads-git
|
||||
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck
|
||||
- name: Install winpthreads package
|
||||
run: pacman --noconfirm -U MINGW-packages/mingw-w64-winpthreads-git/mingw-w64-i686-*-any.pkg.tar.zst
|
||||
|
||||
# OpenSSL
|
||||
- name: Get openssl package version
|
||||
id: version-openssl
|
||||
run: |
|
||||
echo "version=$(pacman -Si mingw-w64-i686-openssl | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT
|
||||
- name: Cache openssl package
|
||||
uses: actions/cache@v4
|
||||
id: cache-openssl
|
||||
with:
|
||||
path: MINGW-packages/mingw-w64-openssl/*.zst
|
||||
key: winxp-openssl-${{ steps.version-openssl.outputs.version }}
|
||||
- name: Build WinXP-capable openssl package
|
||||
if: steps.cache-openssl.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd MINGW-packages/mingw-w64-openssl
|
||||
gpg --recv-keys D894E2CE8B3D79F5
|
||||
gpg --recv-keys 216094DFD0CB81EF
|
||||
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck
|
||||
- name: Install openssl package
|
||||
run: pacman --noconfirm -U MINGW-packages/mingw-w64-openssl/mingw-w64-i686-*-any.pkg.tar.zst
|
||||
|
||||
# Boost
|
||||
#- name: Get boost package version
|
||||
# id: version-boost
|
||||
# run: |
|
||||
# echo "version=$(pacman -Si mingw-w64-i686-boost | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT
|
||||
- name: Cache boost package
|
||||
uses: actions/cache@v4
|
||||
id: cache-boost
|
||||
with:
|
||||
path: MINGW-packages/mingw-w64-boost/*.zst
|
||||
key: winxp-boost-1.85.0+crt-${{ steps.version-headers.outputs.version }}+ossl-${{ steps.version-openssl.outputs.version }}
|
||||
# Rebuild package if packages above has changed
|
||||
- name: Build WinXP-capable boost package
|
||||
if: steps.cache-boost.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd MINGW-packages/mingw-w64-boost
|
||||
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck
|
||||
- name: Remove boost packages
|
||||
run: pacman --noconfirm -R mingw-w64-i686-boost mingw-w64-i686-boost-libs
|
||||
- name: Install boost package
|
||||
run: pacman --noconfirm -U MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst
|
||||
|
||||
# Building i2pd
|
||||
- name: Build application
|
||||
run: |
|
||||
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
|
||||
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2pd-xp.exe
|
||||
path: i2pd.exe
|
||||
make USE_UPNP=yes DEBUG=no -j3
|
||||
|
|
60
.github/workflows/build.yml
vendored
60
.github/workflows/build.yml
vendored
|
@ -1,67 +1,37 @@
|
|||
name: Build on Ubuntu
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- .github/workflows/build.yml
|
||||
- build/CMakeLists.txt
|
||||
- build/cmake_modules/**
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Makefile
|
||||
- Makefile.linux
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-make:
|
||||
name: Make with USE_UPNP=${{ matrix.with_upnp }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
build:
|
||||
name: With USE_UPNP=${{ matrix.with_upnp }}
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
with_upnp: ['yes', 'no']
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- 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 libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||
|
||||
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||
- name: build application
|
||||
run: make USE_UPNP=${{ matrix.with_upnp }} -j3
|
||||
|
||||
build-cmake:
|
||||
name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
with_upnp: ['ON', 'OFF']
|
||||
|
||||
build_qt:
|
||||
name: With QT GUI
|
||||
runs-on: ubuntu-16.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- name: install packages
|
||||
run: |
|
||||
sudo add-apt-repository ppa:mhier/libboost-latest
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential cmake libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||
|
||||
sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||
- name: build application
|
||||
run: |
|
||||
cd build
|
||||
cmake -DWITH_UPNP=${{ matrix.with_upnp }} .
|
||||
cd qt/i2pd_qt
|
||||
qmake
|
||||
make -j3
|
140
.github/workflows/docker.yml
vendored
140
.github/workflows/docker.yml
vendored
|
@ -1,140 +0,0 @@
|
|||
name: Build containers
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- openssl
|
||||
- docker
|
||||
paths:
|
||||
- .github/workflows/docker.yml
|
||||
- contrib/docker/**
|
||||
- contrib/certificates/**
|
||||
- daemon/**
|
||||
- i18n/**
|
||||
- libi2pd/**
|
||||
- libi2pd_client/**
|
||||
- Makefile
|
||||
- Makefile.linux
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Building container for ${{ matrix.platform }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include: [
|
||||
{ platform: 'linux/amd64', archname: 'amd64' },
|
||||
{ platform: 'linux/386', archname: 'i386' },
|
||||
{ platform: 'linux/arm64', archname: 'arm64' },
|
||||
{ platform: 'linux/arm/v7', archname: 'armv7' },
|
||||
]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build container for ${{ matrix.archname }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./contrib/docker
|
||||
file: ./contrib/docker/Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: true
|
||||
tags: |
|
||||
purplei2p/i2pd:latest-${{ matrix.archname }}
|
||||
ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
|
||||
provenance: false
|
||||
|
||||
push:
|
||||
name: Pushing merged manifest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create and push latest manifest image to Docker Hub
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
inputs: purplei2p/i2pd:latest
|
||||
tags: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
|
||||
push: true
|
||||
|
||||
- name: Create and push latest manifest image to GHCR
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
inputs: ghcr.io/purplei2p/i2pd:latest
|
||||
tags: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
|
||||
push: true
|
||||
|
||||
- name: Store release version to env
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
|
||||
|
||||
- name: Create and push release manifest to Docker Hub
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||
tags: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
|
||||
push: true
|
||||
|
||||
- name: Create and push release manifest to GHCR
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||
tags: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
|
||||
push: true
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -7,13 +7,8 @@ netDb
|
|||
/i2pd
|
||||
/libi2pd.a
|
||||
/libi2pdclient.a
|
||||
/libi2pdlang.a
|
||||
/libi2pd.so
|
||||
/libi2pdclient.so
|
||||
/libi2pdlang.so
|
||||
/libi2pd.dll
|
||||
/libi2pdclient.dll
|
||||
/libi2pdlang.dll
|
||||
*.exe
|
||||
|
||||
|
||||
|
@ -260,7 +255,6 @@ docs/generated
|
|||
build/Makefile
|
||||
|
||||
# debian stuff
|
||||
debian/i2pd.1.gz
|
||||
.pc/
|
||||
|
||||
# qt
|
||||
|
|
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
54
.travis.yml
Normal file
54
.travis.yml
Normal file
|
@ -0,0 +1,54 @@
|
|||
language: cpp
|
||||
cache:
|
||||
apt: true
|
||||
os:
|
||||
- linux
|
||||
#- osx
|
||||
dist: xenial
|
||||
sudo: required
|
||||
compiler:
|
||||
- g++
|
||||
- clang++
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j 2"
|
||||
matrix:
|
||||
- BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
||||
- BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
||||
- BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
||||
- BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
||||
- os: osx
|
||||
env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- build-essential
|
||||
- cmake
|
||||
- g++
|
||||
- clang
|
||||
- libboost-chrono-dev
|
||||
- libboost-date-time-dev
|
||||
- libboost-filesystem-dev
|
||||
- libboost-program-options-dev
|
||||
- libboost-system-dev
|
||||
- libboost-thread-dev
|
||||
- libminiupnpc-dev
|
||||
- libssl-dev
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi
|
||||
script:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi
|
685
ChangeLog
685
ChangeLog
|
@ -1,691 +1,6 @@
|
|||
# for this file format description,
|
||||
# see https://github.com/olivierlacan/keep-a-changelog
|
||||
|
||||
## [2.56.0] - 2025-02-11
|
||||
### Added
|
||||
- Config params for shared local destination
|
||||
- AddressBook full addresses cache
|
||||
- Decline transit tunnel to duplicated router
|
||||
- Recreate tunnels in random order
|
||||
### Changed
|
||||
- Exclude disk operations from SSU2 and NTCP2 threads
|
||||
- Set minimal version for peer test to 0.9.62
|
||||
- Send ack requested flag after second SSU2 resend attempt
|
||||
- Shorter ECIESx25519 ack request interval for datagram and I2CP sessions
|
||||
- Don't change datagram routing path too often if unidirectional data stream
|
||||
- Reduce LeaseSet and local RouterInfo publishing confirmation intervals
|
||||
- Don't delete buffer of connected routers or if an update received
|
||||
- Smaller RouterInfo request timeout if sent directly
|
||||
- Persist local RouterInfo in separate thread
|
||||
- Don't recalculate and process ranges for every SSU2 Ack block
|
||||
- Reseeds list
|
||||
### Fixed
|
||||
- Termination deadlock if SAM session is active
|
||||
- Race condition at tunnel endpoint
|
||||
- Inbound tunnel build encryption
|
||||
|
||||
## [2.55.0] - 2024-12-30
|
||||
### Added
|
||||
- Support boost 1.87
|
||||
- "i2p.streaming.maxConcurrentStreams" tunnel's param to limit number of simultaneous streams
|
||||
- Separate thread for tunnel build requests
|
||||
- Show next peer and connectivity on "Transit tunnels" page
|
||||
- Tunnel name for local destination thread
|
||||
- Throttle incoming ECIESx25519 sessions
|
||||
- Send tunnel data to transport session directly if possible
|
||||
- Publish 'R' cap for yggdrasil-only routers, and 'U' cap for routers through proxy
|
||||
- Random tunnel rejection when medium congestion
|
||||
- Save unreachable router's endpoint to use it next time without introducers
|
||||
- Recognize symmetric NAT from peer test message 7
|
||||
- Resend HolePunch and RelayResponse messages
|
||||
### Changed
|
||||
- Removed own implementation of AESNI and always use one from openssl
|
||||
- Renamed main thread to i2pd-daemon
|
||||
- Set i2p.streaming.profile=2 for shared local destination
|
||||
- Reduced LeaseSet and RouterInfo lookup timeouts
|
||||
- Cleanup ECIES sessions and tags more often
|
||||
- Check LeaseSet expiration time
|
||||
- Handle NTCP2 session handshakes in separate thread
|
||||
- Limit last decline time by 1.5 hours in router's profile
|
||||
- Don't handle RelayRequest and RelayIntro with same nonce twice
|
||||
- Increased hole punch expiration interval
|
||||
- Send peer test message 6 with delay if message 4 was received before message 5
|
||||
- Pre-calculate more x25519 keys for transports in runtime
|
||||
- Don't request LeaseSet for incoming stream
|
||||
- Terminate incoming stream right away if no remote LeaseSet
|
||||
- Handle choked, new RTO and window size calculation and resetting algorithm for streams
|
||||
### Fixed
|
||||
- Empty string in addressbook subscriptions
|
||||
- ECIESx25519 sessions without destination
|
||||
- Missing RouterInfo buffer in NetDb
|
||||
- Invalid I2PControl certificate
|
||||
- Routers disappear from NetDb when offline
|
||||
- Peer test message 6 sent to unknown endpoint
|
||||
- Race condition with LeaseSet update
|
||||
- Excessive CPU usage by streams
|
||||
- Crash on shutdown
|
||||
|
||||
## [2.54.0] - 2024-10-06
|
||||
### Added
|
||||
- Maintain recently connected routers list to avoid false-positive peer test
|
||||
- Limited connectivity mode(through proxy)
|
||||
- "i2p.streaming.profile" tunnel's param to let tunnel select also low-bandwidth routers
|
||||
- Limit stream's inbound speed
|
||||
- Periodic ack requests in ratchets session
|
||||
- Set congestion cap G immediately if through proxy
|
||||
- Show tunnel's routers bandwidth caps in web console
|
||||
- Handle immediate ack requested flag in SSU2 data packets
|
||||
- Resend and ack peer test and relay messages
|
||||
- "senduseragent" HTTP proxy's param to pass through user's User-Agent
|
||||
### Changed
|
||||
- Exclude 'N' routers from high-bandwidth routers for client tunnels
|
||||
- C++11 support has been dropped, the minimal requirement is C++17 now, C++20 for some compilers
|
||||
- Removed dependency from boost::date_time and boost::filesystem
|
||||
- Set default i2cp.leaseSetEncType to 0,4 and to 4 for server tunnels
|
||||
- Handle i2cp.inboundlimit and i2cp.outboundlimit params in I2CP
|
||||
- Publish LeaseSet with new timestamp update if tunnel was replaced in the same second
|
||||
- Increase max number of generated tags to 800 per tagset
|
||||
- Routing path expiration by time instead num attempts
|
||||
- Save timestamp from epoch instead local time to profiles
|
||||
- Update introducer's iTag if session to introducer was replaced to new one
|
||||
- RTT, window size and number of NACKs calculation for streaming
|
||||
- Don't select same peer for tunnel too often
|
||||
- Use WinApi for data path UTF-8 conversion for Windows
|
||||
### Fixed
|
||||
- Jump link crash if address book is disabled
|
||||
- Race condition if connect through an introducer
|
||||
- "Date" header in I2PControl response
|
||||
- Incomplete response from web console
|
||||
- AEAD verification with LibreSSL
|
||||
- Number of generated tags and new keys for follow-on tagsets
|
||||
- Expired leases in LeaseSet
|
||||
- Attempts to send HolePunch to 0.0.0.0
|
||||
- Incorrect options size in quick ack streaming packet
|
||||
- Low bandwidth router appeared as first peer in high-bandwidth client tunnel
|
||||
|
||||
## [2.53.1] - 2024-07-29
|
||||
### Changed
|
||||
- I2CP performance improvement
|
||||
### Fixed
|
||||
- 100% CPU usage after I2CP/SAM/BOB session termination
|
||||
- Incorrect client limits returned through I2CP
|
||||
- Build with LibreSSL
|
||||
|
||||
## [2.53.0] - 2024-07-19
|
||||
### Added
|
||||
- New congestion control algorithm for streaming
|
||||
- Support miniupnp-2.2.8
|
||||
- Limit stream's outbound speed
|
||||
- Flood to next day closest floodfills before UTC midnight
|
||||
- Recognize duplicated routers and bypass them
|
||||
- Random SSU2 resend interval
|
||||
### Changed
|
||||
- Set minimal version to 0.9.69 for floodfills and 0.9.58 for client tunnels
|
||||
- Removed openssl 1.0.2 support
|
||||
- Move unsent I2NP messages to the new session if replaced
|
||||
- Use mt19937 RNG instead rand()
|
||||
- Update router's congestion caps before initial publishing
|
||||
- Don't try introducer with invalid address
|
||||
- Select newest introducers to publish
|
||||
- Don't request relay tag for every session if we have enough introducers
|
||||
- Update timestamp for non-reachable or hidden router
|
||||
- Reset streaming routing path if duplicated SYN received
|
||||
- Update LeaseSet if inbound tunnel failed
|
||||
- Reseeds list
|
||||
### Fixed
|
||||
- Crash when a destination gets terminated
|
||||
- Expired offline signature upon destination creation
|
||||
- Race condition between local RouterInfo buffer creation and sending it through the transports
|
||||
|
||||
## [2.52.0] - 2024-05-12
|
||||
### Added
|
||||
- Separate threads for persisting RouterInfos and profiles to disk
|
||||
- Give preference to address with direct connection
|
||||
- Exclude addresses with incorrect static or intro key
|
||||
- Avoid two firewalled routers in the row in tunnel
|
||||
- Drop unsolicited database search replies
|
||||
### Changed
|
||||
- Increase number of hashes to 16 in exploratory lookup reply
|
||||
- Reduce number of a RouterInfo lookup attempts to 5
|
||||
- Reset stream RTO if outbound tunnel was changed
|
||||
- Insert previously excluded floodfill back when successfully connected
|
||||
- Increase maximum stream resend attempts to 9
|
||||
- Reply to exploratory lookups with only confirmed routers if low tunnel build rate
|
||||
- Don't accept too old RouterInfo
|
||||
- Build client tunnels through confirmed routers only if low tunnel build rate
|
||||
- Manage netDb requests more frequently
|
||||
- Don't reply with closer than us only floodfills for lookup
|
||||
### Fixed
|
||||
- Crash on router lookup if exploratory pool is not ready
|
||||
- Race condition in excluded peers for next lookup
|
||||
- Excessive number of lookups for same destination
|
||||
- Race condition with transport peers during shutdown
|
||||
- Corrupted RouterInfo files
|
||||
|
||||
## [2.51.0] - 2024-04-06
|
||||
### Added
|
||||
- Non-blocking mode for UDP sockets
|
||||
- Set SSU2 socket buffer size based on bandwidth limit
|
||||
- Encrypted tunnel tests
|
||||
- Support for multiple UDP server tunnels on one destination
|
||||
- Publish medium congestion indication
|
||||
- Local domain sockets for SOCKS proxy upstream
|
||||
- Tunnel status "declined" in web console
|
||||
- SAM error reply "Incompatible crypto" if remote destination has incompatible crypto
|
||||
- Reduce amount of traffic by handling local message drops
|
||||
- Keep SSU2 socket open even if it fails to bind
|
||||
- Lower SSU2 resend traffic spikes
|
||||
- Expiration for messages in SSU2 send queue
|
||||
- Use EWMA for stream RTT estimation
|
||||
- Request choking delay if too many NACKs in stream
|
||||
- Allow 0ms latency for tunnel
|
||||
- Randomize tunnels selection for tests
|
||||
### Changed
|
||||
- Upstream SOCKS proxy from SOCKS4 to SOCKS5
|
||||
- Transit tunnels limit to 4 bytes. Default value to 10K
|
||||
- Reply CANT_REACH_PEER if connect to ourselves in SAM
|
||||
- Don't send already expired I2NP messages
|
||||
- Use monotonic timer to measure tunnel test latency
|
||||
- Standard NTCP2 frame doesn't exceed 16K
|
||||
- Always send request through tunnels in case of restricted routes
|
||||
- Don't delete connected routers from NetDb
|
||||
- Send lookup reply directly to reply tunnel gateway if possible
|
||||
- Reduce unreachable router ban interval to 8 minutes
|
||||
- Don't request banned routers / don't try to connect to unreachable router
|
||||
- Consider 'M' routers as low bandwidth
|
||||
- Limit minimal received SSU2 packet size to 40 bytes
|
||||
- Bob picks peer test session only if Charlie's address supports peer testing
|
||||
- Reject peer test msg 2 if peer testing is not supported
|
||||
- Don't request termination if SSU2 session was not established
|
||||
- Set maximum SSU2 queue size depending on RTT value
|
||||
- New streaming RTT calculation algorithm
|
||||
- Don't double initial RTO for streams when changing tunnels
|
||||
- Restore failed tunnel if test or data for inbound tunnel received
|
||||
- Don't fail last remaining tunnel in pool
|
||||
- Publish LeasetSet again if local destination was not ready or no tunnels
|
||||
- Make more attempts to pick high bandwidth hop for client tunnel
|
||||
- Reduced SSU2 session termination timeout to 165 seconds
|
||||
- Reseeds list
|
||||
### Fixed
|
||||
- ECIESx25519 symmetric key tagset early expiration
|
||||
- Encrypted LeaseSet lookup
|
||||
- Outbound tunnel build fails if it's endpoint is the same as reply tunnel gateway
|
||||
- I2PControl RouterManager returns invalid JSON when unknown params are passed
|
||||
- Mix of data between different UDP sessions on the same server
|
||||
- TARGET_OS_SIMULATOR check
|
||||
- Handling of "reservedrange" param
|
||||
- New NTCP2 session gets teminated upon termination of old one
|
||||
- New SSU2 session gets teminated upon termination of old one
|
||||
- Peer test to non-supporting router
|
||||
- Streaming ackThrough off 1 if number of NACKs exceeds 255
|
||||
- Race condition in ECIESx25519 tags table
|
||||
- Good tunnel becomes failed
|
||||
- Crash when packet comes to terminated stream
|
||||
- Stream hangs during LeaseSet update
|
||||
|
||||
## [2.50.2] - 2024-01-06
|
||||
###Fixed
|
||||
- Crash with OpenSSL 3.2.0
|
||||
- False positive clock skew detection
|
||||
|
||||
## [2.50.1] - 2023-12-23
|
||||
###Fixed
|
||||
- Support for new EdDSA usage behavior in OpenSSL 3.2.0
|
||||
|
||||
## [2.50.0] - 2023-12-18
|
||||
### Added
|
||||
- Support of concurrent ACCEPTs on SAM 3.1
|
||||
- Haiku OS support
|
||||
- Low bandwidth and far routers can expire before 1 hour
|
||||
### Changed
|
||||
- Don't pick too active peer for first hop
|
||||
- Try peer test again if status is Unknown
|
||||
- Send peer tests with random delay
|
||||
- Reseeds list
|
||||
### Fixed
|
||||
- XSS vulnerability in addresshelper
|
||||
- Publishing NAT64 ipv6 addresses
|
||||
- Deadlock in AsyncSend callback
|
||||
|
||||
## [2.49.0] - 2023-09-18
|
||||
### Added
|
||||
- Handle SOCK5 authorization with empty user/password
|
||||
- Drop incoming transport sessions from too old or from future routers
|
||||
- Memory pool for router profiles
|
||||
- Allow 0 hops in explicitPeers
|
||||
### Changed
|
||||
- Separate network and testing status
|
||||
- Remove AVX code
|
||||
- Improve NTCP2 transport session logging
|
||||
- Select router with ipv4 for tunnel endpoint
|
||||
- Consider all addresses non-published for U and H routers even if they have host/port
|
||||
- Don't pick completely unreachable routers for tunnels
|
||||
- Exclude SSU1 introducers from SSU2 addresses
|
||||
- Don't create paired inbound tunnel if length is different
|
||||
- Remove introducer from RouterInfo after 60 minutes
|
||||
- Reduce SSU2 keep alive interval and add keep alive interval variance
|
||||
- Don't pick too old sessions for introducer
|
||||
### Fixed
|
||||
- Version of the subnegotiation in user/password SOCKS5 response
|
||||
- Send keepalive for existing session with introducer
|
||||
- Buffer offset for EVP_EncryptFinal_ex() to include outlen
|
||||
- Termination block size processing for transport sessions
|
||||
- Crash if deleted BOB destination was shared between few BOB sessions
|
||||
- Introducers with zero tag
|
||||
- Padding for SSU2 path response
|
||||
|
||||
## [2.48.0] - 2023-06-12
|
||||
### Added
|
||||
- Allow user/password authentication method for SOCK5 proxy
|
||||
- Publish reject all congestion cap 'G' if transit is not accepted
|
||||
- 'critical' log level
|
||||
- Print b32 on webconsole destination page
|
||||
- Webconsole button to drop a remote LeaseSet
|
||||
- limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup
|
||||
- Recognize real routers if successfully connected or responded to tunnel build request
|
||||
### Changed
|
||||
- Bypass slow transport sessions for first hop selection
|
||||
- Limit AESNI inline asm to x86/x64
|
||||
- Create smaller I2NP packets if possible
|
||||
- Make router unreachable if AEAD tag verification fails in SessionCreated
|
||||
- Don't include a router to floodfills list until it's confirmed as real
|
||||
- Drop LeaseSet store request if not floodfill
|
||||
- Bypass medium congestion('D') routers for client tunnels
|
||||
- Publish encrypted RouterInfo through tunnels
|
||||
- Check if s is valid x25519 public key
|
||||
- Check if socket is open before sending data in SSU2
|
||||
### Fixed
|
||||
- Webconsole empty page if destination is not found
|
||||
- i2p.streaming.answerPings param
|
||||
- Reload tunnels
|
||||
- Address caps for unspecified ipv6 address
|
||||
- Incomplete HTTP headers in I2P tunnels
|
||||
- SSU2 socket network exceptions on Windows
|
||||
- Use of 'server' type tunnel port as inport (#1936)
|
||||
|
||||
## [2.47.0] - 2023-03-11
|
||||
### Added
|
||||
- Congestion caps
|
||||
- SAM UDP port parameter
|
||||
- Support domain addresses for yggdrasil reseeds
|
||||
### Changed
|
||||
- DHT for floodfills instead plain list
|
||||
- Process router's messages in separate thread
|
||||
- Don't publish non-reachable router
|
||||
- Send and check target destination in first streaming SYN packet
|
||||
- Reseeds list
|
||||
### Fixed
|
||||
- Memory leak in windows network state detection
|
||||
- Reseed attempts from invalid address
|
||||
|
||||
## [2.46.1] - 2023-02-20
|
||||
### Fixed
|
||||
- Race condition while getting router's peer profile
|
||||
- Creation of new router.info
|
||||
- Displaying LeaseSets in the webconsole
|
||||
- Crash when processing ACK request
|
||||
|
||||
## [2.46.0] - 2023-02-15
|
||||
### Added
|
||||
- Limit number of acked SSU2 packets to 511
|
||||
- Localization to Swedish, Portuguese, Turkish, Polish
|
||||
- Periodically send Datetime block in NTCP2 and SSU2
|
||||
- Don't select random port from reserved
|
||||
- In memory table for peer profiles
|
||||
- Store if router was unreachable in it's peer profile
|
||||
- Show IPv6 addresses in square brackets in webconsole
|
||||
- Check referer when processing Addresshelper
|
||||
### Changed
|
||||
- Algorithm for tunnel creation success rate calculation
|
||||
- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint
|
||||
- Exclude actually unreachable router from netdb for 2 hours
|
||||
- Select first hop from high bandwidth peers for client tunnels
|
||||
- Drop too long or too short LeaseSet
|
||||
- Delete router from netdb if became invalid after update
|
||||
- Terminate existing session if clock skew detected
|
||||
- Close previous UDP socket if open before reopening
|
||||
- Minimal version for floodfill is 0.9.51
|
||||
- Sort transports by endpoints in webconsole
|
||||
### Fixed
|
||||
- Deadlock during processing I2NP block with Garlic in ECIES encrypted message to router
|
||||
- Race condition with encrypted LeaseSets
|
||||
- HTTP query detection
|
||||
- Connection attempts to IPs from invalid ranges
|
||||
- Publish "0.0.0.0" in RouterInfo
|
||||
- Crash upon receiving PeerTest 7
|
||||
- Tunnels for closed SAM session socket
|
||||
- Missing NTCP2 address in RouterInfo if enabled back
|
||||
|
||||
## [2.45.1] - 2023-01-11
|
||||
### Added
|
||||
- Full Cone NAT status error
|
||||
### Changed
|
||||
- Drop duplicated I2NP messages in SSU2
|
||||
- Set rejection code 30 if tunnel with id already exists
|
||||
- Network status is always OK if peer test msg 5 received
|
||||
### Fixed
|
||||
- UPnP crash if SSU2 or NTCP2 is disabled
|
||||
- Crash on termination for some platforms
|
||||
|
||||
## [2.45.0] - 2023-01-03
|
||||
### Added
|
||||
- Test for Symmetric NAT with peer test msgs 6 and 7
|
||||
- Webconsole "No Descriptors" router error state
|
||||
- 1 and 15 seconds bandwidth calculation for i2pcontrol
|
||||
- Show non-zero send queue size for transports in web console
|
||||
- Compressible padding for I2P addresses
|
||||
- Localization to Czech
|
||||
- Don't accept incoming session from invalid/reserved addresses for NTCP2 and SSU2
|
||||
- Limit simultaneous tunnel build requests by 4 per pool
|
||||
### Changed
|
||||
- Removed SSU support
|
||||
- Reduced bandwidth calculation interval from 60 to 15 seconds
|
||||
- Increased default max transit tunnels number from 2500 to 5000 or 10000 for floodfill
|
||||
- Transit tunnels limit is doubled if floodfill mode is enabled
|
||||
- NTCP2 and SSU2 timestamps are rounded to seconds
|
||||
- Drop RouterInfos and LeaseSets with timestamp from future
|
||||
- Don't delete unreachable routers if tunnel creation success rate is too low
|
||||
- Refuse duplicated incoming pending NTCP2 session from same IP
|
||||
- Don't send SSU2 termination again if termination received block received
|
||||
- Handle standard network error for SSU2 without throwing an exception
|
||||
- Don't select overloaded peer for next tunnel
|
||||
- Remove "X-Requested-With" in HTTP Proxy for non-AJAX requests
|
||||
### Fixed
|
||||
- File descriptors leak
|
||||
- Random crash on AddressBook update
|
||||
- Crash if incorrect LeaseSet size
|
||||
- Spamming to log if no descriptors
|
||||
- ::1 address in RouterInfo
|
||||
- SSU2 network error handling (especially for Windows)
|
||||
- Race condition with pending outgoing SSU2 sessions
|
||||
- RTT self-reduction for long-live streams
|
||||
|
||||
## [2.44.0] - 2022-11-20
|
||||
### Added
|
||||
- SSL connection for server I2P tunnels
|
||||
- Localization to Italian and Spanish
|
||||
- SSU2 through SOCKS5 UDP proxy
|
||||
- Reload tunnels through web console
|
||||
- SSU2 send immediate ack request flag
|
||||
- SSU2 send and verify path challenge
|
||||
- Configurable ssu2.mtu4 and ssu2.mtu6
|
||||
### Changed
|
||||
- SSU2 is enabled and SSU is disabled by default
|
||||
- Separate network status and error
|
||||
- Random selection between NTCP2 and SSU2 priority
|
||||
- Added notbob.i2p to jump services
|
||||
- Remove DoNotTrack flag from HTTP Request header
|
||||
- Skip addresshelper page if destination was not changed
|
||||
- SSU2 allow different ports from RelayReponse and HolePunch
|
||||
- SSU2 resend PeerTest msg 1 and msg 2
|
||||
- SSU2 Send Retry instead SessionCreated if clock skew detected
|
||||
### Fixed
|
||||
- Long HTTP headers for HTTP proxy and HTTP server tunnel
|
||||
- SSU2 resends and resend limits
|
||||
- Crash at startup if addressbook is disabled
|
||||
- NTCP2 ipv6 connection through SOCKS5 proxy
|
||||
- SSU2 SessionRequest with zero token
|
||||
- SSU2 MTU less than 1280
|
||||
- SSU2 port=1
|
||||
- Incorrect addresses from network interfaces
|
||||
- Definitions for Darwin PPC; do not use pthread_setname_np
|
||||
|
||||
## [2.43.0] - 2022-08-22
|
||||
### Added
|
||||
- Complete SSU2 implementation
|
||||
- Localization to Chinese
|
||||
- Send RouterInfo update for long live sessions
|
||||
- Explicit ipv6 ranges of known tunnel brokers for MTU detection
|
||||
- Always send "Connection: close" and strip out Keep-Alive for server HTTP tunnel
|
||||
- Show ports for all transports in web console
|
||||
- Translation of webconsole site title
|
||||
- Support for Windows ProgramData path when running as service
|
||||
- Ability to turn off address book
|
||||
- Handle signals TSTP and CONT to stop and resume network
|
||||
### Changed
|
||||
- Case insensitive headers for server HTTP tunnel
|
||||
- Do not show 'Address registration' line if LeaseSet is encrypted
|
||||
- SSU2 transports have higher priority than SSU
|
||||
- Disable ElGamal precalculated table if no SSU
|
||||
- Deprecate limits.ntcpsoft, limits.ntcphard and limits.ntcpthreads config options
|
||||
- SSU2 is enabled and SSU is disabled by default for new installations
|
||||
### Fixed
|
||||
- Typo with Referer header name in HTTP proxy
|
||||
- Can't handle garlic message from an exploratory tunnel
|
||||
- Incorrect encryption key for exploratory lookup reply
|
||||
- Bound checks issues in LeaseSets code
|
||||
- MTU detection on Windows
|
||||
- Crash on stop of active server tunnel
|
||||
- Send datagram to wrong destination in SAM
|
||||
- Incorrect static key in RouterInfo if the keys were regenerated
|
||||
- Duplicated sessions in BOB
|
||||
|
||||
## [2.42.1] - 2022-05-24
|
||||
### Fixed
|
||||
- Incorrect jump link in HTTP Proxy
|
||||
|
||||
## [2.42.0] - 2022-05-22
|
||||
### Added
|
||||
- Preliminary SSU2 implementation
|
||||
- Tunnel length variance
|
||||
- Localization to French
|
||||
- Daily cleanup of obsolete peer profiles
|
||||
- Ordered jump services list in HTTP proxy
|
||||
- Win32 service
|
||||
- Show port for local non-published SSU addresses in web console
|
||||
### Changed
|
||||
- Maximum RouterInfo length increased to 3K
|
||||
- Skip unknown addresses in RouterInfo
|
||||
- Don't pick own router for peer test
|
||||
- Reseeds list
|
||||
- Internal numeric id for families
|
||||
- Use ipv6 preference only when netinet headers not used
|
||||
- Close stream if delete requested
|
||||
- Remove version from title in web console
|
||||
- Drop MESHNET build option
|
||||
- Set data path before initialization
|
||||
- Don't show registration block in web console if token is not provided
|
||||
### Fixed
|
||||
- Encrypted LeaseSet for EdDSA signature
|
||||
- Clients tunnels are not built if clock is not synced on start
|
||||
- Incorrect processing of i2cp.dontPublishLeaseSet param
|
||||
- UDP tunnels reload
|
||||
- Build for LibreSSL 3.5.2
|
||||
- Race condition in short tunnel build message
|
||||
- Race condition in local RouterInfo buffer allocation
|
||||
|
||||
## [2.41.0] - 2022-02-20
|
||||
### Added
|
||||
- Clock syncronization through SSU
|
||||
- Drop routers older than 6 months on start
|
||||
- Localization to German
|
||||
- Don't send streaming ack too frequently
|
||||
- Select compatible outbound tunnel for I2CP messages
|
||||
- Restart webconsole's acceptor in case of exception
|
||||
### Changed
|
||||
- Use builtin bitswap for endian on windows
|
||||
- Send SessionCreated before connection close if clock skew
|
||||
- Try another floodfill for publishing if no compatible tunnels found
|
||||
- Reduce memory usage for RouterInfo structures
|
||||
- Avoid duplicated addresses in RouterInfo. Check presence of netId and version
|
||||
- Use TCP/IP sockets for I2CP on Android instead local sockets
|
||||
- Return uptime as integer in I2PControl
|
||||
- Reseed servers list/cerificates
|
||||
- Webconsole's dark style colors
|
||||
### Fixed
|
||||
- Attempt to use Yggdrasil on start on Android
|
||||
- Attempts to send peer tests to itself
|
||||
- Severe packets drop in SSU
|
||||
- Crash on tunnel tests
|
||||
- Loading addressbook subscriptions from config
|
||||
- Multiple I2CP session to the same destination
|
||||
- Build on Apple Silicon
|
||||
|
||||
## [2.40.0] - 2021-11-29
|
||||
### Added
|
||||
- Keep alive parameter for client tunnels
|
||||
- Support openssl 3.0.0
|
||||
- Localization to Armenian
|
||||
- Show git commit info in version
|
||||
- Windows menu item for opening datadir
|
||||
- Reseed if too few floodfills
|
||||
- Don't publish old and replacing tunnel in LeaseSet
|
||||
- Webconsole light/dark theme depending on system settings (via CSS)
|
||||
### Changed
|
||||
- Set gzip compression to false by default
|
||||
- Build tunnel through ECIES routers only
|
||||
- Removed ElGamal support for tunnels
|
||||
- Moved webconsole resources to separate file
|
||||
- Pick tunnels with compatible transport with another tunnel of floodfill
|
||||
- Use common cleanup timer for all SSU sessions
|
||||
- Reduced memory usage
|
||||
- Reseed servers list
|
||||
- i18n code called from ClientContext
|
||||
### Fixed
|
||||
- Tunnels reload
|
||||
- Some typos in log messages
|
||||
- Cleanup relay requests table
|
||||
- Server tunnel is not published
|
||||
- Build on GNU/Hurd. Disable pthread_setname_np
|
||||
- Crash when incorrect sigtype used with blinding
|
||||
|
||||
## [2.39.0] - 2021-08-23
|
||||
### Added
|
||||
- Short tunnel build messages
|
||||
- Localization. To: Russian, Ukrainian, Turkmen, Uzbek and Afrikaans
|
||||
- Custom CSS styles for webconsole
|
||||
- Avoid slow tunnels with more than 250 ms per hop
|
||||
- Process DELAY_REQUESTED streaming option
|
||||
- "certsdir" options for certificates location
|
||||
- Keep own RouterInfo in NetBb
|
||||
- Pick ECIES routers only for tunnels on non-x64
|
||||
- NTP sync through ipv6
|
||||
- Allow ipv6 addresses for UDP server tunnels
|
||||
### Changed
|
||||
- Rekey of all routers to ECIES
|
||||
- Better distribution for random tunnel's peer selection
|
||||
- Yggdrasil reseed for v0.4, added two more
|
||||
- Encryption type 0,4 by default for server tunnels
|
||||
- Handle i2cp.dontPublishLeaseSet param for all destinations
|
||||
- reg.i2p for subscriptions
|
||||
- LeaseSet type 3 by default
|
||||
- Don't allocate payload buffer for every single ECIESx25519 message
|
||||
- Prefer public ipv6 instead rfc4941
|
||||
- Optimal padding for one-time ECIESx25519 message
|
||||
- Don't send datetime block for one-time ECIESx25519 message with one-time key
|
||||
- Router with expired introducer is still valid
|
||||
- Don't disable floodfill if still reachable by ipv6
|
||||
- Set minimal version for floodfill to 0.9.38
|
||||
- Eliminate extra lookups for sequential fragments on tunnel endpoint
|
||||
- Consistent path for explicit peers
|
||||
- Always create new tunnel from exploratory pool
|
||||
- Don't try to connect to a router not reachable from us
|
||||
- Mark additional ipv6 addresses/nets as reserved (#1679)
|
||||
### Fixed
|
||||
- Zero-hop tunnels
|
||||
- Crash upon SAM session termination
|
||||
- Build with boost < 1.55.0
|
||||
- Address type for NTCP2 acceptors
|
||||
- Check of ipv4/ipv6 address
|
||||
- Request router to send to if not in NetDb
|
||||
- Count outbound traffic for zero-hop tunnels
|
||||
- URLdecode domain for registration string generator in webconsole
|
||||
|
||||
## [2.38.0] - 2021-05-17
|
||||
### Added
|
||||
- Publish ipv6 introducers
|
||||
- Bind ipv6 or yggdrasil NTCP2 acceptor to specified address
|
||||
- Support .b32.i2p addresses and hostnames for SAM STREAM CREATE
|
||||
- ipv6 peer tests
|
||||
- Publish iexp param for introducers
|
||||
- Show ipv6 network status on the webconsole
|
||||
- EdDSA signing keys can also be blinded
|
||||
- Show router version on the webconsole
|
||||
### Changed
|
||||
- Rekey of all routers but floodfills to ECIES
|
||||
- Increased number of precalculated x25519 keys to 15
|
||||
- Don't publish LeaseSet without inbound tunnels
|
||||
- Reseed from compatible address(ipv4 or ipv6)
|
||||
- Recongnize v4 and v6 SSU addresses without host
|
||||
- Inbound tunnel gateway must be ipv4 compatible
|
||||
- Don't select next introducers from existing sessions
|
||||
- Set X bandwidth for floodfill by default
|
||||
### Fixed
|
||||
- Incoming ECIES-x25519 session doesn't send updated LeaseSet
|
||||
- Unique local address for server tunnels
|
||||
- Race condition for LeaseSet creation in I2CP
|
||||
- Relay tag for ipv6 introducer
|
||||
- Already expired introducers
|
||||
- Find connected router for first peer in tunnel
|
||||
- Failed outgoing ECIES-x25519 session's tagset stays forever
|
||||
- Yggdrasil address disappears if router becomes unreachable through ipv6
|
||||
- Ignore SSU address/introducers if port is not specified
|
||||
- Check identity and signature length for SSU SessionConfirmed
|
||||
|
||||
## [2.37.0] - 2021-03-15
|
||||
### Added
|
||||
- Address registration line for reg.i2p and stats.i2p through the web console
|
||||
- "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
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2013-2025, The PurpleI2P Project
|
||||
Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
115
Makefile
115
Makefile
|
@ -1,43 +1,22 @@
|
|||
.DEFAULT_GOAL := all
|
||||
|
||||
SYS := $(shell $(CXX) -dumpmachine)
|
||||
|
||||
ifneq (, $(findstring darwin, $(SYS)))
|
||||
SHARED_SUFFIX = dylib
|
||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
||||
SHARED_SUFFIX = dll
|
||||
else
|
||||
SHARED_SUFFIX = so
|
||||
endif
|
||||
|
||||
SHLIB := libi2pd.$(SHARED_SUFFIX)
|
||||
SHLIB := libi2pd.so
|
||||
ARLIB := libi2pd.a
|
||||
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
|
||||
ARLIB_LANG := libi2pdlang.a
|
||||
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
|
||||
SHLIB_CLIENT := libi2pdclient.so
|
||||
ARLIB_CLIENT := libi2pdclient.a
|
||||
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
|
||||
ARLIB_WRAP := libi2pdwrapper.a
|
||||
I2PD := i2pd
|
||||
|
||||
LIB_SRC_DIR := libi2pd
|
||||
LIB_CLIENT_SRC_DIR := libi2pd_client
|
||||
WRAP_SRC_DIR := libi2pd_wrapper
|
||||
LANG_SRC_DIR := i18n
|
||||
DAEMON_SRC_DIR := daemon
|
||||
|
||||
# import source files lists
|
||||
include filelist.mk
|
||||
|
||||
USE_STATIC := $(or $(USE_STATIC),no)
|
||||
USE_UPNP := $(or $(USE_UPNP),no)
|
||||
DEBUG := $(or $(DEBUG),yes)
|
||||
|
||||
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string
|
||||
USE_GIT_VERSION := $(or $(USE_GIT_VERSION),no)
|
||||
|
||||
# for MacOS only, waiting for "1", not "yes"
|
||||
HOMEBREW := $(or $(HOMEBREW),0)
|
||||
USE_AESNI := yes
|
||||
USE_STATIC := no
|
||||
USE_MESHNET := no
|
||||
USE_UPNP := no
|
||||
DEBUG := yes
|
||||
|
||||
ifeq ($(DEBUG),yes)
|
||||
CXX_DEBUG = -g
|
||||
|
@ -46,10 +25,6 @@ else
|
|||
LD_DEBUG = -s
|
||||
endif
|
||||
|
||||
ifneq (, $(DESTDIR))
|
||||
PREFIX = $(DESTDIR)
|
||||
endif
|
||||
|
||||
ifneq (, $(findstring darwin, $(SYS)))
|
||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||
ifeq ($(HOMEBREW),1)
|
||||
|
@ -57,57 +32,41 @@ ifneq (, $(findstring darwin, $(SYS)))
|
|||
else
|
||||
include Makefile.osx
|
||||
endif
|
||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
|
||||
include Makefile.mingw
|
||||
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||
include Makefile.linux
|
||||
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||
include Makefile.bsd
|
||||
else ifneq (, $(findstring haiku, $(SYS)))
|
||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||
include Makefile.haiku
|
||||
else ifneq (, $(findstring solaris, $(SYS)))
|
||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||
include Makefile.solaris
|
||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp
|
||||
include Makefile.mingw
|
||||
else # not supported
|
||||
$(error Not supported platform)
|
||||
endif
|
||||
|
||||
INCFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
|
||||
DEFINES += -DOPENSSL_SUPPRESS_DEPRECATED
|
||||
NEEDED_CXXFLAGS += -MMD -MP
|
||||
|
||||
ifeq ($(USE_GIT_VERSION),yes)
|
||||
GIT_VERSION := $(shell git describe --tags)
|
||||
DEFINES += -DGITVER=$(GIT_VERSION)
|
||||
ifeq ($(USE_MESHNET),yes)
|
||||
NEEDED_CXXFLAGS += -DMESHNET
|
||||
endif
|
||||
|
||||
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))
|
||||
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
||||
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
||||
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
|
||||
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
|
||||
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
|
||||
|
||||
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
|
||||
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD)
|
||||
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
|
||||
|
||||
mk_obj_dir:
|
||||
@mkdir -p obj
|
||||
@mkdir -p obj/Win32
|
||||
@mkdir -p obj/$(LIB_SRC_DIR)
|
||||
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
||||
@mkdir -p obj/$(LANG_SRC_DIR)
|
||||
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
||||
@mkdir -p obj/$(WRAP_SRC_DIR)
|
||||
@mkdir -p obj/Win32
|
||||
|
||||
api: $(SHLIB) $(ARLIB)
|
||||
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||
lang: $(SHLIB_LANG) $(ARLIB_LANG)
|
||||
api_client: api client lang
|
||||
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||
api: mk_obj_dir $(SHLIB) $(ARLIB)
|
||||
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
|
||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||
|
@ -116,33 +75,23 @@ wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
|||
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
||||
## custom FLAGS to work at build-time.
|
||||
|
||||
obj/%.o: %.cpp | mk_obj_dir
|
||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(DEFINES) $(INCFLAGS) -c -o $@ $<
|
||||
obj/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
|
||||
|
||||
# '-' is 'ignore if missing' on first run
|
||||
-include $(DEPS)
|
||||
|
||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
||||
$(CXX) $(DEFINES) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
||||
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||
|
||||
$(SHLIB): $(LIB_OBJS)
|
||||
ifneq ($(USE_STATIC),yes)
|
||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||
endif
|
||||
|
||||
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG)
|
||||
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||
ifneq ($(USE_STATIC),yes)
|
||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
|
||||
endif
|
||||
|
||||
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||
ifneq ($(USE_STATIC),yes)
|
||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||
endif
|
||||
|
||||
$(SHLIB_LANG): $(LANG_OBJS)
|
||||
ifneq ($(USE_STATIC),yes)
|
||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB)
|
||||
endif
|
||||
|
||||
$(ARLIB): $(LIB_OBJS)
|
||||
|
@ -151,18 +100,12 @@ $(ARLIB): $(LIB_OBJS)
|
|||
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||
$(AR) -r $@ $^
|
||||
|
||||
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||
$(AR) -r $@ $^
|
||||
|
||||
$(ARLIB_LANG): $(LANG_OBJS)
|
||||
$(AR) -r $@ $^
|
||||
|
||||
clean:
|
||||
$(RM) -r obj
|
||||
$(RM) -r docs/generated
|
||||
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||
|
||||
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
||||
strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
|
||||
strip $^
|
||||
|
||||
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
||||
|
@ -185,8 +128,6 @@ doxygen:
|
|||
.PHONY: last-dist
|
||||
.PHONY: api
|
||||
.PHONY: api_client
|
||||
.PHONY: client
|
||||
.PHONY: lang
|
||||
.PHONY: mk_obj_dir
|
||||
.PHONY: install
|
||||
.PHONY: strip
|
||||
|
|
18
Makefile.bsd
18
Makefile.bsd
|
@ -1,22 +1,12 @@
|
|||
CXX = clang++
|
||||
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
||||
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
|
||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||
LDLIBS = -lssl -lcrypto -lz -lpthread -lboost_system -lboost_program_options
|
||||
|
||||
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||
## For example, when adding 'hardening flags' to the build
|
||||
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
|
||||
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
||||
## custom FLAGS to work at build-time.
|
||||
CXXVER := $(shell $(CXX) -dumpversion|cut -c 1-2)
|
||||
ifeq (${CXXVER}, "4.") # older clang always returned 4.2.1
|
||||
$(error Compiler too old)
|
||||
else ifeq (${CXXVER}, ${filter ${CXXVER},16 17 18 19}) # clang 16 - 19
|
||||
NEEDED_CXXFLAGS = -std=c++20
|
||||
else
|
||||
NEEDED_CXXFLAGS = -std=c++17
|
||||
endif
|
||||
|
||||
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
ifeq ($(shell $(CXX) -dumpmachine | cut -c 1-4), i586)
|
||||
CXX = g++-x86
|
||||
else
|
||||
CXX = g++
|
||||
endif
|
||||
CXXFLAGS := -Wall -std=c++20
|
||||
INCFLAGS = -I/system/develop/headers
|
||||
DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE
|
||||
LDLIBS = -lbe -lbsd -lnetwork -lz -lssl -lcrypto -lboost_program_options -lpthread
|
||||
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
DEFINES += -DUSE_UPNP
|
||||
LDLIBS += -lminiupnpc
|
||||
endif
|
|
@ -1,49 +1,51 @@
|
|||
# root directory holding homebrew
|
||||
BREWROOT = /opt/homebrew
|
||||
BREWROOT = /usr/local
|
||||
BOOSTROOT = ${BREWROOT}/opt/boost
|
||||
SSLROOT = ${BREWROOT}/opt/openssl@1.1
|
||||
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
||||
CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
||||
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||
LDFLAGS = ${LD_DEBUG}
|
||||
|
||||
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wno-overloaded-virtual
|
||||
NEEDED_CXXFLAGS ?= -std=c++17
|
||||
INCFLAGS ?= -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||
LDFLAGS ?= ${LD_DEBUG}
|
||||
DEFINES += -DMAC_OSX
|
||||
ifndef TRAVIS
|
||||
CXX = clang++
|
||||
endif
|
||||
|
||||
ifeq ($(USE_STATIC),yes)
|
||||
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
|
||||
endif
|
||||
LDLIBS += -lpthread -ldl
|
||||
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread
|
||||
else
|
||||
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
||||
LDLIBS = -lz -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
LDFLAGS += -L${UPNPROOT}/lib
|
||||
LDLIBS += -lminiupnpc
|
||||
endif
|
||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
DEFINES += -DUSE_UPNP
|
||||
LDFLAGS += -ldl
|
||||
CXXFLAGS += -DUSE_UPNP
|
||||
INCFLAGS += -I${UPNPROOT}/include
|
||||
ifeq ($(USE_STATIC),yes)
|
||||
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
|
||||
else
|
||||
LDFLAGS += -L${UPNPROOT}/lib
|
||||
LDLIBS += -lminiupnpc
|
||||
endif
|
||||
endif
|
||||
|
||||
# OSX Notes
|
||||
# http://www.hutsby.net/2011/08/macs-with-aes-ni.html
|
||||
# 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
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
CXXFLAGS += -D__AES__ -maes
|
||||
endif
|
||||
|
||||
install: all
|
||||
install -d ${PREFIX}/bin
|
||||
install -m 755 ${I2PD} ${PREFIX}/bin
|
||||
install -d ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d
|
||||
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
|
||||
install -m 755 ${I2PD} ${PREFIX}/bin/
|
||||
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
||||
install -d ${PREFIX}/share ${PREFIX}/share/doc ${PREFIX}/share/doc/i2pd
|
||||
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
||||
install -d ${PREFIX}/share/i2pd
|
||||
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
|
||||
install -d ${PREFIX}/share/man ${PREFIX}/share/man/man1
|
||||
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
||||
install -d ${PREFIX}/var ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
|
||||
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/certificates
|
||||
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
|
||||
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
||||
@gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
||||
@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/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
||||
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
||||
|
|
|
@ -9,17 +9,20 @@ LDFLAGS ?= ${LD_DEBUG}
|
|||
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
||||
## custom FDLAGS to work at build-time.
|
||||
|
||||
# detect proper flag for c++17 support by compilers
|
||||
# detect proper flag for c++11 support by compilers
|
||||
CXXVER := $(shell $(CXX) -dumpversion)
|
||||
ifeq ($(shell expr match $(CXX) 'clang'),5)
|
||||
NEEDED_CXXFLAGS += -std=c++11
|
||||
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
|
||||
NEEDED_CXXFLAGS += -std=c++11
|
||||
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
|
||||
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
|
||||
NEEDED_CXXFLAGS += -std=c++11
|
||||
LDLIBS = -latomic
|
||||
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
|
||||
NEEDED_CXXFLAGS += -std=c++17
|
||||
else ifeq ($(shell expr match ${CXXVER} "[8-9]"),1) # gcc 8 - 9
|
||||
NEEDED_CXXFLAGS += -std=c++17
|
||||
LDLIBS = -lboost_system -lstdc++fs
|
||||
else ifeq ($(shell expr match ${CXXVER} "1[0-2]"),2) # gcc 10 - 12
|
||||
NEEDED_CXXFLAGS += -std=c++17
|
||||
else ifeq ($(shell expr match ${CXXVER} "1[3-9]"),2) # gcc 13+
|
||||
NEEDED_CXXFLAGS += -std=c++20
|
||||
LDLIBS = -latomic
|
||||
else # not supported
|
||||
$(error Compiler too old)
|
||||
endif
|
||||
|
@ -31,6 +34,9 @@ ifeq ($(USE_STATIC),yes)
|
|||
# Using 'getaddrinfo' in statically linked applications requires at runtime
|
||||
# the shared libraries from the glibc version used for linking
|
||||
LIBDIR := /usr/lib/$(SYS)
|
||||
LDLIBS += $(LIBDIR)/libboost_system.a
|
||||
LDLIBS += $(LIBDIR)/libboost_date_time.a
|
||||
LDLIBS += $(LIBDIR)/libboost_filesystem.a
|
||||
LDLIBS += $(LIBDIR)/libboost_program_options.a
|
||||
LDLIBS += $(LIBDIR)/libssl.a
|
||||
LDLIBS += $(LIBDIR)/libcrypto.a
|
||||
|
@ -40,7 +46,7 @@ ifeq ($(USE_UPNP),yes)
|
|||
endif
|
||||
LDLIBS += -lpthread -ldl
|
||||
else
|
||||
LDLIBS += -lssl -lcrypto -lz -lboost_program_options -lpthread -latomic
|
||||
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
LDLIBS += -lminiupnpc
|
||||
endif
|
||||
|
@ -48,23 +54,11 @@ endif
|
|||
|
||||
# UPNP Support (miniupnpc 1.5 and higher)
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
DEFINES += -DUSE_UPNP
|
||||
NEEDED_CXXFLAGS += -DUSE_UPNP
|
||||
endif
|
||||
|
||||
install: all
|
||||
install -d ${PREFIX}/bin
|
||||
install -m 755 ${I2PD} ${PREFIX}/bin
|
||||
install -d ${PREFIX}/etc ${PREFIX}/etc/i2pd ${PREFIX}/etc/i2pd/tunnels.conf.d
|
||||
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
||||
install -d ${PREFIX}/share ${PREFIX}/share/doc ${PREFIX}/share/doc/i2pd
|
||||
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
||||
install -d ${PREFIX}/share/i2pd
|
||||
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
|
||||
install -d ${PREFIX}/share/man ${PREFIX}/share/man/man1
|
||||
@gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
||||
install -d ${PREFIX}/var ${PREFIX}/var/lib ${PREFIX}/var/lib/i2pd
|
||||
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/certificates
|
||||
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf.d ${PREFIX}/var/lib/i2pd/tunnels.d
|
||||
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
|
||||
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
||||
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
ifeq (, $(findstring arm, $(SYS))$(findstring aarch64, $(SYS))) # no arm and aarch64 in dumpmachine
|
||||
NEEDED_CXXFLAGS += -D__AES__ -maes
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -3,48 +3,63 @@ USE_WIN32_APP := yes
|
|||
|
||||
WINDRES = windres
|
||||
|
||||
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
|
||||
INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32
|
||||
LDFLAGS := ${LD_DEBUG} -static -fPIC -msse
|
||||
CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse
|
||||
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
|
||||
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc
|
||||
|
||||
NEEDED_CXXFLAGS += -std=c++20
|
||||
DEFINES += -DWIN32_LEAN_AND_MEAN
|
||||
# detect proper flag for c++11 support by compilers
|
||||
CXXVER := $(shell $(CXX) -dumpversion)
|
||||
ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6
|
||||
NEEDED_CXXFLAGS += -std=c++11
|
||||
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
|
||||
NEEDED_CXXFLAGS += -std=c++17
|
||||
else # not supported
|
||||
$(error Compiler too old)
|
||||
endif
|
||||
|
||||
# Boost libraries suffix
|
||||
BOOST_SUFFIX = -mt
|
||||
|
||||
# UPNP Support
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
||||
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
||||
LDLIBS = -lminiupnpc
|
||||
endif
|
||||
|
||||
ifeq ($(USE_WINXP_FLAGS), yes)
|
||||
DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
|
||||
LDLIBS += \
|
||||
$(MINGW_PREFIX)/lib/libboost_filesystem-mt.a \
|
||||
$(MINGW_PREFIX)/lib/libboost_program_options-mt.a \
|
||||
$(MINGW_PREFIX)/lib/libssl.a \
|
||||
$(MINGW_PREFIX)/lib/libcrypto.a \
|
||||
$(MINGW_PREFIX)/lib/libz.a \
|
||||
-lboost_system$(BOOST_SUFFIX) \
|
||||
-lboost_date_time$(BOOST_SUFFIX) \
|
||||
-lboost_filesystem$(BOOST_SUFFIX) \
|
||||
-lboost_program_options$(BOOST_SUFFIX) \
|
||||
-lssl \
|
||||
-lcrypto \
|
||||
-lz \
|
||||
-lwsock32 \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
-lcrypt32 \
|
||||
-lgdi32 \
|
||||
-liphlpapi \
|
||||
-lole32 \
|
||||
-luuid \
|
||||
-lpthread
|
||||
|
||||
ifeq ($(USE_WIN32_APP), yes)
|
||||
DEFINES += -DWIN32_APP
|
||||
NEEDED_CXXFLAGS += -DWIN32_APP
|
||||
LDFLAGS += -mwindows
|
||||
DAEMON_RC += Win32/Resource.rc
|
||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||
endif
|
||||
|
||||
ifeq ($(USE_WINXP_FLAGS), yes)
|
||||
NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
NEEDED_CXXFLAGS += -D__AES__ -maes
|
||||
endif
|
||||
|
||||
ifeq ($(USE_ASLR),yes)
|
||||
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols
|
||||
endif
|
||||
|
||||
obj/%.o : %.rc | mk_obj_dir
|
||||
$(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@
|
||||
obj/%.o : %.rc
|
||||
$(WINDRES) -i $< -o $@
|
||||
|
|
16
Makefile.osx
16
Makefile.osx
|
@ -1,20 +1,20 @@
|
|||
CXX = clang++
|
||||
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++17
|
||||
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
|
||||
INCFLAGS = -I/usr/local/include
|
||||
DEFINES := -DMAC_OSX
|
||||
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||
LDFLAGS += -Wl,-dead_strip
|
||||
LDFLAGS += -Wl,-dead_strip_dylibs
|
||||
LDFLAGS += -Wl,-bind_at_load
|
||||
|
||||
ifeq ($(USE_STATIC),yes)
|
||||
LDLIBS = -lz /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
||||
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
||||
else
|
||||
LDLIBS = -lz -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
LDFLAGS += -ldl
|
||||
DEFINES += -DUSE_UPNP
|
||||
CXXFLAGS += -DUSE_UPNP
|
||||
ifeq ($(USE_STATIC),yes)
|
||||
LDLIBS += /usr/local/lib/libminiupnpc.a
|
||||
else
|
||||
|
@ -22,8 +22,8 @@ ifeq ($(USE_UPNP),yes)
|
|||
endif
|
||||
endif
|
||||
|
||||
OSARCH = $(shell uname -p)
|
||||
|
||||
ifneq ($(OSARCH),powerpc)
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
CXXFLAGS += -D__AES__ -maes
|
||||
else
|
||||
CXXFLAGS += -msse
|
||||
endif
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
CXX = g++
|
||||
INCFLAGS = -I/usr/openssl/3/include
|
||||
CXXFLAGS := -Wall -std=c++20
|
||||
LDLIBS = -L/usr/openssl/3/lib/64 -lssl -lcrypto -lboost_program_options -lz -lpthread -lsocket
|
||||
|
||||
ifeq ($(USE_UPNP),yes)
|
||||
DEFINES += -DUSE_UPNP
|
||||
LDLIBS += -lminiupnpc
|
||||
endif
|
56
README.md
56
README.md
|
@ -3,9 +3,6 @@
|
|||
[](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE)
|
||||
[](https://repology.org/project/i2pd/versions)
|
||||
[](https://hub.docker.com/r/purplei2p/i2pd)
|
||||
[](https://crowdin.com/project/i2pd)
|
||||
|
||||
*note: i2pd for Android can be found in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository and with Qt GUI in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository*
|
||||
|
||||
i2pd
|
||||
====
|
||||
|
@ -56,8 +53,6 @@ Building
|
|||
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
||||
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:
|
||||
|
||||
|
@ -69,15 +64,15 @@ Build instructions:
|
|||
|
||||
**Supported systems:**
|
||||
|
||||
* GNU/Linux (Debian, Ubuntu, etc) - [](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
|
||||
* CentOS, Fedora, Mageia - [](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
|
||||
* Alpine, ArchLinux, openSUSE, Gentoo, etc.
|
||||
* Windows - [](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
|
||||
* Mac OS - [](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
|
||||
* Docker image - [](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
|
||||
* Snap - [](https://snapcraft.io/i2pd) [](https://snapcraft.io/i2pd)
|
||||
* FreeBSD - [](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
|
||||
* Android - [](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
|
||||
* GNU/Linux - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||
* CentOS / Fedora / Mageia - [](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
|
||||
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
|
||||
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
||||
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||
* Docker image - [](https://hub.docker.com/r/purplei2p/i2pd/builds/)
|
||||
* Snap - [](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap)
|
||||
* FreeBSD
|
||||
* Android
|
||||
* iOS
|
||||
|
||||
Using i2pd
|
||||
|
@ -86,36 +81,15 @@ Using i2pd
|
|||
See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and
|
||||
[example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf).
|
||||
|
||||
Localization
|
||||
------------
|
||||
|
||||
You can help us with translation i2pd to your language using Crowdin platform!
|
||||
Translation project can be found [here](https://crowdin.com/project/i2pd).
|
||||
|
||||
New languages can be requested on project's [discussion page](https://crowdin.com/project/i2pd/discussions).
|
||||
|
||||
Current status: [](https://crowdin.com/project/i2pd)
|
||||
|
||||
Donations
|
||||
---------
|
||||
|
||||
**E-Mail**: ```i2porignal at yandex.com```
|
||||
|
||||
**BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f```
|
||||
|
||||
**LTC**: ```LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59```
|
||||
|
||||
**ETH**: ```0x9e5bac70d20d1079ceaa111127f4fb3bccce379d```
|
||||
|
||||
**GST**: ```GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG```
|
||||
|
||||
**DASH**: ```Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF```
|
||||
|
||||
**ZEC**: ```t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ```
|
||||
|
||||
**ANC**: ```AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z```
|
||||
|
||||
**XMR**: ```497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH```
|
||||
BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
|
||||
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
|
||||
ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
|
||||
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
|
||||
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
|
||||
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
|
||||
|
||||
License
|
||||
-------
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
|
@ -29,30 +29,51 @@ namespace util
|
|||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
//setlocale(LC_ALL, "Russian");
|
||||
setlocale(LC_ALL, "Russian");
|
||||
setlocale(LC_TIME, "C");
|
||||
|
||||
i2p::log::SetThrowFunction ([](const std::string& s)
|
||||
{
|
||||
MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (!Daemon_Singleton::init(argc, argv))
|
||||
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(eLogCritical, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -61,10 +82,13 @@ namespace util
|
|||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
//setlocale(LC_ALL, "Russian");
|
||||
setlocale(LC_ALL, "Russian");
|
||||
setlocale(LC_TIME, "C");
|
||||
#ifdef WIN32_APP
|
||||
if (!i2p::win32::StartWin32App (isDaemon)) return false;
|
||||
if (!i2p::win32::StartWin32App ()) return false;
|
||||
|
||||
// override log
|
||||
i2p::config::SetOption("log", std::string ("file"));
|
||||
#endif
|
||||
bool ret = Daemon_Singleton::start();
|
||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#error this file is not editable by Microsoft Visual C++
|
||||
#endif //APSTUDIO_INVOKED
|
||||
|
||||
#include "version.h"
|
||||
#include "../libi2pd/version.h"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
|
||||
|
@ -25,7 +25,7 @@ BEGIN
|
|||
VALUE "FileDescription", "C++ I2P daemon"
|
||||
VALUE "FileVersion", I2PD_VERSION
|
||||
VALUE "InternalName", CODENAME
|
||||
VALUE "LegalCopyright", "Copyright (C) 2013-2023, The PurpleI2P Project"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project"
|
||||
VALUE "OriginalFilename", "i2pd"
|
||||
VALUE "ProductName", "Purple I2P"
|
||||
VALUE "ProductVersion", I2P_VERSION
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
|
@ -31,7 +31,6 @@
|
|||
#define ID_RELOAD 2006
|
||||
#define ID_ACCEPT_TRANSIT 2007
|
||||
#define ID_DECLINE_TRANSIT 2008
|
||||
#define ID_DATADIR 2009
|
||||
|
||||
#define ID_TRAY_ICON 2050
|
||||
#define WM_TRAYICON (WM_USER + 1)
|
||||
|
@ -45,14 +44,12 @@ namespace i2p
|
|||
namespace win32
|
||||
{
|
||||
DWORD g_GracefulShutdownEndtime = 0;
|
||||
bool g_isWinService;
|
||||
|
||||
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
|
||||
{
|
||||
HMENU hPopup = CreatePopupMenu();
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DATADIR, "Open &datadir");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "&Show app");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||
if(!i2p::context.AcceptsTunnels())
|
||||
|
@ -83,19 +80,18 @@ namespace win32
|
|||
DestroyMenu(hPopup);
|
||||
}
|
||||
|
||||
static void AddTrayIcon (HWND hWnd, bool notify = false)
|
||||
static void AddTrayIcon (HWND hWnd)
|
||||
{
|
||||
NOTIFYICONDATA nid;
|
||||
memset(&nid, 0, sizeof(nid));
|
||||
nid.cbSize = sizeof(nid);
|
||||
nid.hWnd = hWnd;
|
||||
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.uCallbackMessage = WM_TRAYICON;
|
||||
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
|
||||
strcpy (nid.szTip, "i2pd");
|
||||
if (notify) strcpy (nid.szInfo, "i2pd is starting");
|
||||
strcpy (nid.szInfo, "i2pd is starting");
|
||||
Shell_NotifyIcon(NIM_ADD, &nid );
|
||||
}
|
||||
|
||||
|
@ -134,7 +130,7 @@ namespace win32
|
|||
transfer >>= 10;
|
||||
auto mbytes = transfer & 0x03ff;
|
||||
transfer >>= 10;
|
||||
auto gbytes = transfer;
|
||||
auto gbytes = transfer & 0x03ff;
|
||||
|
||||
if (gbytes)
|
||||
s << gbytes << " GB, ";
|
||||
|
@ -145,52 +141,25 @@ namespace win32
|
|||
s << bytes << " Bytes\n";
|
||||
}
|
||||
|
||||
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing, RouterError error)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case eRouterStatusOK: s << "OK"; break;
|
||||
case eRouterStatusFirewalled: s << "FW"; break;
|
||||
case eRouterStatusUnknown: s << "Unk"; break;
|
||||
case eRouterStatusProxy: s << "Proxy"; break;
|
||||
case eRouterStatusMesh: s << "Mesh"; break;
|
||||
default: s << "Unk";
|
||||
};
|
||||
if (testing)
|
||||
s << " (Test)";
|
||||
if (error != eRouterErrorNone)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case eRouterErrorClockSkew:
|
||||
s << " - " << tr("Clock skew");
|
||||
break;
|
||||
case eRouterErrorOffline:
|
||||
s << " - " << tr("Offline");
|
||||
break;
|
||||
case eRouterErrorSymmetricNAT:
|
||||
s << " - " << tr("Symmetric NAT");
|
||||
break;
|
||||
case eRouterErrorFullConeNAT:
|
||||
s << " - " << tr("Full cone NAT");
|
||||
break;
|
||||
case eRouterErrorNoDescriptors:
|
||||
s << " - " << tr("No Descriptors");
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintMainWindowText (std::stringstream& s)
|
||||
{
|
||||
s << "\n";
|
||||
s << "Status: ";
|
||||
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting(), i2p::context.GetError ());
|
||||
if (i2p::context.SupportsV6 ())
|
||||
switch (i2p::context.GetStatus())
|
||||
{
|
||||
s << " / ";
|
||||
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6(), i2p::context.GetErrorV6 ());
|
||||
case eRouterStatusOK: s << "OK"; break;
|
||||
case eRouterStatusTesting: s << "Testing"; break;
|
||||
case eRouterStatusFirewalled: s << "Firewalled"; break;
|
||||
case eRouterStatusError:
|
||||
{
|
||||
switch (i2p::context.GetError())
|
||||
{
|
||||
case eRouterErrorClockSkew: s << "Clock skew"; break;
|
||||
default: s << "Error";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: s << "Unknown";
|
||||
}
|
||||
s << "; ";
|
||||
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
|
||||
|
@ -226,7 +195,7 @@ namespace win32
|
|||
case WM_CREATE:
|
||||
{
|
||||
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||
AddTrayIcon (hWnd, true);
|
||||
AddTrayIcon (hWnd);
|
||||
break;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
|
@ -311,12 +280,6 @@ namespace win32
|
|||
SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL);
|
||||
return 0;
|
||||
}
|
||||
case ID_DATADIR:
|
||||
{
|
||||
std::string datadir(i2p::fs::GetDataDir());
|
||||
ShellExecute(NULL, "explore", datadir.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -355,7 +318,6 @@ namespace win32
|
|||
}
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case WM_TRAYICON:
|
||||
{
|
||||
|
@ -418,16 +380,15 @@ namespace win32
|
|||
default:
|
||||
{
|
||||
if (uMsg == s_uTaskbarRestart)
|
||||
AddTrayIcon (hWnd, false);
|
||||
AddTrayIcon (hWnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
bool StartWin32App (bool isWinService)
|
||||
bool StartWin32App ()
|
||||
{
|
||||
g_isWinService = isWinService;
|
||||
if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")))
|
||||
{
|
||||
MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK);
|
||||
|
@ -456,8 +417,6 @@ namespace win32
|
|||
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
|
||||
return false;
|
||||
}
|
||||
// COM requires message loop to work, which is not implemented in service mode
|
||||
if (!g_isWinService)
|
||||
SubscribeToEvents();
|
||||
return true;
|
||||
}
|
||||
|
@ -478,8 +437,7 @@ namespace win32
|
|||
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
|
||||
if (hWnd)
|
||||
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0);
|
||||
else if(!g_isWinService)
|
||||
UnSubscribeFromEvents();
|
||||
// UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app
|
||||
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace win32
|
|||
{
|
||||
extern DWORD g_GracefulShutdownEndtime;
|
||||
|
||||
bool StartWin32App (bool isWinService);
|
||||
bool StartWin32App ();
|
||||
void StopWin32App ();
|
||||
int RunWin32App ();
|
||||
bool GracefulShutdown ();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
|
@ -15,7 +15,6 @@ IUnknown *pUnknown = nullptr;
|
|||
INetworkListManager *pNetworkListManager = nullptr;
|
||||
IConnectionPointContainer *pCPContainer = nullptr;
|
||||
IConnectionPoint *pConnectPoint = nullptr;
|
||||
CNetworkListManagerEvent *pNetEvent = nullptr;
|
||||
DWORD Cookie = 0;
|
||||
|
||||
void SubscribeToEvents()
|
||||
|
@ -30,14 +29,10 @@ void SubscribeToEvents()
|
|||
if (SUCCEEDED(Result))
|
||||
{
|
||||
VARIANT_BOOL IsConnect = VARIANT_FALSE;
|
||||
#if defined(_MSC_VER)
|
||||
Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
|
||||
#else
|
||||
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
|
||||
#endif
|
||||
if (SUCCEEDED(Result)) {
|
||||
i2p::transport::transports.SetOnline (true);
|
||||
LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
|
||||
LogPrint(eLogInfo, "NetState: current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
|
||||
}
|
||||
|
||||
Result = pNetworkListManager->QueryInterface(IID_IConnectionPointContainer, (void **)&pCPContainer);
|
||||
|
@ -46,8 +41,8 @@ void SubscribeToEvents()
|
|||
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
|
||||
if(SUCCEEDED(Result))
|
||||
{
|
||||
pNetEvent = new CNetworkListManagerEvent;
|
||||
Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie);
|
||||
CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
|
||||
Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
|
||||
if (SUCCEEDED(Result))
|
||||
LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages");
|
||||
else
|
||||
|
@ -64,7 +59,6 @@ void SubscribeToEvents()
|
|||
|
||||
void UnSubscribeFromEvents()
|
||||
{
|
||||
LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
|
||||
try
|
||||
{
|
||||
if (pConnectPoint) {
|
||||
|
@ -72,31 +66,20 @@ void UnSubscribeFromEvents()
|
|||
pConnectPoint->Release();
|
||||
}
|
||||
|
||||
if (pNetEvent)
|
||||
{
|
||||
pNetEvent->Release();
|
||||
}
|
||||
|
||||
if (pCPContainer)
|
||||
{
|
||||
pCPContainer->Release();
|
||||
}
|
||||
|
||||
if (pNetworkListManager)
|
||||
{
|
||||
pNetworkListManager->Release();
|
||||
}
|
||||
|
||||
if (pUnknown)
|
||||
{
|
||||
pUnknown->Release();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "NetState: Received exception: ", ex.what ());
|
||||
LogPrint (eLogError, "NetState: received exception: ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
#include "Log.h"
|
||||
#include "Transports.h"
|
||||
|
||||
class CNetworkListManagerEvent final : public INetworkListManagerEvents
|
||||
class CNetworkListManagerEvent : public INetworkListManagerEvents
|
||||
{
|
||||
public:
|
||||
CNetworkListManagerEvent() : m_ref(1) { }
|
||||
|
@ -23,15 +23,17 @@ public:
|
|||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
HRESULT Result = S_OK;
|
||||
if (IsEqualIID(riid, IID_IUnknown)) {
|
||||
*ppvObject = (IUnknown *)this;
|
||||
} else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) {
|
||||
*ppvObject = (INetworkListManagerEvents *)this;
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
Result = E_NOINTERFACE;
|
||||
}
|
||||
AddRef();
|
||||
return S_OK;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||
* 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"
|
||||
|
@ -21,7 +26,7 @@ BOOL I2PService::isService()
|
|||
HWINSTA hWinStation = GetProcessWindowStation();
|
||||
if (hWinStation != NULL)
|
||||
{
|
||||
USEROBJECTFLAGS uof = { FALSE, FALSE, 0 };
|
||||
USEROBJECTFLAGS uof = { 0 };
|
||||
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
|
||||
{
|
||||
bIsService = TRUE;
|
||||
|
@ -119,20 +124,24 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
|
|||
}
|
||||
catch (DWORD dwError)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Start error: ", dwError);
|
||||
LogPrint(eLogError, "Win32Service Start", dwError);
|
||||
SetServiceStatus(SERVICE_STOPPED, dwError);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
|
||||
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, ")");
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -157,12 +166,12 @@ void I2PService::Stop()
|
|||
}
|
||||
catch (DWORD dwError)
|
||||
{
|
||||
LogPrint(eLogInfo, "Win32Service: Stop error: ", dwError);
|
||||
LogPrint(eLogInfo, "Win32Service Stop", dwError);
|
||||
SetServiceStatus(dwOriginalState);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
|
||||
LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE);
|
||||
SetServiceStatus(dwOriginalState);
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +179,7 @@ void I2PService::Stop()
|
|||
void I2PService::OnStop()
|
||||
{
|
||||
// Log a service stop message to the Application log.
|
||||
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
|
||||
LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE);
|
||||
Daemon.stop();
|
||||
m_fStopping = TRUE;
|
||||
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||
|
@ -191,12 +200,12 @@ void I2PService::Pause()
|
|||
}
|
||||
catch (DWORD dwError)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError);
|
||||
LogPrint(eLogError, "Win32Service Pause", dwError);
|
||||
SetServiceStatus(SERVICE_RUNNING);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
|
||||
LogPrint(eLogError, "Win32Service failed to pause.", EVENTLOG_ERROR_TYPE);
|
||||
SetServiceStatus(SERVICE_RUNNING);
|
||||
}
|
||||
}
|
||||
|
@ -215,12 +224,12 @@ void I2PService::Continue()
|
|||
}
|
||||
catch (DWORD dwError)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError);
|
||||
LogPrint(eLogError, "Win32Service Continue", dwError);
|
||||
SetServiceStatus(SERVICE_PAUSED);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
|
||||
LogPrint(eLogError, "Win32Service failed to resume.", EVENTLOG_ERROR_TYPE);
|
||||
SetServiceStatus(SERVICE_PAUSED);
|
||||
}
|
||||
}
|
||||
|
@ -238,11 +247,11 @@ void I2PService::Shutdown()
|
|||
}
|
||||
catch (DWORD dwError)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError);
|
||||
LogPrint(eLogError, "Win32Service Shutdown", dwError);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
|
||||
LogPrint(eLogError, "Win32Service failed to shut down.", EVENTLOG_ERROR_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,3 +290,125 @@ void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE 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,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
|
@ -12,8 +12,26 @@
|
|||
#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:
|
||||
|
@ -60,4 +78,15 @@ class I2PService
|
|||
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__
|
||||
|
|
BIN
Win32/mask.bmp
Normal file
BIN
Win32/mask.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
18
android/.gitignore
vendored
Normal file
18
android/.gitignore
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
gen
|
||||
tests
|
||||
bin
|
||||
libs
|
||||
log*
|
||||
obj
|
||||
.cxx
|
||||
.gradle
|
||||
.idea
|
||||
.externalNativeBuild
|
||||
ant.properties
|
||||
local.properties
|
||||
build.sh
|
||||
android.iml
|
||||
build
|
||||
*.iml
|
||||
*.local
|
||||
*.jks
|
56
android/AndroidManifest.xml
Executable file
56
android/AndroidManifest.xml
Executable file
|
@ -0,0 +1,56 @@
|
|||
<?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:requestLegacyExternalStorage="true"
|
||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity android:name=".WebConsoleActivity"></activity>
|
||||
|
||||
<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>
|
19
android/README.md
Normal file
19
android/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# 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
|
693
android/assets/addressbook/addresses.csv
Normal file
693
android/assets/addressbook/addresses.csv
Normal file
|
@ -0,0 +1,693 @@
|
|||
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
android/assets/certificates
Symbolic link
1
android/assets/certificates
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../contrib/certificates
|
92
android/assets/i2pd.conf
Normal file
92
android/assets/i2pd.conf
Normal file
|
@ -0,0 +1,92 @@
|
|||
## 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
|
3
android/assets/subscriptions.txt
Normal file
3
android/assets/subscriptions.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
http://inr.i2p/export/alive-hosts.txt
|
||||
http://stats.i2p/cgi-bin/newhosts.txt
|
||||
http://i2p-projekt.i2p/hosts.txt
|
33
android/assets/tunnels.conf
Normal file
33
android/assets/tunnels.conf
Normal file
|
@ -0,0 +1,33 @@
|
|||
#[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
android/assets/tunnels.d
Symbolic link
1
android/assets/tunnels.d
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../contrib/tunnels.d
|
104
android/build.gradle
Normal file
104
android/build.gradle
Normal file
|
@ -0,0 +1,104 @@
|
|||
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 2350
|
||||
versionName "2.35.0"
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
96
android/build.xml
Normal file
96
android/build.xml
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?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>
|
3
android/gradle.properties
Normal file
3
android/gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.parallel=true
|
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#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
Executable file
172
android/gradlew
vendored
Executable file
|
@ -0,0 +1,172 @@
|
|||
#!/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
Normal file
84
android/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
@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
|
73
android/jni/Android.mk
Executable file
73
android/jni/Android.mk
Executable file
|
@ -0,0 +1,73 @@
|
|||
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.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-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.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-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)
|
36
android/jni/Application.mk
Executable file
36
android/jni/Application.mk
Executable file
|
@ -0,0 +1,36 @@
|
|||
#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
|
222
android/jni/DaemonAndroid.cpp
Normal file
222
android/jni/DaemonAndroid.cpp
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
97
android/jni/DaemonAndroid.h
Normal file
97
android/jni/DaemonAndroid.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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
|
114
android/jni/i2pd_android.cpp
Executable file
114
android/jni/i2pd_android.cpp
Executable file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
53
android/jni/org_purplei2p_i2pd_I2PD_JNI.h
Normal file
53
android/jni/org_purplei2p_i2pd_I2PD_JNI.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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
|
20
android/proguard-project.txt
Normal file
20
android/proguard-project.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
# 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 *;
|
||||
#}
|
14
android/project.properties
Normal file
14
android/project.properties
Normal file
|
@ -0,0 +1,14 @@
|
|||
# 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
|
BIN
android/res/drawable/icon.png
Normal file
BIN
android/res/drawable/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
android/res/drawable/itoopie_notification_icon.png
Normal file
BIN
android/res/drawable/itoopie_notification_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
26
android/res/layout/activity_perms_asker.xml
Normal file
26
android/res/layout/activity_perms_asker.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<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>
|
25
android/res/layout/activity_perms_explanation.xml
Normal file
25
android/res/layout/activity_perms_explanation.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<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>
|
14
android/res/layout/activity_web_console.xml
Normal file
14
android/res/layout/activity_web_console.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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=".WebConsoleActivity">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
</LinearLayout>
|
||||
|
31
android/res/menu/options_main.xml
Normal file
31
android/res/menu/options_main.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<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>
|
40
android/res/values-ru/strings.xml
Executable file
40
android/res/values-ru/strings.xml
Executable file
|
@ -0,0 +1,40 @@
|
|||
<?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>
|
41
android/res/values/strings.xml
Executable file
41
android/res/values/strings.xml
Executable file
|
@ -0,0 +1,41 @@
|
|||
<?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>
|
16
android/res/values/template-dimens.xml
Normal file
16
android/res/values/template-dimens.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<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
android/settings.gradle
Normal file
1
android/settings.gradle
Normal file
|
@ -0,0 +1 @@
|
|||
rootProject.name = "i2pd"
|
374
android/src/org/purplei2p/i2pd/DaemonWrapper.java
Normal file
374
android/src/org/purplei2p/i2pd/DaemonWrapper.java
Normal file
|
@ -0,0 +1,374 @@
|
|||
package org.purplei2p.i2pd;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class DaemonWrapper {
|
||||
private static final String TAG = "i2pd";
|
||||
private final AssetManager assetManager;
|
||||
private final ConnectivityManager connectivityManager;
|
||||
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
|
||||
private boolean assetsCopied;
|
||||
|
||||
public interface StateUpdateListener {
|
||||
void daemonStateUpdate(State oldValue, State newValue);
|
||||
}
|
||||
|
||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
||||
|
||||
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(oldState, newState);
|
||||
}
|
||||
|
||||
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 int getTransitTunnelsCount() {
|
||||
return I2PD_JNI.GetTransitTunnelsCount();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isStartedOkay() {
|
||||
return equals(State.startedOkay) || equals(State.gracefulShutdownInProgress);
|
||||
}
|
||||
}
|
||||
|
||||
private volatile State state = State.uninitialized;
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public DaemonWrapper(AssetManager assetManager, ConnectivityManager connectivityManager){
|
||||
this.assetManager = assetManager;
|
||||
this.connectivityManager = connectivityManager;
|
||||
setState(State.starting);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
processAssets();
|
||||
I2PD_JNI.loadLibraries();
|
||||
setState(State.jniLibraryLoaded);
|
||||
registerNetworkCallback();
|
||||
} catch (Throwable tr) {
|
||||
lastThrowable = tr;
|
||||
setState(State.startFailed);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
synchronized (DaemonWrapper.this) {
|
||||
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
|
||||
daemonStartResult = I2PD_JNI.startDaemon();
|
||||
if ("ok".equals(daemonStartResult)) {
|
||||
setState(State.startedOkay);
|
||||
} 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(State oldValue, State newValue) {
|
||||
Log.i(TAG, "daemon state change: " + state);
|
||||
for (StateUpdateListener listener : stateUpdateListeners) {
|
||||
try {
|
||||
listener.daemonStateUpdate(oldValue, newValue);
|
||||
} catch (Throwable tr) {
|
||||
Log.e(TAG, "exception in listener ignored", tr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Throwable getLastThrowable() {
|
||||
return lastThrowable;
|
||||
}
|
||||
|
||||
public String getDaemonStartResult() {
|
||||
return daemonStartResult;
|
||||
}
|
||||
|
||||
public boolean isStartedOkay() {
|
||||
return getState().isStartedOkay();
|
||||
}
|
||||
|
||||
public synchronized void stopDaemon() {
|
||||
if (isStartedOkay()) {
|
||||
try {
|
||||
I2PD_JNI.stopDaemon();
|
||||
} catch(Throwable tr) {
|
||||
Log.e(TAG, "", tr);
|
||||
}
|
||||
|
||||
setState(State.stopped);
|
||||
}
|
||||
}
|
||||
|
||||
private void processAssets() {
|
||||
if (!assetsCopied) {
|
||||
try {
|
||||
assetsCopied = true;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
// If we have a directory, we make it and recurse. If a file, we copy its
|
||||
// contents.
|
||||
try {
|
||||
String[] contents = assetManager.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 = assetManager.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 registerNetworkCallback(){
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) registerNetworkCallback0();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
private void registerNetworkCallback0() {
|
||||
NetworkRequest request = new NetworkRequest.Builder()
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
.build();
|
||||
NetworkStateCallbackImpl networkCallback = new NetworkStateCallbackImpl();
|
||||
connectivityManager.registerNetworkCallback(request, networkCallback);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
private static final class NetworkStateCallbackImpl extends ConnectivityManager.NetworkCallback {
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
super.onAvailable(network);
|
||||
I2PD_JNI.onNetworkStateChanged(true);
|
||||
Log.i(TAG, "NetworkCallback.onAvailable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLost(Network network) {
|
||||
super.onLost(network);
|
||||
I2PD_JNI.onNetworkStateChanged(false);
|
||||
Log.i(TAG, " NetworkCallback.onLost");
|
||||
}
|
||||
}
|
||||
}
|
188
android/src/org/purplei2p/i2pd/ForegroundService.java
Normal file
188
android/src/org/purplei2p/i2pd/ForegroundService.java
Normal file
|
@ -0,0 +1,188 @@
|
|||
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 static ForegroundService instance;
|
||||
|
||||
private static volatile DaemonWrapper daemon;
|
||||
|
||||
private static final Object initDeinitLock = new Object();
|
||||
|
||||
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener =
|
||||
new DaemonWrapper.StateUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) {
|
||||
updateNotificationText();
|
||||
}
|
||||
};
|
||||
|
||||
private void updateNotificationText() {
|
||||
try {
|
||||
synchronized (initDeinitLock) {
|
||||
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 static final 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(DaemonWrapper daemon) {
|
||||
ForegroundService.daemon = daemon;
|
||||
initCheck();
|
||||
}
|
||||
|
||||
private static void initCheck() {
|
||||
synchronized (initDeinitLock) {
|
||||
if (instance != null && daemon != null) instance.setListener();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
instance = this;
|
||||
initCheck();
|
||||
}
|
||||
|
||||
private void setListener() {
|
||||
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
||||
updateNotificationText();
|
||||
}
|
||||
|
||||
@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() {
|
||||
cancelNotification();
|
||||
deinitCheck();
|
||||
instance=null;
|
||||
}
|
||||
|
||||
public static void deinit() {
|
||||
deinitCheck();
|
||||
}
|
||||
|
||||
private static void deinitCheck() {
|
||||
synchronized (initDeinitLock) {
|
||||
if (daemon != null && instance != null)
|
||||
daemon.removeStateChangeListener(instance.daemonStateUpdatedListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelNotification() {
|
||||
synchronized (initDeinitLock) {
|
||||
// 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 void showNotification() {
|
||||
synchronized (initDeinitLock) {
|
||||
if (daemon != null) {
|
||||
// In this sample, we'll use the same text for the ticker and the expanded notification
|
||||
CharSequence text = getText(daemon.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;
|
||||
}
|
||||
}
|
486
android/src/org/purplei2p/i2pd/I2PDActivity.java
Executable file
486
android/src/org/purplei2p/i2pd/I2PDActivity.java
Executable file
|
@ -0,0 +1,486 @@
|
|||
package org.purplei2p.i2pd;
|
||||
|
||||
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.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Build;
|
||||
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 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 ConfigParser parser = new ConfigParser(i2pdpath); // TODO
|
||||
|
||||
private static volatile DaemonWrapper daemon;
|
||||
|
||||
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() {
|
||||
@Override
|
||||
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) {
|
||||
updateStatusText();
|
||||
}
|
||||
};
|
||||
|
||||
private void updateStatusText() {
|
||||
runOnUiThread(() -> {
|
||||
try {
|
||||
if (textView == null)
|
||||
return;
|
||||
Throwable tr = daemon.getLastThrowable();
|
||||
if (tr!=null) {
|
||||
textView.setText(throwableToString(tr));
|
||||
return;
|
||||
}
|
||||
DaemonWrapper.State state = daemon.getState();
|
||||
String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
|
||||
String graceStr = DaemonWrapper.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);
|
||||
|
||||
if (daemon==null) {
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
daemon = new DaemonWrapper(getAssets(), connectivityManager);
|
||||
}
|
||||
ForegroundService.init(daemon);
|
||||
|
||||
textView = new TextView(this);
|
||||
setContentView(textView);
|
||||
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
||||
daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState());
|
||||
|
||||
// request permissions
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
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;
|
||||
ForegroundService.deinit();
|
||||
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 >= Build.VERSION_CODES.M;
|
||||
}
|
||||
|
||||
@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:
|
||||
startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class));
|
||||
return true;
|
||||
}
|
||||
|
||||
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() == DaemonWrapper.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();
|
||||
return;
|
||||
}
|
||||
|
||||
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() {
|
||||
updateStatusText();
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
170
android/src/org/purplei2p/i2pd/I2PDPermsAskerActivity.java
Normal file
170
android/src/org/purplei2p/i2pd/I2PDPermsAskerActivity.java
Normal file
|
@ -0,0 +1,170 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
31
android/src/org/purplei2p/i2pd/I2PD_JNI.java
Normal file
31
android/src/org/purplei2p/i2pd/I2PD_JNI.java
Normal file
|
@ -0,0 +1,31 @@
|
|||
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");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
39
android/src/org/purplei2p/i2pd/WebConsoleActivity.java
Normal file
39
android/src/org/purplei2p/i2pd/WebConsoleActivity.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package org.purplei2p.i2pd;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class WebConsoleActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_web_console);
|
||||
|
||||
Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
final WebView webView = findViewById(R.id.webview1);
|
||||
webView.setWebViewClient(new WebViewClient());
|
||||
|
||||
final WebSettings webSettings = webView.getSettings();
|
||||
webSettings.setBuiltInZoomControls(true);
|
||||
webSettings.setJavaScriptEnabled(false);
|
||||
webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort
|
||||
}
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id==android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
18
android_binary_only/.gitignore
vendored
Normal file
18
android_binary_only/.gitignore
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
gen
|
||||
tests
|
||||
bin
|
||||
libs
|
||||
log*
|
||||
obj
|
||||
.gradle
|
||||
.idea
|
||||
.externalNativeBuild
|
||||
ant.properties
|
||||
local.properties
|
||||
build.sh
|
||||
android.iml
|
||||
build
|
||||
gradle
|
||||
gradlew
|
||||
gradlew.bat
|
||||
|
74
android_binary_only/jni/Android.mk
Executable file
74
android_binary_only/jni/Android.mk
Executable file
|
@ -0,0 +1,74 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := i2pd
|
||||
LOCAL_CPP_FEATURES := rtti exceptions
|
||||
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
boost_system \
|
||||
boost_date_time \
|
||||
boost_filesystem \
|
||||
boost_program_options \
|
||||
crypto ssl \
|
||||
miniupnpc
|
||||
LOCAL_LDLIBS := -lz
|
||||
|
||||
LOCAL_SRC_FILES := $(IFADDRS_PATH)/ifaddrs.c \
|
||||
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
|
||||
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
|
||||
$(DAEMON_SRC_PATH)/UnixDaemon.cpp \
|
||||
$(DAEMON_SRC_PATH)/Daemon.cpp \
|
||||
$(DAEMON_SRC_PATH)/UPnP.cpp \
|
||||
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
|
||||
$(DAEMON_SRC_PATH)/I2PControl.cpp \
|
||||
$(DAEMON_SRC_PATH)/i2pd.cpp
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := boost_system
|
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := boost_date_time
|
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := boost_filesystem
|
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := boost_program_options
|
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := crypto
|
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := ssl
|
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||
LOCAL_STATIC_LIBRARIES := crypto
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := miniupnpc
|
||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
40
android_binary_only/jni/Application.mk
Executable file
40
android_binary_only/jni/Application.mk
Executable file
|
@ -0,0 +1,40 @@
|
|||
APP_ABI := all
|
||||
#APP_ABI += x86
|
||||
#APP_ABI += x86_64
|
||||
#APP_ABI += armeabi-v7a
|
||||
#APP_ABI += arm64-v8a
|
||||
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
|
||||
APP_PLATFORM := android-14
|
||||
|
||||
NDK_TOOLCHAIN_VERSION := clang
|
||||
APP_STL := c++_static
|
||||
|
||||
# Enable c++17 extensions in source code
|
||||
APP_CPPFLAGS += -std=c++17 -fvisibility=default -fPIE
|
||||
|
||||
APP_CPPFLAGS += -DANDROID_BINARY -DANDROID -D__ANDROID__ -DUSE_UPNP
|
||||
APP_LDFLAGS += -rdynamic -fPIE -pie
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
APP_CPPFLAGS += -DANDROID_ARM7A
|
||||
endif
|
||||
|
||||
# Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead.
|
||||
#APP_OPTIM := debug
|
||||
|
||||
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
|
||||
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
||||
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
||||
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
||||
# change to your own
|
||||
I2PD_LIBS_PATH = /path/to/libraries
|
||||
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
|
||||
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
|
||||
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
|
||||
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
|
||||
|
||||
# don't change me
|
||||
I2PD_SRC_PATH = $(PWD)/..
|
||||
|
||||
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
|
||||
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
|
||||
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon
|
57
appveyor.yml
Normal file
57
appveyor.yml
Normal file
|
@ -0,0 +1,57 @@
|
|||
version: 2.35.0.{build}
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
branches:
|
||||
only:
|
||||
- openssl
|
||||
skip_tags: true
|
||||
os: Visual Studio 2015
|
||||
shallow_clone: true
|
||||
clone_depth: 1
|
||||
|
||||
# avoid building 32-bit if 64-bit failed already
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
environment:
|
||||
APPVEYOR_SAVE_CACHE_ON_ERROR: true
|
||||
MSYS2_PATH_TYPE: inherit
|
||||
CHERE_INVOKING: enabled_from_arguments
|
||||
matrix:
|
||||
- MSYSTEM: MINGW64
|
||||
- MSYSTEM: MINGW32
|
||||
|
||||
cache:
|
||||
- c:\msys64\var\cache\pacman\pkg\
|
||||
|
||||
install:
|
||||
# install new signing keyring
|
||||
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
||||
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
||||
- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
||||
# remove packages which can break build
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc"
|
||||
# update runtime
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
||||
# Kill bash before next try
|
||||
- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0
|
||||
# update packages and install required
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc"
|
||||
|
||||
build_script:
|
||||
- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3"
|
||||
# prepare archive for uploading
|
||||
- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
||||
- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt
|
||||
- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST%
|
||||
|
||||
after_build:
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc"
|
||||
|
||||
test: off
|
||||
|
||||
deploy: off
|
||||
|
||||
artifacts:
|
||||
- path: i2pd-*.zip
|
15
build/.gitignore
vendored
15
build/.gitignore
vendored
|
@ -1,27 +1,14 @@
|
|||
# Various generated files
|
||||
/CMakeFiles/
|
||||
/Testing/
|
||||
/tests/
|
||||
/.ninja_*
|
||||
/arch.c
|
||||
/build.ninja
|
||||
/i2pd
|
||||
/i2pd.exe
|
||||
/i2pd.exe.debug
|
||||
/libi2pd.a
|
||||
/libi2pdclient.a
|
||||
/libi2pdlang.a
|
||||
/cmake_install.cmake
|
||||
/CMakeCache.txt
|
||||
/CPackConfig.cmake
|
||||
/CPackSourceConfig.cmake
|
||||
/CTestTestfile.cmake
|
||||
/install_manifest.txt
|
||||
/Makefile
|
||||
/arch.c
|
||||
# windows build script
|
||||
i2pd*.zip
|
||||
build*.log
|
||||
# MVS project files
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.sln
|
||||
|
|
|
@ -1,160 +1,164 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.22)
|
||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
else()
|
||||
cmake_policy(VERSION 3.22)
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
# this addresses CMP0059 with CMake > 3.3 for PCH flags
|
||||
cmake_policy(VERSION 2.8.12)
|
||||
project("i2pd")
|
||||
|
||||
# for debugging
|
||||
#set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# paths
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
|
||||
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
|
||||
set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd)
|
||||
set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client)
|
||||
set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n)
|
||||
set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon)
|
||||
|
||||
include(Version)
|
||||
set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION)
|
||||
|
||||
project(
|
||||
i2pd
|
||||
VERSION ${PROJECT_VERSION}
|
||||
HOMEPAGE_URL "https://i2pd.website/"
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
# Win32 build with cmake is not supported
|
||||
if(WIN32 OR MSVC OR MSYS OR MINGW)
|
||||
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
|
||||
endif()
|
||||
|
||||
# configurable options
|
||||
option(WITH_AESNI "Use AES-NI instructions set" ON)
|
||||
option(WITH_HARDENING "Use hardening compiler flags" OFF)
|
||||
option(WITH_LIBRARY "Build library" ON)
|
||||
option(WITH_BINARY "Build binary" ON)
|
||||
option(WITH_STATIC "Static build" OFF)
|
||||
option(WITH_UPNP "Include support for UPnP client" OFF)
|
||||
option(WITH_GIT_VERSION "Use git commit info as version" OFF)
|
||||
option(WITH_PCH "Use precompiled header" OFF)
|
||||
option(WITH_MESHNET "Build for cjdns test network" OFF)
|
||||
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
||||
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
||||
option(BUILD_TESTING "Build tests" OFF)
|
||||
|
||||
IF(BUILD_TESTING)
|
||||
enable_testing()
|
||||
ENDIF()
|
||||
# paths
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
|
||||
set(CMAKE_SOURCE_DIR "..")
|
||||
|
||||
# Handle paths nicely
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Architecture
|
||||
# architecture
|
||||
include(TargetArch)
|
||||
target_architecture(ARCHITECTURE)
|
||||
|
||||
include(CheckAtomic)
|
||||
|
||||
if(WITH_STATIC)
|
||||
if(MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
endif()
|
||||
set(LIBI2PD_SRC_DIR ../libi2pd)
|
||||
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
||||
set(DAEMON_SRC_DIR ../daemon)
|
||||
|
||||
include_directories(${LIBI2PD_SRC_DIR})
|
||||
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
|
||||
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
||||
include_directories(${DAEMON_SRC_DIR})
|
||||
|
||||
set(LIBI2PD_SRC
|
||||
"${LIBI2PD_SRC_DIR}/api.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Base.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Blinding.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/BloomFilter.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/ChaCha20.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Config.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/CPU.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Crypto.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/CryptoKey.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Datagram.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Destination.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Ed25519.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Elligator.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Family.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/FS.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Garlic.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Gost.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Gzip.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/HTTP.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/I2NPProtocol.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Identity.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/LeaseSet.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Log.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/NetDb.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/NetDbRequests.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Profiling.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Reseed.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/RouterContext.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/RouterInfo.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Signature.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/SSU.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/SSUData.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/SSUSession.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Streaming.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Timestamp.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/TransitTunnel.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Transports.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/Tunnel.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/TunnelGateway.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/TunnelPool.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/TunnelConfig.cpp"
|
||||
"${LIBI2PD_SRC_DIR}/util.cpp"
|
||||
)
|
||||
|
||||
add_library(libi2pd ${LIBI2PD_SRC})
|
||||
set_target_properties(libi2pd PROPERTIES PREFIX "")
|
||||
|
||||
if(WITH_LIBRARY)
|
||||
install(TARGETS libi2pd
|
||||
EXPORT libi2pd
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT Libraries)
|
||||
# TODO Make libi2pd available to 3rd party projects via CMake as imported target
|
||||
# FIXME This pulls stdafx
|
||||
# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
||||
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
|
||||
set(CLIENT_SRC
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/MatchedDestination.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/I2PTunnel.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/I2PService.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/SAM.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp"
|
||||
"${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp"
|
||||
)
|
||||
|
||||
add_library(libi2pdclient ${CLIENT_SRC})
|
||||
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
|
||||
|
||||
if(WITH_LIBRARY)
|
||||
install(TARGETS libi2pdclient
|
||||
EXPORT libi2pdclient
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT Libraries)
|
||||
endif()
|
||||
|
||||
include_directories(${LANG_SRC_DIR})
|
||||
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
||||
add_library(libi2pdlang ${LANG_SRC})
|
||||
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
||||
|
||||
if(WITH_LIBRARY)
|
||||
install(TARGETS libi2pdlang
|
||||
EXPORT libi2pdlang
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT Libraries)
|
||||
endif()
|
||||
|
||||
include_directories(${DAEMON_SRC_DIR})
|
||||
|
||||
set(DAEMON_SRC
|
||||
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
||||
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
|
||||
"${DAEMON_SRC_DIR}/I2PControl.cpp"
|
||||
"${DAEMON_SRC_DIR}/I2PControlHandlers.cpp"
|
||||
"${DAEMON_SRC_DIR}/i2pd.cpp"
|
||||
"${DAEMON_SRC_DIR}/UPnP.cpp"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(WIN32_SRC_DIR ${CMAKE_SOURCE_DIR}/Win32)
|
||||
include_directories(${WIN32_SRC_DIR})
|
||||
|
||||
list(APPEND DAEMON_SRC
|
||||
"${WIN32_SRC_DIR}/DaemonWin32.cpp"
|
||||
"${WIN32_SRC_DIR}/Win32App.cpp"
|
||||
"${WIN32_SRC_DIR}/Win32Service.cpp"
|
||||
"${WIN32_SRC_DIR}/Win32NetState.cpp"
|
||||
)
|
||||
|
||||
file(GLOB WIN32_RC ${WIN32_SRC_DIR}/*.rc)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN -DNOMINMAX")
|
||||
|
||||
if(WITH_MESHNET)
|
||||
add_definitions(-DMESHNET)
|
||||
endif()
|
||||
|
||||
if(WITH_UPNP)
|
||||
add_definitions(-DUSE_UPNP)
|
||||
endif()
|
||||
|
||||
if(WITH_GIT_VERSION)
|
||||
include(GetGitRevisionDescription)
|
||||
git_describe(GIT_VERSION)
|
||||
add_definitions(-DGITVER=${GIT_VERSION})
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
||||
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
||||
# Multiple definitions of __stack_chk_fail(libssp & libc)
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
|
||||
|
||||
if(APPLE)
|
||||
add_definitions(-DMAC_OSX)
|
||||
endif()
|
||||
|
||||
if(HAIKU)
|
||||
add_definitions(-D_DEFAULT_SOURCE -D_GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-DWINVER=0x0600)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
# check for c++17 & c++11 support
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
|
||||
if(CXX17_SUPPORTED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
elseif(CXX11_SUPPORTED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
||||
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
||||
# Multiple definitions of __stack_chk_fail(libssp & libc)
|
||||
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -ffunction-sections -fdata-sections")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
|
||||
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
|
@ -184,6 +188,13 @@ if(UNIX)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# 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")
|
||||
add_definitions(-D__AES__)
|
||||
endif()
|
||||
|
||||
if(WITH_ADDRSANITIZER)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
|
@ -198,52 +209,27 @@ if(WITH_THREADSANITIZER)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) # gcc 8-9
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "stdc++fs")
|
||||
endif()
|
||||
|
||||
# Use std::atomic instead of GCC builtins on macOS PowerPC:
|
||||
# For more information refer to: https://github.com/PurpleI2P/i2pd/issues/1726#issuecomment-1306335111
|
||||
# This has been fixed in Boost 1.81, nevertheless we retain the setting for the sake of compatibility.
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
||||
add_definitions(-DBOOST_SP_USE_STD_ATOMIC)
|
||||
endif()
|
||||
|
||||
# libraries
|
||||
# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826
|
||||
# use imported Threads::Threads instead
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
if(IOS)
|
||||
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
||||
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
||||
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
||||
set(CMAKE_USE_PTHREADS_INIT 1)
|
||||
else()
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
if(THREADS_HAVE_PTHREAD_ARG) # compile time flag
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
endif()
|
||||
|
||||
if(WITH_STATIC)
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||
endif()
|
||||
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
if(MSVC)
|
||||
set(Boost_USE_STATIC_RUNTIME ON)
|
||||
else()
|
||||
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(OPENSSL_MSVC_STATIC_RT ON)
|
||||
endif()
|
||||
set(OPENSSL_USE_STATIC_LIBS ON)
|
||||
|
||||
set(ZLIB_USE_STATIC_LIBS ON)
|
||||
if(MSVC)
|
||||
set(ZLIB_NAMES zlibstatic zlibstat)
|
||||
else()
|
||||
set(ZLIB_NAMES libz zlibstatic zlibstat zlib z)
|
||||
endif()
|
||||
|
||||
if(WITH_UPNP)
|
||||
set(MINIUPNPC_USE_STATIC_LIBS ON)
|
||||
add_definitions(-DMINIUPNP_STATICLIB)
|
||||
endif()
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
# set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
|
||||
|
@ -253,30 +239,36 @@ else()
|
|||
# TODO: Consider separate compilation for LIBI2PD_SRC for library.
|
||||
# No need in -fPIC overhead for binary if not interested in library
|
||||
# HINT: revert c266cff CMakeLists.txt: compilation speed up
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK)
|
||||
if(WIN32)
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
endif()
|
||||
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
||||
endif()
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem program_options)
|
||||
if(NOT DEFINED Boost_FOUND)
|
||||
if(WITH_PCH)
|
||||
include_directories(BEFORE ${CMAKE_BINARY_DIR})
|
||||
add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp")
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BTU)
|
||||
get_directory_property(DEFS DEFINITIONS)
|
||||
string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}")
|
||||
add_custom_command(TARGET stdafx PRE_BUILD
|
||||
COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch
|
||||
)
|
||||
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
||||
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
|
||||
target_link_libraries(libi2pd stdafx)
|
||||
endif()
|
||||
|
||||
target_link_libraries(libi2pdclient libi2pd)
|
||||
|
||||
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||
message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!")
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
if(NOT DEFINED OPENSSL_FOUND)
|
||||
if(NOT DEFINED OPENSSL_INCLUDE_DIR)
|
||||
message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
|
||||
endif()
|
||||
|
||||
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
|
||||
add_definitions(-DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
endif()
|
||||
|
||||
if(WITH_UPNP)
|
||||
find_package(MiniUPnPc REQUIRED)
|
||||
if(NOT MINIUPNPC_FOUND)
|
||||
|
@ -291,29 +283,19 @@ if(ZLIB_FOUND)
|
|||
link_directories(${ZLIB_ROOT}/lib)
|
||||
endif()
|
||||
|
||||
# C++ standard to use, based on compiler and version of boost
|
||||
if(NOT MSVC)
|
||||
# check for c++20 & c++17 support
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
if(Boost_VERSION VERSION_GREATER_EQUAL "1.83") # min boost version for c++20
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++20" CXX20_SUPPORTED)
|
||||
endif()
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
|
||||
|
||||
|
||||
if(CXX20_SUPPORTED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
|
||||
elseif(CXX17_SUPPORTED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
else()
|
||||
message(SEND_ERROR "C++20 nor C++17 standard not seems to be supported by compiler. Too old version?")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# load includes
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||
|
||||
# warn if for meshnet
|
||||
if(WITH_MESHNET)
|
||||
message(STATUS "Building for testnet")
|
||||
message(WARNING "This build will NOT work on mainline i2p")
|
||||
endif()
|
||||
|
||||
if(NOT MSYS)
|
||||
include(CheckAtomic)
|
||||
endif()
|
||||
|
||||
# show summary
|
||||
message(STATUS "---------------------------------------")
|
||||
message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
|
||||
|
@ -321,72 +303,57 @@ message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}")
|
|||
message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}")
|
||||
message(STATUS "Architecture : ${ARCHITECTURE}")
|
||||
message(STATUS "Compiler flags : ${CMAKE_CXX_FLAGS}")
|
||||
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
|
||||
message(STATUS "Options:")
|
||||
message(STATUS " AESNI : ${WITH_AESNI}")
|
||||
message(STATUS " HARDENING : ${WITH_HARDENING}")
|
||||
message(STATUS " LIBRARY : ${WITH_LIBRARY}")
|
||||
message(STATUS " BINARY : ${WITH_BINARY}")
|
||||
message(STATUS " STATIC BUILD : ${WITH_STATIC}")
|
||||
message(STATUS " UPnP : ${WITH_UPNP}")
|
||||
if(WITH_GIT_VERSION)
|
||||
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION} (${GIT_VERSION})")
|
||||
else()
|
||||
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}")
|
||||
endif()
|
||||
message(STATUS " PCH : ${WITH_PCH}")
|
||||
message(STATUS " MESHNET : ${WITH_MESHNET}")
|
||||
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
||||
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
||||
message(STATUS "---------------------------------------")
|
||||
|
||||
if(WITH_BINARY)
|
||||
if(WIN32)
|
||||
add_executable("${PROJECT_NAME}" WIN32 ${DAEMON_SRC} ${WIN32_RC})
|
||||
else()
|
||||
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
|
||||
endif()
|
||||
#Handle paths nicely
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi")
|
||||
# OpenSSL may require Crypt32 library on MSVC build, which is not added by CMake lesser than 3.21
|
||||
if(MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.21)
|
||||
list(APPEND MINGW_EXTRA "crypt32")
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_BINARY)
|
||||
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
|
||||
|
||||
if(WITH_STATIC)
|
||||
if(NOT MSVC)
|
||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
||||
endif()
|
||||
|
||||
if(WITH_PCH)
|
||||
target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h)
|
||||
endif()
|
||||
|
||||
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now")
|
||||
endif()
|
||||
|
||||
if(WITH_UPNP)
|
||||
set(UPNP_LIB ${MINIUPNPC_LIBRARY})
|
||||
endif()
|
||||
|
||||
# FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04
|
||||
list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES)
|
||||
if(${LAST_Boost_LIBRARIES} MATCHES ".*pthread.*")
|
||||
list(REMOVE_AT Boost_LIBRARIES -1)
|
||||
endif()
|
||||
|
||||
# synchronization library is incompatible with Windows 7
|
||||
if(WIN32)
|
||||
get_target_property(BOOSTFSLIBS Boost::filesystem INTERFACE_LINK_LIBRARIES)
|
||||
list(REMOVE_ITEM BOOSTFSLIBS synchronization)
|
||||
set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}")
|
||||
endif()
|
||||
|
||||
if(WITH_STATIC)
|
||||
set(DL_LIB ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
||||
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||
|
||||
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
||||
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin")
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/tests)
|
||||
endif()
|
||||
|
|
|
@ -2,25 +2,26 @@
|
|||
setlocal enableextensions enabledelayedexpansion
|
||||
title Building i2pd
|
||||
|
||||
REM Copyright (c) 2013-2022, 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 See full license text in LICENSE file at top of project tree
|
||||
|
||||
REM To use that script, you must have installed in your MSYS installation these packages:
|
||||
REM Base: git make zip
|
||||
REM UCRT64: mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-gcc
|
||||
REM MINGW32: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
||||
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
|
||||
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
||||
|
||||
REM setting up variables for MSYS
|
||||
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)
|
||||
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)!
|
||||
set "WD=C:\msys64\usr\bin\"
|
||||
set MSYS2_PATH_TYPE=inherit
|
||||
set CHERE_INVOKING=enabled_from_arguments
|
||||
REM set MSYSTEM=MSYS
|
||||
set MSYSTEM=MINGW32
|
||||
|
||||
set "WD=C:\msys64\usr\bin\"
|
||||
set "xSH=%WD%bash -lc"
|
||||
|
||||
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d contrib/webconsole"
|
||||
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
||||
|
||||
REM detecting number of processors
|
||||
set /a threads=%NUMBER_OF_PROCESSORS%
|
||||
|
@ -33,73 +34,38 @@ del /S build_*.log >> nul 2>&1
|
|||
|
||||
echo Receiving latest commit and cleaning up...
|
||||
%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1
|
||||
echo.
|
||||
|
||||
REM set to variable current commit hash
|
||||
for /F "usebackq" %%a in (`%xSH% "git describe --tags"`) DO (
|
||||
FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO (
|
||||
set tag=%%a
|
||||
)
|
||||
|
||||
REM set to variable latest released tag
|
||||
for /F "usebackq" %%b in (`%xSH% "git describe --abbrev=0"`) DO (
|
||||
set reltag=%%b
|
||||
)
|
||||
|
||||
echo Preparing configuration files and README for packaging...
|
||||
|
||||
%xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
|
||||
|
||||
REM converting configuration files to DOS format (make usable in Windows Notepad)
|
||||
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
|
||||
|
||||
REM Prepare binary signing command if signing key and password provided
|
||||
if defined SIGN (
|
||||
echo Signing enabled
|
||||
|
||||
for %%X in (signtool.exe) do (set xSIGNTOOL=%%~$PATH:X)
|
||||
if not defined xSIGNTOOL (
|
||||
if not defined SIGNTOOL (
|
||||
echo Error: Can't find signtool. Please provide path to binary using SIGNTOOL variable.
|
||||
exit /b 1
|
||||
) else (
|
||||
set "xSIGNTOOL=%SIGNTOOL%"
|
||||
)
|
||||
)
|
||||
|
||||
if defined SIGNKEY (
|
||||
set "xSIGNKEYOPTS=/f ^"%SIGNKEY%^""
|
||||
)
|
||||
|
||||
if defined SIGNPASS (
|
||||
set "xSIGNPASSOPTS=/p ^"%SIGNPASS%^""
|
||||
)
|
||||
|
||||
set "xSIGNOPTS=sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 %xSIGNKEYOPTS% %xSIGNPASSOPTS%"
|
||||
)
|
||||
REM 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
|
||||
set MSYSTEM=MINGW32
|
||||
set bitness=32
|
||||
call :BUILDING
|
||||
|
||||
set MSYSTEM=UCRT64
|
||||
set MSYSTEM=MINGW64
|
||||
set bitness=64
|
||||
call :BUILDING
|
||||
|
||||
REM build for Windows XP
|
||||
if exist C:\msys64-xp\ ( call :BUILDING_XP )
|
||||
|
||||
REM building for WinXP
|
||||
set "WD=C:\msys64-xp\usr\bin\"
|
||||
set MSYSTEM=MINGW32
|
||||
set bitness=32
|
||||
set "xSH=%WD%bash -lc"
|
||||
call :BUILDING_XP
|
||||
echo.
|
||||
|
||||
REM compile installer
|
||||
echo Building installer...
|
||||
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1
|
||||
C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_ver="%tag%" build\win_installer.iss >> build\build.log 2>&1
|
||||
|
||||
REM Sign binary
|
||||
if defined xSIGNOPTS (
|
||||
"%xSIGNTOOL%" %xSIGNOPTS% build\setup_i2pd_v%tag%.exe
|
||||
)
|
||||
|
||||
%xSH% "git checkout contrib/*" >> build\build.log 2>&1
|
||||
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
|
||||
|
||||
echo Build complete...
|
||||
|
@ -108,42 +74,13 @@ exit /b 0
|
|||
|
||||
:BUILDING
|
||||
%xSH% "make clean" >> nul
|
||||
echo Building i2pd %tag% for win%bitness%...
|
||||
REM Build i2pd
|
||||
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads%" > build\build_win%bitness%_%tag%.log 2>&1
|
||||
|
||||
REM Sign binary
|
||||
if defined xSIGNOPTS (
|
||||
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
|
||||
)
|
||||
|
||||
REM Copy binary for installer and create distribution archive
|
||||
%xSH% "cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST%" >> build\build_win%bitness%_%tag%.log 2>&1
|
||||
|
||||
REM Clean work directory
|
||||
%xSH% "make clean" >> build\build_win%bitness%_%tag%.log 2>&1
|
||||
echo Building i2pd %tag% for win%bitness%
|
||||
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build\build_win%bitness%_%tag%.log 2>&1
|
||||
goto EOF
|
||||
|
||||
:BUILDING_XP
|
||||
set MSYSTEM=MINGW32
|
||||
set bitness=32
|
||||
set "WD=C:\msys64-xp\usr\bin\"
|
||||
set "xSH=%WD%bash -lc"
|
||||
|
||||
%xSH% "make clean" >> nul
|
||||
echo Building i2pd %tag% for winxp...
|
||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads%" > build\build_winxp_%tag%.log 2>&1
|
||||
|
||||
REM Sign binary
|
||||
if defined xSIGNOPTS (
|
||||
"%xSIGNTOOL%" %xSIGNOPTS% i2pd.exe
|
||||
)
|
||||
|
||||
REM Copy binary for installer and create distribution archive
|
||||
%xSH% "cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST%" >> build\build_winxp_%tag%.log 2>&1
|
||||
|
||||
REM Clean work directory
|
||||
%xSH% "make clean" >> build\build_winxp_%tag%.log 2>&1
|
||||
goto EOF
|
||||
echo Building i2pd %tag% for winxp
|
||||
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1
|
||||
|
||||
:EOF
|
|
@ -1,23 +1,18 @@
|
|||
# atomic builtins are required for threading support.
|
||||
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
|
||||
# Sometimes linking against libatomic is required for atomic ops, if
|
||||
# the platform doesn't support lock-free atomics.
|
||||
|
||||
function(check_working_cxx_atomics varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++17")
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <atomic>
|
||||
std::atomic<int> x;
|
||||
std::atomic<short> y;
|
||||
std::atomic<char> z;
|
||||
int main() {
|
||||
++z;
|
||||
++y;
|
||||
return ++x;
|
||||
return x;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
|
@ -25,14 +20,13 @@ endfunction(check_working_cxx_atomics)
|
|||
|
||||
function(check_working_cxx_atomics64 varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++17 ${CMAKE_REQUIRED_FLAGS}")
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint64_t> x (0);
|
||||
int main() {
|
||||
uint64_t i = x.load(std::memory_order_relaxed);
|
||||
(void)i;
|
||||
return 0;
|
||||
}
|
||||
" ${varname})
|
||||
|
@ -40,16 +34,15 @@ int main() {
|
|||
endfunction(check_working_cxx_atomics64)
|
||||
|
||||
|
||||
# Check for (non-64-bit) atomic operations.
|
||||
if(MSVC)
|
||||
set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
|
||||
else()
|
||||
# This isn't necessary on MSVC, so avoid command-line switch annoyance
|
||||
# by only running on GCC-like hosts.
|
||||
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
# First check if atomics work without the library.
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||
if(HAVE_LIBATOMIC)
|
||||
if( HAVE_LIBATOMIC )
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
|
@ -65,20 +58,20 @@ endif()
|
|||
if(MSVC)
|
||||
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
|
||||
else()
|
||||
# First check if atomics work without the library.
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
endif()
|
||||
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||
if(HAVE_CXX_LIBATOMICS64)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
message(FATAL_ERROR "Host compiler must support std::atomic!")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
|
||||
endif()
|
||||
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -87,6 +80,7 @@ endif()
|
|||
## assumes C++11 <atomic> works.
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#ifdef _MSC_VER
|
||||
#include <Intrin.h> /* Workaround for PR19898. */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
int main() {
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
# - Try to find the CHECK libraries
|
||||
# Once done this will define
|
||||
#
|
||||
# CHECK_FOUND - system has check
|
||||
# CHECK_INCLUDE_DIRS - the check include directory
|
||||
# CHECK_LIBRARIES - check library
|
||||
#
|
||||
# Copyright (c) 2007 Daniel Gollub <gollub@b1-systems.de>
|
||||
# Copyright (c) 2007-2009 Bjoern Ricks <bjoern.ricks@gmail.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
INCLUDE( FindPkgConfig )
|
||||
|
||||
IF ( Check_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "REQUIRED" )
|
||||
ELSE( Check_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "" )
|
||||
ENDIF ( Check_FIND_REQUIRED )
|
||||
|
||||
IF ( CHECK_MIN_VERSION )
|
||||
PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} )
|
||||
ELSE ( CHECK_MIN_VERSION )
|
||||
PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check )
|
||||
ENDIF ( CHECK_MIN_VERSION )
|
||||
|
||||
# Look for CHECK include dir and libraries
|
||||
IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
|
||||
FIND_PATH( CHECK_INCLUDE_DIRS check.h )
|
||||
|
||||
FIND_LIBRARY( CHECK_LIBRARIES NAMES check )
|
||||
|
||||
IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
|
||||
SET( CHECK_FOUND 1 )
|
||||
IF ( NOT Check_FIND_QUIETLY )
|
||||
MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" )
|
||||
ENDIF ( NOT Check_FIND_QUIETLY )
|
||||
ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
|
||||
IF ( Check_FIND_REQUIRED )
|
||||
MESSAGE( FATAL_ERROR "Could NOT find CHECK" )
|
||||
ELSE ( Check_FIND_REQUIRED )
|
||||
IF ( NOT Check_FIND_QUIETLY )
|
||||
MESSAGE( STATUS "Could NOT find CHECK" )
|
||||
ENDIF ( NOT Check_FIND_QUIETLY )
|
||||
ENDIF ( Check_FIND_REQUIRED )
|
||||
ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
|
||||
ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
|
||||
# Hide advanced variables from CMake GUIs
|
||||
MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES )
|
||||
|
|
@ -1,284 +0,0 @@
|
|||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the working tree (--dirty option),
|
||||
# and adjusting the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# git_local_changes(<var>)
|
||||
#
|
||||
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
|
||||
# Uses the return code of "git diff-index --quiet HEAD --".
|
||||
# Does not regard untracked files.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
#
|
||||
# Copyright 2009-2013, Iowa State University.
|
||||
# Copyright 2013-2020, Ryan Pavlik
|
||||
# Copyright 2013-2020, Contributors
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
# Function _git_find_closest_git_dir finds the next closest .git directory
|
||||
# that is part of any directory in the path defined by _start_dir.
|
||||
# The result is returned in the parent scope variable whose name is passed
|
||||
# as variable _git_dir_var. If no .git directory can be found, the
|
||||
# function returns an empty string via _git_dir_var.
|
||||
#
|
||||
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
||||
# neither foo nor bar contain a file/directory .git. This will return
|
||||
# C:/bla/.git
|
||||
#
|
||||
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
||||
set(cur_dir "${_start_dir}")
|
||||
set(git_dir "${_start_dir}/.git")
|
||||
while(NOT EXISTS "${git_dir}")
|
||||
# .git dir not found, search parent directories
|
||||
set(git_previous_parent "${cur_dir}")
|
||||
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
|
||||
if(cur_dir STREQUAL git_previous_parent)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_git_dir_var}
|
||||
""
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(git_dir "${cur_dir}/.git")
|
||||
endwhile()
|
||||
set(${_git_dir_var}
|
||||
"${git_dir}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
|
||||
|
||||
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
|
||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
|
||||
else()
|
||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
|
||||
endif()
|
||||
if(NOT "${GIT_DIR}" STREQUAL "")
|
||||
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
|
||||
"${GIT_DIR}")
|
||||
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
|
||||
# We've gone above the CMake root dir.
|
||||
set(GIT_DIR "")
|
||||
endif()
|
||||
endif()
|
||||
if("${GIT_DIR}" STREQUAL "")
|
||||
set(${_refspecvar}
|
||||
"GITDIR-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
set(${_hashvar}
|
||||
"GITDIR-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check if the current source dir is a git submodule or a worktree.
|
||||
# In both cases .git is a file instead of a directory.
|
||||
#
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
# The following git command will return a non empty string that
|
||||
# points to the super project working tree if the current
|
||||
# source dir is inside a git submodule.
|
||||
# Otherwise the command will return an empty string.
|
||||
#
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse
|
||||
--show-superproject-working-tree
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT "${out}" STREQUAL "")
|
||||
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
|
||||
${submodule})
|
||||
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
|
||||
ABSOLUTE)
|
||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
||||
else()
|
||||
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
|
||||
file(READ ${GIT_DIR} worktree_ref)
|
||||
# The .git directory contains a path to the worktree information directory
|
||||
# inside the parent git repo of the worktree.
|
||||
#
|
||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
|
||||
${worktree_ref})
|
||||
string(STRIP ${git_worktree_dir} git_worktree_dir)
|
||||
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
|
||||
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
|
||||
endif()
|
||||
else()
|
||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake" @ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar}
|
||||
"${HEAD_REF}"
|
||||
PARENT_SCOPE)
|
||||
set(${_hashvar}
|
||||
"${HEAD_HASH}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe_working_tree _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_local_changes _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(res EQUAL 0)
|
||||
set(${_var}
|
||||
"CLEAN"
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
set(${_var}
|
||||
"DIRTY"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
|
@ -1,43 +0,0 @@
|
|||
#
|
||||
# Internal file for GetGitRevisionDescription.cmake
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright 2009-2012, Iowa State University
|
||||
# Copyright 2011-2015, Contributors
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
set(HEAD_HASH)
|
||||
|
||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
||||
|
||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
||||
if(HEAD_CONTENTS MATCHES "ref")
|
||||
# named branch
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
else()
|
||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
|
@ -1,30 +1,16 @@
|
|||
# Copyright (c) 2017-2023, The PurpleI2P Project
|
||||
# This file is part of Purple i2pd project and licensed under BSD3
|
||||
# See full license text in LICENSE file at top of project tree
|
||||
|
||||
# Based on the Qt 5 processor detection code, so should be very accurate
|
||||
# https://github.com/qt/qtbase/blob/dev/src/corelib/global/qprocessordetection.h
|
||||
# Currently handles arm (v5, v6, v7, v8), x86 (32/64), ia64, mips (32/64, mipsel, mips64el) and ppc (32/64)
|
||||
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
|
||||
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
|
||||
|
||||
# Regarding POWER/PowerPC, just as is noted in the Qt source,
|
||||
# "There are many more known variants/revisions that we do not handle/detect."
|
||||
|
||||
set(archdetect_c_code "
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)|| defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||
#if defined(__ARM64_ARCH_8__) \\
|
||||
|| defined(__aarch64__) \\
|
||||
|| defined(__ARMv8__) \\
|
||||
|| defined(__ARMv8_A__) \\
|
||||
|| defined(_M_ARM64) \\
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
|
||||
#error cmake_ARCH arm64
|
||||
#elif defined(__ARM_ARCH_7__) \\
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
|
||||
#if defined(__ARM_ARCH_7__) \\
|
||||
|| defined(__ARM_ARCH_7A__) \\
|
||||
|| defined(__ARM_ARCH_7R__) \\
|
||||
|| defined(__ARM_ARCH_7M__) \\
|
||||
|| defined(__ARM_ARCH_7S__) \\
|
||||
|| defined(_ARM_ARCH_7) \\
|
||||
|| defined(__CORE_CORTEXA__) \\
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
|
||||
#error cmake_ARCH armv7
|
||||
#elif defined(__ARM_ARCH_6__) \\
|
||||
|
@ -37,7 +23,6 @@ set(archdetect_c_code "
|
|||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
|
||||
#error cmake_ARCH armv6
|
||||
#elif defined(__ARM_ARCH_5TEJ__) \\
|
||||
|| defined(__ARM_ARCH_5TE__) \\
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
|
||||
#error cmake_ARCH armv5
|
||||
#else
|
||||
|
@ -49,19 +34,7 @@ set(archdetect_c_code "
|
|||
#error cmake_ARCH x86_64
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
#error cmake_ARCH ia64
|
||||
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||
#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
|
||||
#if defined(__MIPSEL__)
|
||||
#error cmake_ARCH mips64el
|
||||
#else
|
||||
#error cmake_ARCH mips64
|
||||
#endif
|
||||
#elif defined(__MIPSEL__)
|
||||
#error cmake_ARCH mipsel
|
||||
#else
|
||||
#error cmake_ARCH mips
|
||||
#endif
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__POWERPC__) \\
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|
||||
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|
||||
|| defined(_M_MPPC) || defined(_M_PPC)
|
||||
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||
|
@ -74,7 +47,7 @@ set(archdetect_c_code "
|
|||
#error cmake_ARCH unknown
|
||||
")
|
||||
|
||||
# Set ppc_support to TRUE before including this file on ppc and ppc64
|
||||
# Set ppc_support to TRUE before including this file or ppc and ppc64
|
||||
# will be treated as invalid architectures since they are no longer supported by Apple
|
||||
|
||||
function(target_architecture output_var)
|
||||
|
@ -83,25 +56,23 @@ function(target_architecture output_var)
|
|||
# First let's normalize the order of the values
|
||||
|
||||
# Note that it's not possible to compile PowerPC applications if you are using
|
||||
# the OS X SDK version 10.7 or later - you'll need 10.4/10.5/10.6 for that, so we
|
||||
# disable it by default. Also, ppc64 is not supported in 10.6.
|
||||
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
|
||||
# disable it by default
|
||||
# See this page for more information:
|
||||
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
|
||||
|
||||
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
|
||||
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise; 10.6 also supports ppc.
|
||||
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
|
||||
|
||||
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
||||
set(osx_arch_ppc TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "i386")
|
||||
set(osx_arch_i386 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "x86_64")
|
||||
set(osx_arch_x86_64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "arm64")
|
||||
set(osx_arch_arm64 TRUE)
|
||||
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||
set(osx_arch_ppc64 TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
||||
endif()
|
||||
|
@ -112,10 +83,6 @@ function(target_architecture output_var)
|
|||
list(APPEND ARCH ppc)
|
||||
endif()
|
||||
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_i386)
|
||||
list(APPEND ARCH i386)
|
||||
endif()
|
||||
|
@ -124,8 +91,8 @@ function(target_architecture output_var)
|
|||
list(APPEND ARCH x86_64)
|
||||
endif()
|
||||
|
||||
if(osx_arch_arm64)
|
||||
list(APPEND ARCH arm64)
|
||||
if(osx_arch_ppc64)
|
||||
list(APPEND ARCH ppc64)
|
||||
endif()
|
||||
else()
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
|
||||
|
@ -133,11 +100,11 @@ function(target_architecture output_var)
|
|||
enable_language(C)
|
||||
|
||||
# Detect the architecture in a rather creative way...
|
||||
# This compiles a small C program which is a series of ifdefs that selects
|
||||
# a particular #error preprocessor directive whose message string contains
|
||||
# the target architecture. The program will always fail to compile (both because
|
||||
# file is not a valid C program, and obviously because of the presence of
|
||||
# the #error preprocessor directives... but by exploiting the preprocessor in this
|
||||
# This compiles a small C program which is a series of ifdefs that selects a
|
||||
# particular #error preprocessor directive whose message string contains the
|
||||
# target architecture. The program will always fail to compile (both because
|
||||
# file is not a valid C program, and obviously because of the presence of the
|
||||
# #error preprocessor directives... but by exploiting the preprocessor in this
|
||||
# way, we can detect the correct target architecture even when cross-compiling,
|
||||
# since the program itself never needs to be run (only the compiler/preprocessor)
|
||||
try_run(
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# read version
|
||||
|
||||
function(set_version version_file output_var)
|
||||
file(READ "${version_file}" version_data)
|
||||
|
||||
string(REGEX MATCH "I2PD_VERSION_MAJOR ([0-9]*)" _ ${version_data})
|
||||
set(version_major ${CMAKE_MATCH_1})
|
||||
|
||||
string(REGEX MATCH "I2PD_VERSION_MINOR ([0-9]*)" _ ${version_data})
|
||||
set(version_minor ${CMAKE_MATCH_1})
|
||||
|
||||
string(REGEX MATCH "I2PD_VERSION_MICRO ([0-9]*)" _ ${version_data})
|
||||
set(version_micro ${CMAKE_MATCH_1})
|
||||
|
||||
set(${output_var} "${version_major}.${version_minor}.${version_micro}" PARENT_SCOPE)
|
||||
endfunction()
|
34
build/docker/README.md
Normal file
34
build/docker/README.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
Howto build & run
|
||||
==================
|
||||
|
||||
**Build**
|
||||
|
||||
Assuming you're in the root directory of the anoncoin source code.
|
||||
|
||||
$ `cd build/docker`
|
||||
$ `docker -t meeh/i2pd:latest .`
|
||||
|
||||
**Run**
|
||||
|
||||
To run either the local build, or if not found - fetched prebuild from hub.docker.io, run the following command.
|
||||
|
||||
$ `docker run --name anonnode -v /path/to/i2pd/datadir/on/host:/var/lib/i2pd -p 7070:7070 -p 4444:4444 -p 4447:4447 -p 7656:7656 -p 2827:2827 -p 7654:7654 -p 7650:7650 -d meeh/i2pd`
|
||||
|
||||
All the ports ( -p HOSTPORT:DOCKERPORT ) is optional. However the command above enable all features (Webconsole, HTTP Proxy, BOB, SAM, i2cp, etc)
|
||||
|
||||
The volume ( -v HOSTDIR:DOCKERDIR ) is also optional, but if you don't use it, your config, routerid and private keys will die along with the container.
|
||||
|
||||
**Options**
|
||||
|
||||
Options are set via docker environment variables. This can be set at run with -e parameters.
|
||||
|
||||
* **ENABLE_IPV6** - Enable IPv6 support. Any value can be used - it triggers as long as it's not empty.
|
||||
* **LOGLEVEL** - Set the loglevel.
|
||||
* **ENABLE_AUTH** - Enable auth for the webconsole. Username and password needs to be set manually in i2pd.conf cause security reasons.
|
||||
|
||||
**Logging**
|
||||
|
||||
Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :)
|
||||
|
||||
|
||||
|
11
build/docker/old-ubuntu-based/Dockerfile
Normal file
11
build/docker/old-ubuntu-based/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
|||
FROM ubuntu
|
||||
|
||||
RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \
|
||||
libboost-program-options-dev libboost-date-time-dev \
|
||||
libssl-dev git build-essential
|
||||
|
||||
RUN git clone https://github.com/PurpleI2P/i2pd.git
|
||||
WORKDIR /i2pd
|
||||
RUN make
|
||||
|
||||
CMD ./i2pd
|
2
build/fig.yml
Normal file
2
build/fig.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
i2pd:
|
||||
build: .
|
|
@ -1,37 +1,30 @@
|
|||
#define I2Pd_AppName "i2pd"
|
||||
#define I2Pd_Publisher "PurpleI2P"
|
||||
; Get application version from compiled binary
|
||||
; Disabled to use definition from command line
|
||||
;#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe")
|
||||
|
||||
[Setup]
|
||||
AppName={#I2Pd_AppName}
|
||||
AppVersion={#I2Pd_TextVer}
|
||||
AppVersion={#I2Pd_ver}
|
||||
AppPublisher={#I2Pd_Publisher}
|
||||
|
||||
DefaultDirName={pf}\I2Pd
|
||||
DefaultGroupName=I2Pd
|
||||
UninstallDisplayIcon={app}\I2Pd.exe
|
||||
OutputDir=.
|
||||
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_TextVer}
|
||||
|
||||
LicenseFile=..\LICENSE
|
||||
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
|
||||
SetupIconFile=..\Win32\mask.ico
|
||||
|
||||
InternalCompressLevel=ultra64
|
||||
Compression=lzma/ultra64
|
||||
SolidCompression=true
|
||||
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
ExtraDiskSpaceRequired=15
|
||||
|
||||
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
||||
AppVerName={#I2Pd_AppName}
|
||||
AppCopyright=Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
ExtraDiskSpaceRequired=15
|
||||
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
||||
AppPublisherURL=http://i2pd.website/
|
||||
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
|
||||
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
|
||||
|
||||
VersionInfoProductVersion={#I2Pd_Ver}
|
||||
VersionInfoVersion={#I2Pd_Ver}
|
||||
|
||||
CloseApplications=yes
|
||||
|
||||
[Files]
|
||||
|
@ -44,7 +37,6 @@ Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyif
|
|||
Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||
Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||
Source: ..\contrib\tunnels.d\*; DestDir: {userappdata}\i2pd\tunnels.d; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||
Source: ..\contrib\webconsole\*; DestDir: {userappdata}\i2pd\webconsole; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||
|
||||
[Icons]
|
||||
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
|
||||
|
|
2
contrib/android_binary_pack/.gitignore
vendored
Normal file
2
contrib/android_binary_pack/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
archive
|
||||
i2pd_*_android_binary.zip
|
45
contrib/android_binary_pack/build-archive
Executable file
45
contrib/android_binary_pack/build-archive
Executable file
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
#
|
||||
# This file is part of Purple i2pd project and licensed under BSD3
|
||||
#
|
||||
# See full license text in LICENSE file at top of project tree
|
||||
|
||||
GITDESC=$(git describe --tags)
|
||||
|
||||
declare -A ABILIST=(
|
||||
["armeabi-v7a"]="armv7l"
|
||||
["arm64-v8a"]="aarch64"
|
||||
["x86"]="x86"
|
||||
["x86_64"]="x86_64"
|
||||
)
|
||||
|
||||
# Remove old files and archives
|
||||
if [ -d archive ]; then
|
||||
rm -r archive
|
||||
fi
|
||||
|
||||
if [ -f i2pd_*_android_binary.zip ]; then
|
||||
rm i2pd_*_android_binary.zip
|
||||
fi
|
||||
|
||||
# Prepare files for package
|
||||
mkdir archive
|
||||
|
||||
for ABI in "${!ABILIST[@]}"; do
|
||||
if [ -f ../../android_binary_only/libs/${ABI}/i2pd ]; then
|
||||
cp ../../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
|
||||
fi
|
||||
done
|
||||
|
||||
cp i2pd archive/i2pd
|
||||
cp -rH ../../android/assets/* archive/
|
||||
|
||||
# Compress files
|
||||
cd archive
|
||||
zip -r6 ../i2pd_${GITDESC}_android_binary.zip .
|
||||
|
||||
# Remove temporary folder
|
||||
cd ..
|
||||
rm -r archive
|
33
contrib/android_binary_pack/i2pd
Executable file
33
contrib/android_binary_pack/i2pd
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
#
|
||||
# This file is part of Purple i2pd project and licensed under BSD3
|
||||
#
|
||||
# See full license text in LICENSE file at top of project tree
|
||||
#
|
||||
# That script written for use with Termux.
|
||||
|
||||
# https://stackoverflow.com/a/246128
|
||||
SOURCE="${0}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
arch=$(uname -m)
|
||||
|
||||
screenfind=$(which screen)
|
||||
if [ -z $screenfind ]; then
|
||||
echo "Can't find 'screen' installed. That script needs it!";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [ -z i2pd-$arch ]; then
|
||||
echo "Can't find i2pd binary for your archtecture.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR
|
|
@ -1,42 +0,0 @@
|
|||
# _________________________________________
|
||||
# / Copy this file to the right location \
|
||||
# | then load with: |
|
||||
# | |
|
||||
# | apparmor_parser -r -W |
|
||||
# | /etc/apparmor.d/docker-i2pd |
|
||||
# | |
|
||||
# | docker run --security-opt |
|
||||
# | "apparmor=docker-i2pd" ... |
|
||||
# | purplei2p/i2pd |
|
||||
# | |
|
||||
# \ And "aa-status" to verify it's loaded. /
|
||||
# -----------------------------------------
|
||||
# \ ^__^
|
||||
# \ (oo)\_______
|
||||
# (__)\ )\/\
|
||||
# ||----w |
|
||||
# || ||
|
||||
|
||||
#include <tunables/global>
|
||||
|
||||
profile docker-i2pd flags=(attach_disconnected,mediate_deleted) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/openssl>
|
||||
#include <abstractions/nameservice>
|
||||
|
||||
/bin/busybox ix,
|
||||
/usr/local/bin/i2pd ix,
|
||||
/entrypoint.sh ixr,
|
||||
|
||||
/i2pd_certificates/** r,
|
||||
|
||||
/home/i2pd/data/** rw,
|
||||
|
||||
/home/i2pd/data/i2pd.pid k,
|
||||
|
||||
deny /home/i2pd/data/i2pd.conf w,
|
||||
deny /home/i2pd/data/tunnels.conf w,
|
||||
deny /home/i2pd/data/tunnels.d/** w,
|
||||
deny /home/i2pd/data/certificates/** w,
|
||||
deny /home/i2pd/data/i2pd.log r,
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
#include <tunables/global>
|
||||
|
||||
profile i2pd /{usr/,}bin/i2pd {
|
||||
profile i2pd /{usr/,}sbin/i2pd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/openssl>
|
||||
#include <abstractions/nameservice>
|
||||
|
@ -14,12 +14,12 @@ profile i2pd /{usr/,}bin/i2pd {
|
|||
/var/lib/i2pd/** rw,
|
||||
/var/log/i2pd/i2pd.log w,
|
||||
/{var/,}run/i2pd/i2pd.pid rwk,
|
||||
/{usr/,}bin/i2pd mr,
|
||||
/{usr/,}sbin/i2pd mr,
|
||||
@{system_share_dirs}/i2pd/** r,
|
||||
|
||||
# user homedir (if started not by init.d or systemd)
|
||||
owner @{HOME}/.i2pd/ rw,
|
||||
owner @{HOME}/.i2pd/** rwk,
|
||||
|
||||
#include if exists <local/usr.bin.i2pd>
|
||||
#include if exists <local/usr.sbin.i2pd>
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICKDCCAc6gAwIBAgIUcPHZXtYSqGNRCD6z8gp79WUFtI0wCgYIKoZIzj0EAwIw
|
||||
gZMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGlu
|
||||
MRgwFgYDVQQKDA9TdG9ybXlDbG91ZCBJbmMxIzAhBgNVBAMMGnN0b3JteWNsb3Vk
|
||||
LmZhbWlseS5pMnAubmV0MSQwIgYJKoZIhvcNAQkBFhVhZG1pbkBzdG9ybXljbG91
|
||||
ZC5vcmcwHhcNMjIwMzE5MTU1MjU2WhcNMzIwMzE2MTU1MjU2WjCBkzELMAkGA1UE
|
||||
BhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xGDAWBgNVBAoM
|
||||
D1N0b3JteUNsb3VkIEluYzEjMCEGA1UEAwwac3Rvcm15Y2xvdWQuZmFtaWx5Lmky
|
||||
cC5uZXQxJDAiBgkqhkiG9w0BCQEWFWFkbWluQHN0b3JteWNsb3VkLm9yZzBZMBMG
|
||||
ByqGSM49AgEGCCqGSM49AwEHA0IABFUli0hvJEmowNjJVjbKEIWBJhqe973S4VdL
|
||||
cJuA5yY3dC4Y998abWEox7/Y1BhnBbpJuiodA341bXKkLMXQy/kwCgYIKoZIzj0E
|
||||
AwIDSAAwRQIgD12F/TfY3iV1/WDF7BSKgbD5g2MfELUIy1dtUlJQuJUCIQD69mZw
|
||||
V1Z9j2x0ZsuirS3i6AMfVyTDj0RFS3U1jeHzIQ==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,32 +0,0 @@
|
|||
-----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,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIF1zCCA7+gAwIBAgIRAMDqFR09Xuj8ZUu+oetSvAEwDQYJKoZIhvcNAQELBQAw
|
||||
dTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
|
||||
ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxHjAcBgNVBAMM
|
||||
FWFkbWluQHN0b3JteWNsb3VkLm9yZzAeFw0yNDAxMjUxNDE1MzBaFw0zNDAxMjUx
|
||||
NDE1MzBaMHUxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx
|
||||
HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR4w
|
||||
HAYDVQQDDBVhZG1pbkBzdG9ybXljbG91ZC5vcmcwggIiMA0GCSqGSIb3DQEBAQUA
|
||||
A4ICDwAwggIKAoICAQDbGX+GikPzQXr9zvkrhfO9g0l49KHLNQhUKYqd6T+PfnGo
|
||||
Fm0d3ZZVVQZ045vWgroOXDGGZZWxUIlb2inRaR2DF1TxN3pPYt59RgY9ZQ9+TL7o
|
||||
isY91krCRygY8EcAmHIjlfZQ9dBVcL7CfyT0MYZA5Efee9+NDHSewTfQP9T2faIE
|
||||
83Fcyd93a2mIHYjKUbJnojng/wgsy8srbsEuuTok4MIQmDj+B5nz+za2FgI0/ydh
|
||||
srlMt4aGJF4/DIem9z9d0zBCOkwrmtFIzjNF1mOSA8ES4m5YnKA/y9rZlRidLPGu
|
||||
prbXhPVnqHeOnHMz2QCw1wbVo504kl0bMqyEz2tVWsO9ep7iZoQs2xkFAEaegYNT
|
||||
QLUpwVGlyuq3wXXwopFRffOSimGSazICwWI6j+K0pOtgefNJaWrqKYvtkj1SbK2L
|
||||
LBNUIENz6VnB7KPRckuX6zxC8PpOiBK9BcftfO+xAz/wC6qq3riBPw30KKSym0nC
|
||||
Zp5KciDn4Phtw9PGq8Bkl8SyWl0jtFnfTB1tzJkisf2qKcNHaFTEe2JW763YLbh/
|
||||
AU+8X8evFu40qLgvOgKoyy5DLy6i8zetX+3t9K0Fxt9+Vzzq6lm5V/RS8iIPPn+M
|
||||
q1/3Z5kD0KQBG9h/Gl8BH+lB71ZxPAOZ3SMu8DJZcxBLVmDWqQPCr5CKnoz0swID
|
||||
AQABo2IwYDAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG
|
||||
AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHgYDVR0OBBcEFWFkbWluQHN0b3JteWNs
|
||||
b3VkLm9yZzANBgkqhkiG9w0BAQsFAAOCAgEARWOJ69vTHMneSXYscha+4Ytjg0RM
|
||||
faewJNEGj8qy/Qvh9si2bWYNPRK6BlbHFS7pRYBLAnhaeLBGVv1CCR6GUMMe74zQ
|
||||
UuMeAoWU6qMDmB3GfYoZJh8sIxpwHqyJeTdeccRbZ4sX4F6u3IHPXYiU/AgbYqH7
|
||||
pYXQg2lCjXZYaDFAlEf5SlYUDOhhXe5kR8Edhlrsu32/JzA1DQK0JjxKCBp+DQmA
|
||||
ltdOpQtAg03fHP4ssdj7VvjIDl28iIlATwBvHrdNm7T0tYWn6TWhvxbRqvfTxfaH
|
||||
MvxnPdIJwNP4/9TyQkwjwHb1h+ucho3CnxI/AxspdOvT1ElMhP6Ce6rcS9pk11Rl
|
||||
x0ChsqpWwDg7KYpg0qZFSKCTBp4zBq9xoMJ6BQcgMfyl736WbsCzFTEyfifp8beg
|
||||
NxUa/Qk7w7cuSPGyMIKNOmOR7FLlFbtocy8sXVsUQdqnp/edelufdNe39U9uNtY6
|
||||
yoXI9//Tc6NgOwy2Oyia0slZ5qHRkB7e4USXMRzJ3p4q9eCVKjAJs81Utp7O2U+9
|
||||
vhbhwWP8CAnNTT1E5WS6EKtfrdqF7wjkV+noPGLDGmrXi01J1fSMAjMfVO+7/LOL
|
||||
UN+G4ybKWnEhhOO27yidN8Xx6UrCS23DBlPPQAeA74dTsTExiOxf1o1EXzcQiMyO
|
||||
LAj3/Ojbi1xkWhI=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIF2TCCA8GgAwIBAgIQIHQPtSoFU+cUpYD8PZaWZjANBgkqhkiG9w0BAQsFADB2
|
||||
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
||||
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEfMB0GA1UEAwwW
|
||||
YXJuYXZiaGF0dDI4OEBtYWlsLmkycDAeFw0yMzAxMjUxODUzNDFaFw0zMzAxMjUx
|
||||
ODUzNDFaMHYxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx
|
||||
HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR8w
|
||||
HQYDVQQDDBZhcm5hdmJoYXR0Mjg4QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAg8AMIICCgKCAgEAtwG73sC0jYd3fgEzZh0SveAdUd5yD35nINJRrdPSrSwY
|
||||
n3i1qGe3fNLj877PvUDU+qiHH0fFZfyFkXTaq3TUp1u4YkmvaoPHy6FZlojB08lK
|
||||
FBm+iJ1hifQ7MFmvIKUGv+cjlN6xSoQ0U6B2QOy6iZnBgFZ/7jbRY4iZOIj7VJtY
|
||||
aodeHfy0bWe447VJovbkUi7NJPFZQS65LMcAIWcWTxrC0Gj8SmdxL3a5+hxpmmg0
|
||||
+KCQvWQDdxAQjsc16sgUCdUc6cWYO4yw9H6fgdq9GJX+LnXR9OB58GsAjjlLlFoI
|
||||
CZxdARDpoqcIj6AoKIanALf8yfbIyrqqJE47cuaqV9bht5MWKnXbwHplEkT4ZNkh
|
||||
PnRDia7B5HY3uwbt39CBm264PEWXvWG2sozTWKQqBjmMN2cj/NFDUEqKv6BggMY1
|
||||
HcqxWFKRcgKCtRvrmTmfp5l0/ou+OtUaFUg0a6Qhtb93Hj10vK6wZzidBqj0ggzB
|
||||
eJDI95b89u8JgzRoOBriuMKTc91WTkOvBLkB3dgUbUpx2p8KHjvf/pppBH9u0oxp
|
||||
qJFFK840DbnJydEvjKezeVe5Ax6YRSRxyEdKzRoWdvKVxb3qBBKMdCKTYEPxHPBu
|
||||
JMEQVUCXJMti++1KEiQGhcfWvLyT7OewbcIZNk9XWNrxlKcGrTp9AOwaaNC5m1kC
|
||||
AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr
|
||||
BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB8GA1UdDgQYBBZhcm5hdmJoYXR0Mjg4
|
||||
QG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAHiK0ld/1PF9DIhutD660/bzBg
|
||||
mF2Z76hcBqDZ8tnQai/u/RXYrH9wso9BYyrVsvk3fr6tpGT49Ian0MVpPOxMoTU2
|
||||
oBEmQlYrfclQLFsOLmA0y2r1ggXzIrt69jB710Vhwdnz09oOE8rS4E2T5oDD8Wvy
|
||||
Kony+AarRceqtkOlzyquc42KjzdrbHsosF7G2iGhNI6t+T3BfWJ+Q+d5sj3OIh6e
|
||||
gSfvHL44E4vZt6dtofRN3MAZ60kNLF5YWyaUo3Snv9Lso1IwIz3AVr5ehv+8sFL/
|
||||
KxaXdkZ5Yn2YUX7p1t4VQd+eXVPYjf1befg4PvrwSkylu3Jpee3fllZSKXeSVx9x
|
||||
jpJiq5vIakqk22pnWb1Vn7xzSW1vtEG7QLjobOr1WrcGiwdv+HKiWcXJXDzKoWXs
|
||||
h3VEfr51Kap8cIJv+D6lJIG9IcIhiQ6CXWBmtjWJvbdVwFBy1/3Fhaou9liHi+gK
|
||||
4Yh5a5OGCzc7xjtpGaTmoLEz7NzDNOdd/r840qRDOh70izzmFZd5Gwq4hoVcPJcS
|
||||
EAySwtgqK0/4d0zDd2Wg9ASJV9DnDf8QuSmHZgZ9Efs47XcWz9TvkWUS1E66AJsN
|
||||
mmI1NDQ3mv3dv5+WPq+dqqYFsnx3xWL1g5Z3buk0opeuXMzoHwM7UfN8h7Q1M5+t
|
||||
+XBgkaYA4iEwYKqlCQ==
|
||||
-----END CERTIFICATE-----
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue