mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-23 17:36:37 +02:00
commit
245e6b6efd
92 changed files with 1562 additions and 868 deletions
|
@ -30,3 +30,7 @@ indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
25
.github/workflows/build-deb.yml
vendored
25
.github/workflows/build-deb.yml
vendored
|
@ -6,27 +6,34 @@ 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:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: change debian changelog
|
|
||||||
run: |
|
- name: Build package
|
||||||
sudo apt-get update
|
uses: jtdor/build-deb-action@v1
|
||||||
sudo apt-get install devscripts
|
|
||||||
debchange -v "`git describe --tags`-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "trunk build"
|
|
||||||
- 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
|
||||||
- uses: actions/upload-artifact@v3
|
before-build-hook: debchange --controlmaint --local "+${{ github.sha }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build"
|
||||||
|
extra-build-deps: devscripts git
|
||||||
|
|
||||||
|
- name: Upload package
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
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@v3
|
||||||
with:
|
with:
|
||||||
name: i2pd-dbgsym_${{ matrix.dist }}
|
name: i2pd-dbgsym_${{ matrix.dist }}
|
||||||
path: debian/artifacts/i2pd-dbgsym_*.deb
|
path: debian/artifacts/i2pd-dbgsym_*.deb
|
||||||
|
|
10
.github/workflows/build-freebsd.yml
vendored
10
.github/workflows/build-freebsd.yml
vendored
|
@ -6,8 +6,11 @@ jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
name: with UPnP
|
name: with UPnP
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Test in FreeBSD
|
- name: Test in FreeBSD
|
||||||
id: test
|
id: test
|
||||||
uses: vmactions/freebsd-vm@v0.3.0
|
uses: vmactions/freebsd-vm@v0.3.0
|
||||||
|
@ -21,8 +24,9 @@ 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@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: i2pd-freebsd
|
name: i2pd-freebsd
|
||||||
path: build/i2pd
|
path: build/i2pd
|
||||||
|
|
7
.github/workflows/build-osx.yml
vendored
7
.github/workflows/build-osx.yml
vendored
|
@ -6,16 +6,21 @@ 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:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: install packages
|
- name: install packages
|
||||||
run: |
|
run: |
|
||||||
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
|
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: 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
|
||||||
|
|
52
.github/workflows/build-windows-msvc.yml
vendored
Normal file
52
.github/workflows/build-windows-msvc.yml
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
name: Build on Windows with MSVC
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
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
|
||||||
|
uses: crazy-max/ghaction-chocolatey@v2
|
||||||
|
with:
|
||||||
|
args: install boost-msvc-14.3
|
||||||
|
|
||||||
|
- name: Install OpenSSL
|
||||||
|
uses: crazy-max/ghaction-chocolatey@v2
|
||||||
|
with:
|
||||||
|
args: install openssl
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
working-directory: build
|
||||||
|
run: cmake -DWITH_STATIC=ON .
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
working-directory: build
|
||||||
|
run: cmake --build . --config Debug -- -m
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: i2pd-msvc
|
||||||
|
path: build/Debug/i2pd.*
|
||||||
|
|
88
.github/workflows/build-windows.yml
vendored
88
.github/workflows/build-windows.yml
vendored
|
@ -8,44 +8,106 @@ defaults:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Building using ${{ matrix.arch }} toolchain
|
name: ${{ matrix.arch }}
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include: [
|
include: [
|
||||||
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
|
{ msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
|
||||||
{ msystem: MINGW64, arch: x86_64, arch_short: x64 },
|
{ msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
|
||||||
{ msystem: MINGW32, arch: i686, arch_short: x86 }
|
{ msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
|
||||||
|
{ msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
|
||||||
]
|
]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
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 mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
|
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
|
||||||
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@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: i2pd-${{ matrix.arch_short }}.exe
|
name: i2pd-${{ matrix.arch_short }}.exe
|
||||||
path: i2pd.exe
|
path: i2pd.exe
|
||||||
build-xp:
|
|
||||||
name: Building for Windows XP
|
build-cmake:
|
||||||
|
name: CMake ${{ matrix.arch }}
|
||||||
runs-on: windows-latest
|
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:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
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@v3
|
||||||
|
with:
|
||||||
|
name: i2pd-cmake-${{ matrix.arch_short }}.exe
|
||||||
|
path: build/i2pd.exe
|
||||||
|
|
||||||
|
build-xp:
|
||||||
|
name: XP
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
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
|
||||||
update: true
|
update: true
|
||||||
|
|
||||||
- name: Build WinXP-capable CRT packages
|
- name: Build WinXP-capable CRT packages
|
||||||
run: |
|
run: |
|
||||||
git clone https://github.com/msys2/MINGW-packages
|
git clone https://github.com/msys2/MINGW-packages
|
||||||
|
@ -64,12 +126,14 @@ jobs:
|
||||||
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
|
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
|
||||||
popd
|
popd
|
||||||
popd
|
popd
|
||||||
|
|
||||||
- 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@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: i2pd-xp.exe
|
name: i2pd-xp.exe
|
||||||
path: i2pd.exe
|
path: i2pd.exe
|
||||||
|
|
25
.github/workflows/build.yml
vendored
25
.github/workflows/build.yml
vendored
|
@ -5,34 +5,43 @@ on: [push, pull_request]
|
||||||
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-18.04
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
with_upnp: ['yes', 'no']
|
with_upnp: ['yes', 'no']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- 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 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
sudo apt-get install build-essential libboost-all-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-18.04
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
with_upnp: ['ON', 'OFF']
|
with_upnp: ['ON', 'OFF']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- 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 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
sudo apt-get install build-essential cmake libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
|
||||||
|
|
||||||
- name: build application
|
- name: build application
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
|
|
155
.github/workflows/docker.yml
vendored
155
.github/workflows/docker.yml
vendored
|
@ -10,6 +10,7 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: Building container for ${{ matrix.platform }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
|
@ -25,42 +26,44 @@ jobs:
|
||||||
]
|
]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
uses: docker/login-action@v2
|
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@v2
|
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@v3
|
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
|
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
|
||||||
|
@ -68,60 +71,60 @@ jobs:
|
||||||
needs: build
|
needs: build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
uses: docker/login-action@v2
|
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@v2
|
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/') }}
|
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@master
|
||||||
with:
|
with:
|
||||||
inputs: purplei2p/i2pd:latest
|
inputs: purplei2p/i2pd:latest
|
||||||
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/') }}
|
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
|
inputs: ghcr.io/purplei2p/i2pd:latest
|
||||||
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 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 }}
|
inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
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 release manifest to GHCR
|
- name: Create and push release manifest 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 }}
|
inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
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
|
||||||
|
|
15
ChangeLog
15
ChangeLog
|
@ -1,6 +1,21 @@
|
||||||
# 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.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
|
## [2.46.1] - 2023-02-20
|
||||||
### Fixed
|
### Fixed
|
||||||
- Race condition while getting router's peer profile
|
- Race condition while getting router's peer profile
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -71,13 +71,15 @@ 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)
|
||||||
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
|
DEFINES += -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))
|
||||||
|
@ -110,13 +112,13 @@ 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) $(INCFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(DEFINES) $(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) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
$(CXX) -o $@ $(DEFINES) $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(LIB_OBJS)
|
$(SHLIB): $(LIB_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
|
|
|
@ -6,7 +6,8 @@ CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misl
|
||||||
## (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.
|
||||||
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
NEEDED_CXXFLAGS = -std=c++11
|
||||||
|
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||||
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
|
|
|
@ -58,12 +58,13 @@ endif
|
||||||
|
|
||||||
# UPNP Support (miniupnpc 1.5 and higher)
|
# UPNP Support (miniupnpc 1.5 and higher)
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
NEEDED_CXXFLAGS += -DUSE_UPNP
|
DEFINES += -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 += -D__AES__ -maes
|
NEEDED_CXXFLAGS += -maes
|
||||||
|
DEFINES += -D__AES__
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,18 @@ 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
|
LDFLAGS := ${LD_DEBUG} -static
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN
|
NEEDED_CXXFLAGS += -std=c++17
|
||||||
|
DEFINES += -DWIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
# Boost libraries suffix
|
# Boost libraries suffix
|
||||||
BOOST_SUFFIX = -mt
|
BOOST_SUFFIX = -mt
|
||||||
|
|
||||||
# UPNP Support
|
# UPNP Support
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
||||||
LDLIBS = -lminiupnpc
|
LDLIBS = -lminiupnpc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -35,18 +36,19 @@ LDLIBS += \
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
ifeq ($(USE_WIN32_APP), yes)
|
ifeq ($(USE_WIN32_APP), yes)
|
||||||
NEEDED_CXXFLAGS += -DWIN32_APP
|
DEFINES += -DWIN32_APP
|
||||||
LDFLAGS += -mwindows
|
LDFLAGS += -mwindows
|
||||||
DAEMON_RC += Win32/Resource.rc
|
DAEMON_RC += Win32/Resource.rc
|
||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_WINXP_FLAGS), yes)
|
ifeq ($(USE_WINXP_FLAGS), yes)
|
||||||
NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),yes)
|
ifeq ($(USE_AESNI),yes)
|
||||||
NEEDED_CXXFLAGS += -D__AES__ -maes
|
NEEDED_CXXFLAGS += -maes
|
||||||
|
DEFINES += -D__AES__
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_ASLR),yes)
|
ifeq ($(USE_ASLR),yes)
|
||||||
|
@ -54,4 +56,4 @@ ifeq ($(USE_ASLR),yes)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj/%.o : %.rc | mk_obj_dir
|
obj/%.o : %.rc | mk_obj_dir
|
||||||
$(WINDRES) -i $< -o $@
|
$(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@
|
||||||
|
|
17
Makefile.osx
17
Makefile.osx
|
@ -1,6 +1,7 @@
|
||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
|
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11
|
||||||
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
|
||||||
|
@ -14,7 +15,7 @@ endif
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -ldl
|
LDFLAGS += -ldl
|
||||||
CXXFLAGS += -DUSE_UPNP
|
DEFINES += -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,8 +23,12 @@ ifeq ($(USE_UPNP),yes)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),yes)
|
OSARCH = $(shell uname -p)
|
||||||
CXXFLAGS += -D__AES__ -maes
|
|
||||||
else
|
ifneq ($(OSARCH),powerpc)
|
||||||
CXXFLAGS += -msse
|
ifeq ($(USE_AESNI),yes)
|
||||||
|
CXXFLAGS += -D__AES__ -maes
|
||||||
|
else
|
||||||
|
CXXFLAGS += -msse
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
LogPrint(eLogCritical, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,7 +64,7 @@ namespace util
|
||||||
//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 ()) return false;
|
if (!i2p::win32::StartWin32App (isDaemon)) 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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 "../libi2pd/version.h"
|
#include "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-2022, The PurpleI2P Project"
|
VALUE "LegalCopyright", "Copyright (C) 2013-2023, 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
|
||||||
|
|
|
@ -45,6 +45,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -416,8 +417,9 @@ namespace win32
|
||||||
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartWin32App ()
|
bool StartWin32App (bool isWinService)
|
||||||
{
|
{
|
||||||
|
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);
|
||||||
|
@ -446,7 +448,9 @@ 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;
|
||||||
}
|
}
|
||||||
SubscribeToEvents();
|
// COM requires message loop to work, which is not implemented in service mode
|
||||||
|
if (!g_isWinService)
|
||||||
|
SubscribeToEvents();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +470,8 @@ 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);
|
||||||
// UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app
|
else if(!g_isWinService)
|
||||||
|
UnSubscribeFromEvents();
|
||||||
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
|
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace win32
|
||||||
{
|
{
|
||||||
extern DWORD g_GracefulShutdownEndtime;
|
extern DWORD g_GracefulShutdownEndtime;
|
||||||
|
|
||||||
bool StartWin32App ();
|
bool StartWin32App (bool isWinService);
|
||||||
void StopWin32App ();
|
void StopWin32App ();
|
||||||
int RunWin32App ();
|
int RunWin32App ();
|
||||||
bool GracefulShutdown ();
|
bool GracefulShutdown ();
|
||||||
|
|
|
@ -15,6 +15,7 @@ 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()
|
||||||
|
@ -29,7 +30,11 @@ 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");
|
||||||
|
@ -41,8 +46,8 @@ void SubscribeToEvents()
|
||||||
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
|
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
|
||||||
if(SUCCEEDED(Result))
|
if(SUCCEEDED(Result))
|
||||||
{
|
{
|
||||||
CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
|
pNetEvent = new CNetworkListManagerEvent;
|
||||||
Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
|
Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &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
|
||||||
|
@ -59,6 +64,7 @@ void SubscribeToEvents()
|
||||||
|
|
||||||
void UnSubscribeFromEvents()
|
void UnSubscribeFromEvents()
|
||||||
{
|
{
|
||||||
|
LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (pConnectPoint) {
|
if (pConnectPoint) {
|
||||||
|
@ -66,6 +72,9 @@ void UnSubscribeFromEvents()
|
||||||
pConnectPoint->Release();
|
pConnectPoint->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pNetEvent)
|
||||||
|
pNetEvent->Release();
|
||||||
|
|
||||||
if (pCPContainer)
|
if (pCPContainer)
|
||||||
pCPContainer->Release();
|
pCPContainer->Release();
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,18 @@ class CNetworkListManagerEvent : public INetworkListManagerEvents
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CNetworkListManagerEvent() : m_ref(1) { }
|
CNetworkListManagerEvent() : m_ref(1) { }
|
||||||
~CNetworkListManagerEvent() { }
|
|
||||||
|
|
||||||
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 {
|
||||||
Result = E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
AddRef();
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef()
|
ULONG STDMETHODCALLTYPE AddRef()
|
||||||
|
|
|
@ -21,7 +21,7 @@ BOOL I2PService::isService()
|
||||||
HWINSTA hWinStation = GetProcessWindowStation();
|
HWINSTA hWinStation = GetProcessWindowStation();
|
||||||
if (hWinStation != NULL)
|
if (hWinStation != NULL)
|
||||||
{
|
{
|
||||||
USEROBJECTFLAGS uof = { 0 };
|
USEROBJECTFLAGS uof = { FALSE, FALSE, 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(eLogError, "Win32Service: Start error: ", dwError);
|
LogPrint(eLogCritical, "Win32Service: Start error: ", dwError);
|
||||||
SetServiceStatus(SERVICE_STOPPED, dwError);
|
SetServiceStatus(SERVICE_STOPPED, dwError);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
|
LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
|
||||||
SetServiceStatus(SERVICE_STOPPED);
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ void I2PService::Stop()
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
|
LogPrint(eLogCritical, "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(eLogError, "Win32Service: Pause error: ", dwError);
|
LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError);
|
||||||
SetServiceStatus(SERVICE_RUNNING);
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
|
LogPrint(eLogCritical, "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(eLogError, "Win32Service: Continue error: ", dwError);
|
LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError);
|
||||||
SetServiceStatus(SERVICE_PAUSED);
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
|
LogPrint(eLogCritical, "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(eLogError, "Win32Service: Shutdown error: ", dwError);
|
LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
|
LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
build/.gitignore
vendored
11
build/.gitignore
vendored
|
@ -2,7 +2,12 @@
|
||||||
/CMakeFiles/
|
/CMakeFiles/
|
||||||
/Testing/
|
/Testing/
|
||||||
/tests/
|
/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
|
||||||
|
@ -12,7 +17,11 @@
|
||||||
/CPackSourceConfig.cmake
|
/CPackSourceConfig.cmake
|
||||||
/CTestTestfile.cmake
|
/CTestTestfile.cmake
|
||||||
/install_manifest.txt
|
/install_manifest.txt
|
||||||
/arch.c
|
/Makefile
|
||||||
# windows build script
|
# windows build script
|
||||||
i2pd*.zip
|
i2pd*.zip
|
||||||
build*.log
|
build*.log
|
||||||
|
# MVS project files
|
||||||
|
*.vcxproj
|
||||||
|
*.vcxproj.filters
|
||||||
|
*.sln
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
cmake_minimum_required(VERSION 3.7)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
cmake_policy(VERSION 3.7)
|
|
||||||
project("i2pd")
|
if(${CMAKE_VERSION} VERSION_LESS 3.22)
|
||||||
|
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)
|
||||||
|
|
||||||
# Win32 build with cmake is not supported
|
# paths
|
||||||
if(WIN32 OR MSVC OR MSYS OR MINGW)
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
|
||||||
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
|
set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||||
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 CXX
|
||||||
|
)
|
||||||
|
|
||||||
# configurable options
|
# configurable options
|
||||||
option(WITH_AESNI "Use AES-NI instructions set" ON)
|
option(WITH_AESNI "Use AES-NI instructions set" ON)
|
||||||
|
@ -26,27 +44,22 @@ IF(BUILD_TESTING)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# paths
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
|
|
||||||
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)
|
||||||
|
|
||||||
set(LIBI2PD_SRC_DIR ../libi2pd)
|
include(CheckAtomic)
|
||||||
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
|
||||||
set(LANG_SRC_DIR ../i18n)
|
if(WITH_STATIC)
|
||||||
set(DAEMON_SRC_DIR ../daemon)
|
if(MSVC)
|
||||||
|
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 "")
|
||||||
|
@ -57,11 +70,9 @@ 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 "")
|
||||||
|
@ -74,6 +85,7 @@ 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 "")
|
||||||
|
@ -86,6 +98,8 @@ 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"
|
||||||
|
@ -95,6 +109,22 @@ 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")
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_UPNP)
|
if(WITH_UPNP)
|
||||||
add_definitions(-DUSE_UPNP)
|
add_definitions(-DUSE_UPNP)
|
||||||
endif()
|
endif()
|
||||||
|
@ -102,30 +132,40 @@ 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()
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
|
if(MSVC)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
add_definitions(-DWINVER=0x0600)
|
||||||
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||||
# 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
|
|
||||||
|
|
||||||
# check for c++17 & c++11 support
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
|
|
||||||
if(CXX17_SUPPORTED)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
|
||||||
elseif(CXX11_SUPPORTED)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
|
||||||
|
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
||||||
|
# Multiple definitions of __stack_chk_fail(libssp & libc)
|
||||||
|
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s")
|
||||||
|
endif()
|
||||||
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -ffunction-sections -fdata-sections")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
|
||||||
|
|
||||||
|
# check for c++17 & c++11 support
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED)
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED)
|
||||||
|
|
||||||
|
if(CXX17_SUPPORTED)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||||
|
elseif(CXX11_SUPPORTED)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
@ -157,6 +197,12 @@ 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.
|
||||||
|
if(MSVC)
|
||||||
|
message(STATUS "AES-NI is not supported on MSVC, option was disabled")
|
||||||
|
set(WITH_AESNI OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
|
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||||
add_definitions(-D__AES__)
|
add_definitions(-D__AES__)
|
||||||
|
@ -188,10 +234,36 @@ 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)
|
||||||
set(Boost_USE_STATIC_RUNTIME ON)
|
if(MSVC)
|
||||||
|
set(Boost_USE_STATIC_RUNTIME ON)
|
||||||
|
else()
|
||||||
|
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
set(OPENSSL_MSVC_STATIC_RT ON)
|
||||||
|
endif()
|
||||||
set(OPENSSL_USE_STATIC_LIBS ON)
|
set(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")
|
||||||
|
@ -201,17 +273,23 @@ 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
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
if(NOT MSVC)
|
||||||
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||||
|
endif()
|
||||||
|
add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
||||||
|
if(WIN32)
|
||||||
|
set(Boost_USE_STATIC_LIBS OFF)
|
||||||
|
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic)
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_FOUND)
|
||||||
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_INCLUDE_DIR)
|
if(NOT DEFINED OPENSSL_FOUND)
|
||||||
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()
|
||||||
|
|
||||||
|
@ -236,8 +314,6 @@ 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}")
|
||||||
|
@ -259,10 +335,24 @@ message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
|
|
||||||
if(WITH_BINARY)
|
if(WITH_BINARY)
|
||||||
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
|
if(WIN32)
|
||||||
|
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)
|
||||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
if(NOT MSVC)
|
||||||
|
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")
|
||||||
|
@ -275,11 +365,18 @@ 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 ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
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})
|
||||||
|
|
||||||
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}")
|
||||||
|
|
|
@ -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
|
||||||
#if defined(__ARM_ARCH_7__) \\
|
#elif 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__) \\
|
||||||
|
|
16
build/cmake_modules/Version.cmake
Normal file
16
build/cmake_modules/Version.cmake
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# read version
|
||||||
|
|
||||||
|
function(set_version version_file output_var)
|
||||||
|
file(READ "${version_file}" version_data)
|
||||||
|
|
||||||
|
string(REGEX MATCH "I2PD_VERSION_MAJOR ([0-9]*)" _ ${version_data})
|
||||||
|
set(version_major ${CMAKE_MATCH_1})
|
||||||
|
|
||||||
|
string(REGEX MATCH "I2PD_VERSION_MINOR ([0-9]*)" _ ${version_data})
|
||||||
|
set(version_minor ${CMAKE_MATCH_1})
|
||||||
|
|
||||||
|
string(REGEX MATCH "I2PD_VERSION_MICRO ([0-9]*)" _ ${version_data})
|
||||||
|
set(version_micro ${CMAKE_MATCH_1})
|
||||||
|
|
||||||
|
set(${output_var} "${version_major}.${version_minor}.${version_micro}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
34
contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt
Normal file
34
contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
-----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-----
|
|
@ -1,33 +1,33 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt
|
MIIFvjCCA6agAwIBAgIQBnsUOmOu2oZZIwHBmQc1BDANBgkqhkiG9w0BAQsFADBt
|
||||||
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
||||||
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN
|
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN
|
||||||
aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x
|
aWdvckBub3ZnLm5ldDAeFw0yMzAxMjgxNDM4MzFaFw0zMzAxMjgxNDM4MzFaMG0x
|
||||||
CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT
|
CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT
|
||||||
FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p
|
FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p
|
||||||
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4
|
Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLkf
|
||||||
cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF
|
bM3uiYfp9m0vgdoftyXtk2/9bHf3u5iaM0WfoJIsw1iizo/mxJl+Iy7SxLC16nV0
|
||||||
x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h
|
v5FpncVv+Z8x9dgoAYVuLq9zKfsAbpj6kuxAqw6vJMlD1TiIL3nSODV9BJLk47X5
|
||||||
vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm
|
tmvoOSj9BgvemYThTE3nj+DbuJRW5q90KyBV/LdLrQJX3k5R3FFL5tTad2LKFNZ4
|
||||||
w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw
|
vEOcYwwx6mvrkJ2lly6bAQUCtfc648Jyq+NO3Rba1fmn7gcP9zXXc5KYsj/ovyY2
|
||||||
MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy
|
OaocSF5wMhzBuPxO+M2HqbYLMAkc6/GesGds8Rm8wofuhJoI5YtqJuLKZm6nQXSc
|
||||||
Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy
|
fx6PKgbKcTIUWNFMsxyfghz9hpbg0rkvC7PtfAjtV0yaDtUum1eZeNEx1HbRWN2n
|
||||||
f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b
|
TQNCVuv0yaKC41qxqzhEybkdjL9JlgUh7VuskaCelB0lz+kgYjGu8ezOa0ua2iKq
|
||||||
mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d
|
4FC/1MbPulxN8NOt4pmbGqqoxmCdShp38wdnOBM3DsAS9f0JaQZd4CDyY4DCSfVn
|
||||||
Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP
|
xPdWk31+VXVt3Ixh1EUqZWYTRSsZApkCyYzkiZ/qPGG6FR9Hq2SuhC5o4P44k7eo
|
||||||
0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq
|
6wwBWD8a5RjsZhvr05E5yBrKXh/PjLwmtG73QC+ouR54/5xtedvdTwNS94FnNctX
|
||||||
jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/
|
FT6QGZnRwCkhPaRe1oQMzP+88pGoCfO33GBAuwUCAwEAAaNaMFgwDgYDVR0PAQH/
|
||||||
BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E
|
BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E
|
||||||
BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC
|
BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC
|
||||||
AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk
|
AQCteAb5/bqhHr/i5CJbDzlofprXFC826c19GxQ/9Hw0kA52l0J9Q8Vz8Vy7VQyP
|
||||||
5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o
|
QNa8MCv6FeNy8a/wXp6cafyFsBtvehVQO8lFlpCgMEl2Bma43+GaCwkrM6bFNXeW
|
||||||
3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS
|
iQ9h4e1KjsUZ8cQDNEcamiJ80+xbMhBrj5bAZwKmZs8MoGEMyXKEZmcmwA+/fy1c
|
||||||
AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal
|
cx4izsOsmRXmEHXsvB9ydJHZZeKW8+r0DAtgPslwXuXHG6MuBQo7dKCqn+iMxHXV
|
||||||
zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs
|
Jxriq3yvNffdGx4maSLJrjQ1ealt/UMzql7huVSItnVFWoYf7GAELXNJ/PmqVyaK
|
||||||
0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ
|
q11LQ8W/Aud6s/bblaJrFJnK8PbPpaw4RvHoWVLYaZYmQnV2msWs5EuESBlEADbv
|
||||||
cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4
|
UklQXLMc2f9HKWPA5678nvYPrmu8IL5pMkAxgGRqmd+7vCz4lU9M5z3HObU+WRBt
|
||||||
4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6
|
qEMYyXywV8o3tbmnlDS5S5Xxf+tLZn1cxz3ZrmcHPHDbLBNdvszF3CTJH/R2sQvD
|
||||||
GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW
|
bizvYJM+p5F+GWM5mt6w0HrOut5MRlpOws/NRrkbijuVA/A45nzTtKplIFYE3qe8
|
||||||
dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5
|
q5SAbwYLc8cJcZCN3PxtWwbEv81V33abMt5QcjnWGLH5t2+1Z2KLCgKLSCQTxM8s
|
||||||
qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w==
|
zBPHtUe8qtSQaElnNLILYbtJ1w67dPnGYTphHihC+CXjBg==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
8
contrib/dinit/i2pd
Normal file
8
contrib/dinit/i2pd
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
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
|
|
@ -33,7 +33,7 @@
|
||||||
# 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, none)
|
## Log messages above this level (debug, info, *warn, error, critical, 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)
|
||||||
|
@ -168,9 +168,10 @@ port = 4447
|
||||||
[sam]
|
[sam]
|
||||||
## Comment or set to 'false' to disable SAM Bridge
|
## Comment or set to 'false' to disable SAM Bridge
|
||||||
enabled = true
|
enabled = true
|
||||||
## Address and port service will listen on
|
## Address and ports service will listen on
|
||||||
# address = 127.0.0.1
|
# address = 127.0.0.1
|
||||||
# port = 7656
|
# port = 7656
|
||||||
|
# portudp = 7655
|
||||||
|
|
||||||
[bob]
|
[bob]
|
||||||
## Uncomment and set to 'true' to enable BOB command channel
|
## Uncomment and set to 'true' to enable BOB command channel
|
||||||
|
|
|
@ -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.46.1
|
Version: 2.47.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
|
||||||
|
@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* 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
|
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
|
||||||
- update to 2.46.1
|
- update to 2.46.1
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.46.1
|
Version: 2.47.0
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd-git
|
Conflicts: i2pd-git
|
||||||
|
|
||||||
|
@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* 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
|
* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
|
||||||
- update to 2.46.1
|
- update to 2.46.1
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace util
|
||||||
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
||||||
if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels"))
|
if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels"))
|
||||||
transitTunnels *= 2; // double default number of transit tunnels for floodfill
|
transitTunnels *= 2; // double default number of transit tunnels for floodfill
|
||||||
SetMaxNumTransitTunnels (transitTunnels);
|
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);
|
||||||
|
@ -269,7 +269,7 @@ namespace util
|
||||||
if (hidden)
|
if (hidden)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
|
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
|
||||||
i2p::data::netdb.SetHidden(true);
|
i2p::context.SetHidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
|
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
|
||||||
|
@ -310,7 +310,7 @@ namespace util
|
||||||
LogPrint(eLogInfo, "Daemon: Transports started");
|
LogPrint(eLogInfo, "Daemon: Transports started");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Failed to start Transports");
|
LogPrint(eLogCritical, "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();
|
||||||
|
@ -329,15 +329,17 @@ namespace util
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ());
|
LogPrint (eLogCritical, "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 ();
|
||||||
|
|
||||||
|
@ -354,7 +356,7 @@ namespace util
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Daemon: Failed to start I2PControl: ", ex.what ());
|
LogPrint (eLogCritical, "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 ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,6 +368,8 @@ 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();
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace http {
|
||||||
|
|
||||||
static void SetLogLevel (const std::string& level)
|
static void SetLogLevel (const std::string& level)
|
||||||
{
|
{
|
||||||
if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug")
|
if (level == "none" || level == "critical" || 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");
|
||||||
|
@ -625,10 +625,10 @@ 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));
|
ls.reset (new i2p::data::LeaseSet2 (storeType));
|
||||||
ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false);
|
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())
|
||||||
|
@ -748,13 +748,14 @@ namespace http {
|
||||||
|
|
||||||
auto loglevel = i2p::log::Logger().GetLogLevel();
|
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" << (loglevel == eLogNone ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </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" << (loglevel == eLogCritical ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=critical&token=" << token << "\"> critical </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" << (loglevel == eLogError ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </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" << (loglevel == eLogWarning ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \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";
|
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" << (loglevel == eLogDebug ? " selected" : "") << "\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
|
||||||
|
|
||||||
uint16_t maxTunnels = GetMaxNumTransitTunnels ();
|
uint16_t maxTunnels = i2p::tunnel::tunnels.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";
|
||||||
|
@ -838,6 +839,7 @@ namespace http {
|
||||||
tmp_s << " [itag:" << it->GetRelayTag () << "]";
|
tmp_s << " [itag:" << it->GetRelayTag () << "]";
|
||||||
if (it->GetSendQueueSize () > 0)
|
if (it->GetSendQueueSize () > 0)
|
||||||
tmp_s << " [queue:" << it->GetSendQueueSize () << "]";
|
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++;
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1316,7 @@ namespace http {
|
||||||
{
|
{
|
||||||
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 <= TRANSIT_TUNNELS_LIMIT)
|
||||||
SetMaxNumTransitTunnels (limit);
|
i2p::tunnel::tunnels.SetMaxNumTransitTunnels (limit);
|
||||||
else {
|
else {
|
||||||
s << "<b>" << tr("ERROR") << "</b>: " << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\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";
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace i2p
|
||||||
ftruncate(pidFH, 0);
|
ftruncate(pidFH, 0);
|
||||||
if (write(pidFH, pid, strlen(pid)) < 0)
|
if (write(pidFH, pid, strlen(pid)) < 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno));
|
LogPrint(eLogCritical, "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;
|
||||||
}
|
}
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
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
|
i2pd (2.46.1-2) unstable; urgency=critical
|
||||||
|
|
||||||
* re-pushed release due to new critical bug
|
* re-pushed release due to new critical bug
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace german // language namespace
|
||||||
{"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"},
|
||||||
|
@ -116,8 +117,10 @@ namespace german // language namespace
|
||||||
{"Gateway", "Gateway"},
|
{"Gateway", "Gateway"},
|
||||||
{"TunnelID", "TunnelID"},
|
{"TunnelID", "TunnelID"},
|
||||||
{"EndDate", "Enddatum"},
|
{"EndDate", "Enddatum"},
|
||||||
|
{"floodfill mode is disabled", "Floodfill Modus ist deaktiviert"},
|
||||||
{"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"},
|
||||||
|
@ -145,6 +148,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"},
|
||||||
|
{"Transit tunnels count must not exceed %d", "Die Anzahl der Transittunnel darf nicht über %d gehen"},
|
||||||
{"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"},
|
||||||
|
@ -162,6 +167,15 @@ 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"},
|
||||||
|
{"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>."},
|
||||||
|
{"Addresshelper forced update rejected", "Adresshelfer gezwungene Aktualisierung abgelehnt"},
|
||||||
|
{"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>."},
|
||||||
|
{"Addresshelper request", "Adresshelfer gefunden"},
|
||||||
|
{"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 adding", "Adresshelfer hinzufügen"},
|
||||||
|
{"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>."},
|
||||||
|
{"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"},
|
||||||
|
|
|
@ -95,9 +95,8 @@ std::string tr (TValue&& arg, TArgs&&... args)
|
||||||
std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg));
|
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)...);
|
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
|
||||||
size = size + 1;
|
|
||||||
std::string str(size, 0);
|
std::string str(size, 0);
|
||||||
std::snprintf(&str.front(), size, tr_str.c_str(), std::forward<TArgs>(args)...);
|
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -127,9 +126,8 @@ 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));
|
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)...);
|
size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
|
||||||
size = size + 1;
|
|
||||||
std::string str(size, 0);
|
std::string str(size, 0);
|
||||||
std::snprintf(&str.front(), size, tr_str.c_str(), std::forward<TArgs>(args)...);
|
std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@ namespace italian // language namespace
|
||||||
{"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"},
|
||||||
|
@ -116,6 +118,7 @@ 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"},
|
||||||
{"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"},
|
{"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"},
|
||||||
|
@ -165,8 +168,15 @@ 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"},
|
||||||
|
{"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>."},
|
||||||
|
{"Addresshelper forced update rejected", "Aggiornamento forzato dell'helper degli indirizzi rifiutato"},
|
||||||
{"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>."},
|
{"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>."},
|
||||||
|
{"Addresshelper request", "Richiesta di indirizzo helper"},
|
||||||
|
{"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 adding", "Aggiunta di 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>.", "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>."},
|
{"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>."},
|
||||||
|
{"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"},
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace portuguese // language namespace
|
||||||
{"%.2f KiB/s", "%.2f KiB/s"},
|
{"%.2f KiB/s", "%.2f KiB/s"},
|
||||||
{"Sent", "Enviado"},
|
{"Sent", "Enviado"},
|
||||||
{"Transit", "Trânsito"},
|
{"Transit", "Trânsito"},
|
||||||
{"Data path", "Caminho dos dados"},
|
{"Data path", "Diretório dos dados"},
|
||||||
{"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."},
|
{"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."},
|
||||||
{"Router Ident", "Identidade do Roteador"},
|
{"Router Ident", "Identidade do Roteador"},
|
||||||
{"Router Family", "Família do Roteador"},
|
{"Router Family", "Família do Roteador"},
|
||||||
|
@ -122,15 +122,15 @@ namespace portuguese // language namespace
|
||||||
{"Queue size", "Tamanho da fila"},
|
{"Queue size", "Tamanho da fila"},
|
||||||
{"Run peer test", "Executar teste de peers"},
|
{"Run peer test", "Executar teste de peers"},
|
||||||
{"Reload tunnels configuration", "Recarregar a configuração dos túneis"},
|
{"Reload tunnels configuration", "Recarregar a configuração dos túneis"},
|
||||||
{"Decline transit tunnels", "Negar túnel de trânsito"},
|
{"Decline transit tunnels", "Negar túneis de trânsito"},
|
||||||
{"Accept transit tunnels", "Aceitar túnel de trânsito"},
|
{"Accept transit tunnels", "Aceitar túneis de trânsito"},
|
||||||
{"Cancel graceful shutdown", "Cancelar desligamento gracioso"},
|
{"Cancel graceful shutdown", "Cancelar desligamento gracioso"},
|
||||||
{"Start graceful shutdown", "Iniciar desligamento gracioso"},
|
{"Start graceful shutdown", "Iniciar desligamento gracioso"},
|
||||||
{"Force shutdown", "Forçar desligamento"},
|
{"Force shutdown", "Forçar desligamento"},
|
||||||
{"Reload external CSS styles", "Recarregar estilos CSS externos"},
|
{"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."},
|
{"<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"},
|
{"Logging level", "Nível de registro"},
|
||||||
{"Transit tunnels limit", "Limite nos túneis de trânsito"},
|
{"Transit tunnels limit", "Limite de túneis de trânsito"},
|
||||||
{"Change", "Mudar"},
|
{"Change", "Mudar"},
|
||||||
{"Change language", "Trocar idioma"},
|
{"Change language", "Trocar idioma"},
|
||||||
{"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"},
|
{"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"},
|
||||||
|
|
|
@ -149,7 +149,8 @@ namespace config {
|
||||||
sam.add_options()
|
sam.add_options()
|
||||||
("sam.enabled", value<bool>()->default_value(true), "Enable or disable SAM Application bridge")
|
("sam.enabled", value<bool>()->default_value(true), "Enable or disable SAM Application bridge")
|
||||||
("sam.address", value<std::string>()->default_value("127.0.0.1"), "SAM listen address")
|
("sam.address", value<std::string>()->default_value("127.0.0.1"), "SAM listen address")
|
||||||
("sam.port", value<uint16_t>()->default_value(7656), "SAM listen port")
|
("sam.port", value<uint16_t>()->default_value(7656), "SAM listen TCP port")
|
||||||
|
("sam.portudp", value<uint16_t>()->default_value(0), "SAM listen UDP port")
|
||||||
("sam.singlethread", value<bool>()->default_value(true), "Sessions run in the SAM bridge's thread")
|
("sam.singlethread", value<bool>()->default_value(true), "Sessions run in the SAM bridge's thread")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -215,10 +216,11 @@ namespace config {
|
||||||
"https://reseed.onion.im/,"
|
"https://reseed.onion.im/,"
|
||||||
"https://i2pseed.creativecowpat.net:8443/,"
|
"https://i2pseed.creativecowpat.net:8443/,"
|
||||||
"https://reseed.i2pgit.org/,"
|
"https://reseed.i2pgit.org/,"
|
||||||
"https://i2p.novg.net/,"
|
|
||||||
"https://banana.incognet.io/,"
|
"https://banana.incognet.io/,"
|
||||||
"https://reseed-pl.i2pd.xyz/,"
|
"https://reseed-pl.i2pd.xyz/,"
|
||||||
"https://www2.mk16.de/"
|
"https://www2.mk16.de/,"
|
||||||
|
"https://i2p.ghativega.in/,"
|
||||||
|
"https://i2p.novg.net/"
|
||||||
), "Reseed URLs, separated by comma")
|
), "Reseed URLs, separated by comma")
|
||||||
("reseed.yggurls", value<std::string>()->default_value(
|
("reseed.yggurls", value<std::string>()->default_value(
|
||||||
"http://[324:71e:281a:9ed3::ace]:7070/,"
|
"http://[324:71e:281a:9ed3::ace]:7070/,"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -425,7 +425,7 @@ namespace datagram
|
||||||
if (m)
|
if (m)
|
||||||
send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m});
|
send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m});
|
||||||
}
|
}
|
||||||
routingPath->outboundTunnel->SendTunnelDataMsg(send);
|
routingPath->outboundTunnel->SendTunnelDataMsgs(send);
|
||||||
}
|
}
|
||||||
m_SendQueue.clear();
|
m_SendQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace client
|
||||||
if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
|
if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
|
||||||
m_AuthType = authType;
|
m_AuthType = authType;
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Unknown auth type ", authType);
|
LogPrint (eLogError, "Destination: Unknown auth type: ", authType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY);
|
it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY);
|
||||||
|
@ -117,7 +117,7 @@ namespace client
|
||||||
m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>());
|
m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>());
|
||||||
if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32)
|
if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second);
|
LogPrint(eLogCritical, "Destination: Invalid value i2cp.leaseSetPrivKey: ", it->second);
|
||||||
m_LeaseSetPrivKey.reset (nullptr);
|
m_LeaseSetPrivKey.reset (nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -635,7 +635,7 @@ namespace client
|
||||||
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
|
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
|
||||||
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
|
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg);
|
outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, msg);
|
||||||
m_LastSubmissionTime = ts;
|
m_LastSubmissionTime = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +835,7 @@ namespace client
|
||||||
AddSessionKey (replyKey, replyTag);
|
AddSessionKey (replyKey, replyTag);
|
||||||
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
|
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
|
||||||
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
|
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
|
||||||
request->outboundTunnel->SendTunnelDataMsg (
|
request->outboundTunnel->SendTunnelDataMsgs (
|
||||||
{
|
{
|
||||||
i2p::tunnel::TunnelMessageBlock
|
i2p::tunnel::TunnelMessageBlock
|
||||||
{
|
{
|
||||||
|
@ -1000,7 +1000,7 @@ namespace client
|
||||||
m_StreamingAckDelay = std::stoi(it->second);
|
m_StreamingAckDelay = std::stoi(it->second);
|
||||||
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
m_IsStreamingAnswerPings = (it->second == "true");
|
m_IsStreamingAnswerPings = std::stoi (it->second); // 1 for true
|
||||||
|
|
||||||
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
||||||
{
|
{
|
||||||
|
@ -1014,12 +1014,12 @@ namespace client
|
||||||
else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
|
else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
|
||||||
ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params);
|
ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params);
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Unexpected auth type ", authType);
|
LogPrint (eLogError, "Destination: Unexpected auth type: ", authType);
|
||||||
if (m_AuthKeys->size ())
|
if (m_AuthKeys->size ())
|
||||||
LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read");
|
LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType);
|
LogPrint (eLogCritical, "Destination: No auth keys read for auth type: ", authType);
|
||||||
m_AuthKeys = nullptr;
|
m_AuthKeys = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1028,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception & ex)
|
catch (std::exception & ex)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
|
LogPrint(eLogCritical, "Destination: Unable to parse parameters for destination: ", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1336,7 +1336,7 @@ namespace client
|
||||||
f1.write ((char *)keys->priv, 256);
|
f1.write ((char *)keys->priv, 256);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint(eLogError, "Destinations: Can't save keys to ", path);
|
LogPrint(eLogCritical, "Destinations: Can't save keys to ", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDestination::CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels)
|
void ClientDestination::CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels)
|
||||||
|
@ -1413,7 +1413,7 @@ namespace client
|
||||||
if (pubKey.FromBase64 (it.second.substr (pos+1)))
|
if (pubKey.FromBase64 (it.second.substr (pos+1)))
|
||||||
m_AuthKeys->push_back (pubKey);
|
m_AuthKeys->push_back (pubKey);
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1));
|
LogPrint (eLogCritical, "Destination: Unexpected auth key: ", it.second.substr (pos+1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ namespace garlic
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
|
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPMessage ();
|
auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128);
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@ -1176,7 +1176,7 @@ namespace garlic
|
||||||
// Noise_N, we are Alice, routerPublicKey is Bob's
|
// Noise_N, we are Alice, routerPublicKey is Bob's
|
||||||
i2p::crypto::NoiseSymmetricState noiseState;
|
i2p::crypto::NoiseSymmetricState noiseState;
|
||||||
i2p::crypto::InitNoiseNState (noiseState, routerPublicKey);
|
i2p::crypto::InitNoiseNState (noiseState, routerPublicKey);
|
||||||
auto m = NewI2NPMessage ();
|
auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128);
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -413,7 +413,7 @@ namespace crypto
|
||||||
BIGNUM * y = BN_new ();
|
BIGNUM * y = BN_new ();
|
||||||
BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y);
|
BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y);
|
||||||
BIGNUM * x = RecoverX (y, ctx);
|
BIGNUM * x = RecoverX (y, ctx);
|
||||||
if (BN_is_bit_set (x, 0) != isHighestBitSet)
|
if ((bool)BN_is_bit_set (x, 0) != isHighestBitSet)
|
||||||
BN_sub (x, q, x); // x = q - x
|
BN_sub (x, q, x); // x = q - x
|
||||||
BIGNUM * z = BN_new (), * t = BN_new ();
|
BIGNUM * z = BN_new (), * t = BN_new ();
|
||||||
BN_one (z); BN_mod_mul (t, x, y, q, ctx); // pre-calculate t
|
BN_one (z); BN_mod_mul (t, x, y, q, ctx); // pre-calculate t
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
|
@ -88,7 +88,7 @@ namespace data
|
||||||
}
|
}
|
||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
if (verifier && cn)
|
if (verifier && cn)
|
||||||
m_SigningKeys.emplace (cn, std::make_pair(verifier, m_SigningKeys.size () + 1));
|
m_SigningKeys.emplace (cn, std::make_pair(verifier, (int)m_SigningKeys.size () + 1));
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -709,7 +709,7 @@ namespace garlic
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
||||||
if (tunnel) // we have sent it through an outbound tunnel
|
if (tunnel) // we have sent it through an outbound tunnel
|
||||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, msg);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||||
}
|
}
|
||||||
|
@ -1075,7 +1075,7 @@ namespace garlic
|
||||||
{
|
{
|
||||||
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
if (tunnel)
|
if (tunnel)
|
||||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID));
|
tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID));
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ namespace data
|
||||||
if (m_IsDirty) deflateReset (&m_Deflator);
|
if (m_IsDirty) deflateReset (&m_Deflator);
|
||||||
m_IsDirty = true;
|
m_IsDirty = true;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
int err;
|
int err = 0;
|
||||||
for (const auto& it: bufs)
|
for (const auto& it: bufs)
|
||||||
{
|
{
|
||||||
m_Deflator.next_in = const_cast<uint8_t *>(it.first);
|
m_Deflator.next_in = const_cast<uint8_t *>(it.first);
|
||||||
|
|
|
@ -93,15 +93,18 @@ namespace http
|
||||||
std::size_t pos_c = 0; /* < work position */
|
std::size_t pos_c = 0; /* < work position */
|
||||||
if(url.at(0) != '/' || pos_p > 0) {
|
if(url.at(0) != '/' || pos_p > 0) {
|
||||||
std::size_t pos_s = 0;
|
std::size_t pos_s = 0;
|
||||||
|
|
||||||
/* schema */
|
/* schema */
|
||||||
pos_c = url.find("://");
|
pos_c = url.find("://");
|
||||||
if (pos_c != std::string::npos) {
|
if (pos_c != std::string::npos) {
|
||||||
schema = url.substr(0, pos_c);
|
schema = url.substr(0, pos_c);
|
||||||
pos_p = pos_c + 3;
|
pos_p = pos_c + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* user[:pass] */
|
/* user[:pass] */
|
||||||
pos_s = url.find('/', pos_p); /* find first slash */
|
pos_s = url.find('/', pos_p); /* find first slash */
|
||||||
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */
|
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */
|
||||||
|
|
||||||
if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
|
if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
|
||||||
std::size_t delim = url.find(':', pos_p);
|
std::size_t delim = url.find(':', pos_p);
|
||||||
if (delim && delim != std::string::npos && delim < pos_c) {
|
if (delim && delim != std::string::npos && delim < pos_c) {
|
||||||
|
@ -113,21 +116,28 @@ namespace http
|
||||||
}
|
}
|
||||||
pos_p = pos_c + 1;
|
pos_p = pos_c + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hostname[:port][/path] */
|
/* hostname[:port][/path] */
|
||||||
if (url[pos_p] == '[') // ipv6
|
if (url.at(pos_p) == '[') // ipv6
|
||||||
{
|
{
|
||||||
auto pos_b = url.find(']', pos_p);
|
auto pos_b = url.find(']', pos_p);
|
||||||
if (pos_b == std::string::npos) return false;
|
if (pos_b == std::string::npos) return false;
|
||||||
|
ipv6 = true;
|
||||||
pos_c = url.find_first_of(":/", pos_b);
|
pos_c = url.find_first_of(":/", pos_b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pos_c = url.find_first_of(":/", pos_p);
|
pos_c = url.find_first_of(":/", pos_p);
|
||||||
|
|
||||||
if (pos_c == std::string::npos) {
|
if (pos_c == std::string::npos) {
|
||||||
/* only hostname, without post and path */
|
/* only hostname, without post and path */
|
||||||
host = url.substr(pos_p, std::string::npos);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, url.length() - 1) :
|
||||||
|
url.substr(pos_p, std::string::npos);
|
||||||
return true;
|
return true;
|
||||||
} else if (url.at(pos_c) == ':') {
|
} else if (url.at(pos_c) == ':') {
|
||||||
host = url.substr(pos_p, pos_c - pos_p);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, pos_c - pos_p - 2) :
|
||||||
|
url.substr(pos_p, pos_c - pos_p);
|
||||||
/* port[/path] */
|
/* port[/path] */
|
||||||
pos_p = pos_c + 1;
|
pos_p = pos_c + 1;
|
||||||
pos_c = url.find('/', pos_p);
|
pos_c = url.find('/', pos_p);
|
||||||
|
@ -147,7 +157,9 @@ namespace http
|
||||||
pos_p = pos_c;
|
pos_p = pos_c;
|
||||||
} else {
|
} else {
|
||||||
/* start of path part found */
|
/* start of path part found */
|
||||||
host = url.substr(pos_p, pos_c - pos_p);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, pos_c - pos_p - 2) :
|
||||||
|
url.substr(pos_p, pos_c - pos_p);
|
||||||
pos_p = pos_c;
|
pos_p = pos_c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,10 +224,18 @@ namespace http
|
||||||
} else if (user != "") {
|
} else if (user != "") {
|
||||||
out += user + "@";
|
out += user + "@";
|
||||||
}
|
}
|
||||||
if (port) {
|
if (ipv6) {
|
||||||
out += host + ":" + std::to_string(port);
|
if (port) {
|
||||||
|
out += "[" + host + "]:" + std::to_string(port);
|
||||||
|
} else {
|
||||||
|
out += "[" + host + "]";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
out += host;
|
if (port) {
|
||||||
|
out += host + ":" + std::to_string(port);
|
||||||
|
} else {
|
||||||
|
out += host;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out += path;
|
out += path;
|
||||||
|
|
|
@ -36,8 +36,9 @@ namespace http
|
||||||
bool hasquery;
|
bool hasquery;
|
||||||
std::string query;
|
std::string query;
|
||||||
std::string frag;
|
std::string frag;
|
||||||
|
bool ipv6;
|
||||||
|
|
||||||
URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag("") {};
|
URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag(""), ipv6(false) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to parse url from string
|
* @brief Tries to parse url from string
|
||||||
|
|
|
@ -36,6 +36,11 @@ namespace i2p
|
||||||
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<I2NPMessage> NewI2NPMediumMessage ()
|
||||||
|
{
|
||||||
|
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_MEDIUM_MESSAGE_SIZE> >();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint)
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint)
|
||||||
{
|
{
|
||||||
return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint);
|
return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint);
|
||||||
|
@ -43,7 +48,10 @@ namespace i2p
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len)
|
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len)
|
||||||
{
|
{
|
||||||
return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage ();
|
len += I2NP_HEADER_SIZE + 2;
|
||||||
|
if (len <= I2NP_MAX_SHORT_MESSAGE_SIZE) return NewI2NPShortMessage ();
|
||||||
|
if (len <= I2NP_MAX_MEDIUM_MESSAGE_SIZE) return NewI2NPMediumMessage ();
|
||||||
|
return NewI2NPMessage ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum)
|
void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum)
|
||||||
|
@ -126,7 +134,8 @@ namespace i2p
|
||||||
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
||||||
uint32_t replyTunnelID, bool exploratory, std::set<i2p::data::IdentHash> * excludedPeers)
|
uint32_t replyTunnelID, bool exploratory, std::set<i2p::data::IdentHash> * excludedPeers)
|
||||||
{
|
{
|
||||||
auto m = excludedPeers ? NewI2NPMessage () : NewI2NPShortMessage ();
|
int cnt = excludedPeers ? excludedPeers->size () : 0;
|
||||||
|
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
|
||||||
uint8_t * buf = m->GetPayload ();
|
uint8_t * buf = m->GetPayload ();
|
||||||
memcpy (buf, key, 32); // key
|
memcpy (buf, key, 32); // key
|
||||||
buf += 32;
|
buf += 32;
|
||||||
|
@ -147,7 +156,6 @@ namespace i2p
|
||||||
|
|
||||||
if (excludedPeers)
|
if (excludedPeers)
|
||||||
{
|
{
|
||||||
int cnt = excludedPeers->size ();
|
|
||||||
htobe16buf (buf, cnt);
|
htobe16buf (buf, cnt);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
for (auto& it: *excludedPeers)
|
for (auto& it: *excludedPeers)
|
||||||
|
@ -353,21 +361,6 @@ namespace i2p
|
||||||
return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo
|
return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO:
|
|
||||||
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels)
|
|
||||||
{
|
|
||||||
if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels)
|
|
||||||
{
|
|
||||||
LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels);
|
|
||||||
g_MaxNumTransitTunnels = maxNumTransitTunnels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t GetMaxNumTransitTunnels ()
|
|
||||||
{
|
|
||||||
return g_MaxNumTransitTunnels;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText)
|
static bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
|
@ -379,10 +372,7 @@ namespace i2p
|
||||||
if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false;
|
if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false;
|
||||||
uint8_t retCode = 0;
|
uint8_t retCode = 0;
|
||||||
// replace record to reply
|
// replace record to reply
|
||||||
if (i2p::context.AcceptsTunnels () &&
|
if (i2p::context.AcceptsTunnels () && !i2p::context.IsHighCongestion ())
|
||||||
i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels &&
|
|
||||||
!i2p::transport::transports.IsBandwidthExceeded () &&
|
|
||||||
!i2p::transport::transports.IsTransitBandwidthExceeded ())
|
|
||||||
{
|
{
|
||||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
|
@ -576,11 +566,8 @@ namespace i2p
|
||||||
|
|
||||||
// check if we accept this tunnel
|
// check if we accept this tunnel
|
||||||
uint8_t retCode = 0;
|
uint8_t retCode = 0;
|
||||||
if (!i2p::context.AcceptsTunnels () ||
|
if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ())
|
||||||
i2p::tunnel::tunnels.GetTransitTunnels ().size () > g_MaxNumTransitTunnels ||
|
retCode = 30;
|
||||||
i2p::transport::transports.IsBandwidthExceeded () ||
|
|
||||||
i2p::transport::transports.IsTransitBandwidthExceeded ())
|
|
||||||
retCode = 30;
|
|
||||||
if (!retCode)
|
if (!retCode)
|
||||||
{
|
{
|
||||||
// create new transit tunnel
|
// create new transit tunnel
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -140,6 +140,7 @@ namespace tunnel
|
||||||
|
|
||||||
const size_t I2NP_MAX_MESSAGE_SIZE = 62708;
|
const size_t I2NP_MAX_MESSAGE_SIZE = 62708;
|
||||||
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096;
|
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096;
|
||||||
|
const size_t I2NP_MAX_MEDIUM_MESSAGE_SIZE = 16384;
|
||||||
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT)
|
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT)
|
||||||
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
|
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
|
||||||
|
|
||||||
|
@ -262,6 +263,7 @@ namespace tunnel
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
||||||
|
std::shared_ptr<I2NPMessage> NewI2NPMediumMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len);
|
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len);
|
||||||
|
|
||||||
|
@ -308,10 +310,6 @@ namespace tunnel
|
||||||
|
|
||||||
std::vector<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
|
std::vector<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 5000;
|
|
||||||
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels);
|
|
||||||
uint16_t GetMaxNumTransitTunnels ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,6 +36,23 @@
|
||||||
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define htobe16(x) _byteswap_ushort(x)
|
||||||
|
#define htole16(x) (x)
|
||||||
|
#define be16toh(x) _byteswap_ushort(x)
|
||||||
|
#define le16toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe32(x) _byteswap_ulong(x)
|
||||||
|
#define htole32(x) (x)
|
||||||
|
#define be32toh(x) _byteswap_ulong(x)
|
||||||
|
#define le32toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe64(x) _byteswap_uint64(x)
|
||||||
|
#define htole64(x) (x)
|
||||||
|
#define be64toh(x) _byteswap_uint64(x)
|
||||||
|
#define le64toh(x) (x)
|
||||||
|
#else
|
||||||
#define htobe16(x) __builtin_bswap16(x)
|
#define htobe16(x) __builtin_bswap16(x)
|
||||||
#define htole16(x) (x)
|
#define htole16(x) (x)
|
||||||
#define be16toh(x) __builtin_bswap16(x)
|
#define be16toh(x) __builtin_bswap16(x)
|
||||||
|
@ -50,6 +67,7 @@
|
||||||
#define htole64(x) (x)
|
#define htole64(x) (x)
|
||||||
#define be64toh(x) __builtin_bswap64(x)
|
#define be64toh(x) __builtin_bswap64(x)
|
||||||
#define le64toh(x) (x)
|
#define le64toh(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define NEEDS_LOCAL_ENDIAN
|
#define NEEDS_LOCAL_ENDIAN
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -187,7 +187,6 @@ namespace data
|
||||||
|
|
||||||
IdentityEx::~IdentityEx ()
|
IdentityEx::~IdentityEx ()
|
||||||
{
|
{
|
||||||
delete m_Verifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx& IdentityEx::operator=(const IdentityEx& other)
|
IdentityEx& IdentityEx::operator=(const IdentityEx& other)
|
||||||
|
@ -201,9 +200,8 @@ namespace data
|
||||||
if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE;
|
if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE;
|
||||||
memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen);
|
memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_Verifier;
|
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
|
CreateVerifier ();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -212,11 +210,10 @@ namespace data
|
||||||
{
|
{
|
||||||
m_StandardIdentity = standard;
|
m_StandardIdentity = standard;
|
||||||
m_IdentHash = m_StandardIdentity.Hash ();
|
m_IdentHash = m_StandardIdentity.Hash ();
|
||||||
|
|
||||||
m_ExtendedLen = 0;
|
m_ExtendedLen = 0;
|
||||||
|
|
||||||
delete m_Verifier;
|
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
|
CreateVerifier ();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -249,8 +246,8 @@ namespace data
|
||||||
m_ExtendedLen = 0;
|
m_ExtendedLen = 0;
|
||||||
SHA256(buf, GetFullLen (), m_IdentHash);
|
SHA256(buf, GetFullLen (), m_IdentHash);
|
||||||
|
|
||||||
delete m_Verifier;
|
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
|
CreateVerifier ();
|
||||||
|
|
||||||
return GetFullLen ();
|
return GetFullLen ();
|
||||||
}
|
}
|
||||||
|
@ -286,7 +283,6 @@ namespace data
|
||||||
|
|
||||||
size_t IdentityEx::GetSigningPublicKeyLen () const
|
size_t IdentityEx::GetSigningPublicKeyLen () const
|
||||||
{
|
{
|
||||||
if (!m_Verifier) CreateVerifier ();
|
|
||||||
if (m_Verifier)
|
if (m_Verifier)
|
||||||
return m_Verifier->GetPublicKeyLen ();
|
return m_Verifier->GetPublicKeyLen ();
|
||||||
return 128;
|
return 128;
|
||||||
|
@ -301,7 +297,6 @@ namespace data
|
||||||
|
|
||||||
size_t IdentityEx::GetSigningPrivateKeyLen () const
|
size_t IdentityEx::GetSigningPrivateKeyLen () const
|
||||||
{
|
{
|
||||||
if (!m_Verifier) CreateVerifier ();
|
|
||||||
if (m_Verifier)
|
if (m_Verifier)
|
||||||
return m_Verifier->GetPrivateKeyLen ();
|
return m_Verifier->GetPrivateKeyLen ();
|
||||||
return GetSignatureLen ()/2;
|
return GetSignatureLen ()/2;
|
||||||
|
@ -309,14 +304,12 @@ namespace data
|
||||||
|
|
||||||
size_t IdentityEx::GetSignatureLen () const
|
size_t IdentityEx::GetSignatureLen () const
|
||||||
{
|
{
|
||||||
if (!m_Verifier) CreateVerifier ();
|
|
||||||
if (m_Verifier)
|
if (m_Verifier)
|
||||||
return m_Verifier->GetSignatureLen ();
|
return m_Verifier->GetSignatureLen ();
|
||||||
return i2p::crypto::DSA_SIGNATURE_LENGTH;
|
return i2p::crypto::DSA_SIGNATURE_LENGTH;
|
||||||
}
|
}
|
||||||
bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
||||||
{
|
{
|
||||||
if (!m_Verifier) CreateVerifier ();
|
|
||||||
if (m_Verifier)
|
if (m_Verifier)
|
||||||
return m_Verifier->Verify (buf, len, signature);
|
return m_Verifier->Verify (buf, len, signature);
|
||||||
return false;
|
return false;
|
||||||
|
@ -373,52 +366,29 @@ namespace data
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdentityEx::CreateVerifier () const
|
void IdentityEx::CreateVerifier ()
|
||||||
{
|
{
|
||||||
if (m_Verifier) return; // don't create again
|
if (!m_Verifier)
|
||||||
auto verifier = CreateVerifier (GetSigningKeyType ());
|
|
||||||
if (verifier)
|
|
||||||
{
|
{
|
||||||
auto keyLen = verifier->GetPublicKeyLen ();
|
auto verifier = CreateVerifier (GetSigningKeyType ());
|
||||||
if (keyLen <= 128)
|
if (verifier)
|
||||||
verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// for P521
|
auto keyLen = verifier->GetPublicKeyLen ();
|
||||||
uint8_t * signingKey = new uint8_t[keyLen];
|
if (keyLen <= 128)
|
||||||
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
|
verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen);
|
||||||
size_t excessLen = keyLen - 128;
|
else
|
||||||
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
|
{
|
||||||
verifier->SetPublicKey (signingKey);
|
// for P521
|
||||||
delete[] signingKey;
|
uint8_t * signingKey = new uint8_t[keyLen];
|
||||||
|
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
|
||||||
|
size_t excessLen = keyLen - 128;
|
||||||
|
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
|
||||||
|
verifier->SetPublicKey (signingKey);
|
||||||
|
delete[] signingKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
m_Verifier.reset (verifier);
|
||||||
}
|
}
|
||||||
UpdateVerifier (verifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
|
|
||||||
{
|
|
||||||
bool del = false;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> l(m_VerifierMutex);
|
|
||||||
if (!m_Verifier)
|
|
||||||
m_Verifier = verifier;
|
|
||||||
else
|
|
||||||
del = true;
|
|
||||||
}
|
|
||||||
if (del)
|
|
||||||
delete verifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IdentityEx::DropVerifier () const
|
|
||||||
{
|
|
||||||
i2p::crypto::Verifier * verifier;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> l(m_VerifierMutex);
|
|
||||||
verifier = m_Verifier;
|
|
||||||
m_Verifier = nullptr;
|
|
||||||
}
|
|
||||||
delete verifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key)
|
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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,9 +13,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <atomic>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mutex>
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Signature.h"
|
#include "Signature.h"
|
||||||
#include "CryptoKey.h"
|
#include "CryptoKey.h"
|
||||||
|
@ -118,7 +116,6 @@ namespace data
|
||||||
SigningKeyType GetSigningKeyType () const;
|
SigningKeyType GetSigningKeyType () const;
|
||||||
bool IsRSA () const; // signing key type
|
bool IsRSA () const; // signing key type
|
||||||
CryptoKeyType GetCryptoKeyType () const;
|
CryptoKeyType GetCryptoKeyType () const;
|
||||||
void DropVerifier () const; // to save memory
|
|
||||||
|
|
||||||
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
||||||
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
||||||
|
@ -128,15 +125,13 @@ namespace data
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void CreateVerifier () const;
|
void CreateVerifier ();
|
||||||
void UpdateVerifier (i2p::crypto::Verifier * verifier) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Identity m_StandardIdentity;
|
Identity m_StandardIdentity;
|
||||||
IdentHash m_IdentHash;
|
IdentHash m_IdentHash;
|
||||||
mutable i2p::crypto::Verifier * m_Verifier = nullptr;
|
std::unique_ptr<i2p::crypto::Verifier> m_Verifier;
|
||||||
mutable std::mutex m_VerifierMutex;
|
|
||||||
size_t m_ExtendedLen;
|
size_t m_ExtendedLen;
|
||||||
uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE];
|
uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE];
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,13 +81,13 @@ namespace data
|
||||||
{
|
{
|
||||||
if (bit1)
|
if (bit1)
|
||||||
{
|
{
|
||||||
if (root->one) return; // someting wrong
|
if (root->one) return; // something wrong
|
||||||
root->one = new DHTNode;
|
root->one = new DHTNode;
|
||||||
root = root->one;
|
root = root->one;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (root->zero) return; // someting wrong
|
if (root->zero) return; // something wrong
|
||||||
root->zero = new DHTNode;
|
root->zero = new DHTNode;
|
||||||
root = root->zero;
|
root = root->zero;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ namespace data
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, const Filter& filter)
|
std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, const Filter& filter) const
|
||||||
{
|
{
|
||||||
if (filter) m_Filter = filter;
|
if (filter) m_Filter = filter;
|
||||||
auto r = FindClosest (h, m_Root, 0);
|
auto r = FindClosest (h, m_Root, 0);
|
||||||
|
@ -194,7 +194,7 @@ namespace data
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level)
|
std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) const
|
||||||
{
|
{
|
||||||
bool split = false;
|
bool split = false;
|
||||||
do
|
do
|
||||||
|
@ -241,7 +241,7 @@ namespace data
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<RouterInfo> > DHTTable::FindClosest (const IdentHash& h, size_t num, const Filter& filter)
|
std::vector<std::shared_ptr<RouterInfo> > DHTTable::FindClosest (const IdentHash& h, size_t num, const Filter& filter) const
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<RouterInfo> > vec;
|
std::vector<std::shared_ptr<RouterInfo> > vec;
|
||||||
if (num > 0)
|
if (num > 0)
|
||||||
|
@ -253,7 +253,7 @@ namespace data
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector<std::shared_ptr<RouterInfo> >& hashes)
|
void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector<std::shared_ptr<RouterInfo> >& hashes) const
|
||||||
{
|
{
|
||||||
if (hashes.size () >= num) return;
|
if (hashes.size () >= num) return;
|
||||||
bool split = false;
|
bool split = false;
|
||||||
|
@ -292,7 +292,7 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTTable::Cleanup (Filter filter)
|
void DHTTable::Cleanup (const Filter& filter)
|
||||||
{
|
{
|
||||||
if (filter)
|
if (filter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,20 +44,20 @@ namespace data
|
||||||
|
|
||||||
void Insert (const std::shared_ptr<RouterInfo>& r);
|
void Insert (const std::shared_ptr<RouterInfo>& r);
|
||||||
bool Remove (const IdentHash& h);
|
bool Remove (const IdentHash& h);
|
||||||
std::shared_ptr<RouterInfo> FindClosest (const IdentHash& h, const Filter& filter = nullptr);
|
std::shared_ptr<RouterInfo> FindClosest (const IdentHash& h, const Filter& filter = nullptr) const;
|
||||||
std::vector<std::shared_ptr<RouterInfo> > FindClosest (const IdentHash& h, size_t num, const Filter& filter = nullptr);
|
std::vector<std::shared_ptr<RouterInfo> > FindClosest (const IdentHash& h, size_t num, const Filter& filter = nullptr) const;
|
||||||
|
|
||||||
void Print (std::stringstream& s);
|
void Print (std::stringstream& s);
|
||||||
size_t GetSize () const { return m_Size; };
|
size_t GetSize () const { return m_Size; };
|
||||||
void Clear ();
|
void Clear ();
|
||||||
void Cleanup (Filter filter);
|
void Cleanup (const Filter& filter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Insert (const std::shared_ptr<RouterInfo>& r, DHTNode * root, int level); // recursive
|
void Insert (const std::shared_ptr<RouterInfo>& r, DHTNode * root, int level); // recursive
|
||||||
bool Remove (const IdentHash& h, DHTNode * root, int level);
|
bool Remove (const IdentHash& h, DHTNode * root, int level);
|
||||||
std::shared_ptr<RouterInfo> FindClosest (const IdentHash& h, DHTNode * root, int level);
|
std::shared_ptr<RouterInfo> FindClosest (const IdentHash& h, DHTNode * root, int level) const;
|
||||||
void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector<std::shared_ptr<RouterInfo> >& hashes);
|
void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector<std::shared_ptr<RouterInfo> >& hashes) const;
|
||||||
void Cleanup (DHTNode * root);
|
void Cleanup (DHTNode * root);
|
||||||
void Print (std::stringstream& s, DHTNode * root, int level);
|
void Print (std::stringstream& s, DHTNode * root, int level);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace data
|
||||||
DHTNode * m_Root;
|
DHTNode * m_Root;
|
||||||
size_t m_Size;
|
size_t m_Size;
|
||||||
// transient
|
// transient
|
||||||
Filter m_Filter;
|
mutable Filter m_Filter;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace data
|
||||||
void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature)
|
void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature)
|
||||||
{
|
{
|
||||||
if (readIdentity || !m_Identity)
|
if (readIdentity || !m_Identity)
|
||||||
m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
|
m_Identity = netdb.NewIdentity (m_Buffer, m_BufferLen);
|
||||||
size_t size = m_Identity->GetFullLen ();
|
size_t size = m_Identity->GetFullLen ();
|
||||||
if (size + 256 > m_BufferLen)
|
if (size + 256 > m_BufferLen)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ namespace data
|
||||||
LogPrint (eLogDebug, "LeaseSet: Read num=", (int)num);
|
LogPrint (eLogDebug, "LeaseSet: Read num=", (int)num);
|
||||||
if (!num || num > MAX_NUM_LEASES)
|
if (!num || num > MAX_NUM_LEASES)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet: Rncorrect number of leases", (int)num);
|
LogPrint (eLogError, "LeaseSet: Incorrect number of leases", (int)num);
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ namespace data
|
||||||
std::shared_ptr<const IdentityEx> identity;
|
std::shared_ptr<const IdentityEx> identity;
|
||||||
if (readIdentity || !GetIdentity ())
|
if (readIdentity || !GetIdentity ())
|
||||||
{
|
{
|
||||||
identity = std::make_shared<IdentityEx>(buf, len);
|
identity = netdb.NewIdentity (buf, len);
|
||||||
SetIdentity (identity);
|
SetIdentity (identity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,11 +20,12 @@ namespace log {
|
||||||
*/
|
*/
|
||||||
static const char *g_LogLevelStr[eNumLogLevels] =
|
static const char *g_LogLevelStr[eNumLogLevels] =
|
||||||
{
|
{
|
||||||
"none", // eLogNone
|
"none", // eLogNone
|
||||||
"error", // eLogError
|
"critical", // eLogCritical
|
||||||
"warn", // eLogWarning
|
"error", // eLogError
|
||||||
"info", // eLogInfo
|
"warn", // eLogWarning
|
||||||
"debug" // eLogDebug
|
"info", // eLogInfo
|
||||||
|
"debug" // eLogDebug
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,10 +33,11 @@ namespace log {
|
||||||
* @note Using ISO 6429 (ANSI) color sequences
|
* @note Using ISO 6429 (ANSI) color sequences
|
||||||
*/
|
*/
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static const char *LogMsgColors[] = { "", "", "", "", "", "" };
|
static const char *LogMsgColors[] = { "", "", "", "", "", "", "" };
|
||||||
#else /* UNIX */
|
#else /* UNIX */
|
||||||
static const char *LogMsgColors[] = {
|
static const char *LogMsgColors[] = {
|
||||||
"\033[1;32m", /* none: green */
|
"\033[1;32m", /* none: green */
|
||||||
|
"\033[1;41m", /* critical: red background */
|
||||||
"\033[1;31m", /* error: red */
|
"\033[1;31m", /* error: red */
|
||||||
"\033[1;33m", /* warning: yellow */
|
"\033[1;33m", /* warning: yellow */
|
||||||
"\033[1;36m", /* info: cyan */
|
"\033[1;36m", /* info: cyan */
|
||||||
|
@ -53,6 +55,7 @@ namespace log {
|
||||||
int priority = LOG_DEBUG;
|
int priority = LOG_DEBUG;
|
||||||
switch (l) {
|
switch (l) {
|
||||||
case eLogNone : priority = LOG_CRIT; break;
|
case eLogNone : priority = LOG_CRIT; break;
|
||||||
|
case eLogCritical: priority = LOG_CRIT; break;
|
||||||
case eLogError : priority = LOG_ERR; break;
|
case eLogError : priority = LOG_ERR; break;
|
||||||
case eLogWarning : priority = LOG_WARNING; break;
|
case eLogWarning : priority = LOG_WARNING; break;
|
||||||
case eLogInfo : priority = LOG_INFO; break;
|
case eLogInfo : priority = LOG_INFO; break;
|
||||||
|
@ -123,13 +126,14 @@ namespace log {
|
||||||
|
|
||||||
void Log::SetLogLevel (const std::string& level_) {
|
void Log::SetLogLevel (const std::string& level_) {
|
||||||
std::string level=str_tolower(level_);
|
std::string level=str_tolower(level_);
|
||||||
if (level == "none") { m_MinLevel = eLogNone; }
|
if (level == "none") { m_MinLevel = eLogNone; }
|
||||||
else if (level == "error") { m_MinLevel = eLogError; }
|
else if (level == "critical") { m_MinLevel = eLogCritical; }
|
||||||
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
else if (level == "error") { m_MinLevel = eLogError; }
|
||||||
else if (level == "info") { m_MinLevel = eLogInfo; }
|
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
||||||
else if (level == "debug") { m_MinLevel = eLogDebug; }
|
else if (level == "info") { m_MinLevel = eLogInfo; }
|
||||||
|
else if (level == "debug") { m_MinLevel = eLogDebug; }
|
||||||
else {
|
else {
|
||||||
LogPrint(eLogError, "Log: Unknown loglevel: ", level);
|
LogPrint(eLogCritical, "Log: Unknown loglevel: ", level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint(eLogInfo, "Log: Logging level set to ", level);
|
LogPrint(eLogInfo, "Log: Logging level set to ", level);
|
||||||
|
@ -212,7 +216,7 @@ namespace log {
|
||||||
m_LogStream = os;
|
m_LogStream = os;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint(eLogError, "Log: Can't open file ", path);
|
LogPrint(eLogCritical, "Log: Can't open file ", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::SendTo (std::shared_ptr<std::ostream> os) {
|
void Log::SendTo (std::shared_ptr<std::ostream> os) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
enum LogLevel
|
enum LogLevel
|
||||||
{
|
{
|
||||||
eLogNone = 0,
|
eLogNone = 0,
|
||||||
|
eLogCritical,
|
||||||
eLogError,
|
eLogError,
|
||||||
eLogWarning,
|
eLogWarning,
|
||||||
eLogInfo,
|
eLogInfo,
|
||||||
|
|
|
@ -452,6 +452,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
m_Establisher->CreateSessionRequestMessage ();
|
m_Establisher->CreateSessionRequestMessage ();
|
||||||
// send message
|
// send message
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionRequestBuffer, m_Establisher->m_SessionRequestBufferLen), boost::asio::transfer_all (),
|
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionRequestBuffer, m_Establisher->m_SessionRequestBufferLen), boost::asio::transfer_all (),
|
||||||
std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
@ -529,6 +530,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
m_Establisher->CreateSessionCreatedMessage ();
|
m_Establisher->CreateSessionCreatedMessage ();
|
||||||
// send message
|
// send message
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionCreatedBuffer, m_Establisher->m_SessionCreatedBufferLen), boost::asio::transfer_all (),
|
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionCreatedBuffer, m_Establisher->m_SessionCreatedBufferLen), boost::asio::transfer_all (),
|
||||||
std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
@ -542,6 +544,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
|
||||||
LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred);
|
LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred);
|
||||||
uint16_t paddingLen = 0;
|
uint16_t paddingLen = 0;
|
||||||
if (m_Establisher->ProcessSessionCreatedMessage (paddingLen))
|
if (m_Establisher->ProcessSessionCreatedMessage (paddingLen))
|
||||||
|
@ -646,6 +649,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
|
||||||
LogPrint (eLogDebug, "NTCP2: SessionConfirmed received");
|
LogPrint (eLogDebug, "NTCP2: SessionConfirmed received");
|
||||||
// part 1
|
// part 1
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
|
@ -1238,7 +1242,7 @@ namespace transport
|
||||||
boost::system::error_code e;
|
boost::system::error_code e;
|
||||||
auto itr = m_Resolver.resolve(q, e);
|
auto itr = m_Resolver.resolve(q, e);
|
||||||
if(e)
|
if(e)
|
||||||
LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message());
|
LogPrint(eLogCritical, "NTCP2: Failed to resolve proxy ", e.message());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr));
|
m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr));
|
||||||
|
@ -1266,7 +1270,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
catch ( std::exception & ex )
|
catch ( std::exception & ex )
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what());
|
LogPrint(eLogCritical, "NTCP2: Failed to bind to v4 port ", address->port, ex.what());
|
||||||
ThrowFatal ("Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ());
|
ThrowFatal ("Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1309,7 +1313,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
catch ( std::exception & ex )
|
catch ( std::exception & ex )
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NTCP2: Failed to bind to v6 port ", address->port, ": ", ex.what());
|
LogPrint(eLogCritical, "NTCP2: Failed to bind to v6 port ", address->port, ": ", ex.what());
|
||||||
ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ());
|
ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace data
|
||||||
{
|
{
|
||||||
NetDb netdb;
|
NetDb netdb;
|
||||||
|
|
||||||
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true), m_HiddenMode(false)
|
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace data
|
||||||
Load ();
|
Load ();
|
||||||
|
|
||||||
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold);
|
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold);
|
||||||
if (m_RouterInfos.size () < threshold || m_Floodfills.size () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils
|
if (m_RouterInfos.size () < threshold || m_Floodfills.GetSize () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils
|
||||||
{
|
{
|
||||||
Reseed ();
|
Reseed ();
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,13 @@ namespace data
|
||||||
if (it != m_RouterInfos.end ())
|
if (it != m_RouterInfos.end ())
|
||||||
{
|
{
|
||||||
// remove own router
|
// remove own router
|
||||||
m_Floodfills.remove (it->second);
|
m_Floodfills.Remove (it->second->GetIdentHash ());
|
||||||
m_RouterInfos.erase (it);
|
m_RouterInfos.erase (it);
|
||||||
}
|
}
|
||||||
// insert own router
|
// insert own router
|
||||||
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ());
|
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ());
|
||||||
if (i2p::context.IsFloodfill ())
|
if (i2p::context.IsFloodfill ())
|
||||||
m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ());
|
m_Floodfills.Insert (i2p::context.GetSharedRouterInfo ());
|
||||||
|
|
||||||
i2p::config::GetOption("persist.profiles", m_PersistProfiles);
|
i2p::config::GetOption("persist.profiles", m_PersistProfiles);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ namespace data
|
||||||
SaveProfiles ();
|
SaveProfiles ();
|
||||||
DeleteObsoleteProfiles ();
|
DeleteObsoleteProfiles ();
|
||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
m_Floodfills.clear ();
|
m_Floodfills.Clear ();
|
||||||
if (m_Thread)
|
if (m_Thread)
|
||||||
{
|
{
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
|
@ -106,7 +106,7 @@ namespace data
|
||||||
{
|
{
|
||||||
i2p::util::SetThreadName("NetDB");
|
i2p::util::SetThreadName("NetDB");
|
||||||
|
|
||||||
uint64_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
uint64_t lastSave = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
||||||
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
|
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
|
||||||
int16_t profilesCleanupVariance = 0;
|
int16_t profilesCleanupVariance = 0;
|
||||||
|
|
||||||
|
@ -132,9 +132,6 @@ namespace data
|
||||||
case eI2NPDatabaseLookup:
|
case eI2NPDatabaseLookup:
|
||||||
HandleDatabaseLookupMsg (msg);
|
HandleDatabaseLookupMsg (msg);
|
||||||
break;
|
break;
|
||||||
case eI2NPDeliveryStatus:
|
|
||||||
HandleDeliveryStatusMsg (msg);
|
|
||||||
break;
|
|
||||||
case eI2NPDummyMsg:
|
case eI2NPDummyMsg:
|
||||||
// plain RouterInfo from NTCP2 with flags for now
|
// plain RouterInfo from NTCP2 with flags for now
|
||||||
HandleNTCP2RouterInfoMsg (msg);
|
HandleNTCP2RouterInfoMsg (msg);
|
||||||
|
@ -184,33 +181,6 @@ namespace data
|
||||||
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish
|
|
||||||
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
|
||||||
{
|
|
||||||
bool publish = false;
|
|
||||||
if (m_PublishReplyToken)
|
|
||||||
{
|
|
||||||
// next publishing attempt
|
|
||||||
if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true;
|
|
||||||
}
|
|
||||||
else if (i2p::context.GetLastUpdateTime () > lastPublish ||
|
|
||||||
ts - lastPublish >= NETDB_PUBLISH_INTERVAL ||
|
|
||||||
ts + NETDB_PUBLISH_INTERVAL < lastPublish)
|
|
||||||
{
|
|
||||||
// new publish
|
|
||||||
m_PublishExcluded.clear ();
|
|
||||||
if (i2p::context.IsFloodfill ())
|
|
||||||
m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // do publish to ourselves
|
|
||||||
publish = true;
|
|
||||||
}
|
|
||||||
if (publish) // update timestamp and publish
|
|
||||||
{
|
|
||||||
i2p::context.UpdateTimestamp (ts);
|
|
||||||
Publish ();
|
|
||||||
lastPublish = ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts - lastExploratory >= 30 || ts + 30 < lastExploratory) // exploratory every 30 seconds
|
if (ts - lastExploratory >= 30 || ts + 30 < lastExploratory) // exploratory every 30 seconds
|
||||||
{
|
{
|
||||||
auto numRouters = m_RouterInfos.size ();
|
auto numRouters = m_RouterInfos.size ();
|
||||||
|
@ -224,7 +194,7 @@ namespace data
|
||||||
if (numRouters < 1) numRouters = 1;
|
if (numRouters < 1) numRouters = 1;
|
||||||
if (numRouters > 9) numRouters = 9;
|
if (numRouters > 9) numRouters = 9;
|
||||||
m_Requests.ManageRequests ();
|
m_Requests.ManageRequests ();
|
||||||
if(!m_HiddenMode)
|
if(!i2p::context.IsHidden ())
|
||||||
Explore (numRouters);
|
Explore (numRouters);
|
||||||
lastExploratory = ts;
|
lastExploratory = ts;
|
||||||
}
|
}
|
||||||
|
@ -237,12 +207,6 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::SetHidden(bool hide)
|
|
||||||
{
|
|
||||||
// TODO: remove reachable addresses from router info
|
|
||||||
m_HiddenMode = hide;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::AddRouterInfo (const uint8_t * buf, int len)
|
std::shared_ptr<const RouterInfo> NetDb::AddRouterInfo (const uint8_t * buf, int len)
|
||||||
{
|
{
|
||||||
bool updated;
|
bool updated;
|
||||||
|
@ -289,7 +253,7 @@ namespace data
|
||||||
if (wasFloodfill)
|
if (wasFloodfill)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
m_Floodfills.remove (r);
|
m_Floodfills.Remove (r->GetIdentHash ());
|
||||||
}
|
}
|
||||||
m_Requests.RequestComplete (ident, nullptr);
|
m_Requests.RequestComplete (ident, nullptr);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -301,9 +265,9 @@ namespace data
|
||||||
LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64());
|
LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64());
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
if (wasFloodfill)
|
if (wasFloodfill)
|
||||||
m_Floodfills.remove (r);
|
m_Floodfills.Remove (r->GetIdentHash ());
|
||||||
else if (r->IsEligibleFloodfill ())
|
else if (r->IsEligibleFloodfill ())
|
||||||
m_Floodfills.push_back (r);
|
m_Floodfills.Insert (r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -329,7 +293,7 @@ namespace data
|
||||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
m_Floodfills.push_back (r);
|
m_Floodfills.Insert (r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -467,8 +431,8 @@ namespace data
|
||||||
}
|
}
|
||||||
|
|
||||||
// try reseeding from floodfill first if specified
|
// try reseeding from floodfill first if specified
|
||||||
std::string riPath;
|
std::string riPath; i2p::config::GetOption("reseed.floodfill", riPath);
|
||||||
if(i2p::config::GetOption("reseed.floodfill", riPath))
|
if (!riPath.empty())
|
||||||
{
|
{
|
||||||
auto ri = std::make_shared<RouterInfo>(riPath);
|
auto ri = std::make_shared<RouterInfo>(riPath);
|
||||||
if (ri->IsFloodfill())
|
if (ri->IsFloodfill())
|
||||||
|
@ -530,7 +494,7 @@ namespace data
|
||||||
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
||||||
{
|
{
|
||||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||||
m_Floodfills.push_back (r);
|
m_Floodfills.Insert (r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -614,7 +578,7 @@ namespace data
|
||||||
{
|
{
|
||||||
// make sure we cleanup netDb from previous attempts
|
// make sure we cleanup netDb from previous attempts
|
||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
m_Floodfills.clear ();
|
m_Floodfills.Clear ();
|
||||||
|
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
|
@ -622,14 +586,14 @@ namespace data
|
||||||
for (const auto& path : files)
|
for (const auto& path : files)
|
||||||
LoadRouterInfo (path, ts);
|
LoadRouterInfo (path, ts);
|
||||||
|
|
||||||
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)");
|
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.GetSize (), " floodfils)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::SaveUpdated ()
|
void NetDb::SaveUpdated ()
|
||||||
{
|
{
|
||||||
int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0;
|
int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0;
|
||||||
auto total = m_RouterInfos.size ();
|
auto total = m_RouterInfos.size ();
|
||||||
auto totalFloodfills = m_Floodfills.size ();
|
auto totalFloodfills = m_Floodfills.GetSize ();
|
||||||
uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL;
|
uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL;
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
auto uptime = i2p::context.GetUptime ();
|
auto uptime = i2p::context.GetUptime ();
|
||||||
|
@ -698,6 +662,7 @@ namespace data
|
||||||
m_RouterInfoBuffersPool.CleanUpMt ();
|
m_RouterInfoBuffersPool.CleanUpMt ();
|
||||||
m_RouterInfoAddressesPool.CleanUpMt ();
|
m_RouterInfoAddressesPool.CleanUpMt ();
|
||||||
m_RouterInfoAddressVectorsPool.CleanUpMt ();
|
m_RouterInfoAddressVectorsPool.CleanUpMt ();
|
||||||
|
m_IdentitiesPool.CleanUpMt ();
|
||||||
|
|
||||||
if (updatedCount > 0)
|
if (updatedCount > 0)
|
||||||
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
||||||
|
@ -721,11 +686,10 @@ namespace data
|
||||||
// clean up expired floodfills or not floodfills anymore
|
// clean up expired floodfills or not floodfills anymore
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
for (auto it = m_Floodfills.begin (); it != m_Floodfills.end ();)
|
m_Floodfills.Cleanup ([](const std::shared_ptr<RouterInfo>& r)->bool
|
||||||
if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ())
|
{
|
||||||
it = m_Floodfills.erase (it);
|
return r && r->IsFloodfill () && !r->IsUnreachable ();
|
||||||
else
|
});
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,7 +717,7 @@ namespace data
|
||||||
auto outbound = pool ? pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr;
|
auto outbound = pool ? pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr;
|
||||||
auto inbound = pool ? pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr;
|
auto inbound = pool ? pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr;
|
||||||
if (outbound && inbound)
|
if (outbound && inbound)
|
||||||
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound));
|
outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found");
|
LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found");
|
||||||
|
@ -828,7 +792,7 @@ namespace data
|
||||||
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr;
|
auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr;
|
||||||
if (outbound)
|
if (outbound)
|
||||||
outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus);
|
outbound->SendTunnelDataMsgTo (buf + offset, tunnelID, deliveryStatus);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found");
|
LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found");
|
||||||
}
|
}
|
||||||
|
@ -937,7 +901,7 @@ namespace data
|
||||||
{
|
{
|
||||||
// request destination
|
// request destination
|
||||||
LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ());
|
LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ());
|
||||||
outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0,
|
outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0,
|
||||||
dest->CreateRequestMessage (nextFloodfill, inbound));
|
dest->CreateRequestMessage (nextFloodfill, inbound));
|
||||||
deleteDest = false;
|
deleteDest = false;
|
||||||
}
|
}
|
||||||
|
@ -1117,7 +1081,7 @@ namespace data
|
||||||
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
|
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
|
||||||
if (outbound)
|
if (outbound)
|
||||||
outbound->SendTunnelDataMsg (replyIdent, replyTunnelID, replyMsg);
|
outbound->SendTunnelDataMsgTo (replyIdent, replyTunnelID, replyMsg);
|
||||||
else
|
else
|
||||||
transports.SendMessage (replyIdent, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg));
|
transports.SendMessage (replyIdent, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg));
|
||||||
}
|
}
|
||||||
|
@ -1126,16 +1090,6 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::HandleDeliveryStatusMsg (std::shared_ptr<const I2NPMessage> msg)
|
|
||||||
{
|
|
||||||
if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET))
|
|
||||||
{
|
|
||||||
LogPrint (eLogInfo, "NetDb: Publishing confirmed. reply token=", m_PublishReplyToken);
|
|
||||||
m_PublishExcluded.clear ();
|
|
||||||
m_PublishReplyToken = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetDb::Explore (int numDestinations)
|
void NetDb::Explore (int numDestinations)
|
||||||
{
|
{
|
||||||
// new requests
|
// new requests
|
||||||
|
@ -1183,42 +1137,7 @@ namespace data
|
||||||
m_Requests.RequestComplete (randomHash, nullptr);
|
m_Requests.RequestComplete (randomHash, nullptr);
|
||||||
}
|
}
|
||||||
if (throughTunnels && msgs.size () > 0)
|
if (throughTunnels && msgs.size () > 0)
|
||||||
outbound->SendTunnelDataMsg (msgs);
|
outbound->SendTunnelDataMsgs (msgs);
|
||||||
}
|
|
||||||
|
|
||||||
void NetDb::Publish ()
|
|
||||||
{
|
|
||||||
i2p::context.UpdateStats (); // for floodfill
|
|
||||||
|
|
||||||
if (m_PublishExcluded.size () > NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "NetDb: Couldn't publish our RouterInfo to ", NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again");
|
|
||||||
m_PublishExcluded.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto floodfill = GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded);
|
|
||||||
if (floodfill)
|
|
||||||
{
|
|
||||||
uint32_t replyToken;
|
|
||||||
RAND_bytes ((uint8_t *)&replyToken, 4);
|
|
||||||
LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken);
|
|
||||||
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
|
||||||
m_PublishReplyToken = replyToken;
|
|
||||||
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
|
||||||
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
|
||||||
// send directly
|
|
||||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// otherwise through exploratory
|
|
||||||
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
|
||||||
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr;
|
|
||||||
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr;
|
|
||||||
if (inbound && outbound)
|
|
||||||
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0,
|
|
||||||
CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg)
|
void NetDb::Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg)
|
||||||
|
@ -1292,7 +1211,7 @@ namespace data
|
||||||
router->IsReachableFrom (*compatibleWith)) &&
|
router->IsReachableFrom (*compatibleWith)) &&
|
||||||
(router->GetCaps () & RouterInfo::eHighBandwidth) &&
|
(router->GetCaps () & RouterInfo::eHighBandwidth) &&
|
||||||
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION &&
|
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION &&
|
||||||
router->IsECIES ();
|
router->IsECIES () && !router->IsHighCongestion ();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1362,75 +1281,38 @@ namespace data
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination,
|
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination,
|
||||||
const std::set<IdentHash>& excluded) const
|
const std::set<IdentHash>& excluded) const
|
||||||
{
|
{
|
||||||
std::shared_ptr<const RouterInfo> r;
|
|
||||||
XORMetric minMetric;
|
|
||||||
IdentHash destKey = CreateRoutingKey (destination);
|
IdentHash destKey = CreateRoutingKey (destination);
|
||||||
minMetric.SetMax ();
|
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
for (const auto& it: m_Floodfills)
|
return m_Floodfills.FindClosest (destKey, [&excluded](const std::shared_ptr<RouterInfo>& r)->bool
|
||||||
{
|
|
||||||
if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ())
|
|
||||||
{
|
{
|
||||||
XORMetric m = destKey ^ it->GetIdentHash ();
|
return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () &&
|
||||||
if (m < minMetric && !excluded.count (it->GetIdentHash ()))
|
!excluded.count (r->GetIdentHash ());
|
||||||
{
|
});
|
||||||
minMetric = m;
|
|
||||||
r = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num,
|
std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num,
|
||||||
std::set<IdentHash>& excluded, bool closeThanUsOnly) const
|
std::set<IdentHash>& excluded, bool closeThanUsOnly) const
|
||||||
{
|
{
|
||||||
struct Sorted
|
std::vector<IdentHash> res;
|
||||||
{
|
|
||||||
std::shared_ptr<const RouterInfo> r;
|
|
||||||
XORMetric metric;
|
|
||||||
bool operator< (const Sorted& other) const { return metric < other.metric; };
|
|
||||||
};
|
|
||||||
|
|
||||||
std::set<Sorted> sorted;
|
|
||||||
IdentHash destKey = CreateRoutingKey (destination);
|
IdentHash destKey = CreateRoutingKey (destination);
|
||||||
XORMetric ourMetric;
|
std::vector<std::shared_ptr<RouterInfo> > v;
|
||||||
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
|
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
for (const auto& it: m_Floodfills)
|
v = m_Floodfills.FindClosest (destKey, num, [&excluded](const std::shared_ptr<RouterInfo>& r)->bool
|
||||||
{
|
|
||||||
if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ())
|
|
||||||
{
|
{
|
||||||
XORMetric m = destKey ^ it->GetIdentHash ();
|
return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () &&
|
||||||
if (closeThanUsOnly && ourMetric < m) continue;
|
!excluded.count (r->GetIdentHash ());
|
||||||
if (sorted.size () < num)
|
});
|
||||||
sorted.insert ({it, m});
|
}
|
||||||
else if (m < sorted.rbegin ()->metric)
|
if (v.empty ()) return res;
|
||||||
{
|
|
||||||
sorted.insert ({it, m});
|
XORMetric ourMetric;
|
||||||
sorted.erase (std::prev (sorted.end ()));
|
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
|
||||||
}
|
for (auto& it: v)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<IdentHash> res;
|
|
||||||
size_t i = 0;
|
|
||||||
for (const auto& it: sorted)
|
|
||||||
{
|
{
|
||||||
if (i < num)
|
if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break;
|
||||||
{
|
res.push_back (it->GetIdentHash ());
|
||||||
const auto& ident = it.r->GetIdentHash ();
|
}
|
||||||
if (!excluded.count (ident))
|
|
||||||
{
|
|
||||||
res.push_back (ident);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <list>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -31,6 +30,7 @@
|
||||||
#include "Family.h"
|
#include "Family.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "KadDHT.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -45,9 +45,6 @@ namespace data
|
||||||
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
|
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
|
||||||
const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days
|
const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days
|
||||||
const int NETDB_EXPIRATION_TIMEOUT_THRESHOLD = 2*60; // 2 minutes
|
const int NETDB_EXPIRATION_TIMEOUT_THRESHOLD = 2*60; // 2 minutes
|
||||||
const int NETDB_PUBLISH_INTERVAL = 60 * 40;
|
|
||||||
const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
|
|
||||||
const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
|
||||||
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
||||||
const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
||||||
const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
|
||||||
|
@ -86,7 +83,6 @@ namespace data
|
||||||
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void HandleNTCP2RouterInfoMsg (std::shared_ptr<const I2NPMessage> m);
|
void HandleNTCP2RouterInfoMsg (std::shared_ptr<const I2NPMessage> m);
|
||||||
void HandleDeliveryStatusMsg (std::shared_ptr<const I2NPMessage> msg);
|
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||||
|
@ -102,15 +98,12 @@ namespace data
|
||||||
|
|
||||||
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
|
||||||
void SetHidden(bool hide);
|
|
||||||
|
|
||||||
void Reseed ();
|
void Reseed ();
|
||||||
Families& GetFamilies () { return m_Families; };
|
Families& GetFamilies () { return m_Families; };
|
||||||
|
|
||||||
// for web interface
|
// for web interface
|
||||||
int GetNumRouters () const { return m_RouterInfos.size (); };
|
int GetNumRouters () const { return m_RouterInfos.size (); };
|
||||||
int GetNumFloodfills () const { return m_Floodfills.size (); };
|
int GetNumFloodfills () const { return m_Floodfills.GetSize (); };
|
||||||
int GetNumLeaseSets () const { return m_LeaseSets.size (); };
|
int GetNumLeaseSets () const { return m_LeaseSets.size (); };
|
||||||
|
|
||||||
/** visit all lease sets we currently store */
|
/** visit all lease sets we currently store */
|
||||||
|
@ -134,6 +127,7 @@ namespace data
|
||||||
&m_RouterInfoAddressVectorsPool, std::placeholders::_1));
|
&m_RouterInfoAddressVectorsPool, std::placeholders::_1));
|
||||||
};
|
};
|
||||||
std::shared_ptr<Lease> NewLease (const Lease& lease) { return m_LeasesPool.AcquireSharedMt (lease); };
|
std::shared_ptr<Lease> NewLease (const Lease& lease) { return m_LeasesPool.AcquireSharedMt (lease); };
|
||||||
|
std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) { return m_IdentitiesPool.AcquireSharedMt (buf, len); };
|
||||||
|
|
||||||
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
||||||
|
|
||||||
|
@ -144,7 +138,6 @@ namespace data
|
||||||
void SaveUpdated ();
|
void SaveUpdated ();
|
||||||
void Run (); // exploratory thread
|
void Run (); // exploratory thread
|
||||||
void Explore (int numDestinations);
|
void Explore (int numDestinations);
|
||||||
void Publish ();
|
|
||||||
void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg);
|
void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg);
|
||||||
void ManageLeaseSets ();
|
void ManageLeaseSets ();
|
||||||
void ManageRequests ();
|
void ManageRequests ();
|
||||||
|
@ -164,7 +157,7 @@ namespace data
|
||||||
mutable std::mutex m_RouterInfosMutex;
|
mutable std::mutex m_RouterInfosMutex;
|
||||||
std::unordered_map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
|
std::unordered_map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
|
||||||
mutable std::mutex m_FloodfillsMutex;
|
mutable std::mutex m_FloodfillsMutex;
|
||||||
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
DHTTable m_Floodfills;
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::thread * m_Thread;
|
std::thread * m_Thread;
|
||||||
|
@ -183,9 +176,6 @@ namespace data
|
||||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||||
|
|
||||||
/** true if in hidden mode */
|
|
||||||
bool m_HiddenMode;
|
|
||||||
|
|
||||||
std::set<IdentHash> m_PublishExcluded;
|
std::set<IdentHash> m_PublishExcluded;
|
||||||
uint32_t m_PublishReplyToken = 0;
|
uint32_t m_PublishReplyToken = 0;
|
||||||
|
|
||||||
|
@ -193,6 +183,7 @@ namespace data
|
||||||
i2p::util::MemoryPoolMt<RouterInfo::Address> m_RouterInfoAddressesPool;
|
i2p::util::MemoryPoolMt<RouterInfo::Address> m_RouterInfoAddressesPool;
|
||||||
i2p::util::MemoryPoolMt<RouterInfo::Addresses> m_RouterInfoAddressVectorsPool;
|
i2p::util::MemoryPoolMt<RouterInfo::Addresses> m_RouterInfoAddressVectorsPool;
|
||||||
i2p::util::MemoryPoolMt<Lease> m_LeasesPool;
|
i2p::util::MemoryPoolMt<Lease> m_LeasesPool;
|
||||||
|
i2p::util::MemoryPoolMt<IdentityEx> m_IdentitiesPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NetDb netdb;
|
extern NetDb netdb;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -137,7 +137,7 @@ namespace data
|
||||||
auto inbound = pool->GetNextInboundTunnel ();
|
auto inbound = pool->GetNextInboundTunnel ();
|
||||||
auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
|
auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
|
||||||
if (nextFloodfill && outbound && inbound)
|
if (nextFloodfill && outbound && inbound)
|
||||||
outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0,
|
outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0,
|
||||||
dest->CreateRequestMessage (nextFloodfill, inbound));
|
dest->CreateRequestMessage (nextFloodfill, inbound));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -153,7 +153,7 @@ namespace data
|
||||||
return ProcessSU3Stream (s);
|
return ProcessSU3Stream (s);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Can't open file ", filename);
|
LogPrint (eLogCritical, "Reseed: Can't open file ", filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ namespace data
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Can't open file ", filename);
|
LogPrint (eLogCritical, "Reseed: Can't open file ", filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ namespace data
|
||||||
|
|
||||||
if (verify) // not verified
|
if (verify) // not verified
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: SU3 verification failed");
|
LogPrint (eLogCritical, "Reseed: SU3 verification failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ namespace data
|
||||||
uint16_t fileNameLength, extraFieldLength;
|
uint16_t fileNameLength, extraFieldLength;
|
||||||
s.read ((char *)&fileNameLength, 2);
|
s.read ((char *)&fileNameLength, 2);
|
||||||
fileNameLength = le16toh (fileNameLength);
|
fileNameLength = le16toh (fileNameLength);
|
||||||
if ( fileNameLength > 255 ) {
|
if ( fileNameLength >= 255 ) {
|
||||||
// too big
|
// too big
|
||||||
LogPrint(eLogError, "Reseed: SU3 fileNameLength too large: ", fileNameLength);
|
LogPrint(eLogError, "Reseed: SU3 fileNameLength too large: ", fileNameLength);
|
||||||
return numFiles;
|
return numFiles;
|
||||||
|
@ -492,7 +492,7 @@ namespace data
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Can't open certificate file ", filename);
|
LogPrint (eLogCritical, "Reseed: Can't open certificate file ", filename);
|
||||||
SSL_CTX_free (ctx);
|
SSL_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,17 +534,17 @@ namespace data
|
||||||
}
|
}
|
||||||
// check for valid proxy url schema
|
// check for valid proxy url schema
|
||||||
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
|
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
|
||||||
LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy);
|
LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy);
|
LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2p::http::URL url;
|
i2p::http::URL url;
|
||||||
if (!url.parse(address)) {
|
if (!url.parse(address)) {
|
||||||
LogPrint(eLogError, "Reseed: Failed to parse url: ", address);
|
LogPrint(eLogCritical, "Reseed: Failed to parse url: ", address);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
url.schema = "https";
|
url.schema = "https";
|
||||||
|
@ -687,12 +687,23 @@ namespace data
|
||||||
while (it != end)
|
while (it != end)
|
||||||
{
|
{
|
||||||
boost::asio::ip::tcp::endpoint ep = *it;
|
boost::asio::ip::tcp::endpoint ep = *it;
|
||||||
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
if (
|
||||||
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
(
|
||||||
|
!i2p::util::net::IsInReservedRange(ep.address ()) && (
|
||||||
|
(ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
||||||
|
(ep.address ().is_v6 () && i2p::context.SupportsV6 ())
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
i2p::util::net::IsYggdrasilAddress (ep.address ()) &&
|
||||||
|
i2p::context.SupportsMesh ()
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
s.lowest_layer().connect (ep, ecode);
|
s.lowest_layer().connect (ep, ecode);
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Resolved to ", ep.address ());
|
||||||
connected = true;
|
connected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -780,17 +791,45 @@ namespace data
|
||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
|
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
|
||||||
|
|
||||||
if (url.host.length () < 2) return ""; // assume []
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
auto host = url.host.substr (1, url.host.length () - 2);
|
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
||||||
LogPrint (eLogDebug, "Reseed: Connecting to Yggdrasil ", url.host, ":", url.port);
|
|
||||||
s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (host), url.port), ecode);
|
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Reseed: Connected to Yggdrasil ", url.host, ":", url.port);
|
bool connected = false;
|
||||||
|
boost::asio::ip::tcp::resolver::iterator end;
|
||||||
|
while (it != end)
|
||||||
|
{
|
||||||
|
boost::asio::ip::tcp::endpoint ep = *it;
|
||||||
|
if (
|
||||||
|
i2p::util::net::IsYggdrasilAddress (ep.address ()) &&
|
||||||
|
i2p::context.SupportsMesh ()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Yggdrasil: Resolved to ", ep.address ());
|
||||||
|
s.connect (ep, ecode);
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
connected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
if (!connected)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Reseed: Yggdrasil: Failed to connect to ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Yggdrasil: Connected to ", url.host, ":", url.port);
|
||||||
return ReseedRequest (s, url.to_string());
|
return ReseedRequest (s, url.to_string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Couldn't connect to Yggdrasil ", url.host, ": ", ecode.message ());
|
LogPrint (eLogError, "Reseed: Yggdrasil: Couldn't connect to ", url.host, ": ", ecode.message ());
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Family.h"
|
#include "Family.h"
|
||||||
#include "ECIESX25519AEADRatchetSession.h"
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
|
#include "Transports.h"
|
||||||
|
#include "Tunnel.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
|
@ -29,7 +31,8 @@ namespace i2p
|
||||||
RouterContext::RouterContext ():
|
RouterContext::RouterContext ():
|
||||||
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
||||||
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
||||||
m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID)
|
m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID),
|
||||||
|
m_PublishReplyToken (0), m_IsHiddenMode (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +50,34 @@ namespace i2p
|
||||||
m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
|
m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::Start ()
|
||||||
|
{
|
||||||
|
if (!m_Service)
|
||||||
|
{
|
||||||
|
m_Service.reset (new RouterService);
|
||||||
|
m_Service->Start ();
|
||||||
|
if (!m_IsHiddenMode)
|
||||||
|
{
|
||||||
|
m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ()));
|
||||||
|
ScheduleInitialPublish ();
|
||||||
|
m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ()));
|
||||||
|
ScheduleCongestionUpdate ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::Stop ()
|
||||||
|
{
|
||||||
|
if (m_Service)
|
||||||
|
{
|
||||||
|
if (m_PublishTimer)
|
||||||
|
m_PublishTimer->cancel ();
|
||||||
|
if (m_CongestionUpdateTimer)
|
||||||
|
m_CongestionUpdateTimer->cancel ();
|
||||||
|
m_Service->Stop ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::CreateNewRouter ()
|
void RouterContext::CreateNewRouter ()
|
||||||
{
|
{
|
||||||
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||||
|
@ -198,6 +229,7 @@ namespace i2p
|
||||||
routerInfo.CreateBuffer (m_Keys);
|
routerInfo.CreateBuffer (m_Keys);
|
||||||
m_RouterInfo.SetRouterIdentity (GetIdentity ());
|
m_RouterInfo.SetRouterIdentity (GetIdentity ());
|
||||||
m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
|
m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
|
||||||
|
m_RouterInfo.SetUnreachable (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t RouterContext::SelectRandomPort () const
|
uint16_t RouterContext::SelectRandomPort () const
|
||||||
|
@ -1058,6 +1090,8 @@ namespace i2p
|
||||||
UpdateSSU2Keys ();
|
UpdateSSU2Keys ();
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
if (m_RouterInfo.UpdateCongestion (i2p::data::RouterInfo::eLowCongestion))
|
||||||
|
updated = true;
|
||||||
if (updated)
|
if (updated)
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
|
|
||||||
|
@ -1080,6 +1114,13 @@ namespace i2p
|
||||||
return i2p::tunnel::tunnels.GetExploratoryPool ();
|
return i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RouterContext::IsHighCongestion () const
|
||||||
|
{
|
||||||
|
return i2p::tunnel::tunnels.IsTooManyTransitTunnels () ||
|
||||||
|
i2p::transport::transports.IsBandwidthExceeded () ||
|
||||||
|
i2p::transport::transports.IsTransitBandwidthExceeded ();
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len)
|
void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len)));
|
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len)));
|
||||||
|
@ -1087,12 +1128,6 @@ namespace i2p
|
||||||
|
|
||||||
bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID)
|
bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID)
|
||||||
{
|
{
|
||||||
if (typeID == eI2NPGarlic)
|
|
||||||
{
|
|
||||||
// TODO: implement
|
|
||||||
LogPrint (eLogWarning, "Router: garlic message in garlic clove. Dropped");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto msg = CreateI2NPMessage (typeID, payload, len, msgID);
|
auto msg = CreateI2NPMessage (typeID, payload, len, msgID);
|
||||||
if (!msg) return false;
|
if (!msg) return false;
|
||||||
i2p::HandleI2NPMessage (msg);
|
i2p::HandleI2NPMessage (msg);
|
||||||
|
@ -1101,7 +1136,14 @@ namespace i2p
|
||||||
|
|
||||||
void RouterContext::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
void RouterContext::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_GarlicMutex);
|
if (m_Service)
|
||||||
|
m_Service->GetService ().post (std::bind (&RouterContext::PostGarlicMessage, this, msg));
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: service is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::PostGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
|
{
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
uint32_t len = bufbe32toh (buf);
|
uint32_t len = bufbe32toh (buf);
|
||||||
if (len > msg->GetLength ())
|
if (len > msg->GetLength ())
|
||||||
|
@ -1118,23 +1160,38 @@ namespace i2p
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Router: Session is not set for ECIES router");
|
LogPrint (eLogError, "Router: Session is not set for ECIES router");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
|
void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET))
|
if (m_Service)
|
||||||
i2p::data::netdb.PostI2NPMsg (msg);
|
m_Service->GetService ().post (std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg));
|
||||||
else
|
else
|
||||||
{
|
LogPrint (eLogError, "Router: service is NULL");
|
||||||
std::unique_lock<std::mutex> l(m_GarlicMutex);
|
|
||||||
i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::PostDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
|
{
|
||||||
|
if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET))
|
||||||
|
{
|
||||||
|
LogPrint (eLogInfo, "Router: Publishing confirmed. reply token=", m_PublishReplyToken);
|
||||||
|
m_PublishExcluded.clear ();
|
||||||
|
m_PublishReplyToken = 0;
|
||||||
|
SchedulePublish ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::CleanupDestination ()
|
void RouterContext::CleanupDestination ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_GarlicMutex);
|
if (m_Service)
|
||||||
i2p::garlic::GarlicDestination::CleanupExpiredTags ();
|
m_Service->GetService ().post ([this]()
|
||||||
|
{
|
||||||
|
this->i2p::garlic::GarlicDestination::CleanupExpiredTags ();
|
||||||
|
});
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: service is NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RouterContext::GetUptime () const
|
uint32_t RouterContext::GetUptime () const
|
||||||
|
@ -1209,4 +1266,148 @@ namespace i2p
|
||||||
}
|
}
|
||||||
return *m_SSU2StaticKeys;
|
return *m_SSU2StaticKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::ScheduleInitialPublish ()
|
||||||
|
{
|
||||||
|
if (m_PublishTimer)
|
||||||
|
{
|
||||||
|
m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL));
|
||||||
|
m_PublishTimer->async_wait (std::bind (&RouterContext::HandleInitialPublishTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: Publish timer is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::HandleInitialPublishTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
if (m_RouterInfo.IsReachableBy (i2p::data::RouterInfo::eAllTransports))
|
||||||
|
HandlePublishTimer (ecode);
|
||||||
|
else
|
||||||
|
ScheduleInitialPublish ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::SchedulePublish ()
|
||||||
|
{
|
||||||
|
if (m_PublishTimer)
|
||||||
|
{
|
||||||
|
m_PublishTimer->cancel ();
|
||||||
|
m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL +
|
||||||
|
rand () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE));
|
||||||
|
m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: Publish timer is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::HandlePublishTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
m_PublishExcluded.clear ();
|
||||||
|
m_PublishReplyToken = 0;
|
||||||
|
if (IsFloodfill ())
|
||||||
|
{
|
||||||
|
UpdateStats (); // for floodfill
|
||||||
|
m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // don't publish to ourselves
|
||||||
|
}
|
||||||
|
UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ());
|
||||||
|
Publish ();
|
||||||
|
SchedulePublishResend ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::Publish ()
|
||||||
|
{
|
||||||
|
if (!i2p::transport::transports.IsOnline ()) return;
|
||||||
|
if (m_PublishExcluded.size () > ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Router: Couldn't publish our RouterInfo to ", ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again");
|
||||||
|
m_PublishExcluded.clear ();
|
||||||
|
UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto floodfill = i2p::data::netdb.GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded);
|
||||||
|
if (floodfill)
|
||||||
|
{
|
||||||
|
uint32_t replyToken;
|
||||||
|
RAND_bytes ((uint8_t *)&replyToken, 4);
|
||||||
|
LogPrint (eLogInfo, "Router: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken);
|
||||||
|
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
||||||
|
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
||||||
|
// send directly
|
||||||
|
i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// otherwise through exploratory
|
||||||
|
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
|
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr;
|
||||||
|
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr;
|
||||||
|
if (inbound && outbound)
|
||||||
|
outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0,
|
||||||
|
CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound));
|
||||||
|
else
|
||||||
|
LogPrint (eLogInfo, "Router: Can't publish our RouterInfo. No tunnles. Try again in ", ROUTER_INFO_CONFIRMATION_TIMEOUT, " seconds");
|
||||||
|
}
|
||||||
|
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
||||||
|
m_PublishReplyToken = replyToken;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogInfo, "Router: Can't find floodfill to publish our RouterInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::SchedulePublishResend ()
|
||||||
|
{
|
||||||
|
if (m_PublishTimer)
|
||||||
|
{
|
||||||
|
m_PublishTimer->cancel ();
|
||||||
|
m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONFIRMATION_TIMEOUT));
|
||||||
|
m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishResendTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: Publish timer is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::HandlePublishResendTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
i2p::context.UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ());
|
||||||
|
Publish ();
|
||||||
|
SchedulePublishResend ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::ScheduleCongestionUpdate ()
|
||||||
|
{
|
||||||
|
if (m_CongestionUpdateTimer)
|
||||||
|
{
|
||||||
|
m_CongestionUpdateTimer->cancel ();
|
||||||
|
m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONGESTION_UPDATE_INTERVAL));
|
||||||
|
m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Router: Congestion update timer is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterContext::HandleCongestionUpdateTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
auto c = i2p::data::RouterInfo::eLowCongestion;
|
||||||
|
if (!AcceptsTunnels ())
|
||||||
|
c = i2p::data::RouterInfo::eRejectAll;
|
||||||
|
else if (IsHighCongestion ())
|
||||||
|
c = i2p::data::RouterInfo::eHighCongestion;
|
||||||
|
if (m_RouterInfo.UpdateCongestion (c))
|
||||||
|
UpdateRouterInfo ();
|
||||||
|
ScheduleCongestionUpdate ();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,13 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <set>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -30,7 +31,13 @@ namespace garlic
|
||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
const char NTCP2_KEYS[] = "ntcp2.keys";
|
const char NTCP2_KEYS[] = "ntcp2.keys";
|
||||||
const char SSU2_KEYS[] = "ssu2.keys";
|
const char SSU2_KEYS[] = "ssu2.keys";
|
||||||
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
const int ROUTER_INFO_UPDATE_INTERVAL = 30*60; // 30 minutes
|
||||||
|
const int ROUTER_INFO_PUBLISH_INTERVAL = 39*60; // in seconds
|
||||||
|
const int ROUTER_INFO_INITIAL_PUBLISH_INTERVAL = 10; // in seconds
|
||||||
|
const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds
|
||||||
|
const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 5; // in seconds
|
||||||
|
const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
||||||
|
const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 12*60; // in seconds
|
||||||
|
|
||||||
enum RouterStatus
|
enum RouterStatus
|
||||||
{
|
{
|
||||||
|
@ -70,11 +77,23 @@ namespace garlic
|
||||||
uint8_t intro[32];
|
uint8_t intro[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RouterService: public i2p::util::RunnableServiceWithWork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RouterService (): RunnableServiceWithWork ("Router") {};
|
||||||
|
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||||
|
void Start () { StartIOService (); };
|
||||||
|
void Stop () { StopIOService (); };
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RouterContext ();
|
RouterContext ();
|
||||||
void Init ();
|
void Init ();
|
||||||
|
void Start ();
|
||||||
|
void Stop ();
|
||||||
|
|
||||||
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
||||||
i2p::data::LocalRouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
i2p::data::LocalRouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
||||||
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo ()
|
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo ()
|
||||||
|
@ -134,6 +153,7 @@ namespace garlic
|
||||||
void SetShareRatio (int percents); // 0 - 100
|
void SetShareRatio (int percents); // 0 - 100
|
||||||
bool AcceptsTunnels () const { return m_AcceptsTunnels; };
|
bool AcceptsTunnels () const { return m_AcceptsTunnels; };
|
||||||
void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
|
void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
|
||||||
|
bool IsHighCongestion () const;
|
||||||
bool SupportsV6 () const { return m_RouterInfo.IsV6 (); };
|
bool SupportsV6 () const { return m_RouterInfo.IsV6 (); };
|
||||||
bool SupportsV4 () const { return m_RouterInfo.IsV4 (); };
|
bool SupportsV4 () const { return m_RouterInfo.IsV4 (); };
|
||||||
bool SupportsMesh () const { return m_RouterInfo.IsMesh (); };
|
bool SupportsMesh () const { return m_RouterInfo.IsMesh (); };
|
||||||
|
@ -141,6 +161,8 @@ namespace garlic
|
||||||
void SetSupportsV4 (bool supportsV4);
|
void SetSupportsV4 (bool supportsV4);
|
||||||
void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host);
|
void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host);
|
||||||
void SetMTU (int mtu, bool v4);
|
void SetMTU (int mtu, bool v4);
|
||||||
|
void SetHidden(bool hide) { m_IsHiddenMode = hide; };
|
||||||
|
bool IsHidden() const { return m_IsHiddenMode; };
|
||||||
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
|
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
|
||||||
|
|
||||||
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove
|
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove
|
||||||
|
@ -183,7 +205,19 @@ namespace garlic
|
||||||
void PublishNTCP2Address (std::shared_ptr<i2p::data::RouterInfo::Address> address, int port, bool publish) const;
|
void PublishNTCP2Address (std::shared_ptr<i2p::data::RouterInfo::Address> address, int port, bool publish) const;
|
||||||
|
|
||||||
bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize);
|
bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize);
|
||||||
|
void PostGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
void PostDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
|
void ScheduleInitialPublish ();
|
||||||
|
void HandleInitialPublishTimer (const boost::system::error_code& ecode);
|
||||||
|
void SchedulePublish ();
|
||||||
|
void HandlePublishTimer (const boost::system::error_code& ecode);
|
||||||
|
void Publish ();
|
||||||
|
void SchedulePublishResend ();
|
||||||
|
void HandlePublishResendTimer (const boost::system::error_code& ecode);
|
||||||
|
void ScheduleCongestionUpdate ();
|
||||||
|
void HandleCongestionUpdateTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
i2p::data::LocalRouterInfo m_RouterInfo;
|
i2p::data::LocalRouterInfo m_RouterInfo;
|
||||||
|
@ -198,12 +232,17 @@ namespace garlic
|
||||||
RouterStatus m_Status, m_StatusV6;
|
RouterStatus m_Status, m_StatusV6;
|
||||||
RouterError m_Error, m_ErrorV6;
|
RouterError m_Error, m_ErrorV6;
|
||||||
int m_NetID;
|
int m_NetID;
|
||||||
std::mutex m_GarlicMutex;
|
|
||||||
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
||||||
std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
|
std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
|
||||||
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
|
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
|
||||||
// for ECIESx25519
|
// for ECIESx25519
|
||||||
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
||||||
|
// publish
|
||||||
|
std::unique_ptr<RouterService> m_Service;
|
||||||
|
std::unique_ptr<boost::asio::deadline_timer> m_PublishTimer, m_CongestionUpdateTimer;
|
||||||
|
std::set<i2p::data::IdentHash> m_PublishExcluded;
|
||||||
|
uint32_t m_PublishReplyToken;
|
||||||
|
bool m_IsHiddenMode; // not publish
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace data
|
||||||
RouterInfo::RouterInfo (const std::string& fullPath):
|
RouterInfo::RouterInfo (const std::string& fullPath):
|
||||||
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
|
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
|
||||||
m_SupportedTransports (0),m_ReachableTransports (0),
|
m_SupportedTransports (0),m_ReachableTransports (0),
|
||||||
m_Caps (0), m_Version (0)
|
m_Caps (0), m_Version (0), m_Congestion (eLowCongestion)
|
||||||
{
|
{
|
||||||
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
||||||
m_Buffer = NewBuffer (); // always RouterInfo's
|
m_Buffer = NewBuffer (); // always RouterInfo's
|
||||||
|
@ -53,7 +53,7 @@ namespace data
|
||||||
RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
|
RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
|
||||||
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
|
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
|
||||||
m_SupportedTransports (0), m_ReachableTransports (0),
|
m_SupportedTransports (0), m_ReachableTransports (0),
|
||||||
m_Caps (0), m_Version (0)
|
m_Caps (0), m_Version (0), m_Congestion (eLowCongestion)
|
||||||
{
|
{
|
||||||
if (len <= MAX_RI_BUFFER_SIZE)
|
if (len <= MAX_RI_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +161,7 @@ namespace data
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen);
|
m_RouterIdentity = NewIdentity (m_Buffer->data (), m_BufferLen);
|
||||||
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
||||||
if (identityLen >= m_BufferLen)
|
if (identityLen >= m_BufferLen)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +186,6 @@ namespace data
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_RouterIdentity->DropVerifier ();
|
|
||||||
}
|
}
|
||||||
// parse RI
|
// parse RI
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
|
@ -202,7 +201,7 @@ namespace data
|
||||||
void RouterInfo::ReadFromStream (std::istream& s)
|
void RouterInfo::ReadFromStream (std::istream& s)
|
||||||
{
|
{
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
m_Caps = 0;
|
m_Caps = 0; m_Congestion = eLowCongestion;
|
||||||
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
|
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
|
||||||
m_Timestamp = be64toh (m_Timestamp);
|
m_Timestamp = be64toh (m_Timestamp);
|
||||||
// read addresses
|
// read addresses
|
||||||
|
@ -336,11 +335,7 @@ namespace data
|
||||||
address->ssu->introducers.resize (index + 1);
|
address->ssu->introducers.resize (index + 1);
|
||||||
}
|
}
|
||||||
Introducer& introducer = address->ssu->introducers.at (index);
|
Introducer& introducer = address->ssu->introducers.at (index);
|
||||||
if (!strcmp (key, "ihost"))
|
if (!strcmp (key, "itag"))
|
||||||
introducer.isH = false; // SSU1
|
|
||||||
else if (!strcmp (key, "iport"))
|
|
||||||
introducer.isH = false; // SSU1
|
|
||||||
else if (!strcmp (key, "itag"))
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -352,10 +347,7 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "ih"))
|
else if (!strcmp (key, "ih"))
|
||||||
{
|
|
||||||
Base64ToByteStream (value, strlen (value), introducer.iH, 32);
|
Base64ToByteStream (value, strlen (value), introducer.iH, 32);
|
||||||
introducer.isH = true;
|
|
||||||
}
|
|
||||||
else if (!strcmp (key, "iexp"))
|
else if (!strcmp (key, "iexp"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -411,7 +403,7 @@ namespace data
|
||||||
int numValid = 0;
|
int numValid = 0;
|
||||||
for (auto& it: address->ssu->introducers)
|
for (auto& it: address->ssu->introducers)
|
||||||
{
|
{
|
||||||
if (it.iTag && ts < it.iExp && it.isH)
|
if (it.iTag && ts < it.iExp)
|
||||||
numValid++;
|
numValid++;
|
||||||
else
|
else
|
||||||
it.iTag = 0;
|
it.iTag = 0;
|
||||||
|
@ -542,6 +534,15 @@ namespace data
|
||||||
case CAPS_FLAG_UNREACHABLE:
|
case CAPS_FLAG_UNREACHABLE:
|
||||||
m_Caps |= Caps::eUnreachable;
|
m_Caps |= Caps::eUnreachable;
|
||||||
break;
|
break;
|
||||||
|
case CAPS_FLAG_MEDIUM_CONGESTION:
|
||||||
|
m_Congestion = eMediumCongestion;
|
||||||
|
break;
|
||||||
|
case CAPS_FLAG_HIGH_CONGESTION:
|
||||||
|
m_Congestion = eHighCongestion;
|
||||||
|
break;
|
||||||
|
case CAPS_FLAG_REJECT_ALL_CONGESTION:
|
||||||
|
m_Congestion = eRejectAll;
|
||||||
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
cap++;
|
cap++;
|
||||||
|
@ -1059,11 +1060,25 @@ namespace data
|
||||||
return netdb.NewRouterInfoAddresses ();
|
return netdb.NewRouterInfoAddresses ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<IdentityEx> RouterInfo::NewIdentity (const uint8_t * buf, size_t len) const
|
||||||
|
{
|
||||||
|
return netdb.NewIdentity (buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
void RouterInfo::RefreshTimestamp ()
|
void RouterInfo::RefreshTimestamp ()
|
||||||
{
|
{
|
||||||
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RouterInfo::IsHighCongestion () const
|
||||||
|
{
|
||||||
|
if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false;
|
||||||
|
if (m_Congestion == eRejectAll) return true;
|
||||||
|
if (m_Congestion == eHighCongestion)
|
||||||
|
return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL) ? true : false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
||||||
{
|
{
|
||||||
RefreshTimestamp ();
|
RefreshTimestamp ();
|
||||||
|
@ -1115,9 +1130,34 @@ namespace data
|
||||||
if (c & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable
|
if (c & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable
|
||||||
if (c & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable
|
if (c & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable
|
||||||
|
|
||||||
|
switch (GetCongestion ())
|
||||||
|
{
|
||||||
|
case eMediumCongestion:
|
||||||
|
caps += CAPS_FLAG_MEDIUM_CONGESTION;
|
||||||
|
break;
|
||||||
|
case eHighCongestion:
|
||||||
|
caps += CAPS_FLAG_HIGH_CONGESTION;
|
||||||
|
break;
|
||||||
|
case eRejectAll:
|
||||||
|
caps += CAPS_FLAG_REJECT_ALL_CONGESTION;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
};
|
||||||
|
|
||||||
SetProperty ("caps", caps);
|
SetProperty ("caps", caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LocalRouterInfo::UpdateCongestion (Congestion c)
|
||||||
|
{
|
||||||
|
if (c != GetCongestion ())
|
||||||
|
{
|
||||||
|
SetCongestion (c);
|
||||||
|
UpdateCapsProperty ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::WriteToStream (std::ostream& s) const
|
void LocalRouterInfo::WriteToStream (std::ostream& s) const
|
||||||
{
|
{
|
||||||
auto addresses = GetAddresses ();
|
auto addresses = GetAddresses ();
|
||||||
|
@ -1154,44 +1194,37 @@ namespace data
|
||||||
s.write ((const char *)&cost, sizeof (cost));
|
s.write ((const char *)&cost, sizeof (cost));
|
||||||
s.write ((const char *)&address.date, sizeof (address.date));
|
s.write ((const char *)&address.date, sizeof (address.date));
|
||||||
std::stringstream properties;
|
std::stringstream properties;
|
||||||
bool isPublished = false;
|
bool isPublished = address.published && !address.host.is_unspecified () && address.port;
|
||||||
if (address.transportStyle == eTransportNTCP2)
|
if (address.transportStyle == eTransportNTCP2)
|
||||||
{
|
{
|
||||||
if (address.IsNTCP2 ())
|
WriteString ("NTCP2", s);
|
||||||
|
// caps
|
||||||
|
if (!isPublished)
|
||||||
{
|
{
|
||||||
WriteString ("NTCP2", s);
|
WriteString ("caps", properties);
|
||||||
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
|
properties << '=';
|
||||||
isPublished = true;
|
std::string caps;
|
||||||
else
|
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
||||||
{
|
if (address.IsV6 () || address.host.is_v6 ()) caps += CAPS_FLAG_V6; // we set 6 for unspecified ipv6
|
||||||
WriteString ("caps", properties);
|
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||||
properties << '=';
|
WriteString (caps, properties);
|
||||||
std::string caps;
|
properties << ';';
|
||||||
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
|
||||||
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
|
||||||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
|
||||||
WriteString (caps, properties);
|
|
||||||
properties << ';';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
continue; // don't write NTCP address
|
|
||||||
}
|
}
|
||||||
else if (address.transportStyle == eTransportSSU2)
|
else if (address.transportStyle == eTransportSSU2)
|
||||||
{
|
{
|
||||||
WriteString ("SSU2", s);
|
WriteString ("SSU2", s);
|
||||||
// caps
|
// caps
|
||||||
std::string caps;
|
std::string caps;
|
||||||
if (address.published)
|
if (isPublished)
|
||||||
{
|
{
|
||||||
isPublished = true;
|
|
||||||
if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU2_TESTING;
|
if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU2_TESTING;
|
||||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU2_INTRODUCER;
|
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU2_INTRODUCER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
||||||
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
if (address.IsV6 () || address.host.is_v6 ()) caps += CAPS_FLAG_V6; // we set 6 for unspecified ipv6
|
||||||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||||
}
|
}
|
||||||
if (!caps.empty ())
|
if (!caps.empty ())
|
||||||
|
@ -1350,6 +1383,11 @@ namespace data
|
||||||
return boost::make_shared<Addresses> ();
|
return boost::make_shared<Addresses> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<IdentityEx> LocalRouterInfo::NewIdentity (const uint8_t * buf, size_t len) const
|
||||||
|
{
|
||||||
|
return std::make_shared<IdentityEx> (buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4)
|
bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4)
|
||||||
{
|
{
|
||||||
auto addresses = GetAddresses ();
|
auto addresses = GetAddresses ();
|
||||||
|
|
|
@ -44,7 +44,11 @@ namespace data
|
||||||
const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */
|
const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */
|
||||||
const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
|
const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
|
||||||
const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */
|
const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */
|
||||||
|
// congesion flags
|
||||||
|
const char CAPS_FLAG_MEDIUM_CONGESTION = 'D';
|
||||||
|
const char CAPS_FLAG_HIGH_CONGESTION = 'E';
|
||||||
|
const char CAPS_FLAG_REJECT_ALL_CONGESTION = 'G';
|
||||||
|
|
||||||
const char CAPS_FLAG_V4 = '4';
|
const char CAPS_FLAG_V4 = '4';
|
||||||
const char CAPS_FLAG_V6 = '6';
|
const char CAPS_FLAG_V6 = '6';
|
||||||
const char CAPS_FLAG_SSU2_TESTING = 'B';
|
const char CAPS_FLAG_SSU2_TESTING = 'B';
|
||||||
|
@ -56,6 +60,8 @@ namespace data
|
||||||
const uint8_t COST_SSU2_NON_PUBLISHED = 15;
|
const uint8_t COST_SSU2_NON_PUBLISHED = 15;
|
||||||
|
|
||||||
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
|
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
|
||||||
|
const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes
|
||||||
|
|
||||||
class RouterInfo: public RoutingDestination
|
class RouterInfo: public RoutingDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -93,6 +99,14 @@ namespace data
|
||||||
eUnreachable = 0x20
|
eUnreachable = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Congestion
|
||||||
|
{
|
||||||
|
eLowCongestion = 0,
|
||||||
|
eMediumCongestion,
|
||||||
|
eHighCongestion,
|
||||||
|
eRejectAll
|
||||||
|
};
|
||||||
|
|
||||||
enum AddressCaps
|
enum AddressCaps
|
||||||
{
|
{
|
||||||
eV4 = 0x01,
|
eV4 = 0x01,
|
||||||
|
@ -110,11 +124,10 @@ namespace data
|
||||||
|
|
||||||
struct Introducer
|
struct Introducer
|
||||||
{
|
{
|
||||||
Introducer (): iTag (0), iExp (0), isH (false) {};
|
Introducer (): iTag (0), iExp (0) {};
|
||||||
IdentHash iH;
|
IdentHash iH;
|
||||||
uint32_t iTag;
|
uint32_t iTag;
|
||||||
uint32_t iExp;
|
uint32_t iExp;
|
||||||
bool isH; // TODO: remove later
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SSUExt
|
struct SSUExt
|
||||||
|
@ -235,10 +248,13 @@ namespace data
|
||||||
bool IsEligibleFloodfill () const;
|
bool IsEligibleFloodfill () const;
|
||||||
bool IsSSU2PeerTesting (bool v4) const;
|
bool IsSSU2PeerTesting (bool v4) const;
|
||||||
bool IsSSU2Introducer (bool v4) const;
|
bool IsSSU2Introducer (bool v4) const;
|
||||||
|
bool IsHighCongestion () const;
|
||||||
|
|
||||||
uint8_t GetCaps () const { return m_Caps; };
|
uint8_t GetCaps () const { return m_Caps; };
|
||||||
void SetCaps (uint8_t caps) { m_Caps = caps; };
|
void SetCaps (uint8_t caps) { m_Caps = caps; };
|
||||||
|
|
||||||
|
Congestion GetCongestion () const { return m_Congestion; };
|
||||||
|
|
||||||
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
||||||
bool IsUnreachable () const { return m_IsUnreachable; };
|
bool IsUnreachable () const { return m_IsUnreachable; };
|
||||||
|
|
||||||
|
@ -275,7 +291,8 @@ namespace data
|
||||||
void RefreshTimestamp ();
|
void RefreshTimestamp ();
|
||||||
CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; };
|
CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; };
|
||||||
void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; };
|
void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; };
|
||||||
|
void SetCongestion (Congestion c) { m_Congestion = c; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool LoadFile (const std::string& fullPath);
|
bool LoadFile (const std::string& fullPath);
|
||||||
|
@ -290,6 +307,7 @@ namespace data
|
||||||
virtual std::shared_ptr<Buffer> NewBuffer () const;
|
virtual std::shared_ptr<Buffer> NewBuffer () const;
|
||||||
virtual std::shared_ptr<Address> NewAddress () const;
|
virtual std::shared_ptr<Address> NewAddress () const;
|
||||||
virtual boost::shared_ptr<Addresses> NewAddresses () const;
|
virtual boost::shared_ptr<Addresses> NewAddresses () const;
|
||||||
|
virtual std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -303,6 +321,7 @@ namespace data
|
||||||
CompatibleTransports m_SupportedTransports, m_ReachableTransports;
|
CompatibleTransports m_SupportedTransports, m_ReachableTransports;
|
||||||
uint8_t m_Caps;
|
uint8_t m_Caps;
|
||||||
int m_Version;
|
int m_Version;
|
||||||
|
Congestion m_Congestion;
|
||||||
mutable std::shared_ptr<RouterProfile> m_Profile;
|
mutable std::shared_ptr<RouterProfile> m_Profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -311,9 +330,9 @@ namespace data
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LocalRouterInfo () = default;
|
LocalRouterInfo () = default;
|
||||||
LocalRouterInfo (const std::string& fullPath): RouterInfo (fullPath) {};
|
|
||||||
void CreateBuffer (const PrivateKeys& privateKeys);
|
void CreateBuffer (const PrivateKeys& privateKeys);
|
||||||
void UpdateCaps (uint8_t caps);
|
void UpdateCaps (uint8_t caps);
|
||||||
|
bool UpdateCongestion (Congestion c); // returns true if updated
|
||||||
|
|
||||||
void SetProperty (const std::string& key, const std::string& value) override;
|
void SetProperty (const std::string& key, const std::string& value) override;
|
||||||
void DeleteProperty (const std::string& key);
|
void DeleteProperty (const std::string& key);
|
||||||
|
@ -331,6 +350,7 @@ namespace data
|
||||||
std::shared_ptr<Buffer> NewBuffer () const override;
|
std::shared_ptr<Buffer> NewBuffer () const override;
|
||||||
std::shared_ptr<Address> NewAddress () const override;
|
std::shared_ptr<Address> NewAddress () const override;
|
||||||
boost::shared_ptr<Addresses> NewAddresses () const override;
|
boost::shared_ptr<Addresses> NewAddresses () const override;
|
||||||
|
std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "SSU2: Can't start server because port not specified");
|
LogPrint (eLogCritical, "SSU2: Can't start server because port not specified");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
|
@ -224,7 +224,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
catch (std::exception& ex )
|
catch (std::exception& ex )
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what());
|
LogPrint (eLogCritical, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what());
|
||||||
ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ());
|
ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ());
|
||||||
}
|
}
|
||||||
return socket;
|
return socket;
|
||||||
|
@ -918,7 +918,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
uint64_t token;
|
uint64_t token;
|
||||||
RAND_bytes ((uint8_t *)&token, 8);
|
RAND_bytes ((uint8_t *)&token, 8);
|
||||||
m_IncomingTokens.emplace (ep, std::make_pair (token, ts + SSU2_TOKEN_EXPIRATION_TIMEOUT));
|
m_IncomingTokens.emplace (ep, std::make_pair (token, uint32_t(ts + SSU2_TOKEN_EXPIRATION_TIMEOUT)));
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,7 +927,7 @@ namespace transport
|
||||||
m_IncomingTokens.erase (ep); // drop previous
|
m_IncomingTokens.erase (ep); // drop previous
|
||||||
uint64_t token;
|
uint64_t token;
|
||||||
RAND_bytes ((uint8_t *)&token, 8);
|
RAND_bytes ((uint8_t *)&token, 8);
|
||||||
auto ret = std::make_pair (token, i2p::util::GetSecondsSinceEpoch () + SSU2_NEXT_TOKEN_EXPIRATION_TIMEOUT);
|
auto ret = std::make_pair (token, uint32_t(i2p::util::GetSecondsSinceEpoch () + SSU2_NEXT_TOKEN_EXPIRATION_TIMEOUT));
|
||||||
m_IncomingTokens.emplace (ep, ret);
|
m_IncomingTokens.emplace (ep, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1017,6 @@ namespace transport
|
||||||
i2p::data::RouterInfo::Introducer introducer;
|
i2p::data::RouterInfo::Introducer introducer;
|
||||||
introducer.iTag = it->GetRelayTag ();
|
introducer.iTag = it->GetRelayTag ();
|
||||||
introducer.iH = it->GetRemoteIdentity ()->GetIdentHash ();
|
introducer.iH = it->GetRemoteIdentity ()->GetIdentHash ();
|
||||||
introducer.isH = true;
|
|
||||||
introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION;
|
introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION;
|
||||||
excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ());
|
excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ());
|
||||||
if (i2p::context.AddSSU2Introducer (introducer, v4))
|
if (i2p::context.AddSSU2Introducer (introducer, v4))
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace transport
|
||||||
if (msg->len + fragmentSize > msg->maxLen)
|
if (msg->len + fragmentSize > msg->maxLen)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough");
|
LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough");
|
||||||
auto newMsg = NewI2NPMessage ();
|
auto newMsg = NewI2NPMessage (msg->len + fragmentSize);
|
||||||
*newMsg = *msg;
|
*newMsg = *msg;
|
||||||
msg = newMsg;
|
msg = newMsg;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace transport
|
||||||
m_Server (server), m_Address (addr), m_RemoteTransports (0),
|
m_Server (server), m_Address (addr), m_RemoteTransports (0),
|
||||||
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
|
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
|
||||||
m_SendPacketNum (0), m_ReceivePacketNum (0), m_LastDatetimeSentPacketNum (0),
|
m_SendPacketNum (0), m_ReceivePacketNum (0), m_LastDatetimeSentPacketNum (0),
|
||||||
m_IsDataReceived (false), m_WindowSize (SSU2_MIN_WINDOW_SIZE),
|
m_IsDataReceived (false), m_WindowSize (SSU2_MIN_WINDOW_SIZE),
|
||||||
m_RTT (SSU2_RESEND_INTERVAL), m_RTO (SSU2_RESEND_INTERVAL*SSU2_kAPPA), m_RelayTag (0),
|
m_RTT (SSU2_RESEND_INTERVAL), m_RTO (SSU2_RESEND_INTERVAL*SSU2_kAPPA), m_RelayTag (0),
|
||||||
m_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose),
|
m_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose),
|
||||||
m_MaxPayloadSize (SSU2_MIN_PACKET_SIZE - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - 32) // min size
|
m_MaxPayloadSize (SSU2_MIN_PACKET_SIZE - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - 32) // min size
|
||||||
|
@ -608,7 +608,7 @@ namespace transport
|
||||||
* payload = m_SentHandshakePacket->payload;
|
* payload = m_SentHandshakePacket->payload;
|
||||||
// fill packet
|
// fill packet
|
||||||
header.h.connID = m_DestConnID; // dest id
|
header.h.connID = m_DestConnID; // dest id
|
||||||
header.h.packetNum = 0;
|
RAND_bytes (header.buf + 8, 4); // random packet num
|
||||||
header.h.type = eSSU2SessionRequest;
|
header.h.type = eSSU2SessionRequest;
|
||||||
header.h.flags[0] = 2; // ver
|
header.h.flags[0] = 2; // ver
|
||||||
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
|
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
|
||||||
|
@ -636,7 +636,7 @@ namespace transport
|
||||||
m_EphemeralKeys->Agree (m_Address->s, sharedSecret);
|
m_EphemeralKeys->Agree (m_Address->s, sharedSecret);
|
||||||
m_NoiseState->MixKey (sharedSecret);
|
m_NoiseState->MixKey (sharedSecret);
|
||||||
// encrypt
|
// encrypt
|
||||||
const uint8_t nonce[12] = {0};
|
const uint8_t nonce[12] = {0}; // always 0
|
||||||
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
||||||
payloadSize += 16;
|
payloadSize += 16;
|
||||||
header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
|
header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
|
||||||
|
@ -648,6 +648,7 @@ namespace transport
|
||||||
if (m_State == eSSU2SessionStateTokenReceived || m_Server.AddPendingOutgoingSession (shared_from_this ()))
|
if (m_State == eSSU2SessionStateTokenReceived || m_Server.AddPendingOutgoingSession (shared_from_this ()))
|
||||||
{
|
{
|
||||||
m_State = eSSU2SessionStateSessionRequestSent;
|
m_State = eSSU2SessionStateSessionRequestSent;
|
||||||
|
m_HandshakeInterval = ts;
|
||||||
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
|
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -721,7 +722,7 @@ namespace transport
|
||||||
uint8_t * headerX = m_SentHandshakePacket->headerX,
|
uint8_t * headerX = m_SentHandshakePacket->headerX,
|
||||||
* payload = m_SentHandshakePacket->payload;
|
* payload = m_SentHandshakePacket->payload;
|
||||||
header.h.connID = m_DestConnID; // dest id
|
header.h.connID = m_DestConnID; // dest id
|
||||||
header.h.packetNum = 0;
|
RAND_bytes (header.buf + 8, 4); // random packet num
|
||||||
header.h.type = eSSU2SessionCreated;
|
header.h.type = eSSU2SessionCreated;
|
||||||
header.h.flags[0] = 2; // ver
|
header.h.flags[0] = 2; // ver
|
||||||
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
|
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
|
||||||
|
@ -760,7 +761,7 @@ namespace transport
|
||||||
m_EphemeralKeys->Agree (X, sharedSecret);
|
m_EphemeralKeys->Agree (X, sharedSecret);
|
||||||
m_NoiseState->MixKey (sharedSecret);
|
m_NoiseState->MixKey (sharedSecret);
|
||||||
// encrypt
|
// encrypt
|
||||||
const uint8_t nonce[12] = {0};
|
const uint8_t nonce[12] = {0}; // always zero
|
||||||
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
||||||
payloadSize += 16;
|
payloadSize += 16;
|
||||||
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || encrypted Noise payload from Session Created)
|
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || encrypted Noise payload from Session Created)
|
||||||
|
@ -770,6 +771,7 @@ namespace transport
|
||||||
m_State = eSSU2SessionStateSessionCreatedSent;
|
m_State = eSSU2SessionStateSessionCreatedSent;
|
||||||
m_SentHandshakePacket->payloadSize = payloadSize;
|
m_SentHandshakePacket->payloadSize = payloadSize;
|
||||||
// send
|
// send
|
||||||
|
m_HandshakeInterval = ts;
|
||||||
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
|
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,6 +792,7 @@ namespace transport
|
||||||
LogPrint (eLogWarning, "SSU2: SessionCreated message too short ", len);
|
LogPrint (eLogWarning, "SSU2: SessionCreated message too short ", len);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
|
||||||
const uint8_t nonce[12] = {0};
|
const uint8_t nonce[12] = {0};
|
||||||
uint8_t headerX[48];
|
uint8_t headerX[48];
|
||||||
i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX);
|
i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX);
|
||||||
|
@ -832,7 +835,7 @@ namespace transport
|
||||||
// fill packet
|
// fill packet
|
||||||
Header& header = m_SentHandshakePacket->header;
|
Header& header = m_SentHandshakePacket->header;
|
||||||
header.h.connID = m_DestConnID; // dest id
|
header.h.connID = m_DestConnID; // dest id
|
||||||
header.h.packetNum = 0;
|
header.h.packetNum = 0; // always zero
|
||||||
header.h.type = eSSU2SessionConfirmed;
|
header.h.type = eSSU2SessionConfirmed;
|
||||||
memset (header.h.flags, 0, 3);
|
memset (header.h.flags, 0, 3);
|
||||||
header.h.flags[0] = 1; // frag, total fragments always 1
|
header.h.flags[0] = 1; // frag, total fragments always 1
|
||||||
|
@ -855,7 +858,7 @@ namespace transport
|
||||||
// Encrypt part 1
|
// Encrypt part 1
|
||||||
uint8_t * part1 = m_SentHandshakePacket->headerX;
|
uint8_t * part1 = m_SentHandshakePacket->headerX;
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (1, nonce);
|
CreateNonce (1, nonce); // always one
|
||||||
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetSSU2StaticPublicKey (), 32, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, part1, 48, true);
|
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetSSU2StaticPublicKey (), 32, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, part1, 48, true);
|
||||||
m_NoiseState->MixHash (part1, 48); // h = SHA256(h || ciphertext);
|
m_NoiseState->MixHash (part1, 48); // h = SHA256(h || ciphertext);
|
||||||
// KDF for Session Confirmed part 2
|
// KDF for Session Confirmed part 2
|
||||||
|
@ -863,7 +866,7 @@ namespace transport
|
||||||
i2p::context.GetSSU2StaticKeys ().Agree (Y, sharedSecret);
|
i2p::context.GetSSU2StaticKeys ().Agree (Y, sharedSecret);
|
||||||
m_NoiseState->MixKey (sharedSecret);
|
m_NoiseState->MixKey (sharedSecret);
|
||||||
// Encrypt part2
|
// Encrypt part2
|
||||||
memset (nonce, 0, 12);
|
memset (nonce, 0, 12); // always zero
|
||||||
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true);
|
||||||
payloadSize += 16;
|
payloadSize += 16;
|
||||||
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || ciphertext);
|
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || ciphertext);
|
||||||
|
@ -920,6 +923,12 @@ namespace transport
|
||||||
// TODO: queue up
|
// TODO: queue up
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// packet num must be always zero
|
||||||
|
if (header.h.packetNum)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "SSU2: Non zero packet number in SessionConfirmed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// check if fragmented
|
// check if fragmented
|
||||||
uint8_t numFragments = header.h.flags[0] & 0x0F;
|
uint8_t numFragments = header.h.flags[0] & 0x0F;
|
||||||
if (numFragments > 1)
|
if (numFragments > 1)
|
||||||
|
@ -989,6 +998,7 @@ namespace transport
|
||||||
if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr);
|
if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
|
||||||
// KDF for Session Confirmed part 1
|
// KDF for Session Confirmed part 1
|
||||||
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
||||||
// decrypt part1
|
// decrypt part1
|
||||||
|
@ -1661,7 +1671,7 @@ namespace transport
|
||||||
// ranges
|
// ranges
|
||||||
len -= 5;
|
len -= 5;
|
||||||
const uint8_t * ranges = buf + 5;
|
const uint8_t * ranges = buf + 5;
|
||||||
while (len > 0 && firstPacketNum)
|
while (len > 0 && firstPacketNum && ackThrough - firstPacketNum < SSU2_MAX_NUM_ACK_PACKETS)
|
||||||
{
|
{
|
||||||
uint32_t lastPacketNum = firstPacketNum - 1;
|
uint32_t lastPacketNum = firstPacketNum - 1;
|
||||||
if (*ranges > lastPacketNum) break;
|
if (*ranges > lastPacketNum) break;
|
||||||
|
@ -1766,8 +1776,8 @@ namespace transport
|
||||||
|
|
||||||
void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len)
|
void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
|
auto msg = (buf[0] == eI2NPTunnelData) ? NewI2NPTunnelMessage (true) : NewI2NPShortMessage ();
|
||||||
uint32_t msgID; memcpy (&msgID, buf + 1, 4);
|
uint32_t msgID; memcpy (&msgID, buf + 1, 4);
|
||||||
auto msg = NewI2NPShortMessage ();
|
|
||||||
// same format as I2NP message block
|
// same format as I2NP message block
|
||||||
msg->len = msg->offset + len + 7;
|
msg->len = msg->offset + len + 7;
|
||||||
memcpy (msg->GetNTCP2Header (), buf, len);
|
memcpy (msg->GetNTCP2Header (), buf, len);
|
||||||
|
@ -1874,7 +1884,7 @@ namespace transport
|
||||||
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI
|
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI
|
||||||
if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr;
|
if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr;
|
||||||
if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found");
|
if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found");
|
||||||
|
|
||||||
uint8_t payload[SSU2_MAX_PACKET_SIZE];
|
uint8_t payload[SSU2_MAX_PACKET_SIZE];
|
||||||
size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0;
|
size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0;
|
||||||
if (!payloadSize && r)
|
if (!payloadSize && r)
|
||||||
|
@ -2807,13 +2817,13 @@ namespace transport
|
||||||
uint8_t payload[SSU2_MAX_PACKET_SIZE];
|
uint8_t payload[SSU2_MAX_PACKET_SIZE];
|
||||||
size_t payloadSize = 0;
|
size_t payloadSize = 0;
|
||||||
if (m_SendPacketNum > m_LastDatetimeSentPacketNum + SSU2_SEND_DATETIME_NUM_PACKETS)
|
if (m_SendPacketNum > m_LastDatetimeSentPacketNum + SSU2_SEND_DATETIME_NUM_PACKETS)
|
||||||
{
|
{
|
||||||
payload[0] = eSSU2BlkDateTime;
|
payload[0] = eSSU2BlkDateTime;
|
||||||
htobe16buf (payload + 1, 4);
|
htobe16buf (payload + 1, 4);
|
||||||
htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000);
|
htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000);
|
||||||
payloadSize += 7;
|
payloadSize += 7;
|
||||||
m_LastDatetimeSentPacketNum = m_SendPacketNum;
|
m_LastDatetimeSentPacketNum = m_SendPacketNum;
|
||||||
}
|
}
|
||||||
payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize);
|
payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize);
|
||||||
payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize);
|
payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize);
|
||||||
SendData (payload, payloadSize);
|
SendData (payload, payloadSize);
|
||||||
|
|
|
@ -49,10 +49,10 @@ namespace transport
|
||||||
const float SSU2_kAPPA = 1.8;
|
const float SSU2_kAPPA = 1.8;
|
||||||
const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages
|
const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages
|
||||||
const int SSU2_MAX_NUM_ACNT = 255; // acnt, acks or nacks
|
const int SSU2_MAX_NUM_ACNT = 255; // acnt, acks or nacks
|
||||||
const int SSU2_MAX_NUM_ACK_PACKETS = 510; // 2*255 ack + nack
|
const int SSU2_MAX_NUM_ACK_PACKETS = 511; // ackthrough + acnt + 1 range
|
||||||
const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send
|
const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send
|
||||||
const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64;
|
const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64;
|
||||||
const int SSU2_SEND_DATETIME_NUM_PACKETS = 250;
|
const int SSU2_SEND_DATETIME_NUM_PACKETS = 256;
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01;
|
const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -51,8 +51,8 @@ namespace stream
|
||||||
{
|
{
|
||||||
// partially
|
// partially
|
||||||
rem = len - offset;
|
rem = len - offset;
|
||||||
memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset);
|
memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem);
|
||||||
nextBuffer->offset += (len - offset);
|
nextBuffer->offset += rem;
|
||||||
offset = len; // break
|
offset = len; // break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,14 +139,22 @@ namespace stream
|
||||||
{
|
{
|
||||||
m_NumReceivedBytes += packet->GetLength ();
|
m_NumReceivedBytes += packet->GetLength ();
|
||||||
if (!m_SendStreamID)
|
if (!m_SendStreamID)
|
||||||
|
{
|
||||||
m_SendStreamID = packet->GetReceiveStreamID ();
|
m_SendStreamID = packet->GetReceiveStreamID ();
|
||||||
|
if (!m_RemoteIdentity && packet->GetNACKCount () == 8 && // first incoming packet
|
||||||
|
memcmp (packet->GetNACKs (), m_LocalDestination.GetOwner ()->GetIdentHash (), 32))
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Streaming: Destination mismatch for ", m_LocalDestination.GetOwner ()->GetIdentHash ().ToBase32 ());
|
||||||
|
m_LocalDestination.DeletePacket (packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!packet->IsNoAck ()) // ack received
|
if (!packet->IsNoAck ()) // ack received
|
||||||
ProcessAck (packet);
|
ProcessAck (packet);
|
||||||
|
|
||||||
int32_t receivedSeqn = packet->GetSeqn ();
|
int32_t receivedSeqn = packet->GetSeqn ();
|
||||||
bool isSyn = packet->IsSYN ();
|
if (!receivedSeqn && !packet->GetFlags ())
|
||||||
if (!receivedSeqn && !isSyn)
|
|
||||||
{
|
{
|
||||||
// plain ack
|
// plain ack
|
||||||
LogPrint (eLogDebug, "Streaming: Plain ACK received");
|
LogPrint (eLogDebug, "Streaming: Plain ACK received");
|
||||||
|
@ -188,7 +196,7 @@ namespace stream
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isSyn)
|
else if (packet->IsSYN ())
|
||||||
// we have to send SYN back to incoming connection
|
// we have to send SYN back to incoming connection
|
||||||
SendBuffer (); // also sets m_IsOpen
|
SendBuffer (); // also sets m_IsOpen
|
||||||
}
|
}
|
||||||
|
@ -384,7 +392,7 @@ namespace stream
|
||||||
memset (p.buf, 0, 22); // minimal header all zeroes
|
memset (p.buf, 0, 22); // minimal header all zeroes
|
||||||
memcpy (p.buf + 4, packet->buf, 4); // but receiveStreamID is the sendStreamID from the ping
|
memcpy (p.buf + 4, packet->buf, 4); // but receiveStreamID is the sendStreamID from the ping
|
||||||
htobe16buf (p.buf + 18, PACKET_FLAG_ECHO); // and echo flag
|
htobe16buf (p.buf + 18, PACKET_FLAG_ECHO); // and echo flag
|
||||||
ssize_t payloadLen = packet->len - (packet->GetPayload () - packet->buf);
|
auto payloadLen = int(packet->len) - (packet->GetPayload () - packet->buf);
|
||||||
if (payloadLen > 0)
|
if (payloadLen > 0)
|
||||||
memcpy (p.buf + 22, packet->GetPayload (), payloadLen);
|
memcpy (p.buf + 22, packet->GetPayload (), payloadLen);
|
||||||
else
|
else
|
||||||
|
@ -560,8 +568,19 @@ namespace stream
|
||||||
else
|
else
|
||||||
htobe32buf (packet + size, m_LastReceivedSequenceNumber);
|
htobe32buf (packet + size, m_LastReceivedSequenceNumber);
|
||||||
size += 4; // ack Through
|
size += 4; // ack Through
|
||||||
packet[size] = 0;
|
if (m_Status == eStreamStatusNew && !m_SendStreamID && m_RemoteIdentity)
|
||||||
size++; // NACK count
|
{
|
||||||
|
// first SYN packet
|
||||||
|
packet[size] = 8;
|
||||||
|
size++; // NACK count
|
||||||
|
memcpy (packet + size, m_RemoteIdentity->GetIdentHash (), 32);
|
||||||
|
size += 32;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[size] = 0;
|
||||||
|
size++; // NACK count
|
||||||
|
}
|
||||||
packet[size] = m_RTO/1000;
|
packet[size] = m_RTO/1000;
|
||||||
size++; // resend delay
|
size++; // resend delay
|
||||||
if (m_Status == eStreamStatusNew)
|
if (m_Status == eStreamStatusNew)
|
||||||
|
@ -906,7 +925,7 @@ namespace stream
|
||||||
});
|
});
|
||||||
m_NumSentBytes += it->GetLength ();
|
m_NumSentBytes += it->GetLength ();
|
||||||
}
|
}
|
||||||
m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs);
|
m_CurrentOutboundTunnel->SendTunnelDataMsgs (msgs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1428,7 +1447,7 @@ namespace stream
|
||||||
const uint8_t * payload, size_t len, uint16_t toPort, bool checksum, bool gzip)
|
const uint8_t * payload, size_t len, uint16_t toPort, bool checksum, bool gzip)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
auto msg = m_I2NPMsgsPool.AcquireShared ();
|
auto msg = (len <= STREAMING_MTU_RATCHETS) ? m_I2NPMsgsPool.AcquireShared () : NewI2NPMessage ();
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
buf += 4; // reserve for lengthlength
|
buf += 4; // reserve for lengthlength
|
||||||
msg->len += 4;
|
msg->len += 4;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -80,6 +80,7 @@ namespace stream
|
||||||
uint32_t GetAckThrough () const { return bufbe32toh (buf + 12); };
|
uint32_t GetAckThrough () const { return bufbe32toh (buf + 12); };
|
||||||
uint8_t GetNACKCount () const { return buf[16]; };
|
uint8_t GetNACKCount () const { return buf[16]; };
|
||||||
uint32_t GetNACK (int i) const { return bufbe32toh (buf + 17 + 4 * i); };
|
uint32_t GetNACK (int i) const { return bufbe32toh (buf + 17 + 4 * i); };
|
||||||
|
const uint8_t * GetNACKs () const { return buf + 17; };
|
||||||
const uint8_t * GetOption () const { return buf + 17 + GetNACKCount ()*4 + 3; }; // 3 = resendDelay + flags
|
const uint8_t * GetOption () const { return buf + 17 + GetNACKCount ()*4 + 3; }; // 3 = resendDelay + flags
|
||||||
uint16_t GetFlags () const { return bufbe16toh (GetOption () - 2); };
|
uint16_t GetFlags () const { return bufbe16toh (GetOption () - 2); };
|
||||||
uint16_t GetOptionSize () const { return bufbe16toh (GetOption ()); };
|
uint16_t GetOptionSize () const { return bufbe16toh (GetOption ()); };
|
||||||
|
@ -312,7 +313,7 @@ namespace stream
|
||||||
std::unordered_map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
|
std::unordered_map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
|
||||||
|
|
||||||
i2p::util::MemoryPool<Packet> m_PacketsPool;
|
i2p::util::MemoryPool<Packet> m_PacketsPool;
|
||||||
i2p::util::MemoryPool<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> > m_I2NPMsgsPool;
|
i2p::util::MemoryPool<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> > m_I2NPMsgsPool;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
|
@ -34,9 +34,9 @@ namespace tunnel
|
||||||
virtual size_t GetNumTransmittedBytes () const { return 0; };
|
virtual size_t GetNumTransmittedBytes () const { return 0; };
|
||||||
|
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||||
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
i2p::crypto::AESKey m_LayerKey, m_IVKey;
|
i2p::crypto::AESKey m_LayerKey, m_IVKey;
|
||||||
|
@ -54,9 +54,9 @@ namespace tunnel
|
||||||
layerKey, ivKey), m_NumTransmittedBytes (0) {};
|
layerKey, ivKey), m_NumTransmittedBytes (0) {};
|
||||||
~TransitTunnelParticipant ();
|
~TransitTunnelParticipant ();
|
||||||
|
|
||||||
size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; };
|
size_t GetNumTransmittedBytes () const override { return m_NumTransmittedBytes; };
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||||
void FlushTunnelDataMsgs ();
|
void FlushTunnelDataMsgs () override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ namespace tunnel
|
||||||
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
|
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
|
||||||
layerKey, ivKey), m_Gateway(this) {};
|
layerKey, ivKey), m_Gateway(this) {};
|
||||||
|
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||||
void FlushTunnelDataMsgs ();
|
void FlushTunnelDataMsgs () override;
|
||||||
size_t GetNumTransmittedBytes () const { return m_Gateway.GetNumSentBytes (); };
|
size_t GetNumTransmittedBytes () const override { return m_Gateway.GetNumSentBytes (); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -94,10 +94,10 @@ namespace tunnel
|
||||||
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey),
|
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey),
|
||||||
m_Endpoint (false) {}; // transit endpoint is always outbound
|
m_Endpoint (false) {}; // transit endpoint is always outbound
|
||||||
|
|
||||||
void Cleanup () { m_Endpoint.Cleanup (); }
|
void Cleanup () override { m_Endpoint.Cleanup (); }
|
||||||
|
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||||
size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }
|
size_t GetNumTransmittedBytes () const override { return m_Endpoint.GetNumReceivedBytes (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,8 @@ namespace transport
|
||||||
std::stringstream m_Stream;
|
std::stringstream m_Stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int64_t TRANSPORT_SESSION_SLOWNESS_THRESHOLD = 500; // in milliseconds
|
||||||
|
const int64_t TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL = 10000; // in milliseconds
|
||||||
class TransportSession
|
class TransportSession
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -76,7 +78,8 @@ namespace transport
|
||||||
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> router, int terminationTimeout):
|
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> router, int terminationTimeout):
|
||||||
m_NumSentBytes (0), m_NumReceivedBytes (0), m_SendQueueSize (0),
|
m_NumSentBytes (0), m_NumReceivedBytes (0), m_SendQueueSize (0),
|
||||||
m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
|
m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
|
||||||
m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ())
|
m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()),
|
||||||
|
m_HandshakeInterval (0)
|
||||||
{
|
{
|
||||||
if (router)
|
if (router)
|
||||||
m_RemoteIdentity = router->GetRouterIdentity ();
|
m_RemoteIdentity = router->GetRouterIdentity ();
|
||||||
|
@ -103,7 +106,9 @@ namespace transport
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||||
size_t GetSendQueueSize () const { return m_SendQueueSize; };
|
size_t GetSendQueueSize () const { return m_SendQueueSize; };
|
||||||
bool IsOutgoing () const { return m_IsOutgoing; };
|
bool IsOutgoing () const { return m_IsOutgoing; };
|
||||||
|
bool IsSlow () const { return m_HandshakeInterval > TRANSPORT_SESSION_SLOWNESS_THRESHOLD &&
|
||||||
|
m_HandshakeInterval < TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL; };
|
||||||
|
|
||||||
int GetTerminationTimeout () const { return m_TerminationTimeout; };
|
int GetTerminationTimeout () const { return m_TerminationTimeout; };
|
||||||
void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; };
|
void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; };
|
||||||
bool IsTerminationTimeoutExpired (uint64_t ts) const
|
bool IsTerminationTimeoutExpired (uint64_t ts) const
|
||||||
|
@ -129,6 +134,7 @@ namespace transport
|
||||||
int m_TerminationTimeout;
|
int m_TerminationTimeout;
|
||||||
uint64_t m_LastActivityTimestamp;
|
uint64_t m_LastActivityTimestamp;
|
||||||
uint32_t m_CreationTime; // seconds since epoch
|
uint32_t m_CreationTime; // seconds since epoch
|
||||||
|
int64_t m_HandshakeInterval; // in milliseconds between SessionRequest->SessionCreated or SessionCreated->SessionConfirmed
|
||||||
};
|
};
|
||||||
|
|
||||||
// SOCKS5 proxy
|
// SOCKS5 proxy
|
||||||
|
|
|
@ -200,10 +200,10 @@ namespace transport
|
||||||
i2p::context.SetStatusV6 (eRouterStatusProxy);
|
i2p::context.SetStatusV6 (eRouterStatusProxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy);
|
LogPrint(eLogCritical, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy);
|
LogPrint(eLogCritical, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_NTCP2Server = new NTCP2Server ();
|
m_NTCP2Server = new NTCP2Server ();
|
||||||
|
@ -225,10 +225,10 @@ namespace transport
|
||||||
i2p::context.SetStatusV6 (eRouterStatusProxy);
|
i2p::context.SetStatusV6 (eRouterStatusProxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Transports: Can't set SSU2 proxy ", ssu2proxy);
|
LogPrint(eLogCritical, "Transports: Can't set SSU2 proxy ", ssu2proxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Transports: Invalid SSU2 proxy URL ", ssu2proxy);
|
LogPrint(eLogCritical, "Transports: Invalid SSU2 proxy URL ", ssu2proxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,9 +906,10 @@ namespace transport
|
||||||
return GetRandomPeer (
|
return GetRandomPeer (
|
||||||
[isHighBandwidth](const Peer& peer)->bool
|
[isHighBandwidth](const Peer& peer)->bool
|
||||||
{
|
{
|
||||||
// connected and not overloaded
|
// connected, not overloaded and not slow
|
||||||
return !peer.router && !peer.sessions.empty () &&
|
return !peer.router && !peer.sessions.empty () && peer.isReachable &&
|
||||||
peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE &&
|
peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE &&
|
||||||
|
!peer.sessions.front ()->IsSlow () &&
|
||||||
(!isHighBandwidth || peer.isHighBandwidth);
|
(!isHighBandwidth || peer.isHighBandwidth);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,15 +72,18 @@ namespace transport
|
||||||
uint64_t creationTime, nextRouterInfoUpdateTime;
|
uint64_t creationTime, nextRouterInfoUpdateTime;
|
||||||
std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages;
|
std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages;
|
||||||
std::vector<i2p::data::RouterInfo::SupportedTransports> priority;
|
std::vector<i2p::data::RouterInfo::SupportedTransports> priority;
|
||||||
bool isHighBandwidth;
|
bool isHighBandwidth, isReachable;
|
||||||
|
|
||||||
Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts):
|
Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts):
|
||||||
numAttempts (0), router (r), creationTime (ts),
|
numAttempts (0), router (r), creationTime (ts),
|
||||||
nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL),
|
nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL),
|
||||||
isHighBandwidth (false)
|
isHighBandwidth (false), isReachable (false)
|
||||||
{
|
{
|
||||||
if (router)
|
if (router)
|
||||||
|
{
|
||||||
isHighBandwidth = router->IsHighBandwidth ();
|
isHighBandwidth = router->IsHighBandwidth ();
|
||||||
|
isReachable = (bool)router->GetCompatibleTransports (true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Done ()
|
void Done ()
|
||||||
|
@ -93,7 +96,10 @@ namespace transport
|
||||||
{
|
{
|
||||||
router = r;
|
router = r;
|
||||||
if (router)
|
if (router)
|
||||||
|
{
|
||||||
isHighBandwidth = router->IsHighBandwidth ();
|
isHighBandwidth = router->IsHighBandwidth ();
|
||||||
|
isReachable = (bool)router->GetCompatibleTransports (true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace tunnel
|
||||||
if (msg1) msg = msg1;
|
if (msg1) msg = msg1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg);
|
outboundTunnel->SendTunnelDataMsgTo (GetNextIdentHash (), 0, msg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@ namespace tunnel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
void OutboundTunnel::SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
TunnelMessageBlock block;
|
TunnelMessageBlock block;
|
||||||
if (gwHash)
|
if (gwHash)
|
||||||
|
@ -284,10 +284,10 @@ namespace tunnel
|
||||||
block.deliveryType = eDeliveryTypeLocal;
|
block.deliveryType = eDeliveryTypeLocal;
|
||||||
block.data = msg;
|
block.data = msg;
|
||||||
|
|
||||||
SendTunnelDataMsg ({block});
|
SendTunnelDataMsgs ({block});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutboundTunnel::SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs)
|
void OutboundTunnel::SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_SendMutex);
|
std::unique_lock<std::mutex> l(m_SendMutex);
|
||||||
for (auto& it : msgs)
|
for (auto& it : msgs)
|
||||||
|
@ -306,7 +306,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroHopsOutboundTunnel::SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs)
|
void ZeroHopsOutboundTunnel::SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs)
|
||||||
{
|
{
|
||||||
for (auto& msg : msgs)
|
for (auto& msg : msgs)
|
||||||
{
|
{
|
||||||
|
@ -331,14 +331,15 @@ namespace tunnel
|
||||||
|
|
||||||
Tunnels tunnels;
|
Tunnels tunnels;
|
||||||
|
|
||||||
Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr),
|
Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_MaxNumTransitTunnels (DEFAULT_MAX_NUM_TRANSIT_TUNNELS),
|
||||||
m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal avarage
|
m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal average
|
||||||
m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0)
|
m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Tunnels::~Tunnels ()
|
Tunnels::~Tunnels ()
|
||||||
{
|
{
|
||||||
|
DeleteTunnelPool(m_ExploratoryPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TunnelBase> Tunnels::GetTunnel (uint32_t tunnelID)
|
std::shared_ptr<TunnelBase> Tunnels::GetTunnel (uint32_t tunnelID)
|
||||||
|
@ -543,7 +544,7 @@ namespace tunnel
|
||||||
ManageTunnels (ts);
|
ManageTunnels (ts);
|
||||||
lastTs = ts;
|
lastTs = ts;
|
||||||
}
|
}
|
||||||
if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 secondsts
|
if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 seconds
|
||||||
ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs)
|
ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs)
|
||||||
{
|
{
|
||||||
ManageTunnelPools (ts);
|
ManageTunnelPools (ts);
|
||||||
|
@ -697,7 +698,7 @@ namespace tunnel
|
||||||
|
|
||||||
if (m_OutboundTunnels.size () < 3)
|
if (m_OutboundTunnels.size () < 3)
|
||||||
{
|
{
|
||||||
// trying to create one more oubound tunnel
|
// trying to create one more outbound tunnel
|
||||||
auto inboundTunnel = GetNextInboundTunnel ();
|
auto inboundTunnel = GetNextInboundTunnel ();
|
||||||
auto router = i2p::transport::transports.RoutesRestricted() ?
|
auto router = i2p::transport::transports.RoutesRestricted() ?
|
||||||
i2p::transport::transports.GetRestrictedPeer() :
|
i2p::transport::transports.GetRestrictedPeer() :
|
||||||
|
@ -970,5 +971,14 @@ namespace tunnel
|
||||||
// TODO: locking
|
// TODO: locking
|
||||||
return m_OutboundTunnels.size();
|
return m_OutboundTunnels.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tunnels::SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels)
|
||||||
|
{
|
||||||
|
if (maxNumTransitTunnels > 0 && m_MaxNumTransitTunnels != maxNumTransitTunnels)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Tunnel: Max number of transit tunnels set to ", maxNumTransitTunnels);
|
||||||
|
m_MaxNumTransitTunnels = maxNumTransitTunnels;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,11 @@ namespace tunnel
|
||||||
const int MAX_NUM_RECORDS = 8;
|
const int MAX_NUM_RECORDS = 8;
|
||||||
const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds
|
const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds
|
||||||
const int MAX_TUNNEL_MSGS_BATCH_SIZE = 100; // handle messages without interrupt
|
const int MAX_TUNNEL_MSGS_BATCH_SIZE = 100; // handle messages without interrupt
|
||||||
|
const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 5000;
|
||||||
const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds
|
const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds
|
||||||
const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds
|
const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds
|
||||||
const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds
|
const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds
|
||||||
|
|
||||||
const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12
|
const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12
|
||||||
const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6
|
const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6
|
||||||
|
|
||||||
|
@ -102,8 +103,8 @@ namespace tunnel
|
||||||
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
||||||
|
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||||
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
|
||||||
|
|
||||||
/** @brief add latency sample */
|
/** @brief add latency sample */
|
||||||
void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; }
|
void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; }
|
||||||
|
@ -137,15 +138,15 @@ namespace tunnel
|
||||||
OutboundTunnel (std::shared_ptr<const TunnelConfig> config):
|
OutboundTunnel (std::shared_ptr<const TunnelConfig> config):
|
||||||
Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {};
|
Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {};
|
||||||
|
|
||||||
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
|
||||||
virtual void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
virtual void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
||||||
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
|
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
|
||||||
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
||||||
|
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||||
|
|
||||||
bool IsInbound() const { return false; }
|
bool IsInbound() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -159,12 +160,12 @@ namespace tunnel
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg);
|
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg) override;
|
||||||
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
||||||
bool IsInbound() const { return true; }
|
bool IsInbound() const override { return true; }
|
||||||
|
|
||||||
// override TunnelBase
|
// override TunnelBase
|
||||||
void Cleanup () { m_Endpoint.Cleanup (); };
|
void Cleanup () override { m_Endpoint.Cleanup (); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -176,8 +177,8 @@ namespace tunnel
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ZeroHopsInboundTunnel ();
|
ZeroHopsInboundTunnel ();
|
||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const override { return m_NumReceivedBytes; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -189,8 +190,8 @@ namespace tunnel
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ZeroHopsOutboundTunnel ();
|
ZeroHopsOutboundTunnel ();
|
||||||
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs);
|
void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs) override;
|
||||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
size_t GetNumSentBytes () const override { return m_NumSentBytes; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -229,6 +230,10 @@ namespace tunnel
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
||||||
|
|
||||||
|
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels);
|
||||||
|
uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
|
||||||
|
bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<class TTunnel>
|
template<class TTunnel>
|
||||||
|
@ -287,6 +292,7 @@ namespace tunnel
|
||||||
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
|
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
|
||||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
|
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
|
||||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
|
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
|
||||||
|
uint16_t m_MaxNumTransitTunnels;
|
||||||
// count of tunnels for total TCSR algorithm
|
// count of tunnels for total TCSR algorithm
|
||||||
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
|
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
|
||||||
double m_TunnelCreationSuccessRate;
|
double m_TunnelCreationSuccessRate;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -208,7 +208,7 @@ namespace tunnel
|
||||||
if (msg.data->len + size > msg.data->maxLen)
|
if (msg.data->len + size > msg.data->maxLen)
|
||||||
{
|
{
|
||||||
// LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough");
|
// LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough");
|
||||||
auto newMsg = NewI2NPMessage ();
|
auto newMsg = NewI2NPMessage (msg.data->len + size);
|
||||||
*newMsg = *(msg.data);
|
*newMsg = *(msg.data);
|
||||||
msg.data = newMsg;
|
msg.data = newMsg;
|
||||||
}
|
}
|
||||||
|
@ -297,11 +297,11 @@ namespace tunnel
|
||||||
if (msg.data->len + size > msg.data->maxLen)
|
if (msg.data->len + size > msg.data->maxLen)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
|
LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
|
||||||
auto newMsg = NewI2NPMessage ();
|
auto newMsg = NewI2NPMessage (msg.data->len + size);
|
||||||
*newMsg = *(msg.data);
|
*newMsg = *(msg.data);
|
||||||
msg.data = newMsg;
|
msg.data = newMsg;
|
||||||
}
|
}
|
||||||
if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment
|
if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment
|
||||||
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
||||||
if (it->second->isLastFragment)
|
if (it->second->isLastFragment)
|
||||||
// message complete
|
// message complete
|
||||||
|
|
|
@ -383,7 +383,7 @@ namespace tunnel
|
||||||
std::unique_lock<std::mutex> l(m_TestsMutex);
|
std::unique_lock<std::mutex> l(m_TestsMutex);
|
||||||
m_Tests[msgID] = std::make_pair (*it1, *it2);
|
m_Tests[msgID] = std::make_pair (*it1, *it2);
|
||||||
}
|
}
|
||||||
(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
|
(*it1)->SendTunnelDataMsgTo ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
|
||||||
CreateDeliveryStatusMsg (msgID));
|
CreateDeliveryStatusMsg (msgID));
|
||||||
++it1; ++it2;
|
++it1; ++it2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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,11 +67,15 @@ namespace api
|
||||||
i2p::transport::transports.Start();
|
i2p::transport::transports.Start();
|
||||||
LogPrint(eLogInfo, "API: Starting Tunnels");
|
LogPrint(eLogInfo, "API: Starting Tunnels");
|
||||||
i2p::tunnel::tunnels.Start();
|
i2p::tunnel::tunnels.Start();
|
||||||
|
LogPrint(eLogInfo, "API: Starting Router context");
|
||||||
|
i2p::context.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopI2P ()
|
void StopI2P ()
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "API: Shutting down");
|
LogPrint(eLogInfo, "API: Shutting down");
|
||||||
|
LogPrint(eLogInfo, "API: Stopping Router context");
|
||||||
|
i2p::context.Stop();
|
||||||
LogPrint(eLogInfo, "API: Stopping Tunnels");
|
LogPrint(eLogInfo, "API: Stopping Tunnels");
|
||||||
i2p::tunnel::tunnels.Stop();
|
i2p::tunnel::tunnels.Stop();
|
||||||
LogPrint(eLogInfo, "API: Stopping Transports");
|
LogPrint(eLogInfo, "API: Stopping Transports");
|
||||||
|
|
102
libi2pd/util.cpp
102
libi2pd/util.cpp
|
@ -15,7 +15,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
|
|
||||||
#if not defined (__FreeBSD__)
|
#if !defined (__FreeBSD__) && !defined(_MSC_VER)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -37,6 +37,19 @@
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
const DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||||
|
#pragma pack(push,8)
|
||||||
|
typedef struct tagTHREADNAME_INFO
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
LPCSTR szName;
|
||||||
|
DWORD dwThreadID;
|
||||||
|
DWORD dwFlags;
|
||||||
|
} THREADNAME_INFO;
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
||||||
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
||||||
|
|
||||||
|
@ -75,7 +88,8 @@ const char *inet_ntop_xp(int af, const void *src, char *dst, socklen_t size)
|
||||||
ZeroMemory(&ss, sizeof(ss));
|
ZeroMemory(&ss, sizeof(ss));
|
||||||
ss.ss_family = af;
|
ss.ss_family = af;
|
||||||
|
|
||||||
switch(af) {
|
switch (af)
|
||||||
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
|
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
|
||||||
break;
|
break;
|
||||||
|
@ -161,7 +175,23 @@ namespace util
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
pthread_setname_np(pthread_self(), "%s", (void *)name);
|
pthread_setname_np(pthread_self(), "%s", (void *)name);
|
||||||
#elif !defined(__gnu_hurd__)
|
#elif !defined(__gnu_hurd__)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
THREADNAME_INFO info;
|
||||||
|
info.dwType = 0x1000;
|
||||||
|
info.szName = name;
|
||||||
|
info.dwThreadID = -1;
|
||||||
|
info.dwFlags = 0;
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 6320 6322)
|
||||||
|
__try {
|
||||||
|
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||||
|
}
|
||||||
|
#pragma warning(pop)
|
||||||
|
#else
|
||||||
pthread_setname_np(pthread_self(), name);
|
pthread_setname_np(pthread_self(), name);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +209,7 @@ namespace net
|
||||||
PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr;
|
PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
|
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
|
||||||
|
|
||||||
if(GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
|
if (GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
|
||||||
== ERROR_BUFFER_OVERFLOW)
|
== ERROR_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
FREE(pAddresses);
|
FREE(pAddresses);
|
||||||
|
@ -190,7 +220,7 @@ namespace net
|
||||||
AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen
|
AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen
|
||||||
);
|
);
|
||||||
|
|
||||||
if(dwRetVal != NO_ERROR)
|
if (dwRetVal != NO_ERROR)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NetIface: GetMTU: Enclosed GetAdaptersAddresses() call has failed");
|
LogPrint(eLogError, "NetIface: GetMTU: Enclosed GetAdaptersAddresses() call has failed");
|
||||||
FREE(pAddresses);
|
FREE(pAddresses);
|
||||||
|
@ -198,19 +228,17 @@ namespace net
|
||||||
}
|
}
|
||||||
|
|
||||||
pCurrAddresses = pAddresses;
|
pCurrAddresses = pAddresses;
|
||||||
while(pCurrAddresses)
|
while (pCurrAddresses)
|
||||||
{
|
{
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
|
|
||||||
|
|
||||||
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
||||||
if(pUnicast == nullptr)
|
if (pUnicast == nullptr)
|
||||||
LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv4 address, this is not supported");
|
LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv4 address, this is not supported");
|
||||||
|
|
||||||
for(int i = 0; pUnicast != nullptr; ++i)
|
while (pUnicast != nullptr)
|
||||||
{
|
{
|
||||||
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
||||||
sockaddr_in* localInterfaceAddress = (sockaddr_in*) lpAddr;
|
sockaddr_in* localInterfaceAddress = (sockaddr_in*) lpAddr;
|
||||||
if(localInterfaceAddress->sin_addr.S_un.S_addr == inputAddress.sin_addr.S_un.S_addr)
|
if (localInterfaceAddress->sin_addr.S_un.S_addr == inputAddress.sin_addr.S_un.S_addr)
|
||||||
{
|
{
|
||||||
char addr[INET_ADDRSTRLEN];
|
char addr[INET_ADDRSTRLEN];
|
||||||
inetntop(AF_INET, &(((struct sockaddr_in *)localInterfaceAddress)->sin_addr), addr, INET_ADDRSTRLEN);
|
inetntop(AF_INET, &(((struct sockaddr_in *)localInterfaceAddress)->sin_addr), addr, INET_ADDRSTRLEN);
|
||||||
|
@ -264,12 +292,11 @@ namespace net
|
||||||
pCurrAddresses = pAddresses;
|
pCurrAddresses = pAddresses;
|
||||||
while (pCurrAddresses)
|
while (pCurrAddresses)
|
||||||
{
|
{
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
|
|
||||||
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
||||||
if (pUnicast == nullptr)
|
if (pUnicast == nullptr)
|
||||||
LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv6 address, this is not supported");
|
LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv6 address, this is not supported");
|
||||||
|
|
||||||
for (int i = 0; pUnicast != nullptr; ++i)
|
while (pUnicast != nullptr)
|
||||||
{
|
{
|
||||||
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
||||||
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
|
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
|
||||||
|
@ -317,13 +344,13 @@ namespace net
|
||||||
IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
|
IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
|
||||||
if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found
|
if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found
|
||||||
|
|
||||||
if(localAddress.is_v4())
|
if (localAddress.is_v4())
|
||||||
{
|
{
|
||||||
sockaddr_in inputAddress;
|
sockaddr_in inputAddress;
|
||||||
inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr));
|
inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr));
|
||||||
return GetMTUWindowsIpv4(inputAddress, fallback);
|
return GetMTUWindowsIpv4(inputAddress, fallback);
|
||||||
}
|
}
|
||||||
else if(localAddress.is_v6())
|
else if (localAddress.is_v6())
|
||||||
{
|
{
|
||||||
sockaddr_in6 inputAddress;
|
sockaddr_in6 inputAddress;
|
||||||
inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr));
|
inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr));
|
||||||
|
@ -339,7 +366,7 @@ namespace net
|
||||||
int GetMTUUnix (const boost::asio::ip::address& localAddress, int fallback)
|
int GetMTUUnix (const boost::asio::ip::address& localAddress, int fallback)
|
||||||
{
|
{
|
||||||
ifaddrs* ifaddr, *ifa = nullptr;
|
ifaddrs* ifaddr, *ifa = nullptr;
|
||||||
if(getifaddrs(&ifaddr) == -1)
|
if (getifaddrs(&ifaddr) == -1)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno));
|
LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno));
|
||||||
return fallback;
|
return fallback;
|
||||||
|
@ -347,34 +374,34 @@ namespace net
|
||||||
|
|
||||||
int family = 0;
|
int family = 0;
|
||||||
// look for interface matching local address
|
// look for interface matching local address
|
||||||
for(ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
|
for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
|
||||||
{
|
{
|
||||||
if(!ifa->ifa_addr)
|
if (!ifa->ifa_addr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
family = ifa->ifa_addr->sa_family;
|
family = ifa->ifa_addr->sa_family;
|
||||||
if(family == AF_INET && localAddress.is_v4())
|
if (family == AF_INET && localAddress.is_v4())
|
||||||
{
|
{
|
||||||
sockaddr_in* sa = (sockaddr_in*) ifa->ifa_addr;
|
sockaddr_in* sa = (sockaddr_in*) ifa->ifa_addr;
|
||||||
if(!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4))
|
if (!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4))
|
||||||
break; // address matches
|
break; // address matches
|
||||||
}
|
}
|
||||||
else if(family == AF_INET6 && localAddress.is_v6())
|
else if (family == AF_INET6 && localAddress.is_v6())
|
||||||
{
|
{
|
||||||
sockaddr_in6* sa = (sockaddr_in6*) ifa->ifa_addr;
|
sockaddr_in6* sa = (sockaddr_in6*) ifa->ifa_addr;
|
||||||
if(!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16))
|
if (!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16))
|
||||||
break; // address matches
|
break; // address matches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int mtu = fallback;
|
int mtu = fallback;
|
||||||
if(ifa && family)
|
if (ifa && family)
|
||||||
{ // interface found?
|
{ // interface found?
|
||||||
int fd = socket(family, SOCK_DGRAM, 0);
|
int fd = socket(family, SOCK_DGRAM, 0);
|
||||||
if(fd > 0)
|
if (fd > 0)
|
||||||
{
|
{
|
||||||
ifreq ifr;
|
ifreq ifr;
|
||||||
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ-1); // set interface for query
|
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ-1); // set interface for query
|
||||||
if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0)
|
if (ioctl(fd, SIOCGIFMTU, &ifr) >= 0)
|
||||||
mtu = ifr.ifr_mtu; // MTU
|
mtu = ifr.ifr_mtu; // MTU
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "NetIface: Failed to run ioctl: ", strerror(errno));
|
LogPrint (eLogError, "NetIface: Failed to run ioctl: ", strerror(errno));
|
||||||
|
@ -407,7 +434,7 @@ namespace net
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LogPrint(eLogError, "NetIface: Cannot get address by interface name, not implemented on WIN32");
|
LogPrint(eLogError, "NetIface: Cannot get address by interface name, not implemented on WIN32");
|
||||||
if(ipv6)
|
if (ipv6)
|
||||||
return boost::asio::ip::address::from_string("::1");
|
return boost::asio::ip::address::from_string("::1");
|
||||||
else
|
else
|
||||||
return boost::asio::ip::address::from_string("127.0.0.1");
|
return boost::asio::ip::address::from_string("127.0.0.1");
|
||||||
|
@ -426,7 +453,7 @@ namespace net
|
||||||
// match
|
// match
|
||||||
char addr[INET6_ADDRSTRLEN];
|
char addr[INET6_ADDRSTRLEN];
|
||||||
memset (addr, 0, INET6_ADDRSTRLEN);
|
memset (addr, 0, INET6_ADDRSTRLEN);
|
||||||
if(af == AF_INET)
|
if (af == AF_INET)
|
||||||
inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN);
|
inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN);
|
||||||
else
|
else
|
||||||
inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN);
|
inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN);
|
||||||
|
@ -442,9 +469,9 @@ namespace net
|
||||||
LogPrint(eLogError, "NetIface: Exception while searching address using ifaddr: ", ex.what());
|
LogPrint(eLogError, "NetIface: Exception while searching address using ifaddr: ", ex.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addrs) freeifaddrs(addrs);
|
if (addrs) freeifaddrs(addrs);
|
||||||
std::string fallback;
|
std::string fallback;
|
||||||
if(ipv6)
|
if (ipv6)
|
||||||
{
|
{
|
||||||
fallback = "::1";
|
fallback = "::1";
|
||||||
LogPrint(eLogWarning, "NetIface: Cannot find IPv6 address for interface ", ifname);
|
LogPrint(eLogWarning, "NetIface: Cannot find IPv6 address for interface ", ifname);
|
||||||
|
@ -512,7 +539,7 @@ namespace net
|
||||||
PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr;
|
PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
|
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
|
||||||
|
|
||||||
if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
|
if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
|
||||||
== ERROR_BUFFER_OVERFLOW)
|
== ERROR_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
FREE(pAddresses);
|
FREE(pAddresses);
|
||||||
|
@ -523,7 +550,7 @@ namespace net
|
||||||
AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen
|
AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen
|
||||||
);
|
);
|
||||||
|
|
||||||
if(dwRetVal != NO_ERROR)
|
if (dwRetVal != NO_ERROR)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NetIface: GetYggdrasilAddress(): enclosed GetAdaptersAddresses() call has failed");
|
LogPrint(eLogError, "NetIface: GetYggdrasilAddress(): enclosed GetAdaptersAddresses() call has failed");
|
||||||
FREE(pAddresses);
|
FREE(pAddresses);
|
||||||
|
@ -531,12 +558,11 @@ namespace net
|
||||||
}
|
}
|
||||||
|
|
||||||
pCurrAddresses = pAddresses;
|
pCurrAddresses = pAddresses;
|
||||||
while(pCurrAddresses)
|
while (pCurrAddresses)
|
||||||
{
|
{
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
|
|
||||||
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
pUnicast = pCurrAddresses->FirstUnicastAddress;
|
||||||
|
|
||||||
for(int i = 0; pUnicast != nullptr; ++i)
|
while (pUnicast != nullptr)
|
||||||
{
|
{
|
||||||
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
|
||||||
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
|
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
|
||||||
|
@ -580,7 +606,7 @@ namespace net
|
||||||
LogPrint(eLogError, "NetIface: Exception while searching Yggdrasill address using ifaddr: ", ex.what());
|
LogPrint(eLogError, "NetIface: Exception while searching Yggdrasill address using ifaddr: ", ex.what());
|
||||||
}
|
}
|
||||||
LogPrint(eLogWarning, "NetIface: Interface with Yggdrasil network address not found");
|
LogPrint(eLogWarning, "NetIface: Interface with Yggdrasil network address not found");
|
||||||
if(addrs) freeifaddrs(addrs);
|
if (addrs) freeifaddrs(addrs);
|
||||||
return boost::asio::ip::address_v6 ();
|
return boost::asio::ip::address_v6 ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -600,7 +626,7 @@ namespace net
|
||||||
{
|
{
|
||||||
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||||
if (host.is_unspecified ()) return false;
|
if (host.is_unspecified ()) return false;
|
||||||
if(host.is_v4())
|
if (host.is_v4())
|
||||||
{
|
{
|
||||||
static const std::vector< std::pair<uint32_t, uint32_t> > reservedIPv4Ranges {
|
static const std::vector< std::pair<uint32_t, uint32_t> > reservedIPv4Ranges {
|
||||||
address_pair_v4("0.0.0.0", "0.255.255.255"),
|
address_pair_v4("0.0.0.0", "0.255.255.255"),
|
||||||
|
@ -620,12 +646,12 @@ namespace net
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t ipv4_address = host.to_v4 ().to_ulong ();
|
uint32_t ipv4_address = host.to_v4 ().to_ulong ();
|
||||||
for(const auto& it : reservedIPv4Ranges) {
|
for (const auto& it : reservedIPv4Ranges) {
|
||||||
if (ipv4_address >= it.first && ipv4_address <= it.second)
|
if (ipv4_address >= it.first && ipv4_address <= it.second)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(host.is_v6())
|
if (host.is_v6())
|
||||||
{
|
{
|
||||||
static const std::vector< std::pair<boost::asio::ip::address_v6::bytes_type, boost::asio::ip::address_v6::bytes_type> > reservedIPv6Ranges {
|
static const std::vector< std::pair<boost::asio::ip::address_v6::bytes_type, boost::asio::ip::address_v6::bytes_type> > reservedIPv6Ranges {
|
||||||
address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"),
|
address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"),
|
||||||
|
@ -637,7 +663,7 @@ namespace net
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes ();
|
boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes ();
|
||||||
for(const auto& it : reservedIPv6Ranges) {
|
for (const auto& it : reservedIPv6Ranges) {
|
||||||
if (ipv6_address >= it.first && ipv6_address <= it.second)
|
if (ipv6_address >= it.first && ipv6_address <= it.second)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,18 @@
|
||||||
|
|
||||||
#define CODENAME "Purple"
|
#define CODENAME "Purple"
|
||||||
|
|
||||||
|
#define XSTRINGIZE(x) STRINGIZE(x)
|
||||||
#define STRINGIZE(x) #x
|
#define STRINGIZE(x) #x
|
||||||
|
|
||||||
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
||||||
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
||||||
|
|
||||||
#define I2PD_VERSION_MAJOR 2
|
#define I2PD_VERSION_MAJOR 2
|
||||||
#define I2PD_VERSION_MINOR 46
|
#define I2PD_VERSION_MINOR 47
|
||||||
#define I2PD_VERSION_MICRO 1
|
#define I2PD_VERSION_MICRO 0
|
||||||
#define I2PD_VERSION_PATCH 0
|
#define I2PD_VERSION_PATCH 0
|
||||||
#ifdef GITVER
|
#ifdef GITVER
|
||||||
#define I2PD_VERSION GITVER
|
#define I2PD_VERSION XSTRINGIZE(GITVER)
|
||||||
#else
|
#else
|
||||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +33,7 @@
|
||||||
|
|
||||||
#define I2P_VERSION_MAJOR 0
|
#define I2P_VERSION_MAJOR 0
|
||||||
#define I2P_VERSION_MINOR 9
|
#define I2P_VERSION_MINOR 9
|
||||||
#define I2P_VERSION_MICRO 57
|
#define I2P_VERSION_MICRO 58
|
||||||
#define I2P_VERSION_PATCH 0
|
#define I2P_VERSION_PATCH 0
|
||||||
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
|
|
|
@ -661,7 +661,7 @@ namespace client
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Addressbook: Can't start subscriptions: missing shared local destination");
|
LogPrint (eLogCritical, "Addressbook: Can't start subscriptions: missing shared local destination");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBook::StopSubscriptions ()
|
void AddressBook::StopSubscriptions ()
|
||||||
|
|
|
@ -63,18 +63,19 @@ namespace client
|
||||||
if (sam)
|
if (sam)
|
||||||
{
|
{
|
||||||
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
||||||
uint16_t samPort; i2p::config::GetOption("sam.port", samPort);
|
uint16_t samPortTCP; i2p::config::GetOption("sam.port", samPortTCP);
|
||||||
|
uint16_t samPortUDP; i2p::config::GetOption("sam.portudp", samPortUDP);
|
||||||
bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread);
|
bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread);
|
||||||
LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":", samPort);
|
LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP, "]");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_SamBridge = new SAMBridge (samAddr, samPort, singleThread);
|
m_SamBridge = new SAMBridge (samAddr, samPortTCP, samPortUDP, singleThread);
|
||||||
m_SamBridge->Start ();
|
m_SamBridge->Start ();
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what());
|
LogPrint(eLogCritical, "Clients: Exception in SAM bridge: ", e.what());
|
||||||
ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ());
|
ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP,"]: ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what());
|
LogPrint(eLogCritical, "Clients: Exception in BOB bridge: ", e.what());
|
||||||
ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ());
|
ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what());
|
LogPrint(eLogCritical, "Clients: Exception in I2CP: ", e.what());
|
||||||
ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ());
|
ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +279,7 @@ namespace client
|
||||||
s.read ((char *)buf, len);
|
s.read ((char *)buf, len);
|
||||||
if(!keys.FromBuffer (buf, len))
|
if(!keys.FromBuffer (buf, len))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Clients: Failed to load keyfile ", filename);
|
LogPrint (eLogCritical, "Clients: Failed to load keyfile ", filename);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -287,7 +288,7 @@ namespace client
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Clients: Can't open file ", fullPath, " Creating new one with signature type ", sigType, " crypto type ", cryptoType);
|
LogPrint (eLogCritical, "Clients: Can't open file ", fullPath, " Creating new one with signature type ", sigType, " crypto type ", cryptoType);
|
||||||
keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType, true);
|
keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType, true);
|
||||||
std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out);
|
std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out);
|
||||||
size_t len = keys.GetFullLen ();
|
size_t len = keys.GetFullLen ();
|
||||||
|
@ -850,7 +851,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());
|
LogPrint (eLogCritical, "Clients: Can't read tunnel ", name, " params: ", ex.what ());
|
||||||
ThrowFatal ("Unable to start tunnel ", name, ": ", ex.what ());
|
ThrowFatal ("Unable to start tunnel ", name, ": ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -882,7 +883,7 @@ namespace client
|
||||||
if (localDestination) localDestination->Acquire ();
|
if (localDestination) localDestination->Acquire ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Clients: Failed to load HTTP Proxy key");
|
LogPrint(eLogCritical, "Clients: Failed to load HTTP Proxy key");
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -891,7 +892,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what());
|
LogPrint(eLogCritical, "Clients: Exception in HTTP Proxy: ", e.what());
|
||||||
ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ());
|
ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -929,7 +930,7 @@ namespace client
|
||||||
if (localDestination) localDestination->Acquire ();
|
if (localDestination) localDestination->Acquire ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "Clients: Failed to load SOCKS Proxy key");
|
LogPrint(eLogCritical, "Clients: Failed to load SOCKS Proxy key");
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -939,7 +940,7 @@ namespace client
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what());
|
LogPrint(eLogCritical, "Clients: Exception in SOCKS Proxy: ", e.what());
|
||||||
ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ());
|
ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace proxy {
|
||||||
i2p::http::URL m_ProxyURL;
|
i2p::http::URL m_ProxyURL;
|
||||||
i2p::http::URL m_RequestURL;
|
i2p::http::URL m_RequestURL;
|
||||||
uint8_t m_socks_buf[255+8]; // for socks request/response
|
uint8_t m_socks_buf[255+8]; // for socks request/response
|
||||||
ssize_t m_req_len;
|
int m_req_len;
|
||||||
i2p::http::URL m_ClientRequestURL;
|
i2p::http::URL m_ClientRequestURL;
|
||||||
i2p::http::HTTPReq m_ClientRequest;
|
i2p::http::HTTPReq m_ClientRequest;
|
||||||
i2p::http::HTTPRes m_ClientResponse;
|
i2p::http::HTTPRes m_ClientResponse;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -230,7 +230,7 @@ namespace client
|
||||||
remoteLease->tunnelGateway, remoteLease->tunnelID,
|
remoteLease->tunnelGateway, remoteLease->tunnelID,
|
||||||
garlic
|
garlic
|
||||||
});
|
});
|
||||||
outboundTunnel->SendTunnelDataMsg (msgs);
|
outboundTunnel->SendTunnelDataMsgs (msgs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, 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
|
||||||
*
|
*
|
||||||
|
@ -691,7 +691,10 @@ namespace client
|
||||||
int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip):
|
int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip):
|
||||||
I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false)
|
I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false)
|
||||||
{
|
{
|
||||||
m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip);
|
if (!inport) inport = port;
|
||||||
|
m_PortDestination = localDestination->GetStreamingDestination (inport);
|
||||||
|
if (!m_PortDestination)
|
||||||
|
m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PServerTunnel::Start ()
|
void I2PServerTunnel::Start ()
|
||||||
|
|
|
@ -1244,10 +1244,10 @@ namespace client
|
||||||
// TODO: implement datagrams
|
// TODO: implement datagrams
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread):
|
SAMBridge::SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread):
|
||||||
RunnableService ("SAM"), m_IsSingleThread (singleThread),
|
RunnableService ("SAM"), m_IsSingleThread (singleThread),
|
||||||
m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
|
m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), portTCP)),
|
||||||
m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint),
|
m_DatagramEndpoint (boost::asio::ip::address::from_string(address), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint),
|
||||||
m_SignatureTypes
|
m_SignatureTypes
|
||||||
{
|
{
|
||||||
{"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1},
|
{"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1},
|
||||||
|
|
|
@ -233,7 +233,7 @@ namespace client
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SAMBridge (const std::string& address, int port, bool singleThread);
|
SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread);
|
||||||
~SAMBridge ();
|
~SAMBridge ();
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
|
|
Loading…
Add table
Reference in a new issue