Compare commits

..

2 Commits

Author SHA1 Message Date
R4SAS
58e351f5d9 use 15s average bw for transit limits check
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-12-12 18:22:16 +03:00
R4SAS
2a01ad953c calculate bandwidth every 1 and 15 seconds
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2022-12-12 08:12:23 +03:00
220 changed files with 7374 additions and 14731 deletions

View File

@@ -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

View File

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

View File

@@ -1,37 +1,16 @@
name: Build on FreeBSD name: Build on FreeBSD
on: on: [push, pull_request]
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: jobs:
build: build:
runs-on: ubuntu-latest runs-on: macos-12
name: with UPnP name: with UPnP
steps: steps:
- name: Checkout - uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Test in FreeBSD - name: Test in FreeBSD
id: test id: test
uses: vmactions/freebsd-vm@v1 uses: vmactions/freebsd-vm@v0.3.0
with: with:
usesh: true usesh: true
mem: 2048 mem: 2048
@@ -42,9 +21,8 @@ jobs:
cd build cd build
cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
gmake -j2 gmake -j2
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v2
with: with:
name: i2pd-freebsd name: i2pd-freebsd
path: build/i2pd path: build/i2pd

View File

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

View File

@@ -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.*

View File

@@ -1,25 +1,6 @@
name: Build on Windows name: Build on Windows
on: on: [push, pull_request]
push:
branches:
- '*'
paths:
- .github/workflows/build-windows.yml
- build/CMakeLists.txt
- build/cmake_modules/**
- daemon/**
- i18n/**
- libi2pd/**
- libi2pd_client/**
- Win32/**
- Makefile
- Makefile.mingw
tags:
- '*'
pull_request:
branches:
- '*'
defaults: defaults:
run: run:
@@ -27,220 +8,68 @@ defaults:
jobs: jobs:
build: build:
name: ${{ matrix.arch }} name: Building using ${{ matrix.arch }} toolchain
runs-on: windows-latest runs-on: windows-latest
strategy: strategy:
fail-fast: false fail-fast: true
matrix: matrix:
include: [ include: [
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc }, { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang }, { msystem: MINGW64, arch: x86_64, arch_short: x64 },
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc }, { msystem: MINGW32, arch: i686, arch_short: x86 }
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
] ]
steps: steps:
- name: Checkout - uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup MSYS2 - name: Setup MSYS2
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
with: with:
msystem: ${{ matrix.msystem }} 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 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: | run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3 make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v2
with: with:
name: i2pd-${{ matrix.arch_short }}.exe name: i2pd-${{ matrix.arch_short }}.exe
path: i2pd.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: build-xp:
name: XP name: Building for Windows XP
runs-on: windows-latest runs-on: windows-latest
strategy:
fail-fast: false
steps: steps:
- name: Checkout - uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup MSYS2 - name: Setup MSYS2
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
with: with:
msystem: MINGW32 msystem: MINGW32
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
cache: true
update: true update: true
- name: Build WinXP-capable CRT packages
- name: Clone MinGW packages repository and revert boost to 1.85.0
run: | run: |
git clone https://github.com/msys2/MINGW-packages git clone https://github.com/msys2/MINGW-packages
cd MINGW-packages pushd MINGW-packages
git checkout 4cbb366edf2f268ac3146174b40ce38604646fc5 mingw-w64-boost pushd mingw-w64-headers-git
# 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 sed -i 's/0x601/0x501/' PKGBUILD
MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
- name: Install headers package pacman --noconfirm -U mingw-w64-i686-headers-git-*-any.pkg.tar.zst
run: pacman --noconfirm -U MINGW-packages/mingw-w64-headers-git/mingw-w64-i686-*-any.pkg.tar.zst popd
pushd mingw-w64-crt-git
# CRT MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
- name: Get crt package version pacman --noconfirm -U mingw-w64-i686-crt-git-*-any.pkg.tar.zst
id: version-crt popd
run: | pushd mingw-w64-winpthreads-git
echo "version=$(pacman -Si mingw-w64-i686-crt-git | grep -Po '^Version\s*: \K.+')" >> $GITHUB_OUTPUT MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm
- name: Cache crt package pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
uses: actions/cache@v4 popd
id: cache-crt popd
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: Install boost package
run: pacman --noconfirm -U MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst
# Building i2pd
- name: Build application - name: Build application
run: | run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon 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 make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v2
with: with:
name: i2pd-xp.exe name: i2pd-xp.exe
path: i2pd.exe path: i2pd.exe

View File

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

View File

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

337
ChangeLog
View File

@@ -1,341 +1,6 @@
# for this file format description, # for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog # see https://github.com/olivierlacan/keep-a-changelog
## [2.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 ## [2.44.0] - 2022-11-20
### Added ### Added
- SSL connection for server I2P tunnels - SSL connection for server I2P tunnels
@@ -346,7 +11,7 @@
- SSU2 send and verify path challenge - SSU2 send and verify path challenge
- Configurable ssu2.mtu4 and ssu2.mtu6 - Configurable ssu2.mtu4 and ssu2.mtu6
### Changed ### Changed
- SSU2 is enabled and SSU is disabled by default - SSU2 is enbaled and SSU is disabled by default
- Separate network status and error - Separate network status and error
- Random selection between NTCP2 and SSU2 priority - Random selection between NTCP2 and SSU2 priority
- Added notbob.i2p to jump services - Added notbob.i2p to jump services

View File

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

View File

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

View File

@@ -1,22 +1,12 @@
CXX = clang++ CXX = clang++
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation 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 = -lcrypto -lssl -lz -lpthread -lboost_system -lboost_program_options
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time ## 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. ## **without** overwriting the CXXFLAGS which we need in order to build.
## For example, when adding 'hardening flags' to the 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 ## (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 ## -std=c++11. If you want to remove this variable please do so in a way that allows setting
## custom FLAGS to work at build-time. ## custom FLAGS to work at build-time.
CXXVER := $(shell $(CXX) -dumpversion|cut -c 1-2) NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
ifeq (${CXXVER}, "4.") # older clang always returned 4.2.1 INCFLAGS = -I/usr/include/ -I/usr/local/include/
$(error Compiler too old) LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
else ifeq (${CXXVER}, ${filter ${CXXVER},16 17 18 19}) # clang 16 - 19 LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
NEEDED_CXXFLAGS = -std=c++20
else
NEEDED_CXXFLAGS = -std=c++17
endif

View File

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

View File

@@ -1,40 +1,41 @@
# root directory holding homebrew # root directory holding homebrew
BREWROOT = /opt/homebrew BREWROOT = /usr/local
BOOSTROOT = ${BREWROOT}/opt/boost BOOSTROOT = ${BREWROOT}/opt/boost
SSLROOT = ${BREWROOT}/opt/openssl@1.1 SSLROOT = ${BREWROOT}/opt/openssl@1.1
UPNPROOT = ${BREWROOT}/opt/miniupnpc 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 ifndef TRAVIS
NEEDED_CXXFLAGS ?= -std=c++17 CXX = clang++
INCFLAGS ?= -I${SSLROOT}/include -I${BOOSTROOT}/include endif
LDFLAGS ?= ${LD_DEBUG}
DEFINES += -DMAC_OSX
ifeq ($(USE_STATIC),yes) 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 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
ifeq ($(USE_UPNP),yes)
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
endif
LDLIBS += -lpthread -ldl
else else
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_filesystem -lboost_program_options -lpthread LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
ifeq ($(USE_UPNP),yes)
LDFLAGS += -L${UPNPROOT}/lib
LDLIBS += -lminiupnpc
endif
endif endif
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
DEFINES += -DUSE_UPNP LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
INCFLAGS += -I${UPNPROOT}/include INCFLAGS += -I${UPNPROOT}/include
ifeq ($(USE_STATIC),yes)
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
else
LDFLAGS += -L${UPNPROOT}/lib
LDLIBS += -lminiupnpc
endif
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) ifeq ($(USE_AESNI),yes)
ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that CXXFLAGS += -D__AES__ -maes
NEEDED_CXXFLAGS += -maes
DEFINES += -D__AES__
endif
endif endif
install: all install: all

View File

@@ -9,20 +9,20 @@ LDFLAGS ?= ${LD_DEBUG}
## -std=c++11. If you want to remove this variable please do so in a way that allows setting ## -std=c++11. If you want to remove this variable please do so in a way that allows setting
## custom FDLAGS to work at build-time. ## 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) CXXVER := $(shell $(CXX) -dumpversion)
ifeq ($(shell expr match $(CXX) 'clang'),5) 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 NEEDED_CXXFLAGS += -std=c++17
else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 LDLIBS = -latomic
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -lboost_filesystem
else ifeq ($(shell expr match ${CXXVER} "[8-9]"),1) # gcc 8 - 9
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -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
else # not supported else # not supported
$(error Compiler too old) $(error Compiler too old)
endif endif
@@ -35,6 +35,8 @@ ifeq ($(USE_STATIC),yes)
# the shared libraries from the glibc version used for linking # the shared libraries from the glibc version used for linking
LIBDIR := /usr/lib/$(SYS) LIBDIR := /usr/lib/$(SYS)
LDLIBS += $(LIBDIR)/libboost_system.a LDLIBS += $(LIBDIR)/libboost_system.a
LDLIBS += $(LIBDIR)/libboost_date_time.a
LDLIBS += $(LIBDIR)/libboost_filesystem.a
LDLIBS += $(LIBDIR)/libboost_program_options.a LDLIBS += $(LIBDIR)/libboost_program_options.a
LDLIBS += $(LIBDIR)/libssl.a LDLIBS += $(LIBDIR)/libssl.a
LDLIBS += $(LIBDIR)/libcrypto.a LDLIBS += $(LIBDIR)/libcrypto.a
@@ -44,7 +46,7 @@ ifeq ($(USE_UPNP),yes)
endif endif
LDLIBS += -lpthread -ldl LDLIBS += -lpthread -ldl
else else
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_program_options -lpthread -latomic LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
LDLIBS += -lminiupnpc LDLIBS += -lminiupnpc
endif endif
@@ -52,13 +54,12 @@ endif
# UPNP Support (miniupnpc 1.5 and higher) # UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
DEFINES += -DUSE_UPNP NEEDED_CXXFLAGS += -DUSE_UPNP
endif endif
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),yes)
ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that
NEEDED_CXXFLAGS += -maes NEEDED_CXXFLAGS += -D__AES__ -maes
DEFINES += -D__AES__
endif endif
endif endif

View File

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

View File

@@ -1,20 +1,20 @@
CXX = clang++ CXX = clang++
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++17 CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
INCFLAGS = -I/usr/local/include INCFLAGS = -I/usr/local/include
DEFINES := -DMAC_OSX
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDFLAGS += -Wl,-dead_strip LDFLAGS += -Wl,-dead_strip
LDFLAGS += -Wl,-dead_strip_dylibs LDFLAGS += -Wl,-dead_strip_dylibs
LDFLAGS += -Wl,-bind_at_load
ifeq ($(USE_STATIC),yes) ifeq ($(USE_STATIC),yes)
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_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 else
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_filesystem -lboost_program_options -lpthread LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif endif
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl LDFLAGS += -ldl
DEFINES += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes) ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a LDLIBS += /usr/local/lib/libminiupnpc.a
else else
@@ -22,12 +22,8 @@ ifeq ($(USE_UPNP),yes)
endif endif
endif endif
OSARCH = $(shell uname -p) ifeq ($(USE_AESNI),yes)
CXXFLAGS += -D__AES__ -maes
ifneq ($(OSARCH),powerpc) else
ifeq ($(USE_AESNI),yes) CXXFLAGS += -msse
CXXFLAGS += -D__AES__ -maes
else
CXXFLAGS += -msse
endif
endif endif

View File

@@ -69,12 +69,12 @@ Build instructions:
**Supported systems:** **Supported systems:**
* GNU/Linux (Debian, Ubuntu, etc) - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml) * GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
* CentOS, Fedora, Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
* Alpine, ArchLinux, openSUSE, Gentoo, etc. * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml) * Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
* Mac OS - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml) * Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
* Docker image - [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml) * Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd) * Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml) * FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml) * Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
@@ -99,23 +99,13 @@ Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](http
Donations Donations
--------- ---------
**E-Mail**: ```i2porignal at yandex.com``` BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
**BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f``` ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
**LTC**: ```LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59``` ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
**ETH**: ```0x9e5bac70d20d1079ceaa111127f4fb3bccce379d``` XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH
**GST**: ```GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG```
**DASH**: ```Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF```
**ZEC**: ```t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ```
**ANC**: ```AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z```
**XMR**: ```497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH```
License License
------- -------

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2023, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -29,7 +29,7 @@ namespace util
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
SetConsoleCP(1251); SetConsoleCP(1251);
SetConsoleOutputCP(1251); SetConsoleOutputCP(1251);
//setlocale(LC_ALL, "Russian"); setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C"); setlocale(LC_TIME, "C");
i2p::log::SetThrowFunction ([](const std::string& s) i2p::log::SetThrowFunction ([](const std::string& s)
@@ -47,7 +47,7 @@ namespace util
I2PService service((PSTR)SERVICE_NAME); I2PService service((PSTR)SERVICE_NAME);
if (!I2PService::Run(service)) 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;
} }
return false; return false;
@@ -61,10 +61,10 @@ namespace util
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
SetConsoleCP(1251); SetConsoleCP(1251);
SetConsoleOutputCP(1251); SetConsoleOutputCP(1251);
//setlocale(LC_ALL, "Russian"); setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C"); setlocale(LC_TIME, "C");
#ifdef WIN32_APP #ifdef WIN32_APP
if (!i2p::win32::StartWin32App (isDaemon)) return false; if (!i2p::win32::StartWin32App ()) return false;
#endif #endif
bool ret = Daemon_Singleton::start(); bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile) if (ret && i2p::log::Logger().GetLogType() == eLogFile)

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -15,7 +15,6 @@ IUnknown *pUnknown = nullptr;
INetworkListManager *pNetworkListManager = nullptr; INetworkListManager *pNetworkListManager = nullptr;
IConnectionPointContainer *pCPContainer = nullptr; IConnectionPointContainer *pCPContainer = nullptr;
IConnectionPoint *pConnectPoint = nullptr; IConnectionPoint *pConnectPoint = nullptr;
CNetworkListManagerEvent *pNetEvent = nullptr;
DWORD Cookie = 0; DWORD Cookie = 0;
void SubscribeToEvents() void SubscribeToEvents()
@@ -30,11 +29,7 @@ void SubscribeToEvents()
if (SUCCEEDED(Result)) if (SUCCEEDED(Result))
{ {
VARIANT_BOOL IsConnect = VARIANT_FALSE; VARIANT_BOOL IsConnect = VARIANT_FALSE;
#if defined(_MSC_VER)
Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
#else
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect); Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
#endif
if (SUCCEEDED(Result)) { if (SUCCEEDED(Result)) {
i2p::transport::transports.SetOnline (true); 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");
@@ -46,8 +41,8 @@ void SubscribeToEvents()
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint); Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
if(SUCCEEDED(Result)) if(SUCCEEDED(Result))
{ {
pNetEvent = new CNetworkListManagerEvent; CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie); Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
if (SUCCEEDED(Result)) if (SUCCEEDED(Result))
LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages"); LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages");
else else
@@ -64,7 +59,6 @@ void SubscribeToEvents()
void UnSubscribeFromEvents() void UnSubscribeFromEvents()
{ {
LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
try try
{ {
if (pConnectPoint) { if (pConnectPoint) {
@@ -72,25 +66,14 @@ void UnSubscribeFromEvents()
pConnectPoint->Release(); pConnectPoint->Release();
} }
if (pNetEvent)
{
pNetEvent->Release();
}
if (pCPContainer) if (pCPContainer)
{
pCPContainer->Release(); pCPContainer->Release();
}
if (pNetworkListManager) if (pNetworkListManager)
{
pNetworkListManager->Release(); pNetworkListManager->Release();
}
if (pUnknown) if (pUnknown)
{
pUnknown->Release(); pUnknown->Release();
}
CoUninitialize(); CoUninitialize();
} }

View File

@@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -15,7 +15,7 @@
#include "Log.h" #include "Log.h"
#include "Transports.h" #include "Transports.h"
class CNetworkListManagerEvent final : public INetworkListManagerEvents class CNetworkListManagerEvent : public INetworkListManagerEvents
{ {
public: public:
CNetworkListManagerEvent() : m_ref(1) { } CNetworkListManagerEvent() : m_ref(1) { }
@@ -23,15 +23,17 @@ public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
{ {
HRESULT Result = S_OK;
if (IsEqualIID(riid, IID_IUnknown)) { if (IsEqualIID(riid, IID_IUnknown)) {
*ppvObject = (IUnknown *)this; *ppvObject = (IUnknown *)this;
} else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) { } else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) {
*ppvObject = (INetworkListManagerEvents *)this; *ppvObject = (INetworkListManagerEvents *)this;
} else { } else {
return E_NOINTERFACE; Result = E_NOINTERFACE;
} }
AddRef(); AddRef();
return S_OK;
return Result;
} }
ULONG STDMETHODCALLTYPE AddRef() ULONG STDMETHODCALLTYPE AddRef()

View File

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

BIN
Win32/mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

14
build/.gitignore vendored
View File

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

View File

@@ -1,32 +1,14 @@
cmake_minimum_required(VERSION 3.7) cmake_minimum_required(VERSION 3.7)
cmake_policy(VERSION 3.7)
if(${CMAKE_VERSION} VERSION_LESS 3.22) project("i2pd")
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.22)
endif()
# for debugging # for debugging
#set(CMAKE_VERBOSE_MAKEFILE on) #set(CMAKE_VERBOSE_MAKEFILE on)
# paths # Win32 build with cmake is not supported
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") if(WIN32 OR MSVC OR MSYS OR MINGW)
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
endif()
set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client)
set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n)
set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon)
include(Version)
set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION)
project(
i2pd
VERSION ${PROJECT_VERSION}
HOMEPAGE_URL "https://i2pd.website/"
LANGUAGES C CXX
)
# configurable options # configurable options
option(WITH_AESNI "Use AES-NI instructions set" ON) option(WITH_AESNI "Use AES-NI instructions set" ON)
@@ -38,28 +20,28 @@ option(WITH_UPNP "Include support for UPnP client" OFF)
option(WITH_GIT_VERSION "Use git commit info as version" OFF) option(WITH_GIT_VERSION "Use git commit info as version" OFF)
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
option(BUILD_TESTING "Build tests" OFF)
IF(BUILD_TESTING) # paths
enable_testing() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
ENDIF() set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
# Handle paths nicely #Handle paths nicely
include(GNUInstallDirs) include(GNUInstallDirs)
# Architecture # architecture
include(TargetArch) include(TargetArch)
target_architecture(ARCHITECTURE) target_architecture(ARCHITECTURE)
include(CheckAtomic) set(LIBI2PD_SRC_DIR ../libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
if(WITH_STATIC) set(LANG_SRC_DIR ../i18n)
if(MSVC) set(DAEMON_SRC_DIR ../daemon)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
include_directories(${LIBI2PD_SRC_DIR}) include_directories(${LIBI2PD_SRC_DIR})
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
include_directories(${LANG_SRC_DIR})
include_directories(${DAEMON_SRC_DIR})
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp) FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
add_library(libi2pd ${LIBI2PD_SRC}) add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES PREFIX "") set_target_properties(libi2pd PROPERTIES PREFIX "")
@@ -70,9 +52,11 @@ if(WITH_LIBRARY)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries) 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() endif()
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp) FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
add_library(libi2pdclient ${CLIENT_SRC}) add_library(libi2pdclient ${CLIENT_SRC})
set_target_properties(libi2pdclient PROPERTIES PREFIX "") set_target_properties(libi2pdclient PROPERTIES PREFIX "")
@@ -85,7 +69,6 @@ if(WITH_LIBRARY)
COMPONENT Libraries) COMPONENT Libraries)
endif() endif()
include_directories(${LANG_SRC_DIR})
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp) FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
add_library(libi2pdlang ${LANG_SRC}) add_library(libi2pdlang ${LANG_SRC})
set_target_properties(libi2pdlang PROPERTIES PREFIX "") set_target_properties(libi2pdlang PROPERTIES PREFIX "")
@@ -98,8 +81,6 @@ if(WITH_LIBRARY)
COMPONENT Libraries) COMPONENT Libraries)
endif() endif()
include_directories(${DAEMON_SRC_DIR})
set(DAEMON_SRC set(DAEMON_SRC
"${DAEMON_SRC_DIR}/Daemon.cpp" "${DAEMON_SRC_DIR}/Daemon.cpp"
"${DAEMON_SRC_DIR}/HTTPServer.cpp" "${DAEMON_SRC_DIR}/HTTPServer.cpp"
@@ -109,22 +90,6 @@ set(DAEMON_SRC
"${DAEMON_SRC_DIR}/UPnP.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")
endif()
if(WITH_UPNP) if(WITH_UPNP)
add_definitions(-DUSE_UPNP) add_definitions(-DUSE_UPNP)
endif() endif()
@@ -132,30 +97,30 @@ endif()
if(WITH_GIT_VERSION) if(WITH_GIT_VERSION)
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
git_describe(GIT_VERSION) git_describe(GIT_VERSION)
add_definitions(-DGITVER=${GIT_VERSION}) add_definitions(-DGITVER="${GIT_VERSION}")
endif() endif()
if(APPLE) if(APPLE)
add_definitions(-DMAC_OSX) add_definitions(-DMAC_OSX)
endif() endif()
if(HAIKU) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
add_definitions(-D_DEFAULT_SOURCE -D_GNU_SOURCE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
endif() # 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(MSVC) # check for c++17 & c++11 support
add_definitions(-DWINVER=0x0600) include(CheckCXXCompilerFlag)
add_definitions(-D_WIN32_WINNT=0x0600) 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() else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized") message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
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
endif() endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -187,11 +152,8 @@ endif()
# Note: AES-NI and AVX is available on x86-based CPU's. # Note: AES-NI and AVX is available on x86-based CPU's.
# Here also ARM64 implementation, but currently we don't support it. # Here also ARM64 implementation, but currently we don't support it.
# MSVC is not supported due to different ASM processing, so we hope OpenSSL has its own checks to run optimized code.
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386")) if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
add_definitions(-D__AES__) add_definitions(-D__AES__)
endif() endif()
@@ -209,52 +171,23 @@ if(WITH_THREADSANITIZER)
endif() endif()
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: # Enable usage of STD's Atomic instead of Boost's on PowerPC
# For more information refer to: https://github.com/PurpleI2P/i2pd/issues/1726#issuecomment-1306335111 # 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(ARCHITECTURE MATCHES "ppc")
if(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
add_definitions(-DBOOST_SP_USE_STD_ATOMIC) add_definitions(-DBOOST_SP_USE_STD_ATOMIC)
endif() endif()
# libraries # libraries
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
if(WITH_STATIC) if(WITH_STATIC)
if(NOT MSVC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
endif()
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
if(MSVC) set(Boost_USE_STATIC_RUNTIME ON)
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(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) set(BUILD_SHARED_LIBS OFF)
if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
# set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive") # set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
@@ -264,23 +197,17 @@ else()
# TODO: Consider separate compilation for LIBI2PD_SRC for library. # TODO: Consider separate compilation for LIBI2PD_SRC for library.
# No need in -fPIC overhead for binary if not interested in library # No need in -fPIC overhead for binary if not interested in library
# HINT: revert c266cff CMakeLists.txt: compilation speed up # HINT: revert c266cff CMakeLists.txt: compilation speed up
if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
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()
endif() endif()
find_package(Boost REQUIRED COMPONENTS system filesystem program_options) find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
if(NOT DEFINED Boost_FOUND) if(NOT DEFINED Boost_INCLUDE_DIRS)
message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!") message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!")
endif() endif()
find_package(OpenSSL REQUIRED) 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!") message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!")
endif() endif()
@@ -302,29 +229,11 @@ if(ZLIB_FOUND)
link_directories(${ZLIB_ROOT}/lib) link_directories(${ZLIB_ROOT}/lib)
endif() 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 # load includes
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
include(CheckAtomic)
# show summary # show summary
message(STATUS "---------------------------------------") message(STATUS "---------------------------------------")
message(STATUS "Build type : ${CMAKE_BUILD_TYPE}") message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
@@ -332,7 +241,6 @@ message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}") message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}")
message(STATUS "Architecture : ${ARCHITECTURE}") message(STATUS "Architecture : ${ARCHITECTURE}")
message(STATUS "Compiler flags : ${CMAKE_CXX_FLAGS}")
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}") message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Options:") message(STATUS "Options:")
message(STATUS " AESNI : ${WITH_AESNI}") message(STATUS " AESNI : ${WITH_AESNI}")
@@ -341,34 +249,16 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}")
message(STATUS " BINARY : ${WITH_BINARY}") message(STATUS " BINARY : ${WITH_BINARY}")
message(STATUS " STATIC BUILD : ${WITH_STATIC}") message(STATUS " STATIC BUILD : ${WITH_STATIC}")
message(STATUS " UPnP : ${WITH_UPNP}") message(STATUS " UPnP : ${WITH_UPNP}")
if(WITH_GIT_VERSION)
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION} (${GIT_VERSION})")
else()
message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}") message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}")
endif()
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
message(STATUS "---------------------------------------") message(STATUS "---------------------------------------")
if(WITH_BINARY) if(WITH_BINARY)
if(WIN32) add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
add_executable("${PROJECT_NAME}" WIN32 ${DAEMON_SRC} ${WIN32_RC})
else()
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
endif()
if(WIN32)
list(APPEND MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi")
# OpenSSL may require Crypt32 library on MSVC build, which is not added by CMake lesser than 3.21
if(MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.21)
list(APPEND MINGW_EXTRA "crypt32")
endif()
endif()
if(WITH_STATIC) if(WITH_STATIC)
if(NOT MSVC) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
endif()
endif() endif()
if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -381,24 +271,13 @@ if(WITH_BINARY)
list(REMOVE_AT Boost_LIBRARIES -1) list(REMOVE_AT Boost_LIBRARIES -1)
endif() 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) if(WITH_STATIC)
set(DL_LIB ${CMAKE_DL_LIBS}) set(DL_LIB ${CMAKE_DL_LIBS})
endif() 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("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin") set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin")
endif() endif()
if(BUILD_TESTING)
add_subdirectory(${CMAKE_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/tests)
endif()

View File

@@ -1,23 +1,18 @@
# atomic builtins are required for threading support. # atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles) INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckLibraryExists)
# Sometimes linking against libatomic is required for atomic ops, if # Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics. # the platform doesn't support lock-free atomics.
function(check_working_cxx_atomics varname) function(check_working_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) 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(" CHECK_CXX_SOURCE_COMPILES("
#include <atomic> #include <atomic>
std::atomic<int> x; std::atomic<int> x;
std::atomic<short> y;
std::atomic<char> z;
int main() { int main() {
++z; return x;
++y;
return ++x;
} }
" ${varname}) " ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
@@ -25,14 +20,13 @@ endfunction(check_working_cxx_atomics)
function(check_working_cxx_atomics64 varname) function(check_working_cxx_atomics64 varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) 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(" CHECK_CXX_SOURCE_COMPILES("
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
std::atomic<uint64_t> x (0); std::atomic<uint64_t> x (0);
int main() { int main() {
uint64_t i = x.load(std::memory_order_relaxed); uint64_t i = x.load(std::memory_order_relaxed);
(void)i;
return 0; return 0;
} }
" ${varname}) " ${varname})
@@ -40,16 +34,15 @@ int main() {
endfunction(check_working_cxx_atomics64) endfunction(check_working_cxx_atomics64)
# Check for (non-64-bit) atomic operations. # This isn't necessary on MSVC, so avoid command-line switch annoyance
if(MSVC) # by only running on GCC-like hosts.
set(HAVE_CXX_ATOMICS_WITHOUT_LIB True) if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
else()
# First check if atomics work without the library. # First check if atomics work without the library.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it. # If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
if(HAVE_LIBATOMIC) if( HAVE_LIBATOMIC )
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB) if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
@@ -65,20 +58,20 @@ endif()
if(MSVC) if(MSVC)
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
else() else()
# First check if atomics work without the library.
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it. endif()
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) # If not, check if the library exists, and atomics work with it.
if(HAVE_CXX_LIBATOMICS64) if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) if(HAVE_CXX_LIBATOMICS64)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!") check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
endif() if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
else() message(FATAL_ERROR "Host compiler must support std::atomic!")
message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
endif() endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif() endif()
endif() endif()
@@ -87,6 +80,7 @@ endif()
## assumes C++11 <atomic> works. ## assumes C++11 <atomic> works.
CHECK_CXX_SOURCE_COMPILES(" CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER #ifdef _MSC_VER
#include <Intrin.h> /* Workaround for PR19898. */
#include <windows.h> #include <windows.h>
#endif #endif
int main() { int main() {

View File

@@ -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 )

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2017-2023, The PurpleI2P Project # Copyright (c) 2017-2022, The PurpleI2P Project
# This file is part of Purple i2pd project and licensed under BSD3 # This file is part of Purple i2pd project and licensed under BSD3
# See full license text in LICENSE file at top of project tree # See full license text in LICENSE file at top of project tree
@@ -18,7 +18,7 @@ set(archdetect_c_code "
|| defined(_M_ARM64) \\ || defined(_M_ARM64) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8) || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
#error cmake_ARCH arm64 #error cmake_ARCH arm64
#elif defined(__ARM_ARCH_7__) \\ #if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\ || defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\ || defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\ || defined(__ARM_ARCH_7M__) \\
@@ -83,13 +83,13 @@ function(target_architecture output_var)
# First let's normalize the order of the values # First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using # 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 # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default. Also, ppc64 is not supported in 10.6. # disable it by default
# See this page for more information: # 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 # 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. # 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}) foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support) if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
@@ -133,11 +133,11 @@ function(target_architecture output_var)
enable_language(C) enable_language(C)
# Detect the architecture in a rather creative way... # Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects # This compiles a small C program which is a series of ifdefs that selects a
# a particular #error preprocessor directive whose message string contains # particular #error preprocessor directive whose message string contains the
# the target architecture. The program will always fail to compile (both because # 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 # file is not a valid C program, and obviously because of the presence of the
# the #error preprocessor directives... but by exploiting the preprocessor in this # #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling, # 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) # since the program itself never needs to be run (only the compiler/preprocessor)
try_run( try_run(

View File

@@ -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()

View File

@@ -24,7 +24,7 @@ ExtraDiskSpaceRequired=15
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2} AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
AppVerName={#I2Pd_AppName} AppVerName={#I2Pd_AppName}
AppCopyright=Copyright (c) 2013-2024, The PurpleI2P Project AppCopyright=Copyright (c) 2013-2022, The PurpleI2P Project
AppPublisherURL=http://i2pd.website/ AppPublisherURL=http://i2pd.website/
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases

View File

@@ -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,
}

View File

@@ -4,7 +4,7 @@
# #
#include <tunables/global> #include <tunables/global>
profile i2pd /{usr/,}bin/i2pd { profile i2pd /{usr/,}sbin/i2pd {
#include <abstractions/base> #include <abstractions/base>
#include <abstractions/openssl> #include <abstractions/openssl>
#include <abstractions/nameservice> #include <abstractions/nameservice>
@@ -14,12 +14,12 @@ profile i2pd /{usr/,}bin/i2pd {
/var/lib/i2pd/** rw, /var/lib/i2pd/** rw,
/var/log/i2pd/i2pd.log w, /var/log/i2pd/i2pd.log w,
/{var/,}run/i2pd/i2pd.pid rwk, /{var/,}run/i2pd/i2pd.pid rwk,
/{usr/,}bin/i2pd mr, /{usr/,}sbin/i2pd mr,
@{system_share_dirs}/i2pd/** r, @{system_share_dirs}/i2pd/** r,
# user homedir (if started not by init.d or systemd) # user homedir (if started not by init.d or systemd)
owner @{HOME}/.i2pd/ rw, owner @{HOME}/.i2pd/ rw,
owner @{HOME}/.i2pd/** rwk, owner @{HOME}/.i2pd/** rwk,
#include if exists <local/usr.bin.i2pd> #include if exists <local/usr.sbin.i2pd>
} }

View File

@@ -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-----

View File

@@ -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-----

View File

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

View File

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

View File

@@ -1 +0,0 @@
11

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 11~), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 4.2.0
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

@@ -1 +0,0 @@
9

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

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

View File

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

View File

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

View File

@@ -1 +0,0 @@
9

View File

@@ -1,18 +0,0 @@
Source: i2pd
Section: net
Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.

View File

@@ -1,17 +0,0 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
-USE_UPNP := $(or $(USE_UPNP),no)
+USE_UPNP := $(or $(USE_UPNP),yes)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,13 +1,13 @@
# i2pd # i2pd
# Copyright (C) 2021-2023 PurpleI2P team # Copyright (C) 2021-2022 PurpleI2P team
# This file is distributed under the same license as the i2pd package. # This file is distributed under the same license as the i2pd package.
# R4SAS <r4sas@i2pmail.org>, 2021-2023. # R4SAS <r4sas@i2pmail.org>, 2021-2022.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: i2pd\n" "Project-Id-Version: i2pd\n"
"Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" "Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n"
"POT-Creation-Date: 2023-06-10 01:25\n" "POT-Creation-Date: 2022-07-26 21:22\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -18,73 +18,66 @@ msgstr ""
"X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n"
"X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n"
#: daemon/HTTPServer.cpp:107 #: daemon/HTTPServer.cpp:108
#, c-format msgid "day"
msgid "%d day" msgid_plural "days"
msgid_plural "%d days"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: daemon/HTTPServer.cpp:111 #: daemon/HTTPServer.cpp:112
#, c-format msgid "hour"
msgid "%d hour" msgid_plural "hours"
msgid_plural "%d hours"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: daemon/HTTPServer.cpp:115 #: daemon/HTTPServer.cpp:116
#, c-format msgid "minute"
msgid "%d minute" msgid_plural "minutes"
msgid_plural "%d minutes"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: daemon/HTTPServer.cpp:118 #: daemon/HTTPServer.cpp:119
#, c-format msgid "second"
msgid "%d second" msgid_plural "seconds"
msgid_plural "%d seconds"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. tr: Kibibyte #. tr: Kibibit
#: daemon/HTTPServer.cpp:126 #: daemon/HTTPServer.cpp:127 daemon/HTTPServer.cpp:155
#, c-format msgid "KiB"
msgid "%.2f KiB"
msgstr "" msgstr ""
#. tr: Mebibyte #. tr: Mebibit
#: daemon/HTTPServer.cpp:128 #: daemon/HTTPServer.cpp:129
#, c-format msgid "MiB"
msgid "%.2f MiB"
msgstr "" msgstr ""
#. tr: Gibibyte #. tr: Gibibit
#: daemon/HTTPServer.cpp:130 #: daemon/HTTPServer.cpp:131
#, c-format msgid "GiB"
msgid "%.2f GiB"
msgstr ""
#: daemon/HTTPServer.cpp:147
msgid "building"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:148 #: daemon/HTTPServer.cpp:148
msgid "failed" msgid "building"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:149 #: daemon/HTTPServer.cpp:149
msgid "expiring" msgid "failed"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:150 #: daemon/HTTPServer.cpp:150
msgid "established" msgid "expiring"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:151 #: daemon/HTTPServer.cpp:151
msgid "established"
msgstr ""
#: daemon/HTTPServer.cpp:152
msgid "unknown" msgid "unknown"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:153 #: daemon/HTTPServer.cpp:154
msgid "exploratory" msgid "exploratory"
msgstr "" msgstr ""
@@ -101,32 +94,32 @@ msgstr ""
msgid "Main page" msgid "Main page"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:742 #: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:700
msgid "Router commands" msgid "Router commands"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:395 #: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:382
#: daemon/HTTPServer.cpp:407 #: daemon/HTTPServer.cpp:394
msgid "Local Destinations" msgid "Local Destinations"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:365 #: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:352
#: daemon/HTTPServer.cpp:454 daemon/HTTPServer.cpp:474 #: daemon/HTTPServer.cpp:438 daemon/HTTPServer.cpp:444
#: daemon/HTTPServer.cpp:636 daemon/HTTPServer.cpp:682 #: daemon/HTTPServer.cpp:597 daemon/HTTPServer.cpp:640
#: daemon/HTTPServer.cpp:686 #: daemon/HTTPServer.cpp:644
msgid "LeaseSets" msgid "LeaseSets"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:692 #: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:650
msgid "Tunnels" msgid "Tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:372 #: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:359
#: daemon/HTTPServer.cpp:813 daemon/HTTPServer.cpp:830 #: daemon/HTTPServer.cpp:770 daemon/HTTPServer.cpp:786
msgid "Transit Tunnels" msgid "Transit Tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:898 #: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:839
msgid "Transports" msgid "Transports"
msgstr "" msgstr ""
@@ -134,16 +127,15 @@ msgstr ""
msgid "I2P tunnels" msgid "I2P tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:927 #: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:908
#: daemon/HTTPServer.cpp:937 #: daemon/HTTPServer.cpp:918
msgid "SAM sessions" msgid "SAM sessions"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1329 #: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1302
#: daemon/HTTPServer.cpp:1332 daemon/HTTPServer.cpp:1335 #: daemon/HTTPServer.cpp:1305 daemon/HTTPServer.cpp:1308
#: daemon/HTTPServer.cpp:1362 daemon/HTTPServer.cpp:1365 #: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1367
#: daemon/HTTPServer.cpp:1379 daemon/HTTPServer.cpp:1424 #: daemon/HTTPServer.cpp:1370 daemon/HTTPServer.cpp:1373
#: daemon/HTTPServer.cpp:1427 daemon/HTTPServer.cpp:1430
msgid "ERROR" msgid "ERROR"
msgstr "" msgstr ""
@@ -159,14 +151,14 @@ msgstr ""
msgid "Firewalled" msgid "Firewalled"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:235 #: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:253
#: daemon/HTTPServer.cpp:336 #: daemon/HTTPServer.cpp:325
msgid "Unknown" msgid "Unknown"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:382 #: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:369
#: daemon/HTTPServer.cpp:383 daemon/HTTPServer.cpp:1003 #: daemon/HTTPServer.cpp:370 daemon/HTTPServer.cpp:976
#: daemon/HTTPServer.cpp:1011 #: daemon/HTTPServer.cpp:985
msgid "Proxy" msgid "Proxy"
msgstr "" msgstr ""
@@ -174,610 +166,564 @@ msgstr ""
msgid "Mesh" msgid "Mesh"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:242 #: daemon/HTTPServer.cpp:237
msgid "Error"
msgstr ""
#: daemon/HTTPServer.cpp:241
msgid "Clock skew" msgid "Clock skew"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:245 #: daemon/HTTPServer.cpp:244
msgid "Offline" msgid "Offline"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:248 #: daemon/HTTPServer.cpp:247
msgid "Symmetric NAT" msgid "Symmetric NAT"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:251 #: daemon/HTTPServer.cpp:259
msgid "Full cone NAT"
msgstr ""
#: daemon/HTTPServer.cpp:254
msgid "No Descriptors"
msgstr ""
#: daemon/HTTPServer.cpp:263
msgid "Uptime" msgid "Uptime"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:266 #: daemon/HTTPServer.cpp:262
msgid "Network status" msgid "Network status"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:271 #: daemon/HTTPServer.cpp:267
msgid "Network status v6" msgid "Network status v6"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:277 daemon/HTTPServer.cpp:284 #: daemon/HTTPServer.cpp:273 daemon/HTTPServer.cpp:280
msgid "Stopping in" msgid "Stopping in"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:291 #: daemon/HTTPServer.cpp:287
msgid "Family" msgid "Family"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:292 #: daemon/HTTPServer.cpp:288
msgid "Tunnel creation success rate" msgid "Tunnel creation success rate"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:296 #: daemon/HTTPServer.cpp:289
msgid "Total tunnel creation success rate"
msgstr ""
#: daemon/HTTPServer.cpp:298
msgid "Received" msgid "Received"
msgstr "" msgstr ""
#. tr: Kibibyte/s #. tr: Kibibit/s
#: daemon/HTTPServer.cpp:300 daemon/HTTPServer.cpp:303 #: daemon/HTTPServer.cpp:291 daemon/HTTPServer.cpp:294
#: daemon/HTTPServer.cpp:306 #: daemon/HTTPServer.cpp:297
#, c-format msgid "KiB/s"
msgid "%.2f KiB/s"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:301 #: daemon/HTTPServer.cpp:292
msgid "Sent" msgid "Sent"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:304 #: daemon/HTTPServer.cpp:295
msgid "Transit" msgid "Transit"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:307 #: daemon/HTTPServer.cpp:298
msgid "Data path" msgid "Data path"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:310 #: daemon/HTTPServer.cpp:301
msgid "Hidden content. Press on text to see." msgid "Hidden content. Press on text to see."
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:314 #: daemon/HTTPServer.cpp:304
msgid "Router Ident" msgid "Router Ident"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:316 #: daemon/HTTPServer.cpp:306
msgid "Router Family" msgid "Router Family"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:317 #: daemon/HTTPServer.cpp:307
msgid "Router Caps" msgid "Router Caps"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:318 #: daemon/HTTPServer.cpp:308
msgid "Version" msgid "Version"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:319 #: daemon/HTTPServer.cpp:309
msgid "Our external address" msgid "Our external address"
msgstr "" msgstr ""
#. tr: Shown when router doesn't publish itself and have "Firewalled" state #: daemon/HTTPServer.cpp:337
#: daemon/HTTPServer.cpp:349
msgid "supported" msgid "supported"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:363 #: daemon/HTTPServer.cpp:350
msgid "Routers" msgid "Routers"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:364 #: daemon/HTTPServer.cpp:351
msgid "Floodfills" msgid "Floodfills"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:987 #: daemon/HTTPServer.cpp:358 daemon/HTTPServer.cpp:962
msgid "Client Tunnels" msgid "Client Tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:381 #: daemon/HTTPServer.cpp:368
msgid "Services" msgid "Services"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:382 daemon/HTTPServer.cpp:383 #: daemon/HTTPServer.cpp:369 daemon/HTTPServer.cpp:370
#: daemon/HTTPServer.cpp:384 daemon/HTTPServer.cpp:385 #: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:372
#: daemon/HTTPServer.cpp:386 daemon/HTTPServer.cpp:387 #: daemon/HTTPServer.cpp:373 daemon/HTTPServer.cpp:374
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:382 daemon/HTTPServer.cpp:383 #: daemon/HTTPServer.cpp:369 daemon/HTTPServer.cpp:370
#: daemon/HTTPServer.cpp:384 daemon/HTTPServer.cpp:385 #: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:372
#: daemon/HTTPServer.cpp:386 daemon/HTTPServer.cpp:387 #: daemon/HTTPServer.cpp:373 daemon/HTTPServer.cpp:374
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:434 #: daemon/HTTPServer.cpp:417
msgid "Encrypted B33 address" msgid "Encrypted B33 address"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:442 #: daemon/HTTPServer.cpp:426
msgid "Address registration line" msgid "Address registration line"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:447 #: daemon/HTTPServer.cpp:431
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:448 #: daemon/HTTPServer.cpp:432
msgid "Generate" msgid "Generate"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:449 #: daemon/HTTPServer.cpp:433
msgid "" msgid ""
"<b>Note:</b> result string can be used only for registering 2LD domains " "<b>Note:</b> result string can be used only for registering 2LD domains "
"(example.i2p). For registering subdomains please use i2pd-tools." "(example.i2p). For registering subdomains please use i2pd-tools."
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:457 #: daemon/HTTPServer.cpp:439
msgid "Address" msgid "Address"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:459 #: daemon/HTTPServer.cpp:439
msgid "Type" msgid "Type"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:460 #: daemon/HTTPServer.cpp:439
msgid "EncType" msgid "EncType"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:467 #: daemon/HTTPServer.cpp:449 daemon/HTTPServer.cpp:655
msgid "Expire LeaseSet"
msgstr ""
#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:697
msgid "Inbound tunnels" msgid "Inbound tunnels"
msgstr "" msgstr ""
#. tr: Milliseconds #. tr: Milliseconds
#: daemon/HTTPServer.cpp:494 daemon/HTTPServer.cpp:514 #: daemon/HTTPServer.cpp:464 daemon/HTTPServer.cpp:484
#: daemon/HTTPServer.cpp:711 daemon/HTTPServer.cpp:731 #: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:689
#, c-format msgid "ms"
msgid "%dms"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:499 daemon/HTTPServer.cpp:716 #: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:674
msgid "Outbound tunnels" msgid "Outbound tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:521 #: daemon/HTTPServer.cpp:491
msgid "Tags" msgid "Tags"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:522 #: daemon/HTTPServer.cpp:491
msgid "Incoming" msgid "Incoming"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:535 #: daemon/HTTPServer.cpp:498 daemon/HTTPServer.cpp:501
msgid "Outgoing" msgid "Outgoing"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:532 daemon/HTTPServer.cpp:551 #: daemon/HTTPServer.cpp:499 daemon/HTTPServer.cpp:515
msgid "Destination" msgid "Destination"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:532 daemon/HTTPServer.cpp:814 #: daemon/HTTPServer.cpp:499
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:540 #: daemon/HTTPServer.cpp:506
msgid "Incoming Tags" msgid "Incoming Tags"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:548 daemon/HTTPServer.cpp:554 #: daemon/HTTPServer.cpp:514 daemon/HTTPServer.cpp:517
msgid "Tags sessions" msgid "Tags sessions"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:551 #: daemon/HTTPServer.cpp:515
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:561 daemon/HTTPServer.cpp:621 #: daemon/HTTPServer.cpp:524 daemon/HTTPServer.cpp:582
msgid "Local Destination" msgid "Local Destination"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:572 daemon/HTTPServer.cpp:960 #: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:941
msgid "Streams" msgid "Streams"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:595 #: daemon/HTTPServer.cpp:558
msgid "Close stream" msgid "Close stream"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:613 daemon/HTTPServer.cpp:1430 #: daemon/HTTPServer.cpp:587
msgid "Such destination is not found"
msgstr ""
#: daemon/HTTPServer.cpp:626
msgid "I2CP session not found" msgid "I2CP session not found"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:629 #: daemon/HTTPServer.cpp:590
msgid "I2CP is not enabled" msgid "I2CP is not enabled"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:658 #: daemon/HTTPServer.cpp:616
msgid "Invalid" msgid "Invalid"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:661 #: daemon/HTTPServer.cpp:619
msgid "Store type" msgid "Store type"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:662 #: daemon/HTTPServer.cpp:620
msgid "Expires" msgid "Expires"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:667 #: daemon/HTTPServer.cpp:625
msgid "Non Expired Leases" msgid "Non Expired Leases"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:670 #: daemon/HTTPServer.cpp:628
msgid "Gateway" msgid "Gateway"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:671 #: daemon/HTTPServer.cpp:629
msgid "TunnelID" msgid "TunnelID"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:672 #: daemon/HTTPServer.cpp:630
msgid "EndDate" msgid "EndDate"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:682 #: daemon/HTTPServer.cpp:640
msgid "floodfill mode is disabled" msgid "not floodfill"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:693 #: daemon/HTTPServer.cpp:651
msgid "Queue size" msgid "Queue size"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:743 #: daemon/HTTPServer.cpp:701
msgid "Run peer test" msgid "Run peer test"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:744 #: daemon/HTTPServer.cpp:706
msgid "Reload tunnels configuration"
msgstr ""
#: daemon/HTTPServer.cpp:747
msgid "Decline transit tunnels" msgid "Decline transit tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:749 #: daemon/HTTPServer.cpp:708
msgid "Accept transit tunnels" msgid "Accept transit tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:758 #: daemon/HTTPServer.cpp:712 daemon/HTTPServer.cpp:717
msgid "Cancel graceful shutdown" msgid "Cancel graceful shutdown"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:755 daemon/HTTPServer.cpp:760 #: daemon/HTTPServer.cpp:714 daemon/HTTPServer.cpp:719
msgid "Start graceful shutdown" msgid "Start graceful shutdown"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:763 #: daemon/HTTPServer.cpp:722
msgid "Force shutdown" msgid "Force shutdown"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:764 #: daemon/HTTPServer.cpp:723
msgid "Reload external CSS styles" msgid "Reload external CSS styles"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:767 #: daemon/HTTPServer.cpp:726
msgid "" msgid ""
"<b>Note:</b> any action done here are not persistent and not changes your " "<b>Note:</b> any action done here are not persistent and not changes your "
"config files." "config files."
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:770 #: daemon/HTTPServer.cpp:728
msgid "Logging level" msgid "Logging level"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:779 #: daemon/HTTPServer.cpp:736
msgid "Transit tunnels limit" msgid "Transit tunnels limit"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:784 daemon/HTTPServer.cpp:803 #: daemon/HTTPServer.cpp:741 daemon/HTTPServer.cpp:760
msgid "Change" msgid "Change"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:791 #: daemon/HTTPServer.cpp:748
msgid "Change language" msgid "Change language"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:830 #: daemon/HTTPServer.cpp:786
msgid "no transit tunnels currently built" msgid "no transit tunnels currently built"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:921 daemon/HTTPServer.cpp:944 #: daemon/HTTPServer.cpp:902 daemon/HTTPServer.cpp:925
msgid "SAM disabled" msgid "SAM disabled"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:937 #: daemon/HTTPServer.cpp:918
msgid "no sessions currently running" msgid "no sessions currently running"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:950 #: daemon/HTTPServer.cpp:931
msgid "SAM session not found" msgid "SAM session not found"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:955 #: daemon/HTTPServer.cpp:936
msgid "SAM Session" msgid "SAM Session"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1020 #: daemon/HTTPServer.cpp:993
msgid "Server Tunnels" msgid "Server Tunnels"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1036 #: daemon/HTTPServer.cpp:1009
msgid "Client Forwards" msgid "Client Forwards"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1050 #: daemon/HTTPServer.cpp:1023
msgid "Server Forwards" msgid "Server Forwards"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1250 #: daemon/HTTPServer.cpp:1223
msgid "Unknown page" msgid "Unknown page"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1269 #: daemon/HTTPServer.cpp:1242
msgid "Invalid token" msgid "Invalid token"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1327 daemon/HTTPServer.cpp:1359 #: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1357
#: daemon/HTTPServer.cpp:1414 daemon/HTTPServer.cpp:1454 #: daemon/HTTPServer.cpp:1397
msgid "SUCCESS" msgid "SUCCESS"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1327 #: daemon/HTTPServer.cpp:1300
msgid "Stream closed" msgid "Stream closed"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1329 #: daemon/HTTPServer.cpp:1302
msgid "Stream not found or already was closed" msgid "Stream not found or already was closed"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1332 daemon/HTTPServer.cpp:1365 #: daemon/HTTPServer.cpp:1305
msgid "Destination not found" msgid "Destination not found"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1335 #: daemon/HTTPServer.cpp:1308
msgid "StreamID can't be null" msgid "StreamID can't be null"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1337 daemon/HTTPServer.cpp:1367 #: daemon/HTTPServer.cpp:1310 daemon/HTTPServer.cpp:1375
#: daemon/HTTPServer.cpp:1432
msgid "Return to destination page" msgid "Return to destination page"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1338 daemon/HTTPServer.cpp:1368 #: daemon/HTTPServer.cpp:1311 daemon/HTTPServer.cpp:1324
#: daemon/HTTPServer.cpp:1381 daemon/HTTPServer.cpp:1456 #: daemon/HTTPServer.cpp:1399
#, c-format msgid "You will be redirected in 5 seconds"
msgid "You will be redirected in %d seconds"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1359 #: daemon/HTTPServer.cpp:1322
msgid "LeaseSet expiration time updated" msgid "Transit tunnels count must not exceed 65535"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1362 #: daemon/HTTPServer.cpp:1323 daemon/HTTPServer.cpp:1398
msgid "LeaseSet is not found or already expired"
msgstr ""
#: daemon/HTTPServer.cpp:1379
#, c-format
msgid "Transit tunnels count must not exceed %d"
msgstr ""
#: daemon/HTTPServer.cpp:1380 daemon/HTTPServer.cpp:1455
msgid "Back to commands list" msgid "Back to commands list"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1416 #: daemon/HTTPServer.cpp:1359
msgid "Register at reg.i2p" msgid "Register at reg.i2p"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1417 #: daemon/HTTPServer.cpp:1360
msgid "Description" msgid "Description"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1417 #: daemon/HTTPServer.cpp:1360
msgid "A bit information about service on domain" msgid "A bit information about service on domain"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1418 #: daemon/HTTPServer.cpp:1361
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1424 #: daemon/HTTPServer.cpp:1367
msgid "Domain can't end with .b32.i2p" msgid "Domain can't end with .b32.i2p"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1427 #: daemon/HTTPServer.cpp:1370
msgid "Domain must end with .i2p" msgid "Domain must end with .i2p"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1450 #: daemon/HTTPServer.cpp:1373
msgid "Such destination is not found"
msgstr ""
#: daemon/HTTPServer.cpp:1393
msgid "Unknown command" msgid "Unknown command"
msgstr "" msgstr ""
#: daemon/HTTPServer.cpp:1454 #: daemon/HTTPServer.cpp:1397
msgid "Command accepted" msgid "Command accepted"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:166 #: libi2pd_client/HTTPProxy.cpp:163
msgid "Proxy error" msgid "Proxy error"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:174 #: libi2pd_client/HTTPProxy.cpp:171
msgid "Proxy info" msgid "Proxy info"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:182 #: libi2pd_client/HTTPProxy.cpp:179
msgid "Proxy error: Host not found" msgid "Proxy error: Host not found"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:183 #: libi2pd_client/HTTPProxy.cpp:180
msgid "Remote host not found in router's addressbook" msgid "Remote host not found in router's addressbook"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:184 #: libi2pd_client/HTTPProxy.cpp:181
msgid "You may try to find this host on jump services below" msgid "You may try to find this host on jump services below"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:333 libi2pd_client/HTTPProxy.cpp:348 #: libi2pd_client/HTTPProxy.cpp:282 libi2pd_client/HTTPProxy.cpp:297
#: libi2pd_client/HTTPProxy.cpp:417 libi2pd_client/HTTPProxy.cpp:460 #: libi2pd_client/HTTPProxy.cpp:331 libi2pd_client/HTTPProxy.cpp:372
msgid "Invalid request" msgid "Invalid request"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:333 #: libi2pd_client/HTTPProxy.cpp:282
msgid "Proxy unable to parse your request" msgid "Proxy unable to parse your request"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:348 #: libi2pd_client/HTTPProxy.cpp:297
msgid "Addresshelper is not supported" msgid "addresshelper is not supported"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:373 #: libi2pd_client/HTTPProxy.cpp:306 libi2pd_client/HTTPProxy.cpp:315
#, c-format #: libi2pd_client/HTTPProxy.cpp:392
msgid "" msgid "Host"
"Host %s is <font color=red>already in router's addressbook</font>. <b>Be "
"careful: source of this URL may be harmful!</b> Click here to update record: "
"<a href=\"%s%s%s&update=true\">Continue</a>."
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:375 #: libi2pd_client/HTTPProxy.cpp:306
msgid "Addresshelper forced update rejected" msgid "added to router's addressbook from helper"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:382 #: libi2pd_client/HTTPProxy.cpp:307
#, c-format msgid "Click here to proceed:"
msgid ""
"To add host <b>%s</b> in router's addressbook, click here: <a "
"href=\"%s%s%s\">Continue</a>."
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:384 #: libi2pd_client/HTTPProxy.cpp:307 libi2pd_client/HTTPProxy.cpp:317
msgid "Addresshelper request" msgid "Continue"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:393 #: libi2pd_client/HTTPProxy.cpp:308 libi2pd_client/HTTPProxy.cpp:318
#, c-format msgid "Addresshelper found"
msgid ""
"Host %s added to router's addressbook from helper. Click here to proceed: <a "
"href=\"%s\">Continue</a>."
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:395 #: libi2pd_client/HTTPProxy.cpp:315
msgid "Addresshelper adding" msgid "already in router's addressbook"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:402 #. tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it.
#, c-format #: libi2pd_client/HTTPProxy.cpp:316
msgid "" msgid "Click here to update record:"
"Host %s is <font color=red>already in router's addressbook</font>. Click "
"here to update record: <a href=\"%s%s%s&update=true\">Continue</a>."
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:404 #: libi2pd_client/HTTPProxy.cpp:331
msgid "Addresshelper update" msgid "invalid request uri"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:417 #: libi2pd_client/HTTPProxy.cpp:372
msgid "Invalid request URI"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:460
msgid "Can't detect destination host from request" msgid "Can't detect destination host from request"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:477 libi2pd_client/HTTPProxy.cpp:481 #: libi2pd_client/HTTPProxy.cpp:389 libi2pd_client/HTTPProxy.cpp:393
msgid "Outproxy failure" msgid "Outproxy failure"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:477 #: libi2pd_client/HTTPProxy.cpp:389
msgid "Bad outproxy settings" msgid "bad outproxy settings"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:480 #: libi2pd_client/HTTPProxy.cpp:392
#, c-format msgid "not inside I2P network, but outproxy is not enabled"
msgid "Host %s is not inside I2P network, but outproxy is not enabled"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:569 #: libi2pd_client/HTTPProxy.cpp:482
msgid "Unknown outproxy URL" msgid "unknown outproxy url"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:575 #: libi2pd_client/HTTPProxy.cpp:490
msgid "Cannot resolve upstream proxy" msgid "cannot resolve upstream proxy"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:583 #: libi2pd_client/HTTPProxy.cpp:498
msgid "Hostname is too long" msgid "hostname too long"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:610 #: libi2pd_client/HTTPProxy.cpp:525
msgid "Cannot connect to upstream SOCKS proxy" msgid "cannot connect to upstream socks proxy"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:616 #: libi2pd_client/HTTPProxy.cpp:531
msgid "Cannot negotiate with SOCKS proxy" msgid "Cannot negotiate with socks proxy"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:658 #: libi2pd_client/HTTPProxy.cpp:573
msgid "CONNECT error" msgid "CONNECT error"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:658 #: libi2pd_client/HTTPProxy.cpp:573
msgid "Failed to connect" msgid "Failed to Connect"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:669 libi2pd_client/HTTPProxy.cpp:695 #: libi2pd_client/HTTPProxy.cpp:584 libi2pd_client/HTTPProxy.cpp:610
msgid "SOCKS proxy error" msgid "socks proxy error"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:677 #: libi2pd_client/HTTPProxy.cpp:592
msgid "Failed to send request to upstream" msgid "failed to send request to upstream"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:698 #: libi2pd_client/HTTPProxy.cpp:613
msgid "No reply from SOCKS proxy" msgid "No Reply From socks proxy"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:705 #: libi2pd_client/HTTPProxy.cpp:620
msgid "Cannot connect" msgid "cannot connect"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:705 #: libi2pd_client/HTTPProxy.cpp:620
msgid "HTTP out proxy not implemented" msgid "http out proxy not implemented"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:706 #: libi2pd_client/HTTPProxy.cpp:621
msgid "Cannot connect to upstream HTTP proxy" msgid "cannot connect to upstream http proxy"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:739 #: libi2pd_client/HTTPProxy.cpp:654
msgid "Host is down" msgid "Host is down"
msgstr "" msgstr ""
#: libi2pd_client/HTTPProxy.cpp:739 #: libi2pd_client/HTTPProxy.cpp:654
msgid "" msgid ""
"Can't create connection to requested host, it may be down. Please try again " "Can't create connection to requested host, it may be down. Please try again "
"later." "later."

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ RuntimeDirectoryMode=0700
LogsDirectory=i2pd LogsDirectory=i2pd
LogsDirectoryMode=0700 LogsDirectoryMode=0700
Type=forking Type=forking
ExecStart=/usr/bin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID" ExecReload=/bin/sh -c "kill -HUP $MAINPID"
PIDFile=/run/i2pd/i2pd.pid PIDFile=/run/i2pd/i2pd.pid
### Uncomment, if auto restart needed ### Uncomment, if auto restart needed
@@ -29,7 +29,7 @@ SendSIGKILL=yes
#TimeoutStopSec=10m #TimeoutStopSec=10m
# If you have problems with hanging i2pd, you can try increase this # If you have problems with hanging i2pd, you can try increase this
LimitNOFILE=8192 LimitNOFILE=4096
# To enable write of coredump uncomment this # To enable write of coredump uncomment this
#LimitCORE=infinity #LimitCORE=infinity

View File

@@ -7,7 +7,7 @@ tunconf="/etc/i2pd/tunnels.conf"
tundir="/etc/i2pd/tunnels.conf.d" tundir="/etc/i2pd/tunnels.conf.d"
name="i2pd" name="i2pd"
command="/usr/bin/i2pd" command="/usr/sbin/i2pd"
command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --tunnelsdir=$tundir --pidfile=$pidfile" command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --tunnelsdir=$tundir --pidfile=$pidfile"
description="i2p router written in C++" description="i2p router written in C++"
required_dirs="/var/lib/i2pd" required_dirs="/var/lib/i2pd"

View File

@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7) %define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git Name: i2pd-git
Version: 2.54.0 Version: 2.44.0
Release: git%{git_hash}%{?dist} Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd Conflicts: i2pd
@@ -24,19 +24,13 @@ BuildRequires: openssl-devel
BuildRequires: miniupnpc-devel BuildRequires: miniupnpc-devel
BuildRequires: systemd-units BuildRequires: systemd-units
%if 0%{?fedora} == 41
BuildRequires: openssl-devel-engine
%endif
Requires: logrotate Requires: logrotate
Requires: systemd Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description %description
C++ implementation of I2P. C++ implementation of I2P.
%prep %prep
%setup -q -n i2pd-openssl %setup -q -n i2pd-openssl
@@ -44,60 +38,76 @@ C++ implementation of I2P.
%build %build
cd build cd build
%if 0%{?rhel} == 7 %if 0%{?rhel} == 7
%cmake3 \ %cmake3 \
-DWITH_LIBRARY=OFF \ -DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \ -DWITH_UPNP=ON \
-DWITH_HARDENING=ON \ -DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF
%else %else
%cmake \ %cmake \
-DWITH_LIBRARY=OFF \ -DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \ -DWITH_UPNP=ON \
-DWITH_HARDENING=ON \ -DWITH_HARDENING=ON \
%if 0%{?fedora} > 29 %if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_SHARED_LIBS:BOOL=OFF \
. .
%else %else
-DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF
%endif %endif
%endif %endif
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} > 7 %if 0%{?rhel} == 9
pushd build pushd redhat-linux-build
%endif %endif
%if 0%{?fedora} >= 35
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
%endif %endif
make %{?_smp_mflags} make %{?_smp_mflags}
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7 %if 0%{?rhel} == 9
popd popd
%endif %endif
%if 0%{?fedora} >= 33
popd
%endif
%if 0%{?mageia} > 7
popd
%endif
%install %install
pushd build pushd build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} %if 0%{?rhel} == 9
pushd redhat-linux-build pushd redhat-linux-build
%else %endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} %if 0%{?fedora} >= 35
pushd build pushd redhat-linux-build
%endif %else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
%endif %endif
chrpath -d i2pd chrpath -d i2pd
%{__install} -D -m 755 i2pd %{buildroot}%{_bindir}/i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
@@ -133,7 +143,7 @@ getent passwd i2pd >/dev/null || \
%files %files
%doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d
%{_bindir}/i2pd %{_sbindir}/i2pd
%config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/*.conf
%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf
%config %{_sysconfdir}/i2pd/subscriptions.txt %config %{_sysconfdir}/i2pd/subscriptions.txt
@@ -148,51 +158,6 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* Sun Oct 6 2024 orignal <orignal@i2pmail.org> - 2.54.0
- update to 2.54.0
* Tue Jul 30 2024 orignal <orignal@i2pmail.org> - 2.53.1
- update to 2.53.1
* Fri Jul 19 2024 orignal <orignal@i2pmail.org> - 2.53.0
- update to 2.53.0
* Sun May 12 2024 orignal <orignal@i2pmail.org> - 2.52.0
- update to 2.52.0
* Sat Apr 06 2024 orignal <orignal@i2pmail.org> - 2.51.0
- update to 2.51.0
* Sat Jan 06 2024 orignal <orignal@i2pmail.org> - 2.50.2
- update to 2.50.2
* Sat Dec 23 2023 r4sas <r4sas@i2pmail.org> - 2.50.1
- update to 2.50.1
* Mon Dec 18 2023 orignal <orignal@i2pmail.org> - 2.50.0
- update to 2.50.0
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0 * Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0
- update to 2.44.0 - update to 2.44.0

View File

@@ -1,5 +1,5 @@
Name: i2pd Name: i2pd
Version: 2.54.0 Version: 2.44.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd-git Conflicts: i2pd-git
@@ -22,19 +22,13 @@ BuildRequires: openssl-devel
BuildRequires: miniupnpc-devel BuildRequires: miniupnpc-devel
BuildRequires: systemd-units BuildRequires: systemd-units
%if 0%{?fedora} == 41
BuildRequires: openssl-devel-engine
%endif
Requires: logrotate Requires: logrotate
Requires: systemd Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
%description %description
C++ implementation of I2P. C++ implementation of I2P.
%prep %prep
%setup -q %setup -q
@@ -42,60 +36,75 @@ C++ implementation of I2P.
%build %build
cd build cd build
%if 0%{?rhel} == 7 %if 0%{?rhel} == 7
%cmake3 \ %cmake3 \
-DWITH_LIBRARY=OFF \ -DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \ -DWITH_UPNP=ON \
-DWITH_HARDENING=ON \ -DWITH_HARDENING=ON \
-DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF
%else %else
%cmake \ %cmake \
-DWITH_LIBRARY=OFF \ -DWITH_LIBRARY=OFF \
-DWITH_UPNP=ON \ -DWITH_UPNP=ON \
-DWITH_HARDENING=ON \ -DWITH_HARDENING=ON \
%if 0%{?fedora} > 29 %if 0%{?fedora} > 29
-DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_SHARED_LIBS:BOOL=OFF \
. .
%else %else
-DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF
%endif %endif
%endif %endif
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} %if 0%{?rhel} == 9
pushd redhat-linux-build pushd redhat-linux-build
%else %endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} > 7 %if 0%{?fedora} >= 35
pushd build pushd redhat-linux-build
%endif %else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia} > 7
pushd build
%endif %endif
make %{?_smp_mflags} make %{?_smp_mflags}
%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7 %if 0%{?rhel} == 9
popd popd
%endif %endif
%if 0%{?fedora} >= 33
popd
%endif
%if 0%{?mageia} > 7
popd
%endif
%install %install
pushd build pushd build
%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} %if 0%{?rhel} == 9
pushd redhat-linux-build pushd redhat-linux-build
%else %endif
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%if 0%{?mageia} %if 0%{?fedora} >= 35
pushd build pushd redhat-linux-build
%endif %else
%if 0%{?fedora} >= 33
pushd %{_target_platform}
%endif
%endif
%if 0%{?mageia}
pushd build
%endif %endif
chrpath -d i2pd chrpath -d i2pd
%{__install} -D -m 755 i2pd %{buildroot}%{_bindir}/i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
@@ -131,7 +140,7 @@ getent passwd i2pd >/dev/null || \
%files %files
%doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d
%{_bindir}/i2pd %{_sbindir}/i2pd
%config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/*.conf
%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf
%config %{_sysconfdir}/i2pd/subscriptions.txt %config %{_sysconfdir}/i2pd/subscriptions.txt
@@ -146,51 +155,6 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* Sun Oct 6 2024 orignal <orignal@i2pmail.org> - 2.54.0
- update to 2.54.0
* Tue Jul 30 2024 orignal <orignal@i2pmail.org> - 2.53.1
- update to 2.53.1
* Fri Jul 19 2024 orignal <orignal@i2pmail.org> - 2.53.0
- update to 2.53.0
* Sun May 12 2024 orignal <orignal@i2pmail.org> - 2.52.0
- update to 2.52.0
* Sat Apr 06 2024 orignal <orignal@i2pmail.org> - 2.51.0
- update to 2.51.0
* Sat Jan 06 2024 orignal <orignal@i2pmail.org> - 2.50.2
- update to 2.50.2
* Sat Dec 23 2023 r4sas <r4sas@i2pmail.org> - 2.50.1
- update to 2.50.1
* Mon Dec 18 2023 orignal <orignal@i2pmail.org> - 2.50.0
- update to 2.50.0
* Mon Sep 18 2023 orignal <orignal@i2pmail.org> - 2.49.0
- update to 2.49.0
* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
- update to 2.48.0
* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
- update to 2.47.0
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
- update to 2.46.1
* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
- update to 2.46.0
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0 * Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0
- update to 2.44.0 - update to 2.44.0

View File

@@ -8,4 +8,4 @@ env LOGFILE="/var/log/i2pd/i2pd.log"
expect fork expect fork
exec /usr/bin/i2pd --daemon --service --log=file --logfile=$LOGFILE exec /usr/sbin/i2pd --daemon --service --log=file --logfile=$LOGFILE

View File

@@ -1,293 +1,293 @@
/* /*
* Copyright (c) 2021-2023, The PurpleI2P Project * Copyright (c) 2021-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
* See full license text in LICENSE file at top of project tree * See full license text in LICENSE file at top of project tree
* *
****************************************************************** ******************************************************************
* *
* This is style sheet for webconsole, with @media selectors for adaptive * This is style sheet for webconsole, with @media selectors for adaptive
* view on desktop and mobile devices, respecting preferred user's color * view on desktop and mobile devices, respecting preferred user's color
* scheme used in system/browser. * scheme used in system/browser.
* *
* Minified copy of that style sheet is bundled inside i2pd sources. * Minified copy of that style sheet is bundled inside i2pd sources.
*/ */
:root { :root {
--main-bg-color: #fafafa; --main-bg-color: #fafafa;
--main-text-color: #103456; --main-text-color: #103456;
--main-link-color: #894c84; --main-link-color: #894c84;
--main-link-hover-color: #fafafa; --main-link-hover-color: #fafafa;
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:root { :root {
--main-bg-color: #242424; --main-bg-color: #242424;
--main-text-color: #17ab5c; --main-text-color: #17ab5c;
--main-link-color: #bf64b7; --main-link-color: #bf64b7;
--main-link-hover-color: #000000; --main-link-hover-color: #000000;
} }
} }
body { body {
font: 100%/1.5em sans-serif; font: 100%/1.5em sans-serif;
margin: 0; margin: 0;
padding: 1.5em; padding: 1.5em;
background: var(--main-bg-color); background: var(--main-bg-color);
color: var(--main-text-color); color: var(--main-text-color);
} }
a, .slide label { a, .slide label {
text-decoration: none; text-decoration: none;
color: var(--main-link-color); color: var(--main-link-color);
} }
a:hover, a.button.selected, .slide label:hover, button[type=submit]:hover { a:hover, .slide label:hover, button[type=submit]:hover {
color: var(--main-link-hover-color); color: var(--main-link-hover-color);
background: var(--main-link-color); background: var(--main-link-color);
} }
a.button { a.button {
appearance: button; appearance: button;
text-decoration: none; text-decoration: none;
padding: 0 5px; padding: 0 5px;
border: 1px solid var(--main-link-color); border: 1px solid var(--main-link-color);
} }
.header { .header {
font-size: 2.5em; font-size: 2.5em;
text-align: center; text-align: center;
margin: 1em 0; margin: 1em 0;
color: var(--main-link-color); color: var(--main-link-color);
} }
.wrapper { .wrapper {
margin: 0 auto; margin: 0 auto;
padding: 1em; padding: 1em;
max-width: 64em; max-width: 64em;
} }
.menu { .menu {
display: block; display: block;
float: left; float: left;
overflow: hidden; overflow: hidden;
padding: 4px; padding: 4px;
max-width: 12em; max-width: 12em;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.listitem { .listitem {
display: block; display: block;
font-family: monospace; font-family: monospace;
font-size: 1.2em; font-size: 1.2em;
white-space: nowrap; white-space: nowrap;
} }
.tableitem { .tableitem {
font-family: monospace; font-family: monospace;
font-size: 1.2em; font-size: 1.2em;
white-space: nowrap; white-space: nowrap;
} }
.content { .content {
float: left; float: left;
font-size: 1em; font-size: 1em;
margin-left: 2em; margin-left: 2em;
padding: 4px; padding: 4px;
max-width: 50em; max-width: 50em;
overflow: auto; overflow: auto;
} }
.tunnel.established { .tunnel.established {
color: #56B734; color: #56B734;
} }
.tunnel.expiring { .tunnel.expiring {
color: #D3AE3F; color: #D3AE3F;
} }
.tunnel.failed { .tunnel.failed {
color: #D33F3F; color: #D33F3F;
} }
.tunnel.building { .tunnel.building {
color: #434343; color: #434343;
} }
caption { caption {
font-size: 1.5em; font-size: 1.5em;
text-align: center; text-align: center;
color: var(--main-link-color); color: var(--main-link-color);
} }
table { table {
display: table; display: table;
border-collapse: collapse; border-collapse: collapse;
text-align: center; text-align: center;
} }
table.extaddr { table.extaddr {
text-align: left; text-align: left;
} }
table.services { table.services {
width: 100%; width: 100%;
} }
textarea { textarea {
background-color: var(--main-bg-color); background-color: var(--main-bg-color);
color: var(--main-text-color); color: var(--main-text-color);
word-break: break-all; word-break: break-all;
} }
.streamdest { .streamdest {
width: 120px; width: 120px;
max-width: 240px; max-width: 240px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.slide div.slidecontent, .slide [type="checkbox"] { .slide div.slidecontent, .slide [type="checkbox"] {
display: none; display: none;
} }
.slide [type="checkbox"]:checked ~ div.slidecontent { .slide [type="checkbox"]:checked ~ div.slidecontent {
display: block; display: block;
margin-top: 0; margin-top: 0;
padding: 0; padding: 0;
} }
.disabled { .disabled {
color: #D33F3F; color: #D33F3F;
} }
.enabled { .enabled {
color: #56B734; color: #56B734;
} }
button[type=submit] { button[type=submit] {
background-color: transparent; background-color: transparent;
color: var(--main-link-color); color: var(--main-link-color);
text-decoration: none; text-decoration: none;
padding: 5px; padding: 5px;
border: 1px solid var(--main-link-color); border: 1px solid var(--main-link-color);
font-size: 14px; font-size: 14px;
} }
input, select, select option { input, select, select option {
background-color: var(--main-bg-color); background-color: var(--main-bg-color);
color: var(--main-link-color); color: var(--main-link-color);
padding: 5px; padding: 5px;
border: 1px solid var(--main-link-color); border: 1px solid var(--main-link-color);
font-size: 14px; font-size: 14px;
} }
input:focus, select:focus, select option:focus { input:focus, select:focus, select option:focus {
outline: none; outline: none;
} }
input[type=number]::-webkit-inner-spin-button { input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
} }
@media screen and (max-width: 1150px) { /* adaptive style */ @media screen and (max-width: 1150px) { /* adaptive style */
.wrapper { .wrapper {
max-width: 58em; max-width: 58em;
} }
.content { .content {
max-width: 40em; max-width: 40em;
} }
} }
@media screen and (max-width: 980px) { @media screen and (max-width: 980px) {
body { body {
font: 100%/1.2em sans-serif; font: 100%/1.2em sans-serif;
padding: 1.2em 0 0 0; padding: 1.2em 0 0 0;
} }
.menu { .menu {
width: 100%; width: 100%;
max-width: unset; max-width: unset;
display: block; display: block;
float: none; float: none;
position: unset; position: unset;
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
} }
.menu a, .commands a { .menu a, .commands a {
display: inline-block; display: inline-block;
padding: 4px; padding: 4px;
} }
.content { .content {
float: none; float: none;
margin-left: unset; margin-left: unset;
margin-top: 16px; margin-top: 16px;
max-width: 100%; max-width: 100%;
width: 100%; width: 100%;
text-align: center; text-align: center;
} }
a, .slide label { a, .slide label {
display: block; display: block;
} }
.header { .header {
margin: unset; margin: unset;
font-size: 1.5em; font-size: 1.5em;
} }
small { small {
display: block display: block
} }
a.button { a.button {
appearance: button; appearance: button;
text-decoration: none; text-decoration: none;
margin-top: 10px; margin-top: 10px;
padding: 6px; padding: 6px;
border: 2px solid var(--main-link-color); border: 2px solid var(--main-link-color);
border-radius: 5px; border-radius: 5px;
width: -webkit-fill-available; width: -webkit-fill-available;
} }
input, select { input, select {
width: 35%; width: 35%;
text-align: center; text-align: center;
padding: 5px; padding: 5px;
border: 2px solid var(--main-link-color); border: 2px solid var(--main-link-color);
border-radius: 5px; border-radius: 5px;
font-size: 18px; font-size: 18px;
} }
table.extaddr { table.extaddr {
margin: auto; margin: auto;
text-align: unset; text-align: unset;
} }
textarea { textarea {
width: -webkit-fill-available; width: -webkit-fill-available;
height: auto; height: auto;
padding: 5px; padding: 5px;
border: 2px solid var(--main-link-color); border: 2px solid var(--main-link-color);
border-radius: 5px; border-radius: 5px;
font-size: 12px; font-size: 12px;
} }
button[type=submit] { button[type=submit] {
padding: 5px 15px; padding: 5px 15px;
background: transparent; background: transparent;
border: 2px solid var(--main-link-color); border: 2px solid var(--main-link-color);
cursor: pointer; cursor: pointer;
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
border-radius: 5px; border-radius: 5px;
position: relative; position: relative;
height: 36px; height: 36px;
display: -webkit-inline-box; display: -webkit-inline-box;
margin-top: 10px; margin-top: 10px;
} }
} }

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -87,7 +87,8 @@ namespace http {
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css"; const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css";
const char HTTP_COMMAND_EXPIRELEASE[] = "expirelease"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_PARAM_ADDRESS[] = "address";
static std::string ConvertTime (uint64_t time) static std::string ConvertTime (uint64_t time)
{ {
@@ -104,18 +105,18 @@ namespace http {
int num; int num;
if ((num = seconds / 86400) > 0) { if ((num = seconds / 86400) > 0) {
s << ntr("%d day", "%d days", num, num) << ", "; s << num << " " << tr("day", "days", num) << ", ";
seconds -= num * 86400; seconds -= num * 86400;
} }
if ((num = seconds / 3600) > 0) { if ((num = seconds / 3600) > 0) {
s << ntr("%d hour", "%d hours", num, num) << ", "; s << num << " " << tr("hour", "hours", num) << ", ";
seconds -= num * 3600; seconds -= num * 3600;
} }
if ((num = seconds / 60) > 0) { if ((num = seconds / 60) > 0) {
s << ntr("%d minute", "%d minutes", num, num) << ", "; s << num << " " << tr("minute", "minutes", num) << ", ";
seconds -= num * 60; seconds -= num * 60;
} }
s << ntr("%d second", "%d seconds", seconds, seconds); s << seconds << " " << tr("second", "seconds", seconds);
} }
static void ShowTraffic (std::stringstream& s, uint64_t bytes) static void ShowTraffic (std::stringstream& s, uint64_t bytes)
@@ -123,37 +124,40 @@ namespace http {
s << std::fixed << std::setprecision(2); s << std::fixed << std::setprecision(2);
auto numKBytes = (double) bytes / 1024; auto numKBytes = (double) bytes / 1024;
if (numKBytes < 1024) if (numKBytes < 1024)
s << tr(/* tr: Kibibyte */ "%.2f KiB", numKBytes); s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB");
else if (numKBytes < 1024 * 1024) else if (numKBytes < 1024 * 1024)
s << tr(/* tr: Mebibyte */ "%.2f MiB", numKBytes / 1024); s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB");
else else
s << tr(/* tr: Gibibyte */ "%.2f GiB", numKBytes / 1024 / 1024); s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB");
} }
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
{ {
std::string state, stateText; std::string state, stateText;
switch (eState) switch (eState) {
{
case i2p::tunnel::eTunnelStateBuildReplyReceived : case i2p::tunnel::eTunnelStateBuildReplyReceived :
case i2p::tunnel::eTunnelStatePending : state = "building"; break; case i2p::tunnel::eTunnelStatePending : state = "building"; break;
case i2p::tunnel::eTunnelStateBuildFailed : state = "failed"; stateText = "declined"; break; case i2p::tunnel::eTunnelStateBuildFailed :
case i2p::tunnel::eTunnelStateTestFailed : state = "failed"; stateText = "test failed"; break; case i2p::tunnel::eTunnelStateTestFailed :
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; case i2p::tunnel::eTunnelStateEstablished : state = "established"; break;
default: state = "unknown"; break; default: state = "unknown"; break;
} }
if (stateText.empty ()) stateText = tr(state);
if (state == "building") stateText = tr("building");
else if (state == "failed") stateText = tr("failed");
else if (state == "expiring") stateText = tr("expiring");
else if (state == "established") stateText = tr("established");
else stateText = tr("unknown");
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, "; s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
ShowTraffic(s, bytes); s << " " << (int) (bytes / 1024) << "&nbsp;" << tr(/* tr: Kibibit */ "KiB") << "\r\n";
s << "\r\n";
} }
static void SetLogLevel (const std::string& level) static void SetLogLevel (const std::string& level)
{ {
if (level == "none" || level == "critical" || level == "error" || level == "warn" || level == "info" || level == "debug") if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug")
i2p::log::Logger().SetLogLevel(level); i2p::log::Logger().SetLogLevel(level);
else { else {
LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted"); LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted");
@@ -196,7 +200,7 @@ namespace http {
if (i2p::context.AcceptsTunnels () || i2p::tunnel::tunnels.CountTransitTunnels()) if (i2p::context.AcceptsTunnels () || i2p::tunnel::tunnels.CountTransitTunnels())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit Tunnels") << "</a><br>\r\n"; s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit Tunnels") << "</a><br>\r\n";
s << s <<
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr("Transports") << "</a><br>\r\n" " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n"; " <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
if (i2p::client::context.GetSAMBridge ()) if (i2p::client::context.GetSAMBridge ())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n"; s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
@@ -218,21 +222,21 @@ namespace http {
s << "<b>" << tr("ERROR") << ":</b>&nbsp;" << string << "<br>\r\n"; s << "<b>" << tr("ERROR") << ":</b>&nbsp;" << string << "<br>\r\n";
} }
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing, RouterError error) static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, RouterError error)
{ {
switch (status) switch (status)
{ {
case eRouterStatusOK: s << tr("OK"); break; case eRouterStatusOK: s << tr("OK"); break;
case eRouterStatusTesting: s << tr("Testing"); break;
case eRouterStatusFirewalled: s << tr("Firewalled"); break; case eRouterStatusFirewalled: s << tr("Firewalled"); break;
case eRouterStatusUnknown: s << tr("Unknown"); break; case eRouterStatusUnknown: s << tr("Unknown"); break;
case eRouterStatusProxy: s << tr("Proxy"); break; case eRouterStatusProxy: s << tr("Proxy"); break;
case eRouterStatusMesh: s << tr("Mesh"); break; case eRouterStatusMesh: s << tr("Mesh"); break;
default: s << tr("Unknown"); default: s << tr("Unknown");
} }
if (testing)
s << " (" << tr("Testing") << ")";
if (error != eRouterErrorNone) if (error != eRouterErrorNone)
{ {
s << "<br>";
switch (error) switch (error)
{ {
case eRouterErrorClockSkew: case eRouterErrorClockSkew:
@@ -244,9 +248,6 @@ namespace http {
case eRouterErrorSymmetricNAT: case eRouterErrorSymmetricNAT:
s << " - " << tr("Symmetric NAT"); s << " - " << tr("Symmetric NAT");
break; break;
case eRouterErrorFullConeNAT:
s << " - " << tr("Full cone NAT");
break;
case eRouterErrorNoDescriptors: case eRouterErrorNoDescriptors:
s << " - " << tr("No Descriptors"); s << " - " << tr("No Descriptors");
break; break;
@@ -261,12 +262,12 @@ namespace http {
ShowUptime(s, i2p::context.GetUptime ()); ShowUptime(s, i2p::context.GetUptime ());
s << "<br>\r\n"; s << "<br>\r\n";
s << "<b>" << tr("Network status") << ":</b> "; s << "<b>" << tr("Network status") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting(), i2p::context.GetError ()); ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetError ());
s << "<br>\r\n"; s << "<br>\r\n";
if (i2p::context.SupportsV6 ()) if (i2p::context.SupportsV6 ())
{ {
s << "<b>" << tr("Network status v6") << ":</b> "; s << "<b>" << tr("Network status v6") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6(), i2p::context.GetErrorV6 ()); ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetErrorV6 ());
s << "<br>\r\n"; s << "<br>\r\n";
} }
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
@@ -287,26 +288,21 @@ namespace http {
if (family.length () > 0) if (family.length () > 0)
s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n"; s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n";
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n"; s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
bool isTotalTCSR;
i2p::config::GetOption("http.showTotalTCSR", isTotalTCSR);
if (isTotalTCSR) {
s << "<b>" << tr("Total tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTotalTunnelCreationSuccessRate() << "%<br/>\r\n";
}
s << "<b>" << tr("Received") << ":</b> "; s << "<b>" << tr("Received") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")<br>\r\n"; s << " (" << (double) i2p::transport::transports.GetInBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << "<b>" << tr("Sent") << ":</b> "; s << "<b>" << tr("Sent") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")<br>\r\n"; s << " (" << (double) i2p::transport::transports.GetOutBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << "<b>" << tr("Transit") << ":</b> "; s << "<b>" << tr("Transit") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")<br>\r\n"; s << " (" << (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n"; s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
s << "<div class='slide'>"; s << "<div class='slide'>";
if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
s << "<label for=\"slide-info\">" << tr("Hidden content. Press on text to see.") << "</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n"; s << "<label for=\"slide-info\">" << tr("Hidden content. Press on text to see.") << "</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
} }
if (includeHiddenContent) if (includeHiddenContent)
{ {
s << "<b>" << tr("Router Ident") << ":</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n"; s << "<b>" << tr("Router Ident") << ":</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) if (!i2p::context.GetRouterInfo().GetProperty("family").empty())
@@ -316,10 +312,9 @@ namespace http {
s << "<b>"<< tr("Our external address") << ":</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n"; s << "<b>"<< tr("Our external address") << ":</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n";
auto addresses = i2p::context.GetRouterInfo().GetAddresses (); auto addresses = i2p::context.GetRouterInfo().GetAddresses ();
if (addresses) if (addresses)
{ {
for (const auto& address : *addresses) for (const auto& address : *addresses)
{ {
if (!address) continue;
s << "<tr>\r\n<td>"; s << "<tr>\r\n<td>";
switch (address->transportStyle) switch (address->transportStyle)
{ {
@@ -332,25 +327,24 @@ namespace http {
default: default:
s << tr("Unknown"); s << tr("Unknown");
} }
bool v6 = address->IsV6 (); if (address->IsV6 ())
if (v6)
{ {
if (address->IsV4 ()) s << "v4"; if (address->IsV4 ()) s << "v4";
s << "v6"; s << "v6";
} }
s << "</td>\r\n"; s << "</td>\r\n";
if (address->published) if (address->published)
s << "<td>" << (v6 ? "[" : "") << address->host.to_string() << (v6 ? "]:" : ":") << address->port << "</td>\r\n"; s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n";
else else
{ {
s << "<td>" << tr(/* tr: Shown when router doesn't publish itself and have "Firewalled" state */ "supported"); s << "<td>" << tr("supported");
if (address->port) if (address->port)
s << " :" << address->port; s << " :" << address->port;
s << "</td>\r\n"; s << "</td>\r\n";
} }
s << "</tr>\r\n"; s << "</tr>\r\n";
} }
} }
s << "</tbody></table>\r\n"; s << "</tbody></table>\r\n";
} }
s << "</div>\r\n</div>\r\n"; s << "</div>\r\n</div>\r\n";
@@ -417,23 +411,10 @@ namespace http {
} }
} }
static void ShowHop(std::stringstream& s, const i2p::data::IdentityEx& ident)
{
auto identHash = ident.GetIdentHash();
auto router = i2p::data::netdb.FindRouter(identHash);
s << i2p::data::GetIdentHashAbbreviation(identHash);
if (router)
s << "<small style=\"color:gray\"> " << router->GetBandwidthCap() << "</small>";
}
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token) static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
{ {
s << "<b>Base32:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"1\">";
s << dest->GetIdentHash ().ToBase32 () << "</textarea><br>\r\n<br>\r\n";
s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"8\">"; s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"8\">";
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n"; s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
if (dest->IsEncryptedLeaseSet ()) if (dest->IsEncryptedLeaseSet ())
{ {
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
@@ -445,11 +426,12 @@ namespace http {
if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ()) if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ())
{ {
std::string webroot; i2p::config::GetOption("http.webroot", webroot); std::string webroot; i2p::config::GetOption("http.webroot", webroot);
auto base32 = dest->GetIdentHash ().ToBase32 ();
s << "<div class='slide'><label for='slide-regaddr'><b>" << tr("Address registration line") << "</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n" s << "<div class='slide'><label for='slide-regaddr'><b>" << tr("Address registration line") << "</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
"<form method=\"get\" action=\"" << webroot << "\">\r\n" "<form method=\"get\" action=\"" << webroot << "\">\r\n"
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n" " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n" " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
" <input type=\"hidden\" name=\"b32\" value=\"" << dest->GetIdentHash ().ToBase32 () << "\">\r\n" " <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
" <b>" << tr("Domain") << ":</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n" " <b>" << tr("Domain") << ":</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
" <button type=\"submit\">" << tr("Generate") << "</button>\r\n" " <button type=\"submit\">" << tr("Generate") << "</button>\r\n"
"</form>\r\n<small>" << tr("<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "</small>\r\n</div>\r\n</div>\r\n<br>\r\n"; "</form>\r\n<small>" << tr("<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
@@ -458,23 +440,9 @@ namespace http {
if (dest->GetNumRemoteLeaseSets()) if (dest->GetNumRemoteLeaseSets())
{ {
s << "<div class='slide'><label for='slide-lease'><b>" << tr("LeaseSets") << ":</b> <i>" << dest->GetNumRemoteLeaseSets () s << "<div class='slide'><label for='slide-lease'><b>" << tr("LeaseSets") << ":</b> <i>" << dest->GetNumRemoteLeaseSets ()
<< "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n" << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n<table><thead><th>"<< tr("Address") << "</th><th>" << tr("Type") << "</th><th>" << tr("EncType") << "</th></thead><tbody class=\"tableitem\">";
<< "<table><thead>"
<< "<th>" << tr("Address") << "</th>"
<< "<th style=\"width:5px;\">&nbsp;</th>" // LeaseSet expiration button column
<< "<th>" << tr("Type") << "</th>"
<< "<th>" << tr("EncType") << "</th>"
<< "</thead><tbody class=\"tableitem\">";
for(auto& it: dest->GetLeaseSets ()) for(auto& it: dest->GetLeaseSets ())
{ s << "<tr><td>" << it.first.ToBase32 () << "</td><td>" << (int)it.second->GetStoreType () << "</td><td>" << (int)it.second->GetEncryptionType () <<"</td></tr>\r\n";
s << "<tr>"
<< "<td>" << it.first.ToBase32 () << "</td>"
<< "<td><a class=\"button\" href=\"/?cmd=" << HTTP_COMMAND_EXPIRELEASE<< "&b32=" << dest->GetIdentHash ().ToBase32 ()
<< "&lease=" << it.first.ToBase32 () << "&token=" << token << "\" title=\"" << tr("Expire LeaseSet") << "\"> &#10008; </a></td>"
<< "<td>" << (int)it.second->GetStoreType () << "</td>"
<< "<td>" << (int)it.second->GetEncryptionType () <<"</td>"
<< "</tr>\r\n";
}
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n"; s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
} else } else
s << "<b>" << tr("LeaseSets") << ":</b> <i>0</i><br>\r\n<br>\r\n"; s << "<b>" << tr("LeaseSets") << ":</b> <i>0</i><br>\r\n<br>\r\n";
@@ -491,15 +459,13 @@ namespace http {
it->VisitTunnelHops( it->VisitTunnelHops(
[&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent) [&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent)
{ {
s << "&#8658; "; s << "&#8658; " << i2p::data::GetIdentHashAbbreviation (hopIdent->GetIdentHash ()) << " ";
ShowHop(s, *hopIdent);
s << " ";
} }
); );
} }
s << "&#8658; " << it->GetTunnelID () << ":me"; s << "&#8658; " << it->GetTunnelID () << ":me";
if (it->LatencyIsKnown()) if (it->LatencyIsKnown())
s << " ( " << tr(/* tr: Milliseconds */ "%dms", it->GetMeanLatency()) << " )"; s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
s << "</div>\r\n"; s << "</div>\r\n";
} }
@@ -514,33 +480,27 @@ namespace http {
it->VisitTunnelHops( it->VisitTunnelHops(
[&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent) [&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent)
{ {
s << " "; s << " " << i2p::data::GetIdentHashAbbreviation (hopIdent->GetIdentHash ()) << " &#8658;";
ShowHop(s, *hopIdent);
s << " &#8658;";
} }
); );
} }
if (it->LatencyIsKnown()) if (it->LatencyIsKnown())
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
s << "</div>\r\n"; s << "</div>\r\n";
} }
} }
s << "<br>\r\n"; s << "<br>\r\n";
s << "<b>" << tr("Tags") << "</b><br>\r\n" s << "<b>" << tr("Tags") << "</b><br>\r\n" << tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
<< tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
if (!dest->GetSessions ().empty ()) { if (!dest->GetSessions ().empty ()) {
std::stringstream tmp_s; uint32_t out_tags = 0; std::stringstream tmp_s; uint32_t out_tags = 0;
for (const auto& it: dest->GetSessions ()) { for (const auto& it: dest->GetSessions ()) {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n"; tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
out_tags += it.second->GetNumOutgoingTags (); out_tags += it.second->GetNumOutgoingTags ();
} }
s << "<div class='slide'><label for='slide-tags'>" << tr("Outgoing") << ": <i>" << out_tags << "</i></label>\r\n" s << "<div class='slide'><label for='slide-tags'>" << tr("Outgoing") << ": <i>" << out_tags << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-tags\" />\r\n"
<< "<input type=\"checkbox\" id=\"slide-tags\" />\r\n" << "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Amount") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
<< "<div class=\"slidecontent\">\r\n"
<< "<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Amount") << "</th></thead>\r\n"
<< "<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
} else } else
s << tr("Outgoing") << ": <i>0</i><br>\r\n"; s << tr("Outgoing") << ": <i>0</i><br>\r\n";
s << "<br>\r\n"; s << "<br>\r\n";
@@ -555,11 +515,8 @@ namespace http {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n"; tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
ecies_sessions++; ecies_sessions++;
} }
s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("Tags sessions") << ": <i>" << ecies_sessions << "</i></label>\r\n" s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("Tags sessions") << ": <i>" << ecies_sessions << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-ecies-sessions\" />\r\n"
<< "<input type=\"checkbox\" id=\"slide-ecies-sessions\" />\r\n" << "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Status") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
<< "<div class=\"slidecontent\">\r\n<table>\r\n"
<< "<thead><th>" << tr("Destination") << "</th><th>" << tr("Status") << "</th></thead>\r\n"
<< "<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
} else } else
s << tr("Tags sessions") << ": <i>0</i><br>\r\n"; s << tr("Tags sessions") << ": <i>0</i><br>\r\n";
s << "<br>\r\n"; s << "<br>\r\n";
@@ -582,7 +539,7 @@ namespace http {
<< tr("Streams") << tr("Streams")
<< "</caption>\r\n<thead>\r\n<tr>" << "</caption>\r\n<thead>\r\n<tr>"
<< "<th style=\"width:25px;\">StreamID</th>" << "<th style=\"width:25px;\">StreamID</th>"
<< "<th style=\"width:5px;\">&nbsp;</th>" // Stream closing button column << "<th style=\"width:5px;\" \\>" // Stream closing button column
<< "<th class=\"streamdest\">Destination</th>" << "<th class=\"streamdest\">Destination</th>"
<< "<th>Sent</th>" << "<th>Sent</th>"
<< "<th>Received</th>" << "<th>Received</th>"
@@ -619,8 +576,6 @@ namespace http {
} }
s << "</tbody>\r\n</table>"; s << "</tbody>\r\n</table>";
} }
else
ShowError(s, tr("Such destination is not found"));
} }
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
@@ -655,10 +610,7 @@ namespace http {
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET)
ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
else else
{ ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
ls.reset (new i2p::data::LeaseSet2 (storeType));
ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false);
}
if (!ls) return; if (!ls) return;
s << "<div class=\"leaseset listitem"; s << "<div class=\"leaseset listitem";
if (ls->IsExpired()) if (ls->IsExpired())
@@ -689,7 +641,7 @@ namespace http {
} }
else if (!i2p::context.IsFloodfill ()) else if (!i2p::context.IsFloodfill ())
{ {
s << "<b>" << tr("LeaseSets") << ":</b> " << tr(/* Message on LeaseSets page */ "floodfill mode is disabled") << ".<br>\r\n"; s << "<b>" << tr("LeaseSets") << ":</b> " << tr("not floodfill") << ".<br>\r\n";
} }
else else
{ {
@@ -712,15 +664,13 @@ namespace http {
it->VisitTunnelHops( it->VisitTunnelHops(
[&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent) [&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent)
{ {
s << "&#8658; "; s << "&#8658; " << i2p::data::GetIdentHashAbbreviation (hopIdent->GetIdentHash ()) << " ";
ShowHop(s, *hopIdent);
s << " ";
} }
); );
} }
s << "&#8658; " << it->GetTunnelID () << ":me"; s << "&#8658; " << it->GetTunnelID () << ":me";
if (it->LatencyIsKnown()) if (it->LatencyIsKnown())
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
s << "</div>\r\n"; s << "</div>\r\n";
} }
@@ -735,14 +685,12 @@ namespace http {
it->VisitTunnelHops( it->VisitTunnelHops(
[&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent) [&s](std::shared_ptr<const i2p::data::IdentityEx> hopIdent)
{ {
s << " "; s << " " << i2p::data::GetIdentHashAbbreviation (hopIdent->GetIdentHash ()) << " &#8658;";
ShowHop(s, *hopIdent);
s << " &#8658;";
} }
); );
} }
if (it->LatencyIsKnown()) if (it->LatencyIsKnown())
s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ()); ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
s << "</div>\r\n"; s << "</div>\r\n";
} }
@@ -780,21 +728,19 @@ namespace http {
s << "<br>\r\n<small>" << tr("<b>Note:</b> any action done here are not persistent and not changes your config files.") << "</small>\r\n<br>\r\n"; s << "<br>\r\n<small>" << tr("<b>Note:</b> any action done here are not persistent and not changes your config files.") << "</small>\r\n<br>\r\n";
auto loglevel = i2p::log::Logger().GetLogLevel();
s << "<b>" << tr("Logging level") << "</b><br>\r\n"; s << "<b>" << tr("Logging level") << "</b><br>\r\n";
s << " <a class=\"button" << (loglevel == eLogNone ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n"; s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogCritical ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=critical&token=" << token << "\"> critical </a> \r\n"; s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogError ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n"; s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogWarning ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n"; s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\"> info </a> \r\n";
s << " <a class=\"button" << (loglevel == eLogInfo ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\"> info </a> \r\n"; s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
s << " <a class=\"button" << (loglevel == eLogDebug ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
uint32_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels (); uint16_t maxTunnels = GetMaxNumTransitTunnels ();
s << "<b>" << tr("Transit tunnels limit") << "</b><br>\r\n"; s << "<b>" << tr("Transit tunnels limit") << "</b><br>\r\n";
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n"; s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_LIMITTRANSIT << "\">\r\n"; s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_LIMITTRANSIT << "\">\r\n";
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"; s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
s << " <input type=\"number\" min=\"0\" max=\"" << TRANSIT_TUNNELS_LIMIT <<"\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n"; s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n"; s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
s << "</form>\r\n<br>\r\n"; s << "</form>\r\n<br>\r\n";
@@ -824,71 +770,56 @@ namespace http {
{ {
if (i2p::tunnel::tunnels.CountTransitTunnels()) if (i2p::tunnel::tunnels.CountTransitTunnels())
{ {
s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n"; s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
s << "<table><thead><th>&#8658;</th><th>ID</th><th>&#8658;</th><th>" << tr("Amount") << "</th></thead><tbody class=\"tableitem\">";
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
{ {
s << "<div class=\"listitem\">\r\n";
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it)) if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
s << "<tr><td></td><td>" << it->GetTunnelID () << "</td><td>&#8658;</td><td>"; s << it->GetTunnelID () << " &#8658; ";
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it)) else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
s << "<tr><td>&#8658;</td><td>" << it->GetTunnelID () << "</td><td></td><td>"; s << " &#8658; " << it->GetTunnelID ();
else else
s << "<tr><td>&#8658;</td><td>" << it->GetTunnelID () << "</td><td>&#8658;</td><td>"; s << " &#8658; " << it->GetTunnelID () << " &#8658; ";
ShowTraffic(s, it->GetNumTransmittedBytes ()); s << " " << it->GetNumTransmittedBytes () << "</div>\r\n";
s << "</td></tr>\r\n";
} }
s << "</tbody></table>\r\n"; s << "</div>\r\n";
} }
else else
{ {
s << "<b>" << tr("Transit Tunnels") << ":</b> " << tr(/* Message on transit tunnels page */ "no transit tunnels currently built") << ".<br>\r\n"; s << "<b>" << tr("Transit Tunnels") << ":</b> " << tr("no transit tunnels currently built") << ".<br>\r\n";
} }
} }
template<typename Sessions> template<typename Sessions>
static void ShowTransportSessions (std::stringstream& s, const Sessions& sessions, const std::string name) static void ShowTransportSessions (std::stringstream& s, const Sessions& sessions, const std::string name)
{ {
auto comp = [](typename Sessions::mapped_type a, typename Sessions::mapped_type b)
{ return a->GetRemoteEndpoint() < b->GetRemoteEndpoint(); };
std::set<typename Sessions::mapped_type, decltype(comp)> sortedSessions(comp);
for (const auto& it : sessions)
{
auto ret = sortedSessions.insert(it.second);
if (!ret.second)
LogPrint(eLogError, "HTTPServer: Duplicate remote endpoint detected: ", (*ret.first)->GetRemoteEndpoint());
}
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0; std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
for (const auto& it: sortedSessions) for (const auto& it: sessions )
{ {
auto endpoint = it->GetRemoteEndpoint (); auto endpoint = it.second->GetRemoteEndpoint ();
if (it && it->IsEstablished () && endpoint.address ().is_v4 ()) if (it.second && it.second->IsEstablished () && endpoint.address ().is_v4 ())
{ {
tmp_s << "<div class=\"listitem\">\r\n"; tmp_s << "<div class=\"listitem\">\r\n";
if (it->IsOutgoing ()) tmp_s << " &#8658; "; if (it.second->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": " tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
<< endpoint.address ().to_string () << ":" << endpoint.port (); << endpoint.address ().to_string () << ":" << endpoint.port ();
if (!it->IsOutgoing ()) tmp_s << " &#8658; "; if (!it.second->IsOutgoing ()) tmp_s << " &#8658; ";
tmp_s << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]"; tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
if (it->GetRelayTag ()) if (it.second->GetRelayTag ())
tmp_s << " [itag:" << it->GetRelayTag () << "]"; tmp_s << " [itag:" << it.second->GetRelayTag () << "]";
if (it->GetSendQueueSize () > 0)
tmp_s << " [queue:" << it->GetSendQueueSize () << "]";
if (it->IsSlow ()) tmp_s << " [slow]";
tmp_s << "</div>\r\n" << std::endl; tmp_s << "</div>\r\n" << std::endl;
cnt++; cnt++;
} }
if (it && it->IsEstablished () && endpoint.address ().is_v6 ()) if (it.second && it.second->IsEstablished () && endpoint.address ().is_v6 ())
{ {
tmp_s6 << "<div class=\"listitem\">\r\n"; tmp_s6 << "<div class=\"listitem\">\r\n";
if (it->IsOutgoing ()) tmp_s6 << " &#8658; "; if (it.second->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": " tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
<< "[" << endpoint.address ().to_string () << "]:" << endpoint.port (); << "[" << endpoint.address ().to_string () << "]:" << endpoint.port ();
if (!it->IsOutgoing ()) tmp_s6 << " &#8658; "; if (!it.second->IsOutgoing ()) tmp_s6 << " &#8658; ";
tmp_s6 << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]"; tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
if (it->GetRelayTag ()) if (it.second->GetRelayTag ())
tmp_s6 << " [itag:" << it->GetRelayTag () << "]"; tmp_s6 << " [itag:" << it.second->GetRelayTag () << "]";
if (it->GetSendQueueSize () > 0)
tmp_s6 << " [queue:" << it->GetSendQueueSize () << "]";
tmp_s6 << "</div>\r\n" << std::endl; tmp_s6 << "</div>\r\n" << std::endl;
cnt6++; cnt6++;
} }
@@ -948,7 +879,7 @@ namespace http {
s << "</div>\r\n"; s << "</div>\r\n";
} }
else else
s << "<b>" << tr("SAM sessions") << ":</b> " << tr(/* Message on SAM sessions page */ "no sessions currently running") << ".<br>\r\n"; s << "<b>" << tr("SAM sessions") << ":</b> " << tr("no sessions currently running") << ".<br>\r\n";
} }
void ShowSAMSession (std::stringstream& s, const std::string& id) void ShowSAMSession (std::stringstream& s, const std::string& id)
@@ -992,42 +923,34 @@ namespace http {
void ShowI2PTunnels (std::stringstream& s) void ShowI2PTunnels (std::stringstream& s)
{ {
std::string webroot; i2p::config::GetOption("http.webroot", webroot); std::string webroot; i2p::config::GetOption("http.webroot", webroot);
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
auto& clientTunnels = i2p::client::context.GetClientTunnels (); for (auto& it: i2p::client::context.GetClientTunnels ())
auto httpProxy = i2p::client::context.GetHttpProxy ();
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (!clientTunnels.empty () || httpProxy || socksProxy)
{ {
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n"; auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
if (!clientTunnels.empty ()) s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
{ s << it.second->GetName () << "</a> &#8656; ";
for (auto& it: clientTunnels) s << i2p::client::context.GetAddressBook ().ToAddress(ident);
{ s << "</div>\r\n"<< std::endl;
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << it.second->GetName () << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
}
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "HTTP " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "SOCKS " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
s << "</div>\r\n";
} }
auto httpProxy = i2p::client::context.GetHttpProxy ();
if (httpProxy)
{
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "HTTP " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "SOCKS " << tr("Proxy") << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl;
}
s << "</div>\r\n";
auto& serverTunnels = i2p::client::context.GetServerTunnels (); auto& serverTunnels = i2p::client::context.GetServerTunnels ();
if (!serverTunnels.empty ()) { if (!serverTunnels.empty ()) {
@@ -1065,7 +988,7 @@ namespace http {
for (auto& it: serverForwards) for (auto& it: serverForwards)
{ {
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">"; s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << it.second->GetName () << "</a> &#8656; "; s << it.second->GetName () << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "</div>\r\n"<< std::endl; s << "</div>\r\n"<< std::endl;
@@ -1275,7 +1198,7 @@ namespace http {
url.parse_query(params); url.parse_query(params);
std::string webroot; i2p::config::GetOption("http.webroot", webroot); std::string webroot; i2p::config::GetOption("http.webroot", webroot);
std::string redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=commands"; std::string redirect = "5; url=" + webroot + "?page=commands";
std::string token = params["token"]; std::string token = params["token"];
if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ())
@@ -1349,50 +1272,20 @@ namespace http {
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("StreamID can't be null") << "<br>\r\n<br>\r\n"; s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("StreamID can't be null") << "<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n"; s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>"; s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32; redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
res.add_header("Refresh", redirect.c_str());
return;
}
else if (cmd == HTTP_COMMAND_EXPIRELEASE)
{
std::string b32 = params["b32"];
std::string lease = params["lease"];
i2p::data::IdentHash ident, leaseident;
ident.FromBase32 (b32);
leaseident.FromBase32 (lease);
auto dest = i2p::client::context.FindLocalDestination (ident);
if (dest)
{
auto leaseset = dest->FindLeaseSet (leaseident);
if (leaseset)
{
leaseset->ExpireLease ();
s << "<b>" << tr("SUCCESS") << "</b>:&nbsp;" << tr("LeaseSet expiration time updated") << "<br>\r\n<br>\r\n";
}
else
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("LeaseSet is not found or already expired") << "<br>\r\n<br>\r\n";
}
else
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Destination not found") << "<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>";
redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32;
res.add_header("Refresh", redirect.c_str()); res.add_header("Refresh", redirect.c_str());
return; return;
} }
else if (cmd == HTTP_COMMAND_LIMITTRANSIT) else if (cmd == HTTP_COMMAND_LIMITTRANSIT)
{ {
uint32_t limit = std::stoul(params["limit"], nullptr); uint32_t limit = std::stoul(params["limit"], nullptr);
if (limit > 0 && limit <= TRANSIT_TUNNELS_LIMIT) if (limit > 0 && limit <= 65535)
i2p::tunnel::tunnels.SetMaxNumTransitTunnels (limit); SetMaxNumTransitTunnels (limit);
else { else {
s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\r\n<br>\r\n<br>\r\n"; s << "<b>" << tr("ERROR") << "</b>:&nbsp;" << tr("Transit tunnels count must not exceed 65535") << "\r\n<br>\r\n<br>\r\n";
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n"; s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>"; s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
res.add_header("Refresh", redirect.c_str()); res.add_header("Refresh", redirect.c_str());
return; return;
} }
@@ -1467,7 +1360,7 @@ namespace http {
s << "<b>" << tr("SUCCESS") << "</b>:&nbsp;" << tr("Command accepted") << "<br><br>\r\n"; s << "<b>" << tr("SUCCESS") << "</b>:&nbsp;" << tr("Command accepted") << "<br><br>\r\n";
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a><br>\r\n"; s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a><br>\r\n";
s << "<p>" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << "</b>"; s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
res.add_header("Refresh", redirect.c_str()); res.add_header("Refresh", redirect.c_str());
} }
@@ -1480,7 +1373,7 @@ namespace http {
reply.body = content; reply.body = content;
m_SendBuffer = reply.to_string(); m_SendBuffer = reply.to_string();
boost::asio::async_write (*m_Socket, boost::asio::buffer(m_SendBuffer), boost::asio::transfer_all (), boost::asio::async_write (*m_Socket, boost::asio::buffer(m_SendBuffer),
std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1)); std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1));
} }

View File

@@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -24,8 +24,6 @@ namespace http
{ {
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds
const int COMMAND_REDIRECT_TIMEOUT = 5; // in seconds
const int TRANSIT_TUNNELS_LIMIT = 1000000;
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection> class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2023, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -38,7 +38,7 @@ namespace http
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n" "@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n"
"body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n" "body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n"
"a, .slide label { text-decoration: none; color: var(--main-link-color); }\r\n" "a, .slide label { text-decoration: none; color: var(--main-link-color); }\r\n"
"a:hover, a.button.selected, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n" "a:hover, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n"
"a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color); }\r\n" "a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color); }\r\n"
".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color); }\r\n" ".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color); }\r\n"
".wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" ".wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n"

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -8,12 +8,14 @@
#include <stdio.h> #include <stdio.h>
#include <sstream> #include <sstream>
#include <iomanip>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
// Use global placeholders from boost introduced when local_time.hpp is loaded // Use global placeholders from boost introduced when local_time.hpp is loaded
#define BOOST_BIND_GLOBAL_PLACEHOLDERS #define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@@ -256,9 +258,9 @@ namespace client
header << "Content-Length: " << boost::lexical_cast<std::string>(len) << "\r\n"; header << "Content-Length: " << boost::lexical_cast<std::string>(len) << "\r\n";
header << "Content-Type: application/json\r\n"; header << "Content-Type: application/json\r\n";
header << "Date: "; header << "Date: ";
std::time_t t = std::time (nullptr); auto facet = new boost::local_time::local_time_facet ("%a, %d %b %Y %H:%M:%S GMT");
std::tm tm = *std::gmtime (&t); header.imbue(std::locale (header.getloc(), facet));
header << std::put_time(&tm, "%a, %d %b %Y %T GMT") << "\r\n"; header << boost::posix_time::second_clock::local_time() << "\r\n";
header << "\r\n"; header << "\r\n";
offset = header.str ().size (); offset = header.str ().size ();
memcpy (buf->data (), header.str ().c_str (), offset); memcpy (buf->data (), header.str ().c_str (), offset);
@@ -336,11 +338,10 @@ namespace client
{ {
for (auto it = params.begin (); it != params.end (); it++) for (auto it = params.begin (); it != params.end (); it++)
{ {
if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first); LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
auto it1 = m_RouterManagerHandlers.find (it->first); auto it1 = m_RouterManagerHandlers.find (it->first);
if (it1 != m_RouterManagerHandlers.end ()) if (it1 != m_RouterManagerHandlers.end ()) {
{
if (it != params.begin ()) results << ",";
(this->*(it1->second))(results); (this->*(it1->second))(results);
} else } else
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first); LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);

View File

@@ -1,15 +1,10 @@
/*
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifdef USE_UPNP #ifdef USE_UPNP
#include <string> #include <string>
#include <thread> #include <thread>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include "Log.h" #include "Log.h"
#include "RouterContext.h" #include "RouterContext.h"
@@ -115,16 +110,10 @@ namespace transport
return; return;
} }
#if (MINIUPNPC_API_VERSION >= 18)
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr),
m_externalIPAddress, sizeof (m_externalIPAddress));
#else
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
#endif
m_upnpUrlsInitialized=err!=0; m_upnpUrlsInitialized=err!=0;
if (err == UPNP_IGD_VALID_CONNECTED) if (err == UPNP_IGD_VALID_CONNECTED)
{ {
#if (MINIUPNPC_API_VERSION < 18)
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
if(err != UPNPCOMMAND_SUCCESS) if(err != UPNPCOMMAND_SUCCESS)
{ {
@@ -132,7 +121,6 @@ namespace transport
return; return;
} }
else else
#endif
{ {
LogPrint (eLogError, "UPnP: Found Internet Gateway Device ", m_upnpUrls.controlURL); LogPrint (eLogError, "UPnP: Found Internet Gateway Device ", m_upnpUrls.controlURL);
if (!m_externalIPAddress[0]) if (!m_externalIPAddress[0])
@@ -175,14 +163,14 @@ namespace transport
if (!a) return; if (!a) return;
for (const auto& address : *a) for (const auto& address : *a)
{ {
if (address && !address->host.is_v6 () && address->port) if (!address->host.is_v6 () && address->port)
TryPortMapping (address); TryPortMapping (address);
} }
m_Timer.expires_from_now (boost::posix_time::minutes(UPNP_PORT_FORWARDING_INTERVAL)); // every 20 minutes m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
m_Timer.async_wait ([this](const boost::system::error_code& ecode) m_Timer.async_wait ([this](const boost::system::error_code& ecode)
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
PortMapping (); PortMapping ();
}); });
} }
@@ -227,7 +215,7 @@ namespace transport
if (!a) return; if (!a) return;
for (const auto& address : *a) for (const auto& address : *a)
{ {
if (address && !address->host.is_v6 () && address->port) if (!address->host.is_v6 () && address->port)
CloseMapping (address); CloseMapping (address);
} }
} }

View File

@@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -28,8 +28,7 @@ namespace i2p
namespace transport namespace transport
{ {
const int UPNP_RESPONSE_TIMEOUT = 2000; // in milliseconds const int UPNP_RESPONSE_TIMEOUT = 2000; // in milliseconds
const int UPNP_PORT_FORWARDING_INTERVAL = 20; // in minutes
enum enum
{ {
UPNP_IGD_NONE = 0, UPNP_IGD_NONE = 0,

View File

@@ -162,27 +162,18 @@ namespace i2p
#ifndef ANDROID #ifndef ANDROID
if (lockf(pidFH, F_TLOCK, 0) != 0) if (lockf(pidFH, F_TLOCK, 0) != 0)
#else
struct flock fl;
fl.l_len = 0;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
if (fcntl(pidFH, F_SETLK, &fl) != 0)
#endif
{ {
LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno)); LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl; std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl;
return false; return false;
} }
#endif
char pid[10]; char pid[10];
sprintf(pid, "%d\n", getpid()); sprintf(pid, "%d\n", getpid());
ftruncate(pidFH, 0); ftruncate(pidFH, 0);
if (write(pidFH, pid, strlen(pid)) < 0) if (write(pidFH, pid, strlen(pid)) < 0)
{ {
LogPrint(eLogCritical, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno)); LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl; std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl;
return false; return false;
} }

5
debian/NEWS vendored
View File

@@ -1,5 +0,0 @@
i2pd (2.53.0-1) unstable; urgency=medium
i2pd binary moved from /usr/sbin to /usr/bin. Please check your scripts if you used the old path.
-- r4sas <r4sas@i2pmail.org> Fri, 19 Jul 2024 16:00:00 +0000

102
debian/changelog vendored
View File

@@ -1,105 +1,3 @@
i2pd (2.54.0-1) unstable; urgency=medium
* updated to version 2.54.0/0.9.64
-- orignal <orignal@i2pmail.org> Sun, 6 Oct 2024 16:00:00 +0000
i2pd (2.53.1-1) unstable; urgency=medium
* updated to version 2.53.1
-- orignal <orignal@i2pmail.org> Tue, 30 Jul 2024 16:00:00 +0000
i2pd (2.53.0-1) unstable; urgency=medium
* updated to version 2.53.0/0.9.63
* binary moved from /usr/sbin to /usr/bin
-- r4sas <r4sas@i2pmail.org> Sat, 20 Jul 2024 15:10:00 +0000
i2pd (2.52.0-1) unstable; urgency=medium
* updated to version 2.52.0
-- orignal <orignal@i2pmail.org> Sun, 12 May 2024 16:00:00 +0000
i2pd (2.51.0-1) unstable; urgency=medium
* updated to version 2.51.0/0.9.62
-- orignal <orignal@i2pmail.org> Sat, 06 Apr 2024 16:00:00 +0000
i2pd (2.50.2-1) unstable; urgency=medium
* updated to version 2.50.2/0.9.61
-- orignal <orignal@i2pmail.org> Sat, 06 Jan 2024 16:00:00 +0000
i2pd (2.50.1-1) unstable; urgency=medium
* updated to version 2.50.1/0.9.61
-- r4sas <r4sas@i2pmail.org> Sat, 23 Dec 2023 18:30:00 +0000
i2pd (2.50.0-1) unstable; urgency=medium
* updated to version 2.50.0/0.9.61
-- orignal <orignal@i2pmail.org> Mon, 18 Dec 2023 16:00:00 +0000
i2pd (2.49.0-1) unstable; urgency=medium
* updated to version 2.49.0/0.9.60
-- orignal <orignal@i2pmail.org> Mon, 18 Sep 2023 16:00:00 +0000
i2pd (2.48.0-1) unstable; urgency=high
* updated to version 2.48.0/0.9.59
-- orignal <orignal@i2pmail.org> Mon, 12 Jun 2023 16:00:00 +0000
i2pd (2.47.0-1) unstable; urgency=high
* updated to version 2.47.0/0.9.58
-- orignal <orignal@i2pmail.org> Sat, 11 Mar 2023 16:00:00 +0000
i2pd (2.46.1-2) unstable; urgency=critical
* re-pushed release due to new critical bug
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 23:40:00 +0000
i2pd (2.46.1-1) unstable; urgency=high
* updated to version 2.46.1/0.9.57
-- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 02:45:00 +0000
i2pd (2.46.0-1) unstable; urgency=high
* updated to version 2.46.0/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 15 Feb 2023 19:00:00 +0000
i2pd (2.45.1-1) unstable; urgency=medium
* updated to version 2.45.1/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
i2pd (2.45.0-1) unstable; urgency=high
* updated to version 2.45.0/0.9.57
* compat level 12
* standards version 4.3.0
* increased nofile limit in service and init.d to 8192
* added conffiles
* removed #1210 patch
-- r4sas <r4sas@i2pmail.org> Tue, 3 Jan 2023 18:00:00 +0000
i2pd (2.44.0-1) unstable; urgency=medium i2pd (2.44.0-1) unstable; urgency=medium
* updated to version 2.44.0/0.9.56 * updated to version 2.44.0/0.9.56

2
debian/compat vendored
View File

@@ -1 +1 @@
12 9

4
debian/control vendored
View File

@@ -2,8 +2,8 @@ Source: i2pd
Section: net Section: net
Priority: optional Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org> Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 12~), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 4.3.0 Standards-Version: 3.9.8
Homepage: http://i2pd.website/ Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd Vcs-Browser: https://github.com/PurpleI2P/i2pd

6
debian/copyright vendored
View File

@@ -3,18 +3,18 @@ Upstream-Name: i2pd
Source: https://github.com/PurpleI2P Source: https://github.com/PurpleI2P
Files: * Files: *
Copyright: 2013-2023 PurpleI2P Copyright: 2013-2020 PurpleI2P
License: BSD-3-clause License: BSD-3-clause
Files: debian/* Files: debian/*
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org> Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
2014-2016 hagen <hagen@i2pmail.org> 2014-2016 hagen <hagen@i2pmail.org>
2016-2023 R4SAS <r4sas@i2pmail.org> 2016-2020 R4SAS <r4sas@i2pmail.org>
2017-2020 Yangfl <mmyangfl@gmail.com> 2017-2020 Yangfl <mmyangfl@gmail.com>
License: GPL-2+ License: GPL-2+
License: BSD-3-clause License: BSD-3-clause
Copyright (c) 2013-2023, The PurpleI2P Project Copyright (c) 2013-2017, The PurpleI2P Project
. .
All rights reserved. All rights reserved.
. .

2
debian/i2pd.1 vendored
View File

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

2
debian/i2pd.default vendored
View File

@@ -8,4 +8,4 @@ I2PD_ENABLED="yes"
DAEMON_OPTS="" DAEMON_OPTS=""
# If you have problems with hunging i2pd, you can try enable this # If you have problems with hunging i2pd, you can try enable this
ulimit -n 8192 ulimit -n 4096

2
debian/i2pd.init vendored
View File

@@ -13,7 +13,7 @@
PATH=/sbin:/usr/sbin:/bin:/usr/bin PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=i2pd # Introduce a short description here DESC=i2pd # Introduce a short description here
NAME=i2pd # Introduce the short server's name here NAME=i2pd # Introduce the short server's name here
DAEMON=/usr/bin/$NAME # Introduce the server's location here DAEMON=/usr/sbin/$NAME # Introduce the server's location here
DAEMON_OPTS="" # Arguments to run the daemon with DAEMON_OPTS="" # Arguments to run the daemon with
PIDFILE=/var/run/$NAME/$NAME.pid PIDFILE=/var/run/$NAME/$NAME.pid
I2PCONF=/etc/$NAME/i2pd.conf I2PCONF=/etc/$NAME/i2pd.conf

5
debian/i2pd.install vendored
View File

@@ -1,6 +1,7 @@
i2pd usr/bin/ i2pd usr/sbin/
contrib/i2pd.conf etc/i2pd/ contrib/i2pd.conf etc/i2pd/
contrib/tunnels.conf etc/i2pd/ contrib/tunnels.conf etc/i2pd/
contrib/subscriptions.txt etc/i2pd/
contrib/certificates/ usr/share/i2pd/ contrib/certificates/ usr/share/i2pd/
contrib/tunnels.d/README etc/i2pd/tunnels.conf.d/ contrib/tunnels.d/README etc/i2pd/tunnels.conf.d/
contrib/apparmor/usr.bin.i2pd etc/apparmor.d contrib/apparmor/usr.sbin.i2pd etc/apparmor.d

3
debian/i2pd.links vendored
View File

@@ -1,4 +1,5 @@
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf
etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt
etc/i2pd/tunnels.conf.d var/lib/i2pd/tunnels.d etc/i2pd/tunnels.conf.d var/lib/i2pd/tunnels.d
usr/share/i2pd/certificates var/lib/i2pd/certificates usr/share/i2pd/certificates var/lib/i2pd/certificates

27
debian/patches/01-fix-1210.patch vendored Normal file
View File

@@ -0,0 +1,27 @@
Description: fix #1210
Disables two options, which not presented in old systemd versions
Author: r4sas <r4sas@i2pmail.org>
Bug: https://github.com/PurpleI2P/i2pd/issues/1210
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2020-05-25
Index: i2pd/contrib/i2pd.service
===================================================================
--- i2pd.orig/contrib/i2pd.service
+++ i2pd/contrib/i2pd.service
@@ -6,10 +6,10 @@ After=network.target
[Service]
User=i2pd
Group=i2pd
-RuntimeDirectory=i2pd
-RuntimeDirectoryMode=0700
-LogsDirectory=i2pd
-LogsDirectoryMode=0700
+#RuntimeDirectory=i2pd
+#RuntimeDirectoryMode=0700
+#LogsDirectory=i2pd
+#LogsDirectoryMode=0700
Type=forking
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/sh -c "kill -HUP $MAINPID"

View File

@@ -1,17 +0,0 @@
Description: Enable UPnP usage in package
Author: r4sas <r4sas@i2pmail.org>
Reviewed-By: r4sas <r4sas@i2pmail.org>
Last-Update: 2022-03-23
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -31,7 +31,7 @@ include filelist.mk
USE_AESNI := $(or $(USE_AESNI),yes)
USE_STATIC := $(or $(USE_STATIC),no)
-USE_UPNP := $(or $(USE_UPNP),no)
+USE_UPNP := $(or $(USE_UPNP),yes)
DEBUG := $(or $(DEBUG),yes)
# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string

View File

@@ -1 +1,2 @@
01-upnp.patch 01-fix-1210.patch
02-upnp.patch

2
debian/rules vendored
View File

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

3
debian/watch vendored
View File

@@ -1,4 +1,3 @@
version=4 version=4 opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \
https://github.com/PurpleI2P/i2pd/tags \ https://github.com/PurpleI2P/i2pd/tags \
(?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate (?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021-2023, The PurpleI2P Project * Copyright (c) 2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -31,16 +31,15 @@ namespace armenian // language namespace
static std::map<std::string, std::string> strings static std::map<std::string, std::string> strings
{ {
{"%.2f KiB", "%.2f ԿիԲ"}, {"KiB", "ԿիԲ"},
{"%.2f MiB", "%.2f ՄիԲ"}, {"MiB", "ՄիԲ"},
{"%.2f GiB", "%.2f ԳիԲ"}, {"GiB", "ԳիԲ"},
{"building", "կառուցվում է"}, {"building", "կառուցվում է"},
{"failed", "Անհաջող"}, {"failed", "Անհաջող"},
{"expiring", "Լրանում է"}, {"expiring", "Լրանում է"},
{"established", "կարգավոյված է"}, {"established", "կարգավոյված է"},
{"unknown", "անհայտ"}, {"unknown", "անհայտ"},
{"exploratory", "հետազոտոկան"}, {"exploratory", "հետազոտոկան"},
{"Purple I2P Webconsole", "Վեբ-կոնսոլ Purple I2P"},
{"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"}, {"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"},
{"Main page", "Գլխավոր էջ"}, {"Main page", "Գլխավոր էջ"},
{"Router commands", "Երթուղիչի հրահանգներ"}, {"Router commands", "Երթուղիչի հրահանգներ"},
@@ -58,10 +57,10 @@ namespace armenian // language namespace
{"Unknown", "Անհայտ"}, {"Unknown", "Անհայտ"},
{"Proxy", "Պրոկսի"}, {"Proxy", "Պրոկսի"},
{"Mesh", "MESH-ցանց"}, {"Mesh", "MESH-ցանց"},
{"Error", "Սխալ"},
{"Clock skew", "Ոչ ճշգրիտ ժամանակ"}, {"Clock skew", "Ոչ ճշգրիտ ժամանակ"},
{"Offline", "Օֆլայն"}, {"Offline", "Օֆլայն"},
{"Symmetric NAT", "Սիմետրիկ NAT"}, {"Symmetric NAT", "Սիմետրիկ NAT"},
{"Full cone NAT", "Full cone NAT"},
{"Uptime", "Առկայություն"}, {"Uptime", "Առկայություն"},
{"Network status", "Ցանցի կարգավիճակ"}, {"Network status", "Ցանցի կարգավիճակ"},
{"Network status v6", "Ցանցի կարգավիճակ v6"}, {"Network status v6", "Ցանցի կարգավիճակ v6"},
@@ -69,7 +68,7 @@ namespace armenian // language namespace
{"Family", "Խմբատեսակ"}, {"Family", "Խմբատեսակ"},
{"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"}, {"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"},
{"Received", "Ստացվել է"}, {"Received", "Ստացվել է"},
{"%.2f KiB/s", "%.2f ԿիԲ/վ"}, {"KiB/s", "ԿիԲ/վ"},
{"Sent", "Ուղարկվել է"}, {"Sent", "Ուղարկվել է"},
{"Transit", "Տարանցում"}, {"Transit", "Տարանցում"},
{"Data path", "Տվյալների ուղին"}, {"Data path", "Տվյալների ուղին"},
@@ -90,12 +89,12 @@ namespace armenian // language namespace
{"Address registration line", "Հասցեի գրանցման տող"}, {"Address registration line", "Հասցեի գրանցման տող"},
{"Domain", "Տիրույթ"}, {"Domain", "Տիրույթ"},
{"Generate", "Գեներացնել"}, {"Generate", "Գեներացնել"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը:"}, {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը"},
{"Address", "Հասցե"}, {"Address", "Հասցե"},
{"Type", "Տեսակը"}, {"Type", "Տեսակը"},
{"EncType", "Գաղտնագրի տեսակը"}, {"EncType", "Գաղտնագրի տեսակը"},
{"Inbound tunnels", "Մուտքային թունելներ"}, {"Inbound tunnels", "Մուտքային թունելներ"},
{"%dms", "%dմլվ"}, {"ms", "մլվ"},
{"Outbound tunnels", "Ելքային թունելներ"}, {"Outbound tunnels", "Ելքային թունելներ"},
{"Tags", "Թեգեր"}, {"Tags", "Թեգեր"},
{"Incoming", "Մուտքային"}, {"Incoming", "Մուտքային"},
@@ -113,10 +112,11 @@ namespace armenian // language namespace
{"Invalid", "Անվավեր"}, {"Invalid", "Անվավեր"},
{"Store type", "Պահեստավորման տեսակը"}, {"Store type", "Պահեստավորման տեսակը"},
{"Expires", "Սպառվում է"}, {"Expires", "Սպառվում է"},
{"Non Expired Leases", "Չսպառված Lease-եր"}, {"Non Expired Leases", "Չսպառված Lease-եր"},
{"Gateway", "Դարպաս"}, {"Gateway", "Դարպաս"},
{"TunnelID", "Թունելի ID"}, {"TunnelID", "Թունելի ID"},
{"EndDate", "Ավարտ"}, {"EndDate", "Ավարտ"},
{"not floodfill", "ոչ floodfill-ներ"},
{"Queue size", "Հերթի չափսը"}, {"Queue size", "Հերթի չափսը"},
{"Run peer test", "Գործարկել փորձարկումը"}, {"Run peer test", "Գործարկել փորձարկումը"},
{"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"}, {"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"},
@@ -146,7 +146,10 @@ namespace armenian // language namespace
{"Destination not found", "Հասցեի վայրը չի գտնվել"}, {"Destination not found", "Հասցեի վայրը չի գտնվել"},
{"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"}, {"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"},
{"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"}, {"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"},
{"You will be redirected in 5 seconds", "Դուք կտեղափոխվեք 5 վայրկյանից"},
{"Transit tunnels count must not exceed 65535", "Տարանցիկ թունելների քանակը չպետք է գերազանցի 65535-ը"},
{"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"}, {"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"},
{"Register at reg.i2p", "Գրանցել reg.i2p-ում"},
{"Description", "Նկարագրություն"}, {"Description", "Նկարագրություն"},
{"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"}, {"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"},
{"Submit", "Ուղարկվել"}, {"Submit", "Ուղարկվել"},
@@ -162,35 +165,43 @@ namespace armenian // language namespace
{"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"}, {"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"},
{"Invalid request", "Սխալ հարցում"}, {"Invalid request", "Սխալ հարցում"},
{"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"}, {"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"},
{"Invalid request URI", "Սխալ ձևավորված URI հարցում"}, {"addresshelper is not supported", "addresshelper-ը համատեղելի չէ"},
{"Host", "Հոսթ"},
{"added to router's addressbook from helper", "Ավելացված է երթուղիչի հասցեագրքում helper-ի միջոցով"},
{"Click here to proceed:", "Շարունակելու համար սեղմեք այստեղ"},
{"Continue", "Շարունակել"},
{"Addresshelper found", "addresshelper-ը գնտված է"},
{"already in router's addressbook", "արդեն առկա է երթուղիչի հասցեագրքում"},
{"Click here to update record:", "Սեղմեկ այստեղ որպեսզի թարվացնեք գրառումը"},
{"invalid request uri", "Սխալ ձևավորված URI հարցում"},
{"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"}, {"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"},
{"Outproxy failure", "Սխալ արտաքին պրոքսի"}, {"Outproxy failure", "Սխալ արտաքին պրոքսի"},
{"Bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"}, {"bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Հոսթ %s Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"}, {"not inside I2P network, but outproxy is not enabled", "Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
{"Unknown outproxy URL", "Արտաքին պրոքսիի անհայտ URL"}, {"unknown outproxy url", "արտաքին պրոքսիի անհայտ URL"},
{"Cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"}, {"cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
{"Hostname is too long", "Հոսթի անունը չափազանց երկար է"}, {"hostname too long", "Հոսթի անունը չափազանց երկար է"},
{"Cannot connect to upstream SOCKS proxy", "Չհաջողվեց միանալ վերադաս SOCKS պրոկսի սերվերին"}, {"cannot connect to upstream socks proxy", "չհաջողվեց միանալ վերադաս socks պրոկսիին"},
{"Cannot negotiate with SOCKS proxy", "Չհաջողվեց պայմանավորվել վերադաս SOCKS պրոկսիի հետ"}, {"Cannot negotiate with socks proxy", "Չհաջողվեց պայմանավորվել վերադաս socks պրոկսիի հետ"},
{"CONNECT error", "Սխալ CONNECT հարցում"}, {"CONNECT error", "Սխալ CONNECT հարցում"},
{"Failed to connect", "Միանալ չhաջողվեց"}, {"Failed to Connect", "Միանալ չhաջողվեց"},
{"SOCKS proxy error", "Սխալ SOCKS պրոկսի"}, {"socks proxy error", "Սխալ SOCKS պրոկսի"},
{"Failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"}, {"failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
{"No reply from SOCKS proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"}, {"No Reply From socks proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
{"Cannot connect", "Հնարավոր չե միանալ"}, {"cannot connect", "Հնարավոր չե միանալ"},
{"HTTP out proxy not implemented", "Արտաքին HTTP պրոկսին դեռ իրականացված չէ"}, {"http out proxy not implemented", "Արտաքին http պրոկսին դեռ իրականացված չէ"},
{"Cannot connect to upstream HTTP proxy", "Չհաջողվեց միանալ վերադաս HTTP պրոկսի սերվերին"}, {"cannot connect to upstream http proxy", "Չհաջողվեց միանալ վերադաս http պրոկսի սերվերին"},
{"Host is down", "Հոսթն անհասանելի է"}, {"Host is down", "Հոսթն անհասանելի է"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ:"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"},
{"", ""}, {"", ""},
}; };
static std::map<std::string, std::vector<std::string>> plurals static std::map<std::string, std::vector<std::string>> plurals
{ {
{"%d days", {"%d օր", "%d օր"}}, {"days", {"օր", "օր"}},
{"%d hours", {"%d ժամ", "%d ժամ"}}, {"hours", {"ժամ", "ժամ"}},
{"%d minutes", {"%d րոպե", "%d րոպե"}}, {"minutes", {"րոպե", "րոպե"}},
{"%d seconds", {"%d վարկյան", "%d վարկյան"}}, {"seconds", {"վարկյան", "վարկյան"}},
{"", {"", ""}}, {"", {"", ""}},
}; };

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022-2024, The PurpleI2P Project * Copyright (c) 2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -13,6 +13,7 @@
#include "I18N.h" #include "I18N.h"
// Simplified Chinese localization file // Simplified Chinese localization file
// This is an example translation file without strings in it.
namespace i2p namespace i2p
{ {
@@ -31,9 +32,9 @@ namespace chinese // language namespace
static std::map<std::string, std::string> strings static std::map<std::string, std::string> strings
{ {
{"%.2f KiB", "%.2f KiB"}, {"KiB", "KiB"},
{"%.2f MiB", "%.2f MiB"}, {"MiB", "MiB"},
{"%.2f GiB", "%.2f GiB"}, {"GiB", "GiB"},
{"building", "正在构建"}, {"building", "正在构建"},
{"failed", "连接失败"}, {"failed", "连接失败"},
{"expiring", "即将过期"}, {"expiring", "即将过期"},
@@ -45,7 +46,7 @@ namespace chinese // language namespace
{"Main page", "主页"}, {"Main page", "主页"},
{"Router commands", "路由命令"}, {"Router commands", "路由命令"},
{"Local Destinations", "本地目标"}, {"Local Destinations", "本地目标"},
{"LeaseSets", ""}, {"LeaseSets", ""},
{"Tunnels", "隧道"}, {"Tunnels", "隧道"},
{"Transit Tunnels", "中转隧道"}, {"Transit Tunnels", "中转隧道"},
{"Transports", "传输"}, {"Transports", "传输"},
@@ -57,21 +58,19 @@ namespace chinese // language namespace
{"Firewalled", "受到防火墙限制"}, {"Firewalled", "受到防火墙限制"},
{"Unknown", "未知"}, {"Unknown", "未知"},
{"Proxy", "代理"}, {"Proxy", "代理"},
{"Mesh", "组网"}, {"Mesh", "Mesh组网"},
{"Error", "错误"},
{"Clock skew", "时钟偏移"}, {"Clock skew", "时钟偏移"},
{"Offline", "离线"}, {"Offline", "离线"},
{"Symmetric NAT", "对称 NAT"}, {"Symmetric NAT", "对称 NAT"},
{"Full cone NAT", "全锥型NAT"},
{"No Descriptors", "无描述符"},
{"Uptime", "运行时间"}, {"Uptime", "运行时间"},
{"Network status", "网络状态"}, {"Network status", "IPv4 网络状态"},
{"Network status v6", "IPv6 网络状态"}, {"Network status v6", "IPv6 网络状态"},
{"Stopping in", "距停止还有:"}, {"Stopping in", "距停止还有:"},
{"Family", "家族"}, {"Family", "家族"},
{"Tunnel creation success rate", "隧道创建成功率"}, {"Tunnel creation success rate", "隧道创建成功率"},
{"Total tunnel creation success rate", "当前隧道创建成功率"},
{"Received", "已接收"}, {"Received", "已接收"},
{"%.2f KiB/s", "%.2f KiB/s"}, {"KiB/s", "KiB/s"},
{"Sent", "已发送"}, {"Sent", "已发送"},
{"Transit", "中转"}, {"Transit", "中转"},
{"Data path", "数据文件路径"}, {"Data path", "数据文件路径"},
@@ -92,13 +91,12 @@ namespace chinese // language namespace
{"Address registration line", "地址域名注册"}, {"Address registration line", "地址域名注册"},
{"Domain", "域名"}, {"Domain", "域名"},
{"Generate", "生成"}, {"Generate", "生成"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>注意:</b> 结果字符串只能用于注册级域名(例如example.i2p)。若需注册三级域名,请使用 i2pd-tools。"}, {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>注意:</b> 结果字符串只能用于注册级域名(例如example.i2p)。若需注册域名,请使用 i2pd-tools。"},
{"Address", "地址"}, {"Address", "地址"},
{"Type", "类型"}, {"Type", "类型"},
{"EncType", "加密类型"}, {"EncType", "加密类型"},
{"Expire LeaseSet", "到期租约集"},
{"Inbound tunnels", "入站隧道"}, {"Inbound tunnels", "入站隧道"},
{"%dms", "%dms"}, {"ms", "毫秒"},
{"Outbound tunnels", "出站隧道"}, {"Outbound tunnels", "出站隧道"},
{"Tags", "标签"}, {"Tags", "标签"},
{"Incoming", "传入"}, {"Incoming", "传入"},
@@ -111,7 +109,6 @@ namespace chinese // language namespace
{"Local Destination", "本地目标"}, {"Local Destination", "本地目标"},
{"Streams", ""}, {"Streams", ""},
{"Close stream", "断开流"}, {"Close stream", "断开流"},
{"Such destination is not found", "找不到此目标"},
{"I2CP session not found", "未找到 I2CP 会话"}, {"I2CP session not found", "未找到 I2CP 会话"},
{"I2CP is not enabled", "I2CP 未启用"}, {"I2CP is not enabled", "I2CP 未启用"},
{"Invalid", "无效"}, {"Invalid", "无效"},
@@ -121,10 +118,9 @@ namespace chinese // language namespace
{"Gateway", "网关"}, {"Gateway", "网关"},
{"TunnelID", "隧道 ID"}, {"TunnelID", "隧道 ID"},
{"EndDate", "结束日期"}, {"EndDate", "结束日期"},
{"floodfill mode is disabled", "洪泛已禁用"}, {"not floodfill", "洪泛"},
{"Queue size", "队列大小"}, {"Queue size", "队列大小"},
{"Run peer test", "运行节点测试"}, {"Run peer test", "运行节点测试"},
{"Reload tunnels configuration", "重新载入隧道配置"},
{"Decline transit tunnels", "拒绝中转隧道"}, {"Decline transit tunnels", "拒绝中转隧道"},
{"Accept transit tunnels", "允许中转隧道"}, {"Accept transit tunnels", "允许中转隧道"},
{"Cancel graceful shutdown", "取消平滑关闭"}, {"Cancel graceful shutdown", "取消平滑关闭"},
@@ -132,7 +128,7 @@ namespace chinese // language namespace
{"Force shutdown", "强制停止"}, {"Force shutdown", "强制停止"},
{"Reload external CSS styles", "重载外部 CSS 样式"}, {"Reload external CSS styles", "重载外部 CSS 样式"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>注意:</b> 此处完成的任何操作都不是永久的,不会更改您的配置文件。"}, {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>注意:</b> 此处完成的任何操作都不是永久的,不会更改您的配置文件。"},
{"Logging level", "日志级别"}, {"Logging level", "日志记录级别"},
{"Transit tunnels limit", "中转隧道限制"}, {"Transit tunnels limit", "中转隧道限制"},
{"Change", "修改"}, {"Change", "修改"},
{"Change language", "更改语言"}, {"Change language", "更改语言"},
@@ -152,10 +148,8 @@ namespace chinese // language namespace
{"Destination not found", "找不到目标"}, {"Destination not found", "找不到目标"},
{"StreamID can't be null", "StreamID 不能为空"}, {"StreamID can't be null", "StreamID 不能为空"},
{"Return to destination page", "返回目标页面"}, {"Return to destination page", "返回目标页面"},
{"You will be redirected in %d seconds", "您将在%d秒内被重定向"}, {"You will be redirected in 5 seconds", "您将在5秒内被重定向"},
{"LeaseSet expiration time updated", "租约集到期时间已更新"}, {"Transit tunnels count must not exceed 65535", "中转隧道数量不能超过 65535"},
{"LeaseSet is not found or already expired", "租约集未找到或已过期"},
{"Transit tunnels count must not exceed %d", "中转隧道数量限制为 %d"},
{"Back to commands list", "返回命令列表"}, {"Back to commands list", "返回命令列表"},
{"Register at reg.i2p", "在 reg.i2p 注册域名"}, {"Register at reg.i2p", "在 reg.i2p 注册域名"},
{"Description", "描述"}, {"Description", "描述"},
@@ -163,42 +157,42 @@ namespace chinese // language namespace
{"Submit", "提交"}, {"Submit", "提交"},
{"Domain can't end with .b32.i2p", "域名不能以 .b32.i2p 结尾"}, {"Domain can't end with .b32.i2p", "域名不能以 .b32.i2p 结尾"},
{"Domain must end with .i2p", "域名必须以 .i2p 结尾"}, {"Domain must end with .i2p", "域名必须以 .i2p 结尾"},
{"Such destination is not found", "找不到此目标"},
{"Unknown command", "未知指令"}, {"Unknown command", "未知指令"},
{"Command accepted", "已接受指令"}, {"Command accepted", "已接受指令"},
{"Proxy error", "代理错误"}, {"Proxy error", "代理错误"},
{"Proxy info", "代理信息"}, {"Proxy info", "代理信息"},
{"Proxy error: Host not found", "代理错误:未找到主机"}, {"Proxy error: Host not found", "代理错误:未找到主机"},
{"Remote host not found in router's addressbook", "在路由地址簿中未找到远程主机"}, {"Remote host not found in router's addressbook", "在路由地址簿中未找到远程主机"},
{"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到主机"}, {"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到主机"},
{"Invalid request", "无效请求"}, {"Invalid request", "无效请求"},
{"Proxy unable to parse your request", "代理无法解析您的请求"}, {"Proxy unable to parse your request", "代理无法解析您的请求"},
{"Addresshelper is not supported", "不支持地址助手"}, {"addresshelper is not supported", "不支持地址助手"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。<b>请注意:此地址的来源可能是有害的!</b>点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"}, {"Host", "主机"},
{"Addresshelper forced update rejected", "地址助手强制更新被拒绝"}, {"added to router's addressbook from helper", "将此地址从地址助手添加到路由地址簿"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "若要在路由器地址簿中添加主机 <b>%s</b> 请点击这里: <a href=\"%s%s%s\">继续</a>"}, {"Click here to proceed:", "点击此处继续:"},
{"Addresshelper request", "请求地址助手"}, {"Continue", "继续"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "主机 %s 已通过地址助手添加到路由地址簿中。点击此处继续:<a href=\"%s\">继续</a>"}, {"Addresshelper found", "已找到地址助手"},
{"Addresshelper adding", "正在添加地址助手"}, {"already in router's addressbook", "已在路由地址簿中"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"}, {"Click here to update record:", "点击此处更新地址簿记录"},
{"Addresshelper update", "更新地址助手"}, {"invalid request uri", "无效的 URL 请求"},
{"Invalid request URI", "无效的 URI 请求"},
{"Can't detect destination host from request", "无法从请求中检测到目标主机"}, {"Can't detect destination host from request", "无法从请求中检测到目标主机"},
{"Outproxy failure", "出口代理故障"}, {"Outproxy failure", "出口代理故障"},
{"Bad outproxy settings", "错误的出口代理设置"}, {"bad outproxy settings", "错误的出口代理设置"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "主机 %s 不在 I2P 网络内,但出口代理未启用"}, {"not inside I2P network, but outproxy is not enabled", "该地址不在 I2P 网络内,但未启用出口代理"},
{"Unknown outproxy URL", "未知的出口代理地址"}, {"unknown outproxy url", "未知的出口代理地址"},
{"Cannot resolve upstream proxy", "无法解析上游代理"}, {"cannot resolve upstream proxy", "无法解析上游代理"},
{"Hostname is too long", "主机名过长"}, {"hostname too long", "主机名过长"},
{"Cannot connect to upstream SOCKS proxy", "无法连接到上游 SOCKS 代理"}, {"cannot connect to upstream socks proxy", "无法连接到上游 socks 代理"},
{"Cannot negotiate with SOCKS proxy", "无法与 SOCKS 代理协商"}, {"Cannot negotiate with socks proxy", "无法与 socks 代理协商"},
{"CONNECT error", "连接错误"}, {"CONNECT error", "连接错误"},
{"Failed to connect", "连接失败"}, {"Failed to Connect", "连接失败"},
{"SOCKS proxy error", "SOCKS 代理错误"}, {"socks proxy error", "socks 代理错误"},
{"Failed to send request to upstream", "向上游发送请求失败"}, {"failed to send request to upstream", "向上游发送请求失败"},
{"No reply from SOCKS proxy", "没有来自 SOCKS 代理的回复"}, {"No Reply From socks proxy", "没有来自 socks 代理的回复"},
{"Cannot connect", "无法连接"}, {"cannot connect", "无法连接"},
{"HTTP out proxy not implemented", "HTTP 出口代理未实现"}, {"http out proxy not implemented", "http 出口代理未实现"},
{"Cannot connect to upstream HTTP proxy", "无法连接到上游 HTTP 代理"}, {"cannot connect to upstream http proxy", "无法连接到上游 http 代理"},
{"Host is down", "主机已关闭"}, {"Host is down", "主机已关闭"},
{"Can't create connection to requested host, it may be down. Please try again later.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"}, {"Can't create connection to requested host, it may be down. Please try again later.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"},
{"", ""}, {"", ""},
@@ -206,10 +200,10 @@ namespace chinese // language namespace
static std::map<std::string, std::vector<std::string>> plurals static std::map<std::string, std::vector<std::string>> plurals
{ {
{"%d days", {"%d 天"}}, {"days", {""}},
{"%d hours", {"%d 小"}}, {"hours", {""}},
{"%d minutes", {"%d 分钟"}}, {"minutes", {""}},
{"%d seconds", {"%d "}}, {"seconds", {""}},
{"", {""}}, {"", {""}},
}; };

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2022-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Czech localization file
namespace i2p
{
namespace i18n
{
namespace czech // language namespace
{
// language name in lowercase
static std::string language = "czech";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2;
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "vytváří se"},
{"failed", "selhalo"},
{"expiring", "vyprší platnost"},
{"established", "vytvořeno"},
{"unknown", "neznámý"},
{"exploratory", "průzkumné"},
{"Purple I2P Webconsole", "Purple I2P webová konzole"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> webová konzole"},
{"Main page", "Hlavní stránka"},
{"Router commands", "Router příkazy"},
{"Local Destinations", "Místní cíle"},
{"LeaseSets", "Sety pronájmu"},
{"Tunnels", "Tunely"},
{"Transit Tunnels", "Tranzitní tunely"},
{"Transports", "Transporty"},
{"I2P tunnels", "I2P tunely"},
{"SAM sessions", "SAM relace"},
{"ERROR", "CHYBA"},
{"OK", "OK"},
{"Testing", "Testuji"},
{"Firewalled", "Za Firewallem"},
{"Unknown", "Neznámý"},
{"Proxy", "Proxy"},
{"Mesh", "Síť"},
{"Clock skew", "Časová nesrovnalost"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symetrický NAT"},
{"Full cone NAT", "Full cone NAT"},
{"No Descriptors", "Žádné popisovače"},
{"Uptime", "Doba provozu"},
{"Network status", "Stav sítě"},
{"Network status v6", "Stav sítě v6"},
{"Stopping in", "Zastavuji za"},
{"Family", "Rodina"},
{"Tunnel creation success rate", "Úspěšnost vytváření tunelů"},
{"Total tunnel creation success rate", "Celková míra úspěšnosti vytváření tunelů"},
{"Received", "Přijato"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Odesláno"},
{"Transit", "Tranzit"},
{"Data path", "Cesta k datovým souborům"},
{"Hidden content. Press on text to see.", "Skrytý obsah. Pro zobrazení klikněte sem."},
{"Router Ident", "Routerová Identita"},
{"Router Family", "Rodina routerů"},
{"Router Caps", "Omezení Routerů"},
{"Version", "Verze"},
{"Our external address", "Naše externí adresa"},
{"supported", "podporováno"},
{"Routers", "Routery"},
{"Floodfills", "Floodfilly"},
{"Client Tunnels", "Klientské tunely"},
{"Services", "Služby"},
{"Enabled", "Zapnuto"},
{"Disabled", "Vypnuto"},
{"Encrypted B33 address", "Šifrovaná adresa B33"},
{"Address registration line", "Registrační řádek adresy"},
{"Domain", "Doména"},
{"Generate", "Vygenerovat"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Poznámka:</b> výsledný řetězec může být použit pouze pro registraci 2LD domén (example.i2p). Pro registraci subdomén použijte prosím i2pd-tools."},
{"Address", "Adresa"},
{"Type", "Typ"},
{"EncType", "EncType"},
{"Expire LeaseSet", "Zrušit platnost setu pronájmu"},
{"Inbound tunnels", "Příchozí tunely"},
{"%dms", "%dms"},
{"Outbound tunnels", "Odchozí tunely"},
{"Tags", "Štítky"},
{"Incoming", "Příchozí"},
{"Outgoing", "Odchozí"},
{"Destination", "Destinace"},
{"Amount", "Množství"},
{"Incoming Tags", "Příchozí štítky"},
{"Tags sessions", "Relace štítků"},
{"Status", "Stav"},
{"Local Destination", "Místní cíl"},
{"Streams", "Toky"},
{"Close stream", "Uzavřít tok"},
{"Such destination is not found", "Takováto destinace nebyla nalezena"},
{"I2CP session not found", "I2CP relace nenalezena"},
{"I2CP is not enabled", "I2CP není zapnuto"},
{"Invalid", "Neplatný"},
{"Store type", "Druh uložení"},
{"Expires", "Vyprší"},
{"Non Expired Leases", "Pronájmy, kterým nevypršela platnost"},
{"Gateway", "Brána"},
{"TunnelID", "ID tunelu"},
{"EndDate", "Datum ukončení"},
{"floodfill mode is disabled", "režim floodfill je vypnut"},
{"Queue size", "Velikost fronty"},
{"Run peer test", "Spustit peer test"},
{"Reload tunnels configuration", "Znovu načíst nastavení tunelů"},
{"Decline transit tunnels", "Odmítnout tranzitní tunely"},
{"Accept transit tunnels", "Přijmout tranzitní tunely"},
{"Cancel graceful shutdown", "Zrušit hladké vypnutí"},
{"Start graceful shutdown", "Zahájit hladké vypnutí"},
{"Force shutdown", "Vynutit vypnutí"},
{"Reload external CSS styles", "Znovu načíst externí CSS"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Poznámka:</b> žádná vykonaná akce zde není trvalá a nemění konfigurační soubory."},
{"Logging level", "Úroveň logování"},
{"Transit tunnels limit", "Limit tranzitních tunelů"},
{"Change", "Změnit"},
{"Change language", "Změnit jazyk"},
{"no transit tunnels currently built", "Žádný tranzitní tunel není momentálně vytvořen"},
{"SAM disabled", "SAM vypnutý"},
{"no sessions currently running", "Momentálně nejsou spuštěné žádné relace"},
{"SAM session not found", "SAM relace nenalezena"},
{"SAM Session", "SAM Relace"},
{"Server Tunnels", "Server Tunely"},
{"Client Forwards", "Přesměrování Klienta"},
{"Server Forwards", "Přesměrování Serveru"},
{"Unknown page", "Neznámá stránka"},
{"Invalid token", "Neplatný token"},
{"SUCCESS", "ÚSPĚCH"},
{"Stream closed", "Tok uzavřen"},
{"Stream not found or already was closed", "Tok nenalezen nebo byl již uzavřen"},
{"Destination not found", "Destinace nenalezena"},
{"StreamID can't be null", "StreamID nemůže být null"},
{"Return to destination page", "Zpět na stránku destinací"},
{"You will be redirected in %d seconds", "Budete přesměrováni za %d sekund"},
{"LeaseSet expiration time updated", "Aktualizován čas vypršení platnosti setu pronájmu"},
{"LeaseSet is not found or already expired", "Set pronájmu není k nalezení nebo již vypršela jeho platnost"},
{"Transit tunnels count must not exceed %d", "Počet tranzitních tunelů nesmí překročit %d"},
{"Back to commands list", "Zpět na seznam příkazů"},
{"Register at reg.i2p", "Zaregistrovat na reg.i2p"},
{"Description", "Popis"},
{"A bit information about service on domain", "Trochu informací o službě na doméně"},
{"Submit", "Odeslat"},
{"Domain can't end with .b32.i2p", "Doména nesmí končit na .b32.i2p"},
{"Domain must end with .i2p", "Doména musí končit s .i2p"},
{"Unknown command", "Neznámý příkaz"},
{"Command accepted", "Příkaz přijat"},
{"Proxy error", "Chyba proxy serveru"},
{"Proxy info", "Proxy informace"},
{"Proxy error: Host not found", "Chyba proxy serveru: Hostitel nenalezen"},
{"Remote host not found in router's addressbook", "Vzdálený hostitel nebyl nalezen v adresáři routeru"},
{"You may try to find this host on jump services below", "Můžete se pokusit najít tohoto hostitele na startovacích službách níže"},
{"Invalid request", "Neplatný požadavek"},
{"Proxy unable to parse your request", "Proxy server nemohl zpracovat váš požadavek"},
{"Addresshelper is not supported", "Addresshelper není podporován"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Hostitel %s je <font color=red>již v adresáři routeru</font>. <b>Buďte opatrní: zdroj této URL může být škodlivý!</b> Klikněte zde pro aktualizaci záznamu: <a href=\"%s%s%s&update=true\">Pokračovat</a>."},
{"Addresshelper forced update rejected", "Addresshelperem vynucená aktualizace zamítnuta"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Pro přidání hostitele <b>%s</b> do adresáře routeru, klikněte zde: <a href=\"%s%s%s\">Pokračovat</a>."},
{"Addresshelper request", "Požadavek Addresshelperu"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Hostitel %s přidán do adresáře routeru od pomocníka. Klikněte zde pro pokračování: <a href=\"%s\">Pokračovat</a>."},
{"Addresshelper adding", "Addresshelper přidávání"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Hostitel %s je <font color=red>již v adresáři routeru</font>. Klikněte zde pro aktualizaci záznamu: <a href=\"%s%s%s&update=true\">Pokračovat</a>."},
{"Addresshelper update", "Addresshelper aktualizace"},
{"Invalid request URI", "Neplatný URI požadavek"},
{"Can't detect destination host from request", "Nelze zjistit cílového hostitele z požadavku"},
{"Outproxy failure", "Outproxy selhání"},
{"Bad outproxy settings", "Špatné outproxy nastavení"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Hostitel %s není uvnitř I2P sítě a outproxy není nastavena"},
{"Unknown outproxy URL", "Neznámá outproxy URL"},
{"Cannot resolve upstream proxy", "Nelze rozluštit upstream proxy server"},
{"Hostname is too long", "Název hostitele je příliš dlouhý"},
{"Cannot connect to upstream SOCKS proxy", "Nelze se připojit k upstream SOCKS proxy serveru"},
{"Cannot negotiate with SOCKS proxy", "Nelze vyjednávat se SOCKS proxy serverem"},
{"CONNECT error", "Chyba PŘIPOJENÍ"},
{"Failed to connect", "Připojení se nezdařilo"},
{"SOCKS proxy error", "Chyba SOCKS proxy serveru"},
{"Failed to send request to upstream", "Odeslání žádosti upstream serveru se nezdařilo"},
{"No reply from SOCKS proxy", "Žádná odpověď od SOCKS proxy serveru"},
{"Cannot connect", "Nelze se připojit"},
{"HTTP out proxy not implemented", "HTTP out proxy není implementován"},
{"Cannot connect to upstream HTTP proxy", "Nelze se připojit k upstream HTTP proxy serveru"},
{"Host is down", "Hostitel je nedostupný"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Připojení k požadovanému hostiteli nelze vytvořit, může být nedostupný. Zkuste to, prosím, znovu později."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d den", "%d dny", "%d dní", "%d dní"}},
{"%d hours", {"%d hodina", "%d hodiny", "%d hodin", "%d hodin"}},
{"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}},
{"%d seconds", {"%d vteřina", "%d vteřiny", "%d vteřin", "%d vteřin"}},
{"", {"", "", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

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

View File

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

View File

@@ -1,12 +1,11 @@
/* /*
* Copyright (c) 2021-2023, The PurpleI2P Project * Copyright (c) 2021-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
* See full license text in LICENSE file at top of project tree * See full license text in LICENSE file at top of project tree
*/ */
#include <clocale>
#include "ClientContext.h" #include "ClientContext.h"
#include "I18N_langs.h" #include "I18N_langs.h"
#include "I18N.h" #include "I18N.h"
@@ -19,15 +18,9 @@ namespace i18n
{ {
const auto it = i2p::i18n::languages.find(lang); const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback if (it == i2p::i18n::languages.end()) // fallback
{
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale()); i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
setlocale(LC_NUMERIC, "english");
}
else else
{
i2p::client::context.SetLanguage (it->second.LocaleFunc()); i2p::client::context.SetLanguage (it->second.LocaleFunc());
setlocale(LC_NUMERIC, lang.c_str()); // set decimal point based on language
}
} }
std::string translate (const std::string& arg) std::string translate (const std::string& arg)

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021-2023, The PurpleI2P Project * Copyright (c) 2021-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -23,23 +23,18 @@ namespace i18n
}; };
// Add localization here with language name as namespace // Add localization here with language name as namespace
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace polish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace portuguese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace swedish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
/** /**
* That map contains international language name lower-case, name in it's language and it's code * That map contains international language name lower-case, name in it's language and it's code
@@ -49,17 +44,12 @@ namespace i18n
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} }, { "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
{ "armenian", {"hայերէն", "hy", i2p::i18n::armenian::GetLocale} }, { "armenian", {"hայերէն", "hy", i2p::i18n::armenian::GetLocale} },
{ "chinese", {"简体字", "zh-CN", i2p::i18n::chinese::GetLocale} }, { "chinese", {"简体字", "zh-CN", i2p::i18n::chinese::GetLocale} },
{ "czech", {"čeština", "cs", i2p::i18n::czech::GetLocale} },
{ "english", {"English", "en", i2p::i18n::english::GetLocale} }, { "english", {"English", "en", i2p::i18n::english::GetLocale} },
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} }, { "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} }, { "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
{ "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} }, { "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} },
{ "polish", {"Polski", "pl", i2p::i18n::polish::GetLocale} },
{ "portuguese", {"Português", "pt", i2p::i18n::portuguese::GetLocale} },
{ "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} }, { "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} }, { "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} },
{ "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} },
{ "turkish", {"Türk dili", "tr", i2p::i18n::turkish::GetLocale} },
{ "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, { "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, { "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} }, { "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} },

View File

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

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2023-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"
// Polish localization file
namespace i2p
{
namespace i18n
{
namespace polish // language namespace
{
// language name in lowercase
static std::string language = "polish";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
static std::map<std::string, std::string> strings
{
{"%.2f KiB", "%.2f KiB"},
{"%.2f MiB", "%.2f MiB"},
{"%.2f GiB", "%.2f GiB"},
{"building", "Kompilowanie"},
{"failed", "nieudane"},
{"expiring", "wygasający"},
{"established", "ustanowiony"},
{"unknown", "nieznany"},
{"exploratory", "eksploracyjny"},
{"Purple I2P Webconsole", "Konsola webowa Purple I2P"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> konsola webowa"},
{"Main page", "Strona główna"},
{"Router commands", "Komendy routera"},
{"Local Destinations", "Lokalne miejsca docelowe"},
{"LeaseSets", "ZestawyNajmu"},
{"Tunnels", "Tunele"},
{"Transit Tunnels", "Tunele Tranzytu"},
{"Transports", "Transportery"},
{"I2P tunnels", "Tunele I2P"},
{"SAM sessions", "Sesje SAM"},
{"ERROR", "BŁĄD"},
{"OK", "Ok"},
{"Testing", "Testowanie"},
{"Firewalled", "Za zaporą sieciową"},
{"Unknown", "Nieznany"},
{"Proxy", "Proxy"},
{"Mesh", "Sieć"},
{"Clock skew", "Przesunięcie czasu"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symetryczny NAT"},
{"Full cone NAT", "Pełny stożek NAT"},
{"No Descriptors", "Brak deskryptorów"},
{"Uptime", "Czas pracy"},
{"Network status", "Stan sieci"},
{"Network status v6", "Stan sieci v6"},
{"Stopping in", "Zatrzymywanie za"},
{"Family", "Rodzina"},
{"Tunnel creation success rate", "Wskaźnik sukcesu tworzenia tunelu"},
{"Total tunnel creation success rate", "Całkowity wskaźnik sukcesu tworzenia tunelu"},
{"Received", "Odebrano"},
{"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Wysłane"},
{"Transit", "Tranzyt"},
{"Data path", "Ścieżka do danych"},
{"Hidden content. Press on text to see.", "Ukryta zawartość. Naciśnij tekst, aby zobaczyć."},
{"Router Ident", "Identyfikator routera"},
{"Router Family", "Rodzina routera"},
{"Router Caps", "Możliwości routera"},
{"Version", "Wersja"},
{"Our external address", "Nasz zewnętrzny adres"},
{"supported", "wspierane"},
{"Routers", "Routery"},
{"Floodfills", "Floodfille"},
{"Client Tunnels", "Tunele Klienta"},
{"Services", "Usługi"},
{"Enabled", "Aktywny"},
{"Disabled", "Wyłączony"},
{"Encrypted B33 address", "Zaszyfrowany adres B33"},
{"Address registration line", "Linia rejestracji adresu"},
{"Domain", "Domena"},
{"Generate", "Generuj"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Uwaga:</b> wynik string może być używany tylko do rejestracji domen 2LD (przykład.i2p). Do rejestracji subdomen należy użyć narzędzi i2pd."},
{"Address", "Adres"},
{"Type", "Typ"},
{"EncType", "TypEnkrypcji"},
{"Expire LeaseSet", "Wygaśnij LeaseSet"},
{"Inbound tunnels", "Tunele przychodzące"},
{"%dms", "%dms"},
{"Outbound tunnels", "Tunele wychodzące"},
{"Tags", "Tagi"},
{"Incoming", "Przychodzące"},
{"Outgoing", "Wychodzące"},
{"Destination", "Miejsce docelowe"},
{"Amount", "Ilość"},
{"Incoming Tags", "Przychodzące tagi"},
{"Tags sessions", "Sesje tagów"},
{"Status", "Status"},
{"Local Destination", "Lokalne miejsce docelowe"},
{"Streams", "Strumienie"},
{"Close stream", "Zamknij strumień"},
{"Such destination is not found", "Nie znaleziono takiego miejsca docelowego"},
{"I2CP session not found", "Sesja I2CP nie została znaleziona"},
{"I2CP is not enabled", "I2CP nie jest włączone"},
{"Invalid", "Niepoprawny"},
{"Store type", "Rodzaj przechowywania"},
{"Expires", "Wygasa za"},
{"Non Expired Leases", "Leasingi niewygasłe"},
{"Gateway", "Brama"},
{"TunnelID", "IDTunelu"},
{"EndDate", "DataZakończenia"},
{"floodfill mode is disabled", "tryb floodfill jest wyłączony"},
{"Queue size", "Wielkość kolejki"},
{"Run peer test", "Wykonaj test peer"},
{"Reload tunnels configuration", "Załaduj ponownie konfigurację tuneli"},
{"Decline transit tunnels", "Odrzuć tunele tranzytowe"},
{"Accept transit tunnels", "Akceptuj tunele tranzytowe"},
{"Cancel graceful shutdown", "Anuluj łagodne wyłączenie"},
{"Start graceful shutdown", "Rozpocznij łagodne wyłączenie"},
{"Force shutdown", "Wymuś wyłączenie"},
{"Reload external CSS styles", "Odśwież zewnętrzne style CSS"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Uwaga:</b> każda akcja wykonana tutaj nie jest trwała i nie zmienia Twoich plików konfiguracyjnych."},
{"Logging level", "Poziom logowania"},
{"Transit tunnels limit", "Limit tuneli tranzytowych"},
{"Change", "Zmień"},
{"Change language", "Zmień język"},
{"no transit tunnels currently built", "brak obecnie zbudowanych tuneli tranzytowych"},
{"SAM disabled", "SAM wyłączony"},
{"no sessions currently running", "brak aktualnie uruchomionych sesji"},
{"SAM session not found", "Sesja SAM nie została znaleziona"},
{"SAM Session", "Sesja SAM"},
{"Server Tunnels", "Tunele Serwera"},
{"Client Forwards", "Przekierowania Klienta"},
{"Server Forwards", "Przekierowania Serwera"},
{"Unknown page", "Nieznana strona"},
{"Invalid token", "Nieprawidłowy token"},
{"SUCCESS", "SUKCES"},
{"Stream closed", "Strumień zamknięty"},
{"Stream not found or already was closed", "Strumień nie został znaleziony lub został już zamknięty"},
{"Destination not found", "Nie znaleziono punktu docelowego"},
{"StreamID can't be null", "StreamID nie może być null"},
{"Return to destination page", "Wróć do strony miejsca docelowego"},
{"You will be redirected in %d seconds", "Zostaniesz prekierowany za %d sekund"},
{"LeaseSet expiration time updated", "Zaktualizowano czas wygaśnięcia LeaseSet"},
{"LeaseSet is not found or already expired", "LeaseSet nie został znaleziony lub już wygasł"},
{"Transit tunnels count must not exceed %d", "Liczba tuneli tranzytowych nie może przekraczać %d"},
{"Back to commands list", "Powrót do listy poleceń"},
{"Register at reg.i2p", "Zarejestruj się na reg.i2p"},
{"Description", "Opis"},
{"A bit information about service on domain", "Trochę informacji o usłudze w domenie"},
{"Submit", "Zatwierdź"},
{"Domain can't end with .b32.i2p", "Domena nie może kończyć się na .b32.i2p"},
{"Domain must end with .i2p", "Domena musi kończyć się na .i2p"},
{"Unknown command", "Nieznana komenda"},
{"Command accepted", "Polecenie zaakceptowane"},
{"Proxy error", "Błąd serwera proxy"},
{"Proxy info", "Informacje o proxy"},
{"Proxy error: Host not found", "Błąd proxy: Nie znaleziono hosta"},
{"Remote host not found in router's addressbook", "Nie znaleziono zdalnego hosta w książce adresowej routera"},
{"You may try to find this host on jump services below", "Możesz znaleźć tego hosta na poniższych usługach skoku"},
{"Invalid request", "Nieprawidłowe żądanie"},
{"Proxy unable to parse your request", "Serwer proxy nie może przetworzyć Twojego żądania"},
{"Addresshelper is not supported", "Adresshelper nie jest obsługiwany"},
{"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s <font color=red>jest już w książce adresowej routera</font>. <b>Uważaj: źródło tego adresu URL może być szkodliwe!</b> Kliknij tutaj, aby zaktualizować rekord: <a href=\"%s%s%s&update=true\">Kontynuuj</a>."},
{"Addresshelper forced update rejected", "Wymuszona aktualizacja Addreshelper odrzucona"},
{"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Aby dodać host <b>%s</b> w książce adresowej routera, kliknij tutaj: <a href=\"%s%s%s\">Kontynuuj</a>."},
{"Addresshelper request", "Prośba Addresshelper"},
{"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Host %s dodany do książki adresowej routera od pomocnika. Kliknij tutaj, aby kontynuować: <a href=\"%s\">Kontynuuj</a>."},
{"Addresshelper adding", "Dodawanie Addresshelper"},
{"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Host %s jest <font color=red>już w książce adresowej routera</font>. Kliknij tutaj, aby zaktualizować rekord: <a href=\"%s%s%s&update=true\">Kontynuuj</a>."},
{"Addresshelper update", "Aktualizacja Adresshelper"},
{"Invalid request URI", "Nieprawidłowe URI żądania"},
{"Can't detect destination host from request", "Nie można wykryć hosta docelowego z żądania"},
{"Outproxy failure", "Błąd proxy wyjściowego"},
{"Bad outproxy settings", "Błędne ustawienia proxy wyjściowych"},
{"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s nie jest wewnątrz sieci I2P, a proxy wyjściowe nie jest włączone"},
{"Unknown outproxy URL", "Nieznany adres URL proxy wyjściowego"},
{"Cannot resolve upstream proxy", "Nie można rozwiązać serwera proxy upstream"},
{"Hostname is too long", "Nazwa hosta jest zbyt długa"},
{"Cannot connect to upstream SOCKS proxy", "Nie można połączyć się z proxy SOCKS upstream"},
{"Cannot negotiate with SOCKS proxy", "Nie można negocjować z proxy SOCKS"},
{"CONNECT error", "Błąd POŁĄCZENIE"},
{"Failed to connect", "Nie udało się połączyć"},
{"SOCKS proxy error", "Błąd proxy SOCKS"},
{"Failed to send request to upstream", "Nie udało się wysłać żądania do upstream"},
{"No reply from SOCKS proxy", "Brak odpowiedzi od serwera proxy SOCKS"},
{"Cannot connect", "Nie można się połączyć"},
{"HTTP out proxy not implemented", "Serwer wyjściowy proxy HTTP nie został zaimplementowany"},
{"Cannot connect to upstream HTTP proxy", "Nie można połączyć się z proxy HTTP upstream"},
{"Host is down", "Host jest niedostępny"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Nie można utworzyć połączenia z żądanym hostem, może być wyłączony. Spróbuj ponownie później."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"%d days", {"%d dzień", "%d dni", "%d dni", "%d dni"}},
{"%d hours", {"%d godzina", "%d godziny", "%d godzin", "%d godzin"}},
{"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}},
{"%d seconds", {"%d sekunda", "%d sekundy", "%d sekund", "%d sekund"}},
{"", {"", "", "", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

View File

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

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