[-]
[+]
|
Changed |
_service:tar_git:i2pd.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,12 +1,13 @@
<services>
<service name="tar_git">
<param name="url">https://github.com/nephros/i2pd</param>
- <param name="branch"></param>
- <param name="revision">2.45.1+git2</param>
+ <param name="branch">next</param>
<!--
<param name="branch">master</param>
<param name="revision">HEAD</param>
<param name="revision">2.44.0+git1</param>
+ <param name="revision">2.45.1+git2</param>
+ <param name="revision">2.45.1+git2</param>
-->
<param name="token"/>
<param name="debian">N</param>
|
[-]
[+]
|
Deleted |
_service:tar_git:i2pd-2.45.1+git2.tar.gz/upstream/debian/conffiles
^
|
@@ -1,2 +0,0 @@
-/etc/i2pd/i2pd.conf
-/etc/i2pd/tunnels.conf
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.editorconfig
^
|
@@ -30,3 +30,7 @@
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
+
+[*.yml]
+indent_style = space
+indent_size = 2
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build-deb.yml
^
|
@@ -6,27 +6,34 @@
build:
name: ${{ matrix.dist }}
runs-on: ubuntu-latest
+
strategy:
+ fail-fast: false
matrix:
dist: ['buster', 'bullseye', 'bookworm']
+
steps:
- - uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
with:
fetch-depth: 0
- - name: change debian changelog
- run: |
- sudo apt-get update
- 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
+
+ - name: Build package
+ uses: jtdor/build-deb-action@v1
with:
docker-image: debian:${{ matrix.dist }}-slim
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:
name: i2pd_${{ matrix.dist }}
path: debian/artifacts/i2pd_*.deb
- - uses: actions/upload-artifact@v3
+
+ - name: Upload debugging symbols
+ uses: actions/upload-artifact@v3
with:
name: i2pd-dbgsym_${{ matrix.dist }}
path: debian/artifacts/i2pd-dbgsym_*.deb
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build-freebsd.yml
^
|
@@ -6,8 +6,11 @@
build:
runs-on: macos-12
name: with UPnP
+
steps:
- - uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
+
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0.3.0
@@ -21,8 +24,9 @@
cd build
cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release .
gmake -j2
+
- name: Upload artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: i2pd-freebsd
- path: build/i2pd
\ No newline at end of file
+ path: build/i2pd
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build-osx.yml
^
|
@@ -6,16 +6,21 @@
build:
name: With USE_UPNP=${{ matrix.with_upnp }}
runs-on: macOS-latest
+
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
+
steps:
- - uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
+
- name: install packages
run: |
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
brew update
brew install boost miniupnpc openssl@1.1
+
- name: build application
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build-windows-msvc.yml
^
|
@@ -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.*
+
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build-windows.yml
^
|
@@ -8,44 +8,106 @@
jobs:
build:
- name: Building using ${{ matrix.arch }} toolchain
+ name: ${{ matrix.arch }}
runs-on: windows-latest
+
strategy:
- fail-fast: true
+ fail-fast: false
matrix:
include: [
- { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt },
- { msystem: MINGW64, arch: x86_64, arch_short: x64 },
- { msystem: MINGW32, arch: i686, arch_short: x86 }
+ { 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:
- - 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 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
+
+ - name: Install additional clang packages
+ if: ${{ matrix.msystem == 'CLANG64' }}
+ run: pacman --noconfirm -S mingw-w64-${{ matrix.arch }}-gcc-compat
+
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3
+
- name: Upload artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: i2pd-${{ matrix.arch_short }}.exe
path: i2pd.exe
+
+ build-cmake:
+ name: CMake ${{ matrix.arch }}
+ runs-on: windows-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include: [
+ { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc },
+ { msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang },
+ { msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc },
+ { msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc }
+ ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@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: Building for Windows XP
+ name: XP
runs-on: windows-latest
+
+ strategy:
+ fail-fast: false
+
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: MINGW32
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc
update: true
+
- name: Build WinXP-capable CRT packages
run: |
git clone https://github.com/msys2/MINGW-packages
@@ -64,12 +126,14 @@
pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst
popd
popd
+
- name: Build application
run: |
mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon
make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3
+
- name: Upload artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: i2pd-xp.exe
path: i2pd.exe
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/build.yml
^
|
@@ -5,34 +5,43 @@
jobs:
build-make:
name: Make with USE_UPNP=${{ matrix.with_upnp }}
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-latest
+
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
+
steps:
- - uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
+
- name: install packages
run: |
- sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
- sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
+ sudo apt-get install build-essential libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev
+
- name: build application
run: make USE_UPNP=${{ matrix.with_upnp }} -j3
+
build-cmake:
name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }}
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-latest
+
strategy:
fail-fast: true
matrix:
with_upnp: ['ON', 'OFF']
+
steps:
- - uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
+
- name: install packages
run: |
- sudo add-apt-repository ppa:mhier/libboost-latest
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
run: |
cd build
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/.github/workflows/docker.yml
^
|
@@ -10,6 +10,7 @@
jobs:
build:
+ name: Building container for ${{ matrix.platform }}
runs-on: ubuntu-latest
permissions:
packages: write
@@ -25,41 +26,44 @@
]
steps:
- - name: Checkout
- uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
- - name: Login to DockerHub
- uses: docker/login-action@v2
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Login to GitHub Container registry
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build container for ${{ matrix.archname }}
- uses: docker/build-push-action@v3
- with:
- context: ./contrib/docker
- file: ./contrib/docker/Dockerfile
- platforms: ${{ matrix.platform }}
- push: true
- tags: |
- purplei2p/i2pd:latest-${{ matrix.archname }}
- ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
+ - name: Login to DockerHub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Login to GitHub Container registry
+ uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build container for ${{ matrix.archname }}
+ uses: docker/build-push-action@v3
+ with:
+ context: ./contrib/docker
+ file: ./contrib/docker/Dockerfile
+ platforms: ${{ matrix.platform }}
+ push: true
+ tags: |
+ purplei2p/i2pd:latest-${{ matrix.archname }}
+ ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }}
+ provenance: false
push:
+ name: Pushing merged manifest
runs-on: ubuntu-latest
+
permissions:
packages: write
contents: read
@@ -67,74 +71,60 @@
needs: build
steps:
- - name: Checkout
- uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v3
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
- - name: Login to DockerHub
- uses: docker/login-action@v2
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Login to GitHub Container registry
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Create and push latest manifest image to Docker Hub
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: purplei2p/i2pd:latest
- extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
- push: true
-
- - name: Create and push latest manifest image to GHCR
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: ghcr.io/purplei2p/i2pd:latest
- extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
- push: true
-
- - name: Store release version to env
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
-
- - name: Create and push release manifest image to Docker Hub
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: purplei2p/i2pd:latest-release
- extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
- push: true
-
- - name: Create and push release manifest image to GHCR
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: ghcr.io/purplei2p/i2pd:latest-release
- extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
- push: true
-
- - name: Create and push versioned manifest image to Docker Hub
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
- extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
- push: true
-
- - name: Create and push versioned manifest image to GHCR
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- uses: Noelware/docker-manifest-action@master
- with:
- base-image: ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
- extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7
- push: true
+ - name: Login to DockerHub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Login to GitHub Container registry
+ uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Create and push latest manifest image to Docker Hub
+ if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+ uses: Noelware/docker-manifest-action@master
+ with:
+ inputs: purplei2p/i2pd:latest
+ images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7
+ push: true
+
+ - name: Create and push latest manifest image to GHCR
+ if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+ uses: Noelware/docker-manifest-action@master
+ with:
+ inputs: ghcr.io/purplei2p/i2pd:latest
+ 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
+
+ - name: Store release version to env
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
+ run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
+
+ - name: Create and push release manifest to Docker Hub
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
+ uses: Noelware/docker-manifest-action@master
+ with:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/ChangeLog
^
|
@@ -1,6 +1,88 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
+## [2.48.0] - 2023-06-12
+### Added
+- Allow user/password authentication method for SOCK5 proxy
+- Publish reject all congestion cap 'G' if transit is not accepted
+- 'critical' log level
+- Print b32 on webconsole destination page
+- Webconsole button to drop a remote LeaseSet
+- limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup
+- Recognize real routers if successfully connected or responded to tunnel build request
+### Changed
+- Bypass slow transport sessions for first hop selection
+- Limit AESNI inline asm to x86/x64
+- Create smaller I2NP packets if possible
+- Make router unreachable if AEAD tag verification fails in SessionCreated
+- Don't include a router to floodfills list until it's confirmed as real
+- Drop LeaseSet store request if not floodfill
+- Bypass medium congestion('D') routers for client tunnels
+- Publish encrypted RouterInfo through tunnels
+- Check if s is valid x25519 public key
+- Check if socket is open before sending data in SSU2
+### Fixed
+- Webconsole empty page if destination is not found
+- i2p.streaming.answerPings param
+- Reload tunnels
+- Address caps for unspecified ipv6 address
+- Incomplete HTTP headers in I2P tunnels
+- SSU2 socket network exceptions on Windows
+- Use of 'server' type tunnel port as inport (#1936)
+
+## [2.47.0] - 2023-03-11
+### Added
+- Congestion caps
+- SAM UDP port parameter
+- Support domain addresses for yggdrasil reseeds
+### Changed
+- DHT for floodfills instead plain list
+- Process router's messages in separate thread
+- Don't publish non-reachable router
+- Send and check target destination in first streaming SYN packet
+- Reseeds list
+### Fixed
+- Memory leak in windows network state detection
+- Reseed attempts from invalid address
+
+## [2.46.1] - 2023-02-20
+### Fixed
+- Race condition while getting router's peer profile
+- Creation of new router.info
+- Displaying LeaseSets in the webconsole
+- Crash when processing ACK request
+
+## [2.46.0] - 2023-02-15
+### Added
+- Limit number of acked SSU2 packets to 511
+- Localization to Swedish, Portuguese, Turkish, Polish
+- Periodically send Datetime block in NTCP2 and SSU2
+- Don't select random port from reserved
+- In memory table for peer profiles
+- Store if router was unreachable in it's peer profile
+- Show IPv6 addresses in square brackets in webconsole
+- Check referer when processing Addresshelper
+### Changed
+- Algorithm for tunnel creation success rate calculation
+- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint
+- Exclude actually unreachable router from netdb for 2 hours
+- Select first hop from high bandwidth peers for client tunnels
+- Drop too long or too short LeaseSet
+- Delete router from netdb if became invalid after update
+- Terminate existing session if clock skew detected
+- Close previous UDP socket if open before reopening
+- Minimal version for floodfill is 0.9.51
+- Sort transports by endpoints in webconsole
+### Fixed
+- Deadlock during processing I2NP block with Garlic in ECIES encrypted message to router
+- Race condition with encrypted LeaseSets
+- HTTP query detection
+- Connection attempts to IPs from invalid ranges
+- Publish "0.0.0.0" in RouterInfo
+- Crash upon receiving PeerTest 7
+- Tunnels for closed SAM session socket
+- Missing NTCP2 address in RouterInfo if enabled back
+
## [2.45.1] - 2023-01-11
### Added
- Full Cone NAT status error
@@ -9,7 +91,7 @@
- Set rejection code 30 if tunnel with id already exists
- Network status is always OK if peer test msg 5 received
### Fixed
-- UPnP crash if SSU2 or NTCP2 is disabled
+- UPnP crash if SSU2 or NTCP2 is disabled
- Crash on termination for some platforms
## [2.45.0] - 2023-01-03
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/LICENSE
^
|
@@ -1,4 +1,4 @@
-Copyright (c) 2013-2020, The PurpleI2P Project
+Copyright (c) 2013-2023, The PurpleI2P Project
All rights reserved.
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Makefile
^
|
@@ -47,6 +47,10 @@
LD_DEBUG = -s
endif
+ifneq (, $(DESTDIR))
+ PREFIX = $(DESTDIR)
+endif
+
ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
ifeq ($(HOMEBREW),1)
@@ -67,13 +71,15 @@
$(error Not supported platform)
endif
+INCFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
+DEFINES += -DOPENSSL_SUPPRESS_DEPRECATED
+NEEDED_CXXFLAGS += -MMD -MP
+
ifeq ($(USE_GIT_VERSION),yes)
GIT_VERSION := $(shell git describe --tags)
- NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
+ DEFINES += -DGITVER=$(GIT_VERSION)
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_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
@@ -106,17 +112,17 @@
## custom FLAGS to work at build-time.
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
-include $(DEPS)
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
- $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
+ $(CXX) -o $@ $(DEFINES) $(LDFLAGS) $^ $(LDLIBS)
-$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
+$(SHLIB): $(LIB_OBJS)
ifneq ($(USE_STATIC),yes)
- $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG)
+ $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif
$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Makefile.bsd
^
|
@@ -6,7 +6,8 @@
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
## custom FLAGS to work at build-time.
-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/
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
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Makefile.linux
^
|
@@ -20,10 +20,10 @@
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
-else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9
+else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
-else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10 - 19
+else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10+
# NEEDED_CXXFLAGS += -std=c++20
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
@@ -58,12 +58,13 @@
# UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes)
- NEEDED_CXXFLAGS += -DUSE_UPNP
+ DEFINES += -DUSE_UPNP
endif
ifeq ($(USE_AESNI),yes)
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
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Makefile.mingw
^
|
@@ -4,17 +4,18 @@
WINDRES = windres
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
-INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
+INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32
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_SUFFIX = -mt
# UPNP Support
ifeq ($(USE_UPNP),yes)
- CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
+ DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB
LDLIBS = -lminiupnpc
endif
@@ -35,18 +36,19 @@
-lpthread
ifeq ($(USE_WIN32_APP), yes)
- NEEDED_CXXFLAGS += -DWIN32_APP
+ DEFINES += -DWIN32_APP
LDFLAGS += -mwindows
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
ifeq ($(USE_WINXP_FLAGS), yes)
- NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
+ DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
endif
ifeq ($(USE_AESNI),yes)
- NEEDED_CXXFLAGS += -D__AES__ -maes
+ NEEDED_CXXFLAGS += -maes
+ DEFINES += -D__AES__
endif
ifeq ($(USE_ASLR),yes)
@@ -54,4 +56,4 @@
endif
obj/%.o : %.rc | mk_obj_dir
- $(WINDRES) -i $< -o $@
+ $(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Makefile.osx
^
|
@@ -1,6 +1,7 @@
CXX = clang++
-CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
+CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11
INCFLAGS = -I/usr/local/include
+DEFINES := -DMAC_OSX
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDFLAGS += -Wl,-dead_strip
LDFLAGS += -Wl,-dead_strip_dylibs
@@ -14,7 +15,7 @@
ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl
- CXXFLAGS += -DUSE_UPNP
+ DEFINES += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a
else
@@ -22,8 +23,12 @@
endif
endif
-ifeq ($(USE_AESNI),yes)
- CXXFLAGS += -D__AES__ -maes
-else
- CXXFLAGS += -msse
+OSARCH = $(shell uname -p)
+
+ifneq ($(OSARCH),powerpc)
+ ifeq ($(USE_AESNI),yes)
+ CXXFLAGS += -D__AES__ -maes
+ else
+ CXXFLAGS += -msse
+ endif
endif
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/README.md
^
|
@@ -69,12 +69,12 @@
**Supported systems:**
-* GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
- * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
- * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
+* GNU/Linux (Debian, Ubuntu, etc) - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
+* CentOS, Fedora, Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
+* Alpine, ArchLinux, openSUSE, Gentoo, etc.
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
-* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
-* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
+* Mac OS - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
+* Docker image - [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/DaemonWin32.cpp
^
|
@@ -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
*
@@ -29,7 +29,7 @@
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
- setlocale(LC_ALL, "Russian");
+ //setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
i2p::log::SetThrowFunction ([](const std::string& s)
@@ -47,7 +47,7 @@
I2PService service((PSTR)SERVICE_NAME);
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;
@@ -61,10 +61,10 @@
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
- setlocale(LC_ALL, "Russian");
+ //setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
#ifdef WIN32_APP
- if (!i2p::win32::StartWin32App ()) return false;
+ if (!i2p::win32::StartWin32App (isDaemon)) return false;
#endif
bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Resource.rc
^
|
@@ -1,36 +1,36 @@
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-#include "winres.h"
-#undef APSTUDIO_READONLY_SYMBOLS
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-
-#ifdef APSTUDIO_INVOKED
-1 TEXTINCLUDE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""winres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-#endif // APSTUDIO_INVOKED
-
-MAINICON ICON "mask.ico"
-#endif // English (United States) resources
-
-#ifndef APSTUDIO_INVOKED
-#include "Resource.rc2"
-#endif // not APSTUDIO_INVOKED
-
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+#include "winres.h"
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+#endif // APSTUDIO_INVOKED
+
+MAINICON ICON "mask.ico"
+#endif // English (United States) resources
+
+#ifndef APSTUDIO_INVOKED
+#include "Resource.rc2"
+#endif // not APSTUDIO_INVOKED
+
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Resource.rc2
^
|
@@ -2,7 +2,7 @@
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
-#include "../libi2pd/version.h"
+#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
@@ -25,7 +25,7 @@
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
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 "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Win32App.cpp
^
|
@@ -45,6 +45,7 @@
namespace win32
{
DWORD g_GracefulShutdownEndtime = 0;
+ bool g_isWinService;
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{
@@ -347,6 +348,9 @@
}
}
}
+#if (__cplusplus >= 201703L) // C++ 17 or higher
+ [[fallthrough]];
+#endif
}
case WM_TRAYICON:
{
@@ -416,8 +420,9 @@
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
- bool StartWin32App ()
+ bool StartWin32App (bool isWinService)
{
+ g_isWinService = isWinService;
if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")))
{
MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK);
@@ -446,7 +451,9 @@
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;
}
- SubscribeToEvents();
+ // COM requires message loop to work, which is not implemented in service mode
+ if (!g_isWinService)
+ SubscribeToEvents();
return true;
}
@@ -466,7 +473,8 @@
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
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));
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Win32App.h
^
|
@@ -17,7 +17,7 @@
{
extern DWORD g_GracefulShutdownEndtime;
- bool StartWin32App ();
+ bool StartWin32App (bool isWinService);
void StopWin32App ();
int RunWin32App ();
bool GracefulShutdown ();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Win32NetState.cpp
^
|
@@ -15,6 +15,7 @@
INetworkListManager *pNetworkListManager = nullptr;
IConnectionPointContainer *pCPContainer = nullptr;
IConnectionPoint *pConnectPoint = nullptr;
+CNetworkListManagerEvent *pNetEvent = nullptr;
DWORD Cookie = 0;
void SubscribeToEvents()
@@ -29,7 +30,11 @@
if (SUCCEEDED(Result))
{
VARIANT_BOOL IsConnect = VARIANT_FALSE;
+#if defined(_MSC_VER)
+ Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
+#else
Result = pNetworkListManager->IsConnectedToInternet(&IsConnect);
+#endif
if (SUCCEEDED(Result)) {
i2p::transport::transports.SetOnline (true);
LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected");
@@ -41,8 +46,8 @@
Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
if(SUCCEEDED(Result))
{
- CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent;
- Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie);
+ pNetEvent = new CNetworkListManagerEvent;
+ Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie);
if (SUCCEEDED(Result))
LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages");
else
@@ -59,6 +64,7 @@
void UnSubscribeFromEvents()
{
+ LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents");
try
{
if (pConnectPoint) {
@@ -66,6 +72,9 @@
pConnectPoint->Release();
}
+ if (pNetEvent)
+ pNetEvent->Release();
+
if (pCPContainer)
pCPContainer->Release();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Win32NetState.h
^
|
@@ -19,21 +19,18 @@
{
public:
CNetworkListManagerEvent() : m_ref(1) { }
- ~CNetworkListManagerEvent() { }
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
{
- HRESULT Result = S_OK;
if (IsEqualIID(riid, IID_IUnknown)) {
*ppvObject = (IUnknown *)this;
} else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) {
*ppvObject = (INetworkListManagerEvents *)this;
} else {
- Result = E_NOINTERFACE;
+ return E_NOINTERFACE;
}
AddRef();
-
- return Result;
+ return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/Win32/Win32Service.cpp
^
|
@@ -21,7 +21,7 @@
HWINSTA hWinStation = GetProcessWindowStation();
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))
{
bIsService = TRUE;
@@ -119,12 +119,12 @@
}
catch (DWORD dwError)
{
- LogPrint(eLogError, "Win32Service: Start error: ", dwError);
+ LogPrint(eLogCritical, "Win32Service: Start error: ", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
- LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
+ LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED);
}
}
@@ -162,7 +162,7 @@
}
catch (...)
{
- LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
+ LogPrint(eLogCritical, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState);
}
}
@@ -191,12 +191,12 @@
}
catch (DWORD dwError)
{
- LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
+ LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError);
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
- LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
+ LogPrint(eLogCritical, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_RUNNING);
}
}
@@ -215,12 +215,12 @@
}
catch (DWORD dwError)
{
- LogPrint(eLogError, "Win32Service: Continue error: ", dwError);
+ LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError);
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
- LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
+ LogPrint(eLogCritical, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_PAUSED);
}
}
@@ -238,11 +238,11 @@
}
catch (DWORD dwError)
{
- LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError);
+ LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError);
}
catch (...)
{
- LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
+ LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE);
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/build/.gitignore
^
|
@@ -1,6 +1,13 @@
# Various generated files
/CMakeFiles/
+/Testing/
+/tests/
+/.ninja_*
+/arch.c
+/build.ninja
/i2pd
+/i2pd.exe
+/i2pd.exe.debug
/libi2pd.a
/libi2pdclient.a
/libi2pdlang.a
@@ -8,8 +15,13 @@
/CMakeCache.txt
/CPackConfig.cmake
/CPackSourceConfig.cmake
+/CTestTestfile.cmake
/install_manifest.txt
-/arch.c
+/Makefile
# windows build script
i2pd*.zip
build*.log
+# MVS project files
+*.vcxproj
+*.vcxproj.filters
+*.sln
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/build/CMakeLists.txt
^
|
@@ -1,14 +1,32 @@
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
#set(CMAKE_VERBOSE_MAKEFILE on)
-# Win32 build with cmake is not supported
-if(WIN32 OR MSVC OR MSYS OR MINGW)
- message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
-endif()
+# paths
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
+set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+
+set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd)
+set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client)
+set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n)
+set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon)
+
+include(Version)
+set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION)
+
+project(
+ i2pd
+ VERSION ${PROJECT_VERSION}
+ HOMEPAGE_URL "https://i2pd.website/"
+ LANGUAGES CXX
+)
# configurable options
option(WITH_AESNI "Use AES-NI instructions set" ON)
@@ -26,27 +44,22 @@
enable_testing()
ENDIF()
-# paths
-set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
-set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
-
# Handle paths nicely
include(GNUInstallDirs)
-# architecture
+# Architecture
include(TargetArch)
target_architecture(ARCHITECTURE)
-set(LIBI2PD_SRC_DIR ../libi2pd)
-set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
-set(LANG_SRC_DIR ../i18n)
-set(DAEMON_SRC_DIR ../daemon)
+include(CheckAtomic)
-include_directories(${LIBI2PD_SRC_DIR})
-include_directories(${LIBI2PD_CLIENT_SRC_DIR})
-include_directories(${LANG_SRC_DIR})
-include_directories(${DAEMON_SRC_DIR})
+if(WITH_STATIC)
+ if(MSVC)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+ endif()
+endif()
+include_directories(${LIBI2PD_SRC_DIR})
FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp)
add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES PREFIX "")
@@ -57,11 +70,9 @@
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
-# TODO Make libi2pd available to 3rd party projects via CMake as imported target
-# FIXME This pulls stdafx
-# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
+include_directories(${LIBI2PD_CLIENT_SRC_DIR})
FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp)
add_library(libi2pdclient ${CLIENT_SRC})
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
@@ -74,6 +85,7 @@
COMPONENT Libraries)
endif()
+include_directories(${LANG_SRC_DIR})
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
add_library(libi2pdlang ${LANG_SRC})
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
@@ -86,6 +98,8 @@
COMPONENT Libraries)
endif()
+include_directories(${DAEMON_SRC_DIR})
+
set(DAEMON_SRC
"${DAEMON_SRC_DIR}/Daemon.cpp"
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
@@ -95,6 +109,22 @@
"${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)
add_definitions(-DUSE_UPNP)
endif()
@@ -102,30 +132,40 @@
if(WITH_GIT_VERSION)
include(GetGitRevisionDescription)
git_describe(GIT_VERSION)
- add_definitions(-DGITVER="${GIT_VERSION}")
+ add_definitions(-DGITVER=${GIT_VERSION})
endif()
if(APPLE)
add_definitions(-DMAC_OSX)
endif()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter")
-set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
-# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
-# Multiple definitions of __stack_chk_fail(libssp & libc)
-set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
-set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above
-
-# 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")
+if(MSVC)
+ add_definitions(-DWINVER=0x0600)
+ add_definitions(-D_WIN32_WINNT=0x0600)
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()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -157,6 +197,12 @@
# Note: AES-NI and AVX is available on x86-based CPU's.
# 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"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(-D__AES__)
@@ -178,6 +224,7 @@
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/build/cmake_modules/TargetArch.cmake
^
|
@@ -1,4 +1,4 @@
-# Copyright (c) 2017-2022, The PurpleI2P Project
+# Copyright (c) 2017-2023, The PurpleI2P Project
# This file is part of Purple i2pd project and licensed under BSD3
# See full license text in LICENSE file at top of project tree
@@ -18,7 +18,7 @@
|| defined(_M_ARM64) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8)
#error cmake_ARCH arm64
- #if defined(__ARM_ARCH_7__) \\
+ #elif defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
@@ -83,13 +83,13 @@
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
- # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
- # disable it by default
+ # the OS X SDK version 10.7 or later - you'll need 10.4/10.5/10.6 for that, so we
+ # disable it by default. Also, ppc64 is not supported in 10.6.
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
- # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
+ # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise; 10.6 also supports ppc.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
@@ -133,11 +133,11 @@
enable_language(C)
# Detect the architecture in a rather creative way...
- # This compiles a small C program which is a series of ifdefs that selects a
- # particular #error preprocessor directive whose message string contains the
- # target architecture. The program will always fail to compile (both because
- # file is not a valid C program, and obviously because of the presence of the
- # #error preprocessor directives... but by exploiting the preprocessor in this
+ # This compiles a small C program which is a series of ifdefs that selects
+ # a particular #error preprocessor directive whose message string contains
+ # the target architecture. The program will always fail to compile (both because
+ # file is not a valid C program, and obviously because of the presence of
+ # the #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/build/cmake_modules/Version.cmake
^
|
@@ -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()
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt
^
|
@@ -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-----
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/certificates/reseed/igor_at_novg.net.crt
^
|
@@ -1,33 +1,33 @@
-----BEGIN CERTIFICATE-----
-MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt
+MIIFvjCCA6agAwIBAgIQBnsUOmOu2oZZIwHBmQc1BDANBgkqhkiG9w0BAQsFADBt
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN
-aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x
+aWdvckBub3ZnLm5ldDAeFw0yMzAxMjgxNDM4MzFaFw0zMzAxMjgxNDM4MzFaMG0x
CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT
FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p
-Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4
-cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF
-x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h
-vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm
-w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw
-MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy
-Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy
-f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b
-mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d
-Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP
-0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq
-jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/
+Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLkf
+bM3uiYfp9m0vgdoftyXtk2/9bHf3u5iaM0WfoJIsw1iizo/mxJl+Iy7SxLC16nV0
+v5FpncVv+Z8x9dgoAYVuLq9zKfsAbpj6kuxAqw6vJMlD1TiIL3nSODV9BJLk47X5
+tmvoOSj9BgvemYThTE3nj+DbuJRW5q90KyBV/LdLrQJX3k5R3FFL5tTad2LKFNZ4
+vEOcYwwx6mvrkJ2lly6bAQUCtfc648Jyq+NO3Rba1fmn7gcP9zXXc5KYsj/ovyY2
+OaocSF5wMhzBuPxO+M2HqbYLMAkc6/GesGds8Rm8wofuhJoI5YtqJuLKZm6nQXSc
+fx6PKgbKcTIUWNFMsxyfghz9hpbg0rkvC7PtfAjtV0yaDtUum1eZeNEx1HbRWN2n
+TQNCVuv0yaKC41qxqzhEybkdjL9JlgUh7VuskaCelB0lz+kgYjGu8ezOa0ua2iKq
+4FC/1MbPulxN8NOt4pmbGqqoxmCdShp38wdnOBM3DsAS9f0JaQZd4CDyY4DCSfVn
+xPdWk31+VXVt3Ixh1EUqZWYTRSsZApkCyYzkiZ/qPGG6FR9Hq2SuhC5o4P44k7eo
+6wwBWD8a5RjsZhvr05E5yBrKXh/PjLwmtG73QC+ouR54/5xtedvdTwNS94FnNctX
+FT6QGZnRwCkhPaRe1oQMzP+88pGoCfO33GBAuwUCAwEAAaNaMFgwDgYDVR0PAQH/
BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E
BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC
-AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk
-5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o
-3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS
-AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal
-zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs
-0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ
-cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4
-4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6
-GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW
-dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5
-qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w==
+AQCteAb5/bqhHr/i5CJbDzlofprXFC826c19GxQ/9Hw0kA52l0J9Q8Vz8Vy7VQyP
+QNa8MCv6FeNy8a/wXp6cafyFsBtvehVQO8lFlpCgMEl2Bma43+GaCwkrM6bFNXeW
+iQ9h4e1KjsUZ8cQDNEcamiJ80+xbMhBrj5bAZwKmZs8MoGEMyXKEZmcmwA+/fy1c
+cx4izsOsmRXmEHXsvB9ydJHZZeKW8+r0DAtgPslwXuXHG6MuBQo7dKCqn+iMxHXV
+Jxriq3yvNffdGx4maSLJrjQ1ealt/UMzql7huVSItnVFWoYf7GAELXNJ/PmqVyaK
+q11LQ8W/Aud6s/bblaJrFJnK8PbPpaw4RvHoWVLYaZYmQnV2msWs5EuESBlEADbv
+UklQXLMc2f9HKWPA5678nvYPrmu8IL5pMkAxgGRqmd+7vCz4lU9M5z3HObU+WRBt
+qEMYyXywV8o3tbmnlDS5S5Xxf+tLZn1cxz3ZrmcHPHDbLBNdvszF3CTJH/R2sQvD
+bizvYJM+p5F+GWM5mt6w0HrOut5MRlpOws/NRrkbijuVA/A45nzTtKplIFYE3qe8
+q5SAbwYLc8cJcZCN3PxtWwbEv81V33abMt5QcjnWGLH5t2+1Z2KLCgKLSCQTxM8s
+zBPHtUe8qtSQaElnNLILYbtJ1w67dPnGYTphHihC+CXjBg==
-----END CERTIFICATE-----
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/dinit/i2pd
^
|
@@ -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
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/i18n/English.po
^
|
@@ -1,13 +1,13 @@
# i2pd
-# Copyright (C) 2021-2022 PurpleI2P team
+# Copyright (C) 2021-2023 PurpleI2P team
# This file is distributed under the same license as the i2pd package.
-# R4SAS <r4sas@i2pmail.org>, 2021-2022.
+# R4SAS <r4sas@i2pmail.org>, 2021-2023.
#
msgid ""
msgstr ""
"Project-Id-Version: i2pd\n"
"Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n"
-"POT-Creation-Date: 2022-07-26 21:22\n"
+"POT-Creation-Date: 2023-06-10 01:25\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -18,66 +18,73 @@
"X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n"
"X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n"
-#: daemon/HTTPServer.cpp:108
-msgid "day"
-msgid_plural "days"
+#: daemon/HTTPServer.cpp:107
+#, c-format
+msgid "%d day"
+msgid_plural "%d days"
msgstr[0] ""
msgstr[1] ""
-#: daemon/HTTPServer.cpp:112
-msgid "hour"
-msgid_plural "hours"
+#: daemon/HTTPServer.cpp:111
+#, c-format
+msgid "%d hour"
+msgid_plural "%d hours"
msgstr[0] ""
msgstr[1] ""
-#: daemon/HTTPServer.cpp:116
-msgid "minute"
-msgid_plural "minutes"
+#: daemon/HTTPServer.cpp:115
+#, c-format
+msgid "%d minute"
+msgid_plural "%d minutes"
msgstr[0] ""
msgstr[1] ""
-#: daemon/HTTPServer.cpp:119
-msgid "second"
-msgid_plural "seconds"
+#: daemon/HTTPServer.cpp:118
+#, c-format
+msgid "%d second"
+msgid_plural "%d seconds"
msgstr[0] ""
msgstr[1] ""
-#. tr: Kibibit
-#: daemon/HTTPServer.cpp:127 daemon/HTTPServer.cpp:155
-msgid "KiB"
+#. tr: Kibibyte
+#: daemon/HTTPServer.cpp:126
+#, c-format
+msgid "%.2f KiB"
msgstr ""
-#. tr: Mebibit
-#: daemon/HTTPServer.cpp:129
-msgid "MiB"
+#. tr: Mebibyte
+#: daemon/HTTPServer.cpp:128
+#, c-format
+msgid "%.2f MiB"
msgstr ""
-#. tr: Gibibit
-#: daemon/HTTPServer.cpp:131
-msgid "GiB"
+#. tr: Gibibyte
+#: daemon/HTTPServer.cpp:130
+#, c-format
+msgid "%.2f GiB"
msgstr ""
-#: daemon/HTTPServer.cpp:148
+#: daemon/HTTPServer.cpp:147
msgid "building"
msgstr ""
-#: daemon/HTTPServer.cpp:149
+#: daemon/HTTPServer.cpp:148
msgid "failed"
msgstr ""
-#: daemon/HTTPServer.cpp:150
+#: daemon/HTTPServer.cpp:149
msgid "expiring"
msgstr ""
-#: daemon/HTTPServer.cpp:151
+#: daemon/HTTPServer.cpp:150
msgid "established"
msgstr ""
-#: daemon/HTTPServer.cpp:152
+#: daemon/HTTPServer.cpp:151
msgid "unknown"
msgstr ""
-#: daemon/HTTPServer.cpp:154
+#: daemon/HTTPServer.cpp:153
msgid "exploratory"
msgstr ""
@@ -94,32 +101,32 @@
msgid "Main page"
msgstr ""
-#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:700
+#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:742
msgid "Router commands"
msgstr ""
-#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:382
-#: daemon/HTTPServer.cpp:394
+#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:395
+#: daemon/HTTPServer.cpp:407
msgid "Local Destinations"
msgstr ""
-#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:352
-#: daemon/HTTPServer.cpp:438 daemon/HTTPServer.cpp:444
-#: daemon/HTTPServer.cpp:597 daemon/HTTPServer.cpp:640
-#: daemon/HTTPServer.cpp:644
+#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:365
+#: daemon/HTTPServer.cpp:454 daemon/HTTPServer.cpp:474
+#: daemon/HTTPServer.cpp:636 daemon/HTTPServer.cpp:682
+#: daemon/HTTPServer.cpp:686
msgid "LeaseSets"
msgstr ""
-#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:650
+#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:692
msgid "Tunnels"
msgstr ""
-#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:359
-#: daemon/HTTPServer.cpp:770 daemon/HTTPServer.cpp:786
+#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:372
+#: daemon/HTTPServer.cpp:813 daemon/HTTPServer.cpp:830
msgid "Transit Tunnels"
msgstr ""
-#: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:839
+#: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:898
msgid "Transports"
msgstr ""
@@ -127,15 +134,16 @@
msgid "I2P tunnels"
msgstr ""
-#: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:908
-#: daemon/HTTPServer.cpp:918
+#: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:927
+#: daemon/HTTPServer.cpp:937
msgid "SAM sessions"
msgstr ""
-#: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1302
-#: daemon/HTTPServer.cpp:1305 daemon/HTTPServer.cpp:1308
-#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1367
-#: daemon/HTTPServer.cpp:1370 daemon/HTTPServer.cpp:1373
+#: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1329
+#: daemon/HTTPServer.cpp:1332 daemon/HTTPServer.cpp:1335
+#: daemon/HTTPServer.cpp:1362 daemon/HTTPServer.cpp:1365
+#: daemon/HTTPServer.cpp:1379 daemon/HTTPServer.cpp:1424
+#: daemon/HTTPServer.cpp:1427 daemon/HTTPServer.cpp:1430
msgid "ERROR"
msgstr ""
@@ -151,14 +159,14 @@
msgid "Firewalled"
msgstr ""
-#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:253
-#: daemon/HTTPServer.cpp:325
+#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:235
+#: daemon/HTTPServer.cpp:336
msgid "Unknown"
msgstr ""
-#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:369
-#: daemon/HTTPServer.cpp:370 daemon/HTTPServer.cpp:976
-#: daemon/HTTPServer.cpp:985
+#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:382
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/i18n/README.md
^
|
@@ -1,29 +1,30 @@
-`xgettext` command for extracting translation
----
-
-```
-xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp
-```
-
-Regex for transforming gettext translations to our format:
----
-
-```
-in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
-out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n
-```
-
-```
-in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
-out: {"$1", "$2"},\n
-```
-
-```
-in: ^#[:.](.*)$\n
-out: <to empty line>
-```
-
-```
-in: \n\n
-out: \n
-```
+`xgettext` command for extracting translation
+---
+
+```
+xgettext --omit-header -ctr: -ktr -kntr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp
+```
+
+Regex for transforming gettext translations to our format:
+---
+
+```
+in: ^(\"|#[:.,]|msgctxt)(.*)$\n
+out: <to empty line>
+```
+
+```
+in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
+out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n
+```
+
+```
+in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
+out: {"$1", "$2"},\n
+```
+
+
+```
+in: \n\n
+out: \n
+```
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/i2pd.conf
^
|
@@ -19,7 +19,7 @@
## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
# certsdir = /var/lib/i2pd/certificates
-## Where to write pidfile (default: i2pd.pid, not used in Windows)
+## Where to write pidfile (default: /run/i2pd.pid, not used in Windows)
# pidfile = /run/i2pd.pid
## Logging configuration section
@@ -31,15 +31,16 @@
## * file - log entries to a file
## * syslog - use syslog, see man 3 syslog
# log = file
-## Path to logfile (default - autodetect)
+## Path to logfile (default: autodetect)
# 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
# loglevel = warn
## Write full CLF-formatted date and time to log (default: write only time)
# logclftime = true
## Daemon mode. Router will go to background after start. Ignored on Windows
+## (default: true)
# daemon = true
## Specify a family, router belongs to (default - none)
@@ -70,90 +71,97 @@
## don't just uncomment this
# port = 4567
-## Enable communication through ipv4
+## Enable communication through ipv4 (default: true)
ipv4 = true
-## Enable communication through ipv6
+## Enable communication through ipv6 (default: false)
ipv6 = false
-## Enable SSU transport
-ssu = false
-
## Bandwidth configuration
-## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec,
+## L limit bandwidth to 32 KB/sec, O - to 256 KB/sec, P - to 2048 KB/sec,
## X - unlimited
-## Default is L (regular node) and X if floodfill mode enabled. If you want to
-## share more bandwidth without floodfill mode, uncomment that line and adjust
-## value to your possibilities
+## Default is L (regular node) and X if floodfill mode enabled.
+## If you want to share more bandwidth without floodfill mode, uncomment
+## that line and adjust value to your possibilities. Value can be set to
+## integer in kilobytes, it will apply that limit and flag will be used
+## from next upper limit (example: if you set 4096 flag will be X, but real
+## limit will be 4096 KB/s). Same can be done when floodfill mode is used,
+## but keep in mind that low values may be negatively evaluated by Java
+## router algorithms.
# bandwidth = L
-## Max % of bandwidth limit for transit. 0-100. 100 by default
+## Max % of bandwidth limit for transit. 0-100 (default: 100)
# share = 100
## Router will not accept transit tunnels, disabling transit traffic completely
-## (default = false)
+## (default: false)
# notransit = true
-## Router will be floodfill
+## Router will be floodfill (default: false)
## Note: that mode uses much more network connections and CPU!
# floodfill = true
[ntcp2]
-## Enable NTCP2 transport (default = true)
+## Enable NTCP2 transport (default: true)
# enabled = true
-## Publish address in RouterInfo (default = true)
+## Publish address in RouterInfo (default: true)
# published = true
## Port for incoming connections (default is global port option value)
# port = 4567
[ssu2]
-## Enable SSU2 transport
+## Enable SSU2 transport (default: true)
# enabled = true
-## Publish address in RouterInfo
+## Publish address in RouterInfo (default: true)
# published = true
-## Port for incoming connections (default is global port option value or port + 1 if SSU is enabled)
+## Port for incoming connections (default is global port option value)
# port = 4567
[http]
## Web Console settings
-## Uncomment and set to 'false' to disable Web Console
+## Enable the Web Console (default: true)
# enabled = true
-## Address and port service will listen on
-address = 127.0.0.1
-port = 7070
-## Path to web console, default "/"
+## Address and port service will listen on (default: 127.0.0.1:7070)
+# address = 127.0.0.1
+# port = 7070
+## Path to web console (default: /)
# webroot = /
-## Uncomment following lines to enable Web Console authentication
+## Enable Web Console authentication (default: false)
+## You should not use Web Console via public networks without additional encryption.
+## HTTP authentication is not encryption layer!
# auth = true
# user = i2pd
# pass = changeme
## Select webconsole language
## Currently supported english (default), afrikaans, armenian, chinese, czech, french,
-## german, italian, russian, spanish, turkmen, ukrainian and uzbek languages
+## german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian
+## and uzbek languages
# lang = english
[httpproxy]
-## Uncomment and set to 'false' to disable HTTP Proxy
+## Enable the HTTP proxy (default: true)
# enabled = true
-## Address and port service will listen on
-address = 127.0.0.1
-port = 4444
-## Optional keys file for proxy local destination
+## Address and port service will listen on (default: 127.0.0.1:4444)
+# address = 127.0.0.1
+# port = 4444
+## Optional keys file for proxy local destination (default: http-proxy-keys.dat)
# keys = http-proxy-keys.dat
## Enable address helper for adding .i2p domains with "jump URLs" (default: true)
+## You should disable this feature if your i2pd HTTP Proxy is public,
+## because anyone could spoof the short domain via addresshelper and forward other users to phishing links
# addresshelper = true
## Address of a proxy server inside I2P, which is used to visit regular Internet
# outproxy = http://false.i2p
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
[socksproxy]
-## Uncomment and set to 'false' to disable SOCKS Proxy
+## Enable the SOCKS proxy (default: true)
# enabled = true
-## Address and port service will listen on
-address = 127.0.0.1
-port = 4447
-## Optional keys file for proxy local destination
+## Address and port service will listen on (default: 127.0.0.1:4447)
+# address = 127.0.0.1
+# port = 4447
+## Optional keys file for proxy local destination (default: socks-proxy-keys.dat)
# keys = socks-proxy-keys.dat
## Socks outproxy. Example below is set to use Tor for all connections except i2p
-## Uncomment and set to 'true' to enable using of SOCKS outproxy
+## Enable using of SOCKS outproxy (works only with SOCKS4, default: false)
# outproxy.enabled = false
## Address and port of outproxy
# outproxy = 127.0.0.1
@@ -161,33 +169,34 @@
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
-## Comment or set to 'false' to disable SAM Bridge
-enabled = true
-## Address and port service will listen on
+## Enable the SAM bridge (default: true)
+# enabled = false
+## Address and ports service will listen on (default: 127.0.0.1:7656, udp: 7655)
# address = 127.0.0.1
# port = 7656
+# portudp = 7655
[bob]
-## Uncomment and set to 'true' to enable BOB command channel
+## Enable the BOB command channel (default: false)
# enabled = false
-## Address and port service will listen on
+## Address and port service will listen on (default: 127.0.0.1:2827)
# address = 127.0.0.1
# port = 2827
[i2cp]
-## Uncomment and set to 'true' to enable I2CP protocol
+## Enable the I2CP protocol (default: false)
# enabled = false
-## Address and port service will listen on
+## Address and port service will listen on (default: 127.0.0.1:7654)
# address = 127.0.0.1
# port = 7654
[i2pcontrol]
-## Uncomment and set to 'true' to enable I2PControl protocol
+## Enable the I2PControl protocol (default: false)
# enabled = false
-## Address and port service will listen on
+## Address and port service will listen on (default: 127.0.0.1:7650)
# address = 127.0.0.1
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/rpm/i2pd-git.spec
^
|
@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git
-Version: 2.45.1
+Version: 2.48.0
Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd
@@ -158,6 +158,18 @@
%changelog
+* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
+- update to 2.48.0
+
+* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
+- update to 2.47.0
+
+* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
+- update to 2.46.1
+
+* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
+- update to 2.46.0
+
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/rpm/i2pd.spec
^
|
@@ -1,5 +1,5 @@
Name: i2pd
-Version: 2.45.1
+Version: 2.48.0
Release: 1%{?dist}
Summary: I2P router written in C++
Conflicts: i2pd-git
@@ -155,6 +155,18 @@
%changelog
+* Mon Jun 12 2023 orignal <orignal@i2pmail.org> - 2.48.0
+- update to 2.48.0
+
+* Sat Mar 11 2023 orignal <orignal@i2pmail.org> - 2.47.0
+- update to 2.47.0
+
+* Mon Feb 20 2023 r4sas <r4sas@i2pmail.org> - 2.46.1
+- update to 2.46.1
+
+* Wed Feb 15 2023 orignal <orignal@i2pmail.org> - 2.46.0
+- update to 2.46.0
+
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/contrib/webconsole/style.css
^
|
@@ -1,293 +1,293 @@
-/*
- * Copyright (c) 2021-2022, The PurpleI2P Project
- *
- * This file is part of Purple i2pd project and licensed under BSD3
- *
- * See full license text in LICENSE file at top of project tree
- *
- ******************************************************************
- *
- * This is style sheet for webconsole, with @media selectors for adaptive
- * view on desktop and mobile devices, respecting preferred user's color
- * scheme used in system/browser.
- *
- * Minified copy of that style sheet is bundled inside i2pd sources.
-*/
-
-:root {
- --main-bg-color: #fafafa;
- --main-text-color: #103456;
- --main-link-color: #894c84;
- --main-link-hover-color: #fafafa;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --main-bg-color: #242424;
- --main-text-color: #17ab5c;
- --main-link-color: #bf64b7;
- --main-link-hover-color: #000000;
- }
-}
-
-body {
- font: 100%/1.5em sans-serif;
- margin: 0;
- padding: 1.5em;
- background: var(--main-bg-color);
- color: var(--main-text-color);
-}
-
-a, .slide label {
- text-decoration: none;
- color: var(--main-link-color);
-}
-
-a:hover, .slide label:hover, button[type=submit]:hover {
- color: var(--main-link-hover-color);
- background: var(--main-link-color);
-}
-
-a.button {
- appearance: button;
- text-decoration: none;
- padding: 0 5px;
- border: 1px solid var(--main-link-color);
-}
-
-.header {
- font-size: 2.5em;
- text-align: center;
- margin: 1em 0;
- color: var(--main-link-color);
-}
-
-.wrapper {
- margin: 0 auto;
- padding: 1em;
- max-width: 64em;
-}
-
-.menu {
- display: block;
- float: left;
- overflow: hidden;
- padding: 4px;
- max-width: 12em;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-
-.listitem {
- display: block;
- font-family: monospace;
- font-size: 1.2em;
- white-space: nowrap;
-}
-
-.tableitem {
- font-family: monospace;
- font-size: 1.2em;
- white-space: nowrap;
-}
-
-.content {
- float: left;
- font-size: 1em;
- margin-left: 2em;
- padding: 4px;
- max-width: 50em;
- overflow: auto;
-}
-
-.tunnel.established {
- color: #56B734;
-}
-
-.tunnel.expiring {
- color: #D3AE3F;
-}
-
-.tunnel.failed {
- color: #D33F3F;
-}
-
-.tunnel.building {
- color: #434343;
-}
-
-caption {
- font-size: 1.5em;
- text-align: center;
- color: var(--main-link-color);
-}
-
-table {
- display: table;
- border-collapse: collapse;
- text-align: center;
-}
-
-table.extaddr {
- text-align: left;
-}
-
-table.services {
- width: 100%;
-}
-
-textarea {
- background-color: var(--main-bg-color);
- color: var(--main-text-color);
- word-break: break-all;
-}
-
-.streamdest {
- width: 120px;
- max-width: 240px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.slide div.slidecontent, .slide [type="checkbox"] {
- display: none;
-}
-
-.slide [type="checkbox"]:checked ~ div.slidecontent {
- display: block;
- margin-top: 0;
- padding: 0;
-}
-
-.disabled {
- color: #D33F3F;
-}
-
-.enabled {
- color: #56B734;
-}
-
-button[type=submit] {
- background-color: transparent;
- color: var(--main-link-color);
- text-decoration: none;
- padding: 5px;
- border: 1px solid var(--main-link-color);
- font-size: 14px;
-}
-
-input, select, select option {
- background-color: var(--main-bg-color);
- color: var(--main-link-color);
- padding: 5px;
- border: 1px solid var(--main-link-color);
- font-size: 14px;
-}
-
-input:focus, select:focus, select option:focus {
- outline: none;
-}
-
-input[type=number]::-webkit-inner-spin-button {
- -webkit-appearance: none;
-}
-
-@media screen and (max-width: 1150px) { /* adaptive style */
- .wrapper {
- max-width: 58em;
- }
-
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/daemon/Daemon.cpp
^
|
@@ -179,7 +179,7 @@
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels"))
transitTunnels *= 2; // double default number of transit tunnels for floodfill
- SetMaxNumTransitTunnels (transitTunnels);
+ i2p::tunnel::tunnels.SetMaxNumTransitTunnels (transitTunnels);
/* this section also honors 'floodfill' flag, if set above */
std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
@@ -269,7 +269,7 @@
if (hidden)
{
LogPrint(eLogInfo, "Daemon: Hidden mode enabled");
- i2p::data::netdb.SetHidden(true);
+ i2p::context.SetHidden(true);
}
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
@@ -310,7 +310,7 @@
LogPrint(eLogInfo, "Daemon: Transports started");
else
{
- LogPrint(eLogError, "Daemon: Failed to start Transports");
+ LogPrint(eLogCritical, "Daemon: Failed to start Transports");
/** shut down netdb right away */
i2p::transport::transports.Stop();
i2p::data::netdb.Stop();
@@ -329,15 +329,17 @@
}
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 ());
}
}
-
LogPrint(eLogInfo, "Daemon: Starting Tunnels");
i2p::tunnel::tunnels.Start();
+ LogPrint(eLogInfo, "Daemon: Starting Router context");
+ i2p::context.Start();
+
LogPrint(eLogInfo, "Daemon: Starting Client");
i2p::client::context.Start ();
@@ -354,7 +356,7 @@
}
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 ());
}
}
@@ -366,6 +368,8 @@
LogPrint(eLogInfo, "Daemon: Shutting down");
LogPrint(eLogInfo, "Daemon: Stopping Client");
i2p::client::context.Stop();
+ LogPrint(eLogInfo, "Daemon: Stopping Router context");
+ i2p::context.Stop();
LogPrint(eLogInfo, "Daemon: Stopping Tunnels");
i2p::tunnel::tunnels.Stop();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/daemon/HTTPServer.cpp
^
|
@@ -87,6 +87,7 @@
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css";
+ const char HTTP_COMMAND_EXPIRELEASE[] = "expirelease";
static std::string ConvertTime (uint64_t time)
{
@@ -103,18 +104,18 @@
int num;
if ((num = seconds / 86400) > 0) {
- s << num << " " << tr("day", "days", num) << ", ";
+ s << ntr("%d day", "%d days", num, num) << ", ";
seconds -= num * 86400;
}
if ((num = seconds / 3600) > 0) {
- s << num << " " << tr("hour", "hours", num) << ", ";
+ s << ntr("%d hour", "%d hours", num, num) << ", ";
seconds -= num * 3600;
}
if ((num = seconds / 60) > 0) {
- s << num << " " << tr("minute", "minutes", num) << ", ";
+ s << ntr("%d minute", "%d minutes", num, num) << ", ";
seconds -= num * 60;
}
- s << seconds << " " << tr("second", "seconds", seconds);
+ s << ntr("%d second", "%d seconds", seconds, seconds);
}
static void ShowTraffic (std::stringstream& s, uint64_t bytes)
@@ -122,11 +123,11 @@
s << std::fixed << std::setprecision(2);
auto numKBytes = (double) bytes / 1024;
if (numKBytes < 1024)
- s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB");
+ s << tr(/* tr: Kibibyte */ "%.2f KiB", numKBytes);
else if (numKBytes < 1024 * 1024)
- s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB");
+ s << tr(/* tr: Mebibyte */ "%.2f MiB", numKBytes / 1024);
else
- s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB");
+ s << tr(/* tr: Gibibyte */ "%.2f GiB", numKBytes / 1024 / 1024);
}
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
@@ -150,12 +151,13 @@
else stateText = tr("unknown");
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
- s << " " << (int) (bytes / 1024) << " " << tr(/* tr: Kibibit */ "KiB") << "\r\n";
+ ShowTraffic(s, bytes);
+ s << "\r\n";
}
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);
else {
LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted");
@@ -198,7 +200,7 @@
if (i2p::context.AcceptsTunnels () || i2p::tunnel::tunnels.CountTransitTunnels())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit Tunnels") << "</a><br>\r\n";
s <<
- " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
+ " <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr("Transports") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
if (i2p::client::context.GetSAMBridge ())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
@@ -247,7 +249,7 @@
break;
case eRouterErrorFullConeNAT:
s << " - " << tr("Full cone NAT");
- break;
+ break;
case eRouterErrorNoDescriptors:
s << " - " << tr("No Descriptors");
break;
@@ -288,15 +290,20 @@
if (family.length () > 0)
s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n";
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
+ bool isTotalTCSR;
+ i2p::config::GetOption("http.showTotalTCSR", isTotalTCSR);
+ if (isTotalTCSR) {
+ s << "<b>" << tr("Total tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTotalTunnelCreationSuccessRate() << "%<br/>\r\n";
+ }
s << "<b>" << tr("Received") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
- s << " (" << (double) i2p::transport::transports.GetInBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
+ s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Sent") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
- s << " (" << (double) i2p::transport::transports.GetOutBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
+ s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Transit") << ":</b> ";
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
- s << " (" << (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
+ s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")<br>\r\n";
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
s << "<div class='slide'>";
if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
@@ -328,17 +335,18 @@
default:
s << tr("Unknown");
}
- if (address->IsV6 ())
+ bool v6 = address->IsV6 ();
+ if (v6)
{
if (address->IsV4 ()) s << "v4";
s << "v6";
}
s << "</td>\r\n";
if (address->published)
- s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n";
+ s << "<td>" << (v6 ? "[" : "") << address->host.to_string() << (v6 ? "]:" : ":") << address->port << "</td>\r\n";
else
{
- s << "<td>" << tr("supported");
+ s << "<td>" << tr(/* tr: Shown when router doesn't publish itself and have "Firewalled" state */ "supported");
if (address->port)
s << " :" << address->port;
s << "</td>\r\n";
@@ -414,8 +422,12 @@
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
{
+ s << "<b>Base32:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"1\">";
+ s << dest->GetIdentHash ().ToBase32 () << "</textarea><br>\r\n<br>\r\n";
+
s << "<b>Base64:</b><br>\r\n<textarea readonly cols=\"80\" rows=\"8\">";
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
+
if (dest->IsEncryptedLeaseSet ())
{
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
@@ -427,12 +439,11 @@
if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ())
{
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
- auto base32 = dest->GetIdentHash ().ToBase32 ();
s << "<div class='slide'><label for='slide-regaddr'><b>" << tr("Address registration line") << "</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
"<form method=\"get\" action=\"" << webroot << "\">\r\n"
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
- " <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
+ " <input type=\"hidden\" name=\"b32\" value=\"" << dest->GetIdentHash ().ToBase32 () << "\">\r\n"
" <b>" << tr("Domain") << ":</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
" <button type=\"submit\">" << tr("Generate") << "</button>\r\n"
"</form>\r\n<small>" << tr("<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
@@ -441,9 +452,23 @@
if (dest->GetNumRemoteLeaseSets())
{
s << "<div class='slide'><label for='slide-lease'><b>" << tr("LeaseSets") << ":</b> <i>" << dest->GetNumRemoteLeaseSets ()
- << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n<table><thead><th>"<< tr("Address") << "</th><th>" << tr("Type") << "</th><th>" << tr("EncType") << "</th></thead><tbody class=\"tableitem\">";
+ << "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n"
+ << "<table><thead>"
+ << "<th>" << tr("Address") << "</th>"
+ << "<th style=\"width:5px;\"> </th>" // LeaseSet expiration button column
+ << "<th>" << tr("Type") << "</th>"
+ << "<th>" << tr("EncType") << "</th>"
+ << "</thead><tbody class=\"tableitem\">";
for(auto& it: dest->GetLeaseSets ())
- s << "<tr><td>" << it.first.ToBase32 () << "</td><td>" << (int)it.second->GetStoreType () << "</td><td>" << (int)it.second->GetEncryptionType () <<"</td></tr>\r\n";
+ {
+ s << "<tr>"
+ << "<td>" << it.first.ToBase32 () << "</td>"
+ << "<td><a class=\"button\" href=\"/?cmd=" << HTTP_COMMAND_EXPIRELEASE<< "&b32=" << dest->GetIdentHash ().ToBase32 ()
+ << "&lease=" << it.first.ToBase32 () << "&token=" << token << "\" title=\"" << tr("Expire LeaseSet") << "\"> ✘ </a></td>"
+ << "<td>" << (int)it.second->GetStoreType () << "</td>"
+ << "<td>" << (int)it.second->GetEncryptionType () <<"</td>"
+ << "</tr>\r\n";
+ }
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
} else
s << "<b>" << tr("LeaseSets") << ":</b> <i>0</i><br>\r\n<br>\r\n";
@@ -466,7 +491,7 @@
}
s << "⇒ " << it->GetTunnelID () << ":me";
if (it->LatencyIsKnown())
- s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )";
+ s << " ( " << tr(/* tr: Milliseconds */ "%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
s << "</div>\r\n";
}
@@ -486,22 +511,26 @@
);
}
if (it->LatencyIsKnown())
- s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
+ s << " ( " << tr("%dms", it->GetMeanLatency()) << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
s << "</div>\r\n";
}
}
s << "<br>\r\n";
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/daemon/HTTPServer.h
^
|
@@ -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
*
@@ -24,6 +24,8 @@
{
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds
+ const int COMMAND_REDIRECT_TIMEOUT = 5; // in seconds
+ const int TRANSIT_TUNNELS_LIMIT = 65535;
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/daemon/HTTPServerResources.h
^
|
@@ -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
*
@@ -38,7 +38,7 @@
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n"
"body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n"
"a, .slide label { text-decoration: none; color: var(--main-link-color); }\r\n"
- "a:hover, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n"
+ "a:hover, a.button.selected, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n"
"a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color); }\r\n"
".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color); }\r\n"
".wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n"
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/daemon/UnixDaemon.cpp
^
|
@@ -173,7 +173,7 @@
ftruncate(pidFH, 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;
return false;
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/debian/changelog
^
|
@@ -1,8 +1,38 @@
+i2pd (2.48.0-1) unstable; urgency=high
+
+ * updated to version 2.48.0/0.9.59
+
+ -- orignal <orignal@i2pmail.org> Mon, 12 Jun 2023 16:00:00 +0000
+
+i2pd (2.47.0-1) unstable; urgency=high
+
+ * updated to version 2.47.0/0.9.58
+
+ -- orignal <orignal@i2pmail.org> Sat, 11 Mar 2023 16:00:00 +0000
+
+i2pd (2.46.1-2) unstable; urgency=critical
+
+ * re-pushed release due to new critical bug
+
+ -- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 23:40:00 +0000
+
+i2pd (2.46.1-1) unstable; urgency=high
+
+ * updated to version 2.46.1/0.9.57
+
+ -- r4sas <r4sas@i2pmail.org> Mon, 20 Feb 2023 02:45:00 +0000
+
+i2pd (2.46.0-1) unstable; urgency=high
+
+ * updated to version 2.46.0/0.9.57
+
+ -- orignal <orignal@i2pmail.org> Wed, 15 Feb 2023 19:00:00 +0000
+
i2pd (2.45.1-1) unstable; urgency=medium
* updated to version 2.45.1/0.9.57
--- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
+ -- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
i2pd (2.45.0-1) unstable; urgency=high
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/debian/rules
^
|
@@ -8,6 +8,6 @@
export DEB_LDFLAGS_MAINT_APPEND =
%:
- dh $@ --parallel
+ dh $@
override_dh_auto_install:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Afrikaans.cpp
^
|
@@ -64,10 +64,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"dag", "dae"}},
- {"hours", {"uur", "ure"}},
- {"minutes", {"minuut", "minute"}},
- {"seconds", {"seconde", "sekondes"}},
+ {"%d days", {"%d dag", "%d dae"}},
+ {"%d hours", {"%d uur", "%d ure"}},
+ {"%d minutes", {"%d minuut", "%d minute"}},
+ {"%d seconds", {"%d seconde", "%d sekondes"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Armenian.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "ԿիԲ"},
- {"MiB", "ՄիԲ"},
- {"GiB", "ԳիԲ"},
+ {"%.2f KiB", "%.2f ԿիԲ"},
+ {"%.2f MiB", "%.2f ՄիԲ"},
+ {"%.2f GiB", "%.2f ԳիԲ"},
{"building", "կառուցվում է"},
{"failed", "Անհաջող"},
{"expiring", "Լրանում է"},
{"established", "կարգավոյված է"},
{"unknown", "անհայտ"},
{"exploratory", "հետազոտոկան"},
+ {"Purple I2P Webconsole", "Վեբ-կոնսոլ Purple I2P"},
{"<b>i2pd</b> webconsole", "Վեբ-կոնսոլ <b>i2pd</b>"},
{"Main page", "Գլխավոր էջ"},
{"Router commands", "Երթուղիչի հրահանգներ"},
@@ -57,10 +58,10 @@
{"Unknown", "Անհայտ"},
{"Proxy", "Պրոկսի"},
{"Mesh", "MESH-ցանց"},
- {"Error", "Սխալ"},
{"Clock skew", "Ոչ ճշգրիտ ժամանակ"},
{"Offline", "Օֆլայն"},
{"Symmetric NAT", "Սիմետրիկ NAT"},
+ {"Full cone NAT", "Full cone NAT"},
{"Uptime", "Առկայություն"},
{"Network status", "Ցանցի կարգավիճակ"},
{"Network status v6", "Ցանցի կարգավիճակ v6"},
@@ -68,7 +69,7 @@
{"Family", "Խմբատեսակ"},
{"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"},
{"Received", "Ստացվել է"},
- {"KiB/s", "ԿիԲ/վ"},
+ {"%.2f KiB/s", "%.2f ԿիԲ/վ"},
{"Sent", "Ուղարկվել է"},
{"Transit", "Տարանցում"},
{"Data path", "Տվյալների ուղին"},
@@ -89,12 +90,12 @@
{"Address registration line", "Հասցեի գրանցման տող"},
{"Domain", "Տիրույթ"},
{"Generate", "Գեներացնել"},
- {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը"},
+ {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Նշում. </b> արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը:"},
{"Address", "Հասցե"},
{"Type", "Տեսակը"},
{"EncType", "Գաղտնագրի տեսակը"},
{"Inbound tunnels", "Մուտքային թունելներ"},
- {"ms", "մլվ"},
+ {"%dms", "%dմլվ"},
{"Outbound tunnels", "Ելքային թունելներ"},
{"Tags", "Թեգեր"},
{"Incoming", "Մուտքային"},
@@ -112,11 +113,10 @@
{"Invalid", "Անվավեր"},
{"Store type", "Պահեստավորման տեսակը"},
{"Expires", "Սպառվում է"},
- {"Non Expired Leases", "Չսպառված Lease-եր"},
+ {"Non Expired Leases", "Չսպառված Lease-եր"},
{"Gateway", "Դարպաս"},
{"TunnelID", "Թունելի ID"},
{"EndDate", "Ավարտ"},
- {"not floodfill", "ոչ floodfill-ներ"},
{"Queue size", "Հերթի չափսը"},
{"Run peer test", "Գործարկել փորձարկումը"},
{"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"},
@@ -146,10 +146,7 @@
{"Destination not found", "Հասցեի վայրը չի գտնվել"},
{"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"},
{"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"},
- {"You will be redirected in 5 seconds", "Դուք կտեղափոխվեք 5 վայրկյանից"},
- {"Transit tunnels count must not exceed 65535", "Տարանցիկ թունելների քանակը չպետք է գերազանցի 65535-ը"},
{"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"},
- {"Register at reg.i2p", "Գրանցել reg.i2p-ում"},
{"Description", "Նկարագրություն"},
{"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"},
{"Submit", "Ուղարկվել"},
@@ -165,43 +162,35 @@
{"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"},
{"Invalid request", "Սխալ հարցում"},
{"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"},
- {"addresshelper is not supported", "addresshelper-ը համատեղելի չէ"},
- {"Host", "Հոսթ"},
- {"added to router's addressbook from helper", "Ավելացված է երթուղիչի հասցեագրքում helper-ի միջոցով"},
- {"Click here to proceed:", "Շարունակելու համար սեղմեք այստեղ"},
- {"Continue", "Շարունակել"},
- {"Addresshelper found", "addresshelper-ը գնտված է"},
- {"already in router's addressbook", "արդեն առկա է երթուղիչի հասցեագրքում"},
- {"Click here to update record:", "Սեղմեկ այստեղ որպեսզի թարվացնեք գրառումը"},
- {"invalid request uri", "Սխալ ձևավորված URI հարցում"},
+ {"Invalid request URI", "Սխալ ձևավորված URI հարցում"},
{"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"},
{"Outproxy failure", "Սխալ արտաքին պրոքսի"},
- {"bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
- {"not inside I2P network, but outproxy is not enabled", "Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
- {"unknown outproxy url", "արտաքին պրոքսիի անհայտ URL"},
- {"cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
- {"hostname too long", "Հոսթի անունը չափազանց երկար է"},
- {"cannot connect to upstream socks proxy", "չհաջողվեց միանալ վերադաս socks պրոկսիին"},
- {"Cannot negotiate with socks proxy", "Չհաջողվեց պայմանավորվել վերադաս socks պրոկսիի հետ"},
+ {"Bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Հոսթ %s Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"},
+ {"Unknown outproxy URL", "Արտաքին պրոքսիի անհայտ URL"},
+ {"Cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"},
+ {"Hostname is too long", "Հոսթի անունը չափազանց երկար է"},
+ {"Cannot connect to upstream SOCKS proxy", "Չհաջողվեց միանալ վերադաս SOCKS պրոկսի սերվերին"},
+ {"Cannot negotiate with SOCKS proxy", "Չհաջողվեց պայմանավորվել վերադաս SOCKS պրոկսիի հետ"},
{"CONNECT error", "Սխալ CONNECT հարցում"},
- {"Failed to Connect", "Միանալ չhաջողվեց"},
- {"socks proxy error", "Սխալ SOCKS պրոկսի"},
- {"failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
- {"No Reply From socks proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
- {"cannot connect", "Հնարավոր չե միանալ"},
- {"http out proxy not implemented", "Արտաքին http պրոկսին դեռ իրականացված չէ"},
- {"cannot connect to upstream http proxy", "Չհաջողվեց միանալ վերադաս http պրոկսի սերվերին"},
+ {"Failed to connect", "Միանալ չhաջողվեց"},
+ {"SOCKS proxy error", "Սխալ SOCKS պրոկսի"},
+ {"Failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"},
+ {"No reply from SOCKS proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"},
+ {"Cannot connect", "Հնարավոր չե միանալ"},
+ {"HTTP out proxy not implemented", "Արտաքին HTTP պրոկսին դեռ իրականացված չէ"},
+ {"Cannot connect to upstream HTTP proxy", "Չհաջողվեց միանալ վերադաս HTTP պրոկսի սերվերին"},
{"Host is down", "Հոսթն անհասանելի է"},
- {"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"},
+ {"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ:"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"օր", "օր"}},
- {"hours", {"ժամ", "ժամ"}},
- {"minutes", {"րոպե", "րոպե"}},
- {"seconds", {"վարկյան", "վարկյան"}},
+ {"%d days", {"%d օր", "%d օր"}},
+ {"%d hours", {"%d ժամ", "%d ժամ"}},
+ {"%d minutes", {"%d րոպե", "%d րոպե"}},
+ {"%d seconds", {"%d վարկյան", "%d վարկյան"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Chinese.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -13,7 +13,6 @@
#include "I18N.h"
// Simplified Chinese localization file
-// This is an example translation file without strings in it.
namespace i2p
{
@@ -32,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "正在构建"},
{"failed", "连接失败"},
{"expiring", "即将过期"},
@@ -46,7 +45,7 @@
{"Main page", "主页"},
{"Router commands", "路由命令"},
{"Local Destinations", "本地目标"},
- {"LeaseSets", "租契集"},
+ {"LeaseSets", "租约集"},
{"Tunnels", "隧道"},
{"Transit Tunnels", "中转隧道"},
{"Transports", "传输"},
@@ -58,11 +57,12 @@
{"Firewalled", "受到防火墙限制"},
{"Unknown", "未知"},
{"Proxy", "代理"},
- {"Mesh", "Mesh组网"},
- {"Error", "错误"},
+ {"Mesh", "自组网"},
{"Clock skew", "时钟偏移"},
{"Offline", "离线"},
{"Symmetric NAT", "对称 NAT"},
+ {"Full cone NAT", "全锥型NAT"},
+ {"No Descriptors", "无描述符"},
{"Uptime", "运行时间"},
{"Network status", "IPv4 网络状态"},
{"Network status v6", "IPv6 网络状态"},
@@ -70,7 +70,7 @@
{"Family", "家族"},
{"Tunnel creation success rate", "隧道创建成功率"},
{"Received", "已接收"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "已发送"},
{"Transit", "中转"},
{"Data path", "数据文件路径"},
@@ -91,12 +91,12 @@
{"Address registration line", "地址域名注册"},
{"Domain", "域名"},
{"Generate", "生成"},
- {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>注意:</b> 结果字符串只能用于注册次级域名(例如:example.i2p)。若需注册子域名,请使用 i2pd-tools。"},
+ {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>注意:</b> 结果字符串只能用于注册二级域名(例如:example.i2p)。若需注册三级域名,请使用 i2pd-tools。"},
{"Address", "地址"},
{"Type", "类型"},
{"EncType", "加密类型"},
{"Inbound tunnels", "入站隧道"},
- {"ms", "毫秒"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "出站隧道"},
{"Tags", "标签"},
{"Incoming", "传入"},
@@ -109,6 +109,7 @@
{"Local Destination", "本地目标"},
{"Streams", "流"},
{"Close stream", "断开流"},
+ {"Such destination is not found", "找不到此目标"},
{"I2CP session not found", "未找到 I2CP 会话"},
{"I2CP is not enabled", "I2CP 未启用"},
{"Invalid", "无效"},
@@ -118,9 +119,10 @@
{"Gateway", "网关"},
{"TunnelID", "隧道 ID"},
{"EndDate", "结束日期"},
- {"not floodfill", "非洪泛"},
+ {"floodfill mode is disabled", "洪泛已禁用"},
{"Queue size", "队列大小"},
{"Run peer test", "运行节点测试"},
+ {"Reload tunnels configuration", "重新载入隧道配置"},
{"Decline transit tunnels", "拒绝中转隧道"},
{"Accept transit tunnels", "允许中转隧道"},
{"Cancel graceful shutdown", "取消平滑关闭"},
@@ -128,7 +130,7 @@
{"Force shutdown", "强制停止"},
{"Reload external CSS styles", "重载外部 CSS 样式"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>注意:</b> 此处完成的任何操作都不是永久的,不会更改您的配置文件。"},
- {"Logging level", "日志记录级别"},
+ {"Logging level", "日志级别"},
{"Transit tunnels limit", "中转隧道限制"},
{"Change", "修改"},
{"Change language", "更改语言"},
@@ -148,8 +150,8 @@
{"Destination not found", "找不到目标"},
{"StreamID can't be null", "StreamID 不能为空"},
{"Return to destination page", "返回目标页面"},
- {"You will be redirected in 5 seconds", "您将在5秒内被重定向"},
- {"Transit tunnels count must not exceed 65535", "中转隧道数量不能超过 65535"},
+ {"You will be redirected in %d seconds", "您将在%d秒内被重定向"},
+ {"Transit tunnels count must not exceed %d", "中转隧道数量限制为 %d"},
{"Back to commands list", "返回命令列表"},
{"Register at reg.i2p", "在 reg.i2p 注册域名"},
{"Description", "描述"},
@@ -157,42 +159,42 @@
{"Submit", "提交"},
{"Domain can't end with .b32.i2p", "域名不能以 .b32.i2p 结尾"},
{"Domain must end with .i2p", "域名必须以 .i2p 结尾"},
- {"Such destination is not found", "找不到此目标"},
{"Unknown command", "未知指令"},
{"Command accepted", "已接受指令"},
{"Proxy error", "代理错误"},
{"Proxy info", "代理信息"},
{"Proxy error: Host not found", "代理错误:未找到主机"},
{"Remote host not found in router's addressbook", "在路由地址簿中未找到远程主机"},
- {"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到该主机"},
+ {"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到此主机"},
{"Invalid request", "无效请求"},
{"Proxy unable to parse your request", "代理无法解析您的请求"},
- {"addresshelper is not supported", "不支持地址助手"},
- {"Host", "主机"},
- {"added to router's addressbook from helper", "将此地址从地址助手添加到路由地址簿"},
- {"Click here to proceed:", "点击此处继续:"},
- {"Continue", "继续"},
- {"Addresshelper found", "已找到地址助手"},
- {"already in router's addressbook", "已在路由地址簿中"},
- {"Click here to update record:", "点击此处更新地址簿记录"},
- {"invalid request uri", "无效的 URL 请求"},
+ {"Addresshelper is not supported", "不支持地址助手"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。<b>请注意:此地址的来源可能是有害的!</b>点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
+ {"Addresshelper forced update rejected", "地址助手强制更新被拒绝"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "若要在路由器地址簿中添加主机 <b>%s</b> 请点击这里: <a href=\"%s%s%s\">继续</a>"},
+ {"Addresshelper request", "请求地址助手"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "主机 %s 已通过地址助手添加到路由地址簿中。点击此处继续:<a href=\"%s\">继续</a>"},
+ {"Addresshelper adding", "正在添加地址助手"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "主机 %s <font color=red>已在路由地址簿中</font>。点击此处更新记录:<a href=\"%s%s%s&update=true\">继续</a>"},
+ {"Addresshelper update", "更新地址助手"},
+ {"Invalid request URI", "无效的 URI 请求"},
{"Can't detect destination host from request", "无法从请求中检测到目标主机"},
{"Outproxy failure", "出口代理故障"},
- {"bad outproxy settings", "错误的出口代理设置"},
- {"not inside I2P network, but outproxy is not enabled", "该地址不在 I2P 网络内,但未启用出口代理"},
- {"unknown outproxy url", "未知的出口代理地址"},
- {"cannot resolve upstream proxy", "无法解析上游代理"},
- {"hostname too long", "主机名过长"},
- {"cannot connect to upstream socks proxy", "无法连接到上游 socks 代理"},
- {"Cannot negotiate with socks proxy", "无法与 socks 代理协商"},
+ {"Bad outproxy settings", "错误的出口代理设置"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "主机 %s 不在 I2P 网络内,但出口代理未启用"},
+ {"Unknown outproxy URL", "未知的出口代理地址"},
+ {"Cannot resolve upstream proxy", "无法解析上游代理"},
+ {"Hostname is too long", "主机名过长"},
+ {"Cannot connect to upstream SOCKS proxy", "无法连接到上游 SOCKS 代理"},
+ {"Cannot negotiate with SOCKS proxy", "无法与 SOCKS 代理协商"},
{"CONNECT error", "连接错误"},
- {"Failed to Connect", "连接失败"},
- {"socks proxy error", "socks 代理错误"},
- {"failed to send request to upstream", "向上游发送请求失败"},
- {"No Reply From socks proxy", "没有来自 socks 代理的回复"},
- {"cannot connect", "无法连接"},
- {"http out proxy not implemented", "http 出口代理未实现"},
- {"cannot connect to upstream http proxy", "无法连接到上游 http 代理"},
+ {"Failed to connect", "连接失败"},
+ {"SOCKS proxy error", "SOCKS 代理错误"},
+ {"Failed to send request to upstream", "向上游发送请求失败"},
+ {"No reply from SOCKS proxy", "没有来自 SOCKS 代理的回复"},
+ {"Cannot connect", "无法连接"},
+ {"HTTP out proxy not implemented", "HTTP 出口代理未实现"},
+ {"Cannot connect to upstream HTTP proxy", "无法连接到上游 HTTP 代理"},
{"Host is down", "主机已关闭"},
{"Can't create connection to requested host, it may be down. Please try again later.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"},
{"", ""},
@@ -200,10 +202,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"日"}},
- {"hours", {"时"}},
- {"minutes", {"分"}},
- {"seconds", {"秒"}},
+ {"%d days", {"%d 天"}},
+ {"%d hours", {"%d 小时"}},
+ {"%d minutes", {"%d 分钟"}},
+ {"%d seconds", {"%d 秒"}},
{"", {""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Czech.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "vytváří se"},
{"failed", "selhalo"},
{"expiring", "končící"},
@@ -58,7 +58,6 @@
{"Unknown", "Neznámý"},
{"Proxy", "Proxy"},
{"Mesh", "Síť"},
- {"Error", "Chyba"},
{"Clock skew", "Časová nesrovnalost"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symetrický NAT"},
@@ -69,7 +68,7 @@
{"Family", "Rodina"},
{"Tunnel creation success rate", "Úspěšnost vytváření tunelů"},
{"Received", "Přijato"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Odesláno"},
{"Transit", "Tranzit"},
{"Data path", "Cesta k data souborům"},
@@ -95,7 +94,7 @@
{"Type", "Typ"},
{"EncType", "EncType"},
{"Inbound tunnels", "Příchozí tunely"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Odchozí tunely"},
{"Tags", "Štítky"},
{"Incoming", "Příchozí"},
@@ -117,7 +116,6 @@
{"Gateway", "Brána"},
{"TunnelID", "ID tunelu"},
{"EndDate", "Datum ukončení"},
- {"not floodfill", "není floodfill"},
{"Queue size", "Velikost fronty"},
{"Run peer test", "Spustit peer test"},
{"Decline transit tunnels", "Odmítnout tranzitní tunely"},
@@ -147,8 +145,6 @@
{"Destination not found", "Destinace nenalezena"},
{"StreamID can't be null", "StreamID nemůže být null"},
{"Return to destination page", "Zpět na stránku destinací"},
- {"You will be redirected in 5 seconds", "Budete přesměrováni za 5 vteřin"},
- {"Transit tunnels count must not exceed 65535", "Počet tranzitních tunelů nesmí přesáhnout 65535"},
{"Back to commands list", "Zpět na list příkazů"},
{"Register at reg.i2p", "Zaregistrovat na reg.i2p"},
{"Description", "Popis"},
@@ -166,32 +162,24 @@
{"You may try to find this host on jump services below", "Můžete se pokusit najít tohoto hostitele na startovacích službách níže"},
{"Invalid request", "Neplatný požadavek"},
{"Proxy unable to parse your request", "Proxy server nemohl zpracovat váš požadavek"},
- {"addresshelper is not supported", "Adresshelper není podporován"},
- {"Host", "Hostitel"},
- {"added to router's addressbook from helper", "přidáno do adresáře routeru od pomocníka"},
- {"Click here to proceed:", "Pro pokračování, klikněte zde:"},
- {"Continue", "Pokračovat"},
- {"Addresshelper found", "Adresář nalezen"},
- {"already in router's addressbook", "je již v adresáři routeru"},
- {"Click here to update record:", "Pro aktualizaci záznamu, klikněte zde:"},
- {"invalid request uri", "neplatný URI požadavek"},
+ {"Invalid request URI", "Neplatný URI požadavek"},
{"Can't detect destination host from request", "Nelze zjistit cílového hostitele z požadavku"},
{"Outproxy failure", "Outproxy selhání"},
- {"bad outproxy settings", "špatné outproxy nastavení"},
- {"not inside I2P network, but outproxy is not enabled", "není uvnitř I2P sítě a outproxy není nastavena"},
- {"unknown outproxy url", "neznámá outproxy URL"},
- {"cannot resolve upstream proxy", "nelze rozluštit upstream proxy server"},
- {"hostname too long", "Název hostitele je příliš dlouhý"},
- {"cannot connect to upstream socks proxy", "nelze se připojit k upstream socks proxy serveru"},
- {"Cannot negotiate with socks proxy", "Nelze vyjednávat se socks proxy serverem"},
+ {"Bad outproxy settings", "Špatné outproxy nastavení"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Hostitel %s není uvnitř I2P sítě a outproxy není nastavena"},
+ {"Unknown outproxy URL", "Neznámá outproxy URL"},
+ {"Cannot resolve upstream proxy", "Nelze rozluštit upstream proxy server"},
+ {"Hostname is too long", "Název hostitele je příliš dlouhý"},
+ {"Cannot connect to upstream SOCKS proxy", "Nelze se připojit k upstream SOCKS proxy serveru"},
+ {"Cannot negotiate with SOCKS proxy", "Nelze vyjednávat se SOCKS proxy serverem"},
{"CONNECT error", "Chyba PŘIPOJENÍ"},
- {"Failed to Connect", "Připojení se nezdařilo"},
- {"socks proxy error", "chyba socks proxy serveru"},
- {"failed to send request to upstream", "odeslání žádosti upstream serveru se nezdařilo"},
- {"No Reply From socks proxy", "Žádná odpověď od socks proxy serveru"},
- {"cannot connect", "nelze se připojit"},
- {"http out proxy not implemented", "http out proxy není implementován"},
- {"cannot connect to upstream http proxy", "nelze se připojit k upstream socks proxy serveru"},
+ {"Failed to connect", "Připojení se nezdařilo"},
+ {"SOCKS proxy error", "Chyba SOCKS proxy serveru"},
+ {"Failed to send request to upstream", "Odeslání žádosti upstream serveru se nezdařilo"},
+ {"No reply from SOCKS proxy", "Žádná odpověď od SOCKS proxy serveru"},
+ {"Cannot connect", "Nelze se připojit"},
+ {"HTTP out proxy not implemented", "HTTP out proxy není implementován"},
+ {"Cannot connect to upstream HTTP proxy", "Nelze se připojit k upstream HTTP proxy serveru"},
{"Host is down", "Hostitel je nedostupný"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Připojení k požadovanému hostiteli nelze vytvořit, může být nedostupný. Zkuste to, prosím, znovu později."},
{"", ""},
@@ -199,10 +187,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"den", "dny", "dní", "dní"}},
- {"hours", {"hodina", "hodiny", "hodin", "hodin"}},
- {"minutes", {"minuta", "minuty", "minut", "minut"}},
- {"seconds", {"vteřina", "vteřiny", "vteřin", "vteřin"}},
+ {"%d days", {"%d den", "%d dny", "%d dní", "%d dní"}},
+ {"%d hours", {"%d hodina", "%d hodiny", "%d hodin", "%d hodin"}},
+ {"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}},
+ {"%d seconds", {"%d vteřina", "%d vteřiny", "%d vteřin", "%d vteřin"}},
{"", {"", "", "", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/French.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "Kio"},
- {"MiB", "Mio"},
- {"GiB", "Gio"},
+ {"%.2f KiB", "%.2f Kio"},
+ {"%.2f MiB", "%.2f Mio"},
+ {"%.2f GiB", "%.2f Gio"},
{"building", "En construction"},
{"failed", "échoué"},
{"expiring", "expiré"},
@@ -58,18 +58,20 @@
{"Unknown", "Inconnu"},
{"Proxy", "Proxy"},
{"Mesh", "Maillé"},
- {"Error", "Erreur"},
{"Clock skew", "Horloge décalée"},
{"Offline", "Hors ligne"},
{"Symmetric NAT", "NAT symétrique"},
+ {"Full cone NAT", "NAT à cône complet"},
+ {"No Descriptors", "Aucuns Descripteurs"},
{"Uptime", "Temps de fonctionnement"},
{"Network status", "État du réseau"},
{"Network status v6", "État du réseau v6"},
{"Stopping in", "Arrêt dans"},
{"Family", "Famille"},
{"Tunnel creation success rate", "Taux de succès de création de tunnels"},
+ {"Total tunnel creation success rate", "Taux de réussite de création de tunnel"},
{"Received", "Reçu"},
- {"KiB/s", "kio/s"},
+ {"%.2f KiB/s", "%.2f Kio/s"},
{"Sent", "Envoyé"},
{"Transit", "Transité"},
{"Data path", "Emplacement des données"},
@@ -81,6 +83,7 @@
{"Our external address", "Notre adresse externe"},
{"supported", "supporté"},
{"Routers", "Routeurs"},
+ {"Floodfills", "Remplisseurs"},
{"Client Tunnels", "Tunnels clients"},
{"Services", "Services"},
{"Enabled", "Activé"},
@@ -89,11 +92,13 @@
{"Address registration line", "Ligne d'inscription de l'adresse"},
{"Domain", "Domaine"},
{"Generate", "Générer"},
- {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note:</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
+ {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note :</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
{"Address", "Adresse"},
{"Type", "Type"},
+ {"EncType", "EncType"},
+ {"Expire LeaseSet", "Expiration du LeaseSet"},
{"Inbound tunnels", "Tunnels entrants"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Tunnels sortants"},
{"Tags", "Balises"},
{"Incoming", "Entrant"},
@@ -106,6 +111,7 @@
{"Local Destination", "Destination locale"},
{"Streams", "Flux"},
{"Close stream", "Fermer le flux"},
+ {"Such destination is not found", "Cette destination est introuvable"},
{"I2CP session not found", "Session I2CP introuvable"},
{"I2CP is not enabled", "I2CP est désactivé"},
{"Invalid", "Invalide"},
@@ -115,15 +121,17 @@
{"Gateway", "Passerelle"},
{"TunnelID", "ID du tunnel"},
{"EndDate", "Date de fin"},
+ {"floodfill mode is disabled", "le mode de remplissage est désactivé"},
{"Queue size", "Longueur de la file"},
{"Run peer test", "Lancer test des pairs"},
+ {"Reload tunnels configuration", "Recharger la configuration des tunnels"},
{"Decline transit tunnels", "Refuser les tunnels transitoires"},
{"Accept transit tunnels", "Accepter les tunnels transitoires"},
{"Cancel graceful shutdown", "Annuler l'arrêt gracieux"},
{"Start graceful shutdown", "Démarrer l'arrêt gracieux"},
{"Force shutdown", "Forcer l'arrêt"},
{"Reload external CSS styles", "Rafraîchir les styles CSS externes"},
- {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Note:</b> Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."},
+ {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Note :</b> Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."},
{"Logging level", "Niveau de journalisation"},
{"Transit tunnels limit", "Limite sur les tunnels transitoires"},
{"Change", "Changer"},
@@ -134,6 +142,8 @@
{"SAM session not found", "session SAM introuvable"},
{"SAM Session", "Session SAM"},
{"Server Tunnels", "Tunnels serveurs"},
+ {"Client Forwards", "Transmission du client"},
+ {"Server Forwards", "Transmission du serveur"},
{"Unknown page", "Page inconnue"},
{"Invalid token", "Jeton invalide"},
{"SUCCESS", "SUCCÈS"},
@@ -142,8 +152,10 @@
{"Destination not found", "Destination introuvable"},
{"StreamID can't be null", "StreamID ne peut pas être vide"},
{"Return to destination page", "Retourner à la page de destination"},
- {"You will be redirected in 5 seconds", "Vous allez être redirigé dans cinq secondes"},
- {"Transit tunnels count must not exceed 65535", "Le nombre de tunnels transitoires ne doit pas dépasser 65535"},
+ {"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"},
+ {"LeaseSet expiration time updated", "Temps d'expiration du LeaseSet mis à jour"},
+ {"LeaseSet is not found or already expired", "Le LeaseSet est introuvable ou a déjà expirée"},
+ {"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"},
{"Back to commands list", "Retour à la liste des commandes"},
{"Register at reg.i2p", "Inscription à reg.i2p"},
{"Description", "Description"},
@@ -151,42 +163,42 @@
{"Submit", "Soumettre"},
{"Domain can't end with .b32.i2p", "Le domaine ne peut pas terminer par .b32.i2p"},
{"Domain must end with .i2p", "Le domaine doit terminer par .i2p"},
- {"Such destination is not found", "Cette destination est introuvable"},
{"Unknown command", "Commande inconnue"},
{"Command accepted", "Commande acceptée"},
{"Proxy error", "Erreur de proxy"},
{"Proxy info", "Information sur le proxy"},
- {"Proxy error: Host not found", "Erreur de proxy: Hôte introuvable"},
+ {"Proxy error: Host not found", "Erreur de proxy : Hôte introuvable"},
{"Remote host not found in router's addressbook", "Hôte distant introuvable dans le carnet d'adresse du routeur"},
{"You may try to find this host on jump services below", "Vous pouvez essayer de trouver cet hôte sur des services de redirection ci-dessous"},
{"Invalid request", "Requête invalide"},
{"Proxy unable to parse your request", "Proxy incapable de comprendre votre requête"},
- {"addresshelper is not supported", "Assistant d'adresse non supporté"},
- {"Host", "Hôte"},
- {"added to router's addressbook from helper", "Ajouté au carnet d'adresse du routeur par l'assistant"},
- {"Click here to proceed:", "Cliquez ici pour continuer:"},
- {"Continue", "Continuer"},
- {"Addresshelper found", "Assistant d'adresse trouvé"},
- {"already in router's addressbook", "déjà dans le carnet d'adresses du routeur"},
- {"Click here to update record:", "Cliquez ici pour mettre à jour le carnet d'adresse:"},
- {"invalid request uri", "uri de la requête invalide"},
+ {"Addresshelper is not supported", "Assistant d'adresse non supporté"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. <b>Attention : la source de cette URL peut être nuisible !</b> Cliquez ici pour mettre à jour l'enregistrement : <a href=\"%s%s%s&update=true\">Continuer</a>."},
+ {"Addresshelper forced update rejected", "Mise à jour forcée des assistants d'adresses rejetée"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Pour ajouter l'hôte <b>%s</b> au carnet d'adresses du routeur, cliquez ici : <a href=\"%s%s%s\">Continuer</a>."},
+ {"Addresshelper request", "Demande à l'assistant d'adresse"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "L'hôte %s a été ajouté au carnet d'adresses du routeur depuis l'assistant. Cliquez ici pour continuer : <a href=\"%s\">Continuer</a>."},
+ {"Addresshelper adding", "Ajout de l'assistant d'adresse"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "L'hôte %s est <font color=red>déjà dans le carnet d'adresses du routeur</font>. Cliquez ici pour mettre à jour le dossier : <a href=\"%s%s%s&update=true\">Continuer</a>."},
+ {"Addresshelper update", "Mise à jour de l'assistant d'adresse"},
+ {"Invalid request URI", "URI de la requête invalide"},
{"Can't detect destination host from request", "Impossible de détecter l'hôte de destination à partir de la requête"},
{"Outproxy failure", "Échec de proxy de sortie"},
- {"bad outproxy settings", "Mauvaise configuration du proxy de sortie"},
- {"not inside I2P network, but outproxy is not enabled", "pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"},
- {"unknown outproxy url", "URL du proxy de sortie inconnu"},
- {"cannot resolve upstream proxy", "impossible de résoudre l'adresse du proxy en amont"},
- {"hostname too long", "nom d'hôte trop long"},
- {"cannot connect to upstream socks proxy", "impossible de se connecter au proxy socks en amont"},
- {"Cannot negotiate with socks proxy", "Impossible de négocier avec le proxy socks"},
+ {"Bad outproxy settings", "Mauvaise configuration du proxy de sortie"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Hôte %s pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"},
+ {"Unknown outproxy URL", "URL du proxy de sortie inconnu"},
+ {"Cannot resolve upstream proxy", "Impossible de résoudre l'adresse du proxy en amont"},
+ {"Hostname is too long", "Nom d'hôte trop long"},
+ {"Cannot connect to upstream SOCKS proxy", "Impossible de se connecter au proxy SOCKS en amont"},
+ {"Cannot negotiate with SOCKS proxy", "Impossible de négocier avec le proxy SOCKS"},
{"CONNECT error", "Erreur de connexion"},
- {"Failed to Connect", "Échec de connexion"},
- {"socks proxy error", "Erreur de proxy socks"},
- {"failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"},
- {"No Reply From socks proxy", "Pas de réponse du proxy socks"},
- {"cannot connect", "impossible de connecter"},
- {"http out proxy not implemented", "Proxy de sortie HTTP non implémenté"},
- {"cannot connect to upstream http proxy", "impossible de se connecter au proxy HTTP en amont"},
+ {"Failed to connect", "Échec de connexion"},
+ {"SOCKS proxy error", "Erreur de proxy SOCKS"},
+ {"Failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"},
+ {"No reply from SOCKS proxy", "Pas de réponse du proxy SOCKS"},
+ {"Cannot connect", "Impossible de connecter"},
+ {"HTTP out proxy not implemented", "Proxy de sortie HTTP non implémenté"},
+ {"Cannot connect to upstream HTTP proxy", "Impossible de se connecter au proxy HTTP en amont"},
{"Host is down", "Hôte hors service"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossible d'établir une connexion avec l'hôte, il est peut-être hors service. Veuillez réessayer plus tard."},
{"", ""},
@@ -194,10 +206,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"jour", "jours"}},
- {"hours", {"heure", "heures"}},
- {"minutes", {"minute", "minutes"}},
- {"seconds", {"seconde", "secondes"}},
+ {"%d days", {"%d jour", "%d jours"}},
+ {"%d hours", {"%d heure", "%d heures"}},
+ {"%d minutes", {"%d minute", "%d minutes"}},
+ {"%d seconds", {"%d seconde", "%d secondes"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/German.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "In Bau"},
{"failed", "fehlgeschlagen"},
{"expiring", "läuft ab"},
@@ -58,10 +58,10 @@
{"Unknown", "Unbekannt"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
- {"Error", "Fehler"},
{"Clock skew", "Zeitabweichung"},
{"Offline", "Offline"},
{"Symmetric NAT", "Symmetrisches NAT"},
+ {"No Descriptors", "Keine Beschreibungen"},
{"Uptime", "Laufzeit"},
{"Network status", "Netzwerkstatus"},
{"Network status v6", "Netzwerkstatus v6"},
@@ -69,7 +69,7 @@
{"Family", "Familie"},
{"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"},
{"Received", "Eingegangen"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Gesendet"},
{"Transit", "Transit"},
{"Data path", "Datenpfad"},
@@ -95,7 +95,7 @@
{"Type", "Typ"},
{"EncType", "Verschlüsselungstyp"},
{"Inbound tunnels", "Eingehende Tunnel"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Ausgehende Tunnel"},
{"Tags", "Tags"},
{"Incoming", "Eingehend"},
@@ -117,9 +117,10 @@
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Enddatum"},
- {"not floodfill", "kein Floodfill"},
+ {"floodfill mode is disabled", "Floodfill Modus ist deaktiviert"},
{"Queue size", "Größe der Warteschlange"},
{"Run peer test", "Peer-Test durchführen"},
+ {"Reload tunnels configuration", "Tunnel Konfiguration neu laden"},
{"Decline transit tunnels", "Transittunnel ablehnen"},
{"Accept transit tunnels", "Transittunnel akzeptieren"},
{"Cancel graceful shutdown", "Beende das kontrollierte Herunterfahren"},
@@ -147,8 +148,8 @@
{"Destination not found", "Ziel nicht gefunden"},
{"StreamID can't be null", "StreamID kann nicht null sein"},
{"Return to destination page", "Zurück zur Ziel-Seite"},
- {"You will be redirected in 5 seconds", "Du wirst in 5 Sekunden weitergeleitet"},
- {"Transit tunnels count must not exceed 65535", "Es darf maximal 65535 Transittunnel geben"},
+ {"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"},
{"Register at reg.i2p", "Auf reg.i2p registrieren"},
{"Description", "Beschreibung"},
@@ -166,32 +167,33 @@
{"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"},
{"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht verarbeiten"},
- {"addresshelper is not supported", "Addresshelfer wird nicht unterstützt"},
- {"Host", "Host"},
- {"added to router's addressbook from helper", "vom Helfer zum Router-Adressbuch hinzugefügt"},
- {"Click here to proceed:", "Klicke hier um fortzufahren:"},
- {"Continue", "Fortsetzen"},
- {"Addresshelper found", "Adresshelfer gefunden"},
- {"already in router's addressbook", "bereits im Adressbuch des Routers"},
- {"Click here to update record:", "Klicke hier, um den Eintrag zu aktualisieren:"},
- {"invalid request uri", "ungültige Anfrage-URI"},
+ {"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"},
{"Can't detect destination host from request", "Kann den Ziel-Host von der Anfrage nicht erkennen"},
{"Outproxy failure", "Outproxy-Fehler"},
- {"bad outproxy settings", "ungültige Outproxy-Einstellungen"},
- {"not inside I2P network, but outproxy is not enabled", "außerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
- {"unknown outproxy url", "unbekannte Outproxy-URL"},
- {"cannot resolve upstream proxy", "kann den Upstream-Proxy nicht auflösen"},
- {"hostname too long", "Hostname zu lang"},
- {"cannot connect to upstream socks proxy", "Kann keine Verbindung zum Upstream-Socks-Proxy herstellen"},
- {"Cannot negotiate with socks proxy", "Kann nicht mit Socks-Proxy verhandeln"},
+ {"Bad outproxy settings", "Ungültige Outproxy-Einstellungen"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s außerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"},
+ {"Unknown outproxy URL", "Unbekannte Outproxy-URL"},
+ {"Cannot resolve upstream proxy", "Kann den Upstream-Proxy nicht auflösen"},
+ {"Hostname is too long", "Hostname zu lang"},
+ {"Cannot connect to upstream SOCKS proxy", "Kann keine Verbindung zum Upstream-SOCKS-Proxy herstellen"},
+ {"Cannot negotiate with SOCKS proxy", "Kann nicht mit SOCKS-Proxy verhandeln"},
{"CONNECT error", "CONNECT-Fehler"},
- {"Failed to Connect", "Verbindung konnte nicht hergestellt werden"},
- {"socks proxy error", "Socks-Proxy-Fehler"},
- {"failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
- {"No Reply From socks proxy", "Keine Antwort vom Socks-Proxy"},
- {"cannot connect", "kann nicht verbinden"},
- {"http out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
- {"cannot connect to upstream http proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
+ {"Failed to connect", "Verbindung konnte nicht hergestellt werden"},
+ {"SOCKS proxy error", "SOCKS-Proxy-Fehler"},
+ {"Failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"},
+ {"No reply from SOCKS proxy", "Keine Antwort vom SOCKS-Proxy"},
+ {"Cannot connect", "Kann nicht verbinden"},
+ {"HTTP out proxy not implemented", "HTTP-Outproxy nicht implementiert"},
+ {"Cannot connect to upstream HTTP proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"},
{"Host is down", "Host ist offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbauen, vielleicht ist er offline. Versuche es später noch mal."},
{"", ""},
@@ -199,10 +201,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"Tag", "Tage"}},
- {"hours", {"Stunde", "Stunden"}},
- {"minutes", {"Minute", "Minuten"}},
- {"seconds", {"Sekunde", "Sekunden"}},
+ {"%d days", {"%d Tag", "%d Tage"}},
+ {"%d hours", {"%d Stunde", "%d Stunden"}},
+ {"%d minutes", {"%d Minute", "%d Minuten"}},
+ {"%d seconds", {"%d Sekunde", "%d Sekunden"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/I18N.cpp
^
|
@@ -1,11 +1,12 @@
/*
-* Copyright (c) 2021-2022, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
+#include <clocale>
#include "ClientContext.h"
#include "I18N_langs.h"
#include "I18N.h"
@@ -18,9 +19,15 @@
{
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
+ {
i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale());
+ setlocale(LC_NUMERIC, "english");
+ }
else
+ {
i2p::client::context.SetLanguage (it->second.LocaleFunc());
+ setlocale(LC_NUMERIC, lang.c_str()); // set decimal point based on language
+ }
}
std::string translate (const std::string& arg)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/I18N.h
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021-2022, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -67,17 +67,69 @@
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
-
+
void SetLanguage(const std::string &lang);
std::string translate (const std::string& arg);
std::string translate (const std::string& arg, const std::string& arg2, const int& n);
} // i18n
} // i2p
-template<typename... TArgs>
-std::string tr (TArgs&&... args)
+/**
+ * @brief Get translation of string
+ * @param arg String with message
+ */
+template<typename TValue>
+std::string tr (TValue&& arg)
+{
+ return i2p::i18n::translate(std::forward<TValue>(arg));
+}
+
+/**
+ * @brief Get translation of string and format it
+ * @param arg String with message
+ * @param args Array of arguments for string formatting
+*/
+template<typename TValue, typename... TArgs>
+std::string tr (TValue&& arg, TArgs&&... args)
{
- return i2p::i18n::translate(std::forward<TArgs>(args)...);
+ std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg));
+
+ size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
+ std::string str(size, 0);
+ std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
+
+ return str;
+}
+
+/**
+ * @brief Get translation of string with plural forms
+ * @param arg String with message in singular form
+ * @param arg2 String with message in plural form
+ * @param n Integer, used for selection of form
+ */
+template<typename TValue, typename TValue2>
+std::string ntr (TValue&& arg, TValue2&& arg2, int& n)
+{
+ return i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
+}
+
+/**
+ * @brief Get translation of string with plural forms and format it
+ * @param arg String with message in singular form
+ * @param arg2 String with message in plural form
+ * @param n Integer, used for selection of form
+ * @param args Array of arguments for string formatting
+ */
+template<typename TValue, typename TValue2, typename... TArgs>
+std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args)
+{
+ std::string tr_str = i2p::i18n::translate(std::forward<TValue>(arg), std::forward<TValue2>(arg2), std::forward<int>(n));
+
+ size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward<TArgs>(args)...);
+ std::string str(size, 0);
+ std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward<TArgs>(args)...);
+
+ return str;
}
#endif // __I18N_H__
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/I18N_langs.h
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021-2022, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -23,19 +23,23 @@
};
// Add localization here with language name as namespace
- namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
- namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace chinese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace czech { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace italian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace polish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace portuguese { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace spanish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace swedish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace turkish { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
+ namespace uzbek { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
/**
* That map contains international language name lower-case, name in it's language and it's code
@@ -50,8 +54,12 @@
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
{ "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} },
+ { "polish", {"Polski", "pl", i2p::i18n::polish::GetLocale} },
+ { "portuguese", {"Português", "pt", i2p::i18n::portuguese::GetLocale} },
{ "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} },
{ "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} },
+ { "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} },
+ { "turkish", {"Türk dili", "tr", i2p::i18n::turkish::GetLocale} },
{ "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} },
{ "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} },
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Italian.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "in costruzione"},
{"failed", "fallito"},
{"expiring", "in scadenza"},
@@ -58,10 +58,11 @@
{"Unknown", "Sconosciuto"},
{"Proxy", "Proxy"},
{"Mesh", "Mesh"},
- {"Error", "Errore"},
{"Clock skew", "Orologio disallineato"},
{"Offline", "Disconnesso"},
{"Symmetric NAT", "NAT simmetrico"},
+ {"Full cone NAT", "Cono completo NAT"},
+ {"No Descriptors", "Nessun descrittore"},
{"Uptime", "In funzione da"},
{"Network status", "Stato della rete"},
{"Network status v6", "Stato della rete v6"},
@@ -69,7 +70,7 @@
{"Family", "Famiglia"},
{"Tunnel creation success rate", "Percentuale di tunnel creati con successo"},
{"Received", "Ricevuti"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Inviati"},
{"Transit", "Transitati"},
{"Data path", "Percorso dati"},
@@ -95,7 +96,7 @@
{"Type", "Tipologia"},
{"EncType", "Tipo di crittografia"},
{"Inbound tunnels", "Tunnel in entrata"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Tunnel in uscita"},
{"Tags", "Tag"},
{"Incoming", "In entrata"},
@@ -117,9 +118,10 @@
{"Gateway", "Gateway"},
{"TunnelID", "TunnelID"},
{"EndDate", "Data di fine"},
- {"not floodfill", "no floodfill"},
+ {"floodfill mode is disabled", "la modalità floodfill è disabilitata"},
{"Queue size", "Dimensione della coda"},
{"Run peer test", "Esegui il test dei peer"},
+ {"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"},
{"Decline transit tunnels", "Rifiuta tunnel di transito"},
{"Accept transit tunnels", "Accetta tunnel di transito"},
{"Cancel graceful shutdown", "Annulla l'interruzione controllata"},
@@ -147,8 +149,8 @@
{"Destination not found", "Destinazione non trovata"},
{"StreamID can't be null", "Lo StreamID non può essere null"},
{"Return to destination page", "Ritorna alla pagina di destinazione"},
- {"You will be redirected in 5 seconds", "Verrai reindirizzato in 5 secondi"},
- {"Transit tunnels count must not exceed 65535", "Il numero di tunnel di transito non può superare i 65535"},
+ {"You will be redirected in %d seconds", "Sarai reindirizzato tra %d secondi"},
+ {"Transit tunnels count must not exceed %d", "Il conteggio dei tunnel di transito non deve superare %d"},
{"Back to commands list", "Ritorna alla lista dei comandi"},
{"Register at reg.i2p", "Registra a reg.i2p"},
{"Description", "Descrizione"},
@@ -166,32 +168,33 @@
{"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"},
{"Proxy unable to parse your request", "Il proxy non è in grado di elaborare la tua richiesta"},
- {"addresshelper is not supported", "addresshelper non è supportato"},
- {"Host", "Host"},
- {"added to router's addressbook from helper", "aggiunto alla rubrica tramite l'helper"},
- {"Click here to proceed:", "Clicca qui per procedere:"},
- {"Continue", "Continua"},
- {"Addresshelper found", "Addresshelper trovato"},
- {"already in router's addressbook", "già presente nella rubrica del router"},
- {"Click here to update record:", "Clicca qui per aggiornare l'elemento:"},
- {"invalid request uri", "uri della richiesta non valido"},
+ {"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>."},
+ {"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>."},
+ {"Addresshelper update", "Aggiornamento dell'helper degli indirizzi"},
+ {"Invalid request URI", "URI della richiesta non valido"},
{"Can't detect destination host from request", "Impossibile determinare l'host di destinazione dalla richiesta"},
{"Outproxy failure", "Fallimento del proxy di uscita"},
- {"bad outproxy settings", "impostazioni errate del proxy di uscita"},
- {"not inside I2P network, but outproxy is not enabled", "non all'interno della rete I2P, ma il proxy di uscita non è abilitato"},
- {"unknown outproxy url", "url del proxy di uscita sconosciuto"},
- {"cannot resolve upstream proxy", "impossibile identificare il flusso a monte del proxy"},
- {"hostname too long", "il nome dell'host è troppo lungo"},
- {"cannot connect to upstream socks proxy", "impossibile connettersi al flusso a monte del proxy socks"},
- {"Cannot negotiate with socks proxy", "Impossibile negoziare con il proxy socks"},
+ {"Bad outproxy settings", "Impostazioni errate del proxy di uscita"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s non all'interno della rete I2P, ma il proxy di uscita non è abilitato"},
+ {"Unknown outproxy URL", "URL del proxy di uscita sconosciuto"},
+ {"Cannot resolve upstream proxy", "Impossibile identificare il flusso a monte del proxy"},
+ {"Hostname is too long", "Il nome dell'host è troppo lungo"},
+ {"Cannot connect to upstream SOCKS proxy", "Impossibile connettersi al flusso a monte del proxy SOCKS"},
+ {"Cannot negotiate with SOCKS proxy", "Impossibile negoziare con il proxy SOCKS"},
{"CONNECT error", "Errore di connessione"},
- {"Failed to Connect", "Connessione fallita"},
- {"socks proxy error", "errore del proxy socks"},
- {"failed to send request to upstream", "invio della richiesta a monte non riuscito"},
- {"No Reply From socks proxy", "Nessuna risposta dal proxy socks"},
- {"cannot connect", "impossibile connettersi"},
- {"http out proxy not implemented", "proxy http di uscita non implementato"},
- {"cannot connect to upstream http proxy", "impossibile connettersi al proxy http a monte"},
+ {"Failed to connect", "Connessione fallita"},
+ {"SOCKS proxy error", "Errore del proxy SOCKS"},
+ {"Failed to send request to upstream", "Invio della richiesta a monte non riuscito"},
+ {"No reply from SOCKS proxy", "Nessuna risposta dal proxy SOCKS"},
+ {"Cannot connect", "Impossibile connettersi"},
+ {"HTTP out proxy not implemented", "Proxy HTTP di uscita non implementato"},
+ {"Cannot connect to upstream HTTP proxy", "Impossibile connettersi al flusso a monte del proxy HTTP"},
{"Host is down", "L'host è offline"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Impossibile creare la connessione all'host richiesto, probabilmente è offline. Riprova più tardi."},
{"", ""},
@@ -199,10 +202,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"giorno", "giorni"}},
- {"hours", {"ora", "ore"}},
- {"minutes", {"minuto", "minuti"}},
- {"seconds", {"secondo", "secondi"}},
+ {"%d days", {"%d giorno", "%d giorni"}},
+ {"%d hours", {"%d ora", "%d ore"}},
+ {"%d minutes", {"%d minuto", "%d minuti"}},
+ {"%d seconds", {"%d secondo", "%d secondi"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Polish.cpp
^
|
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*/
+
+#include <map>
+#include <vector>
+#include <string>
+#include <memory>
+#include "I18N.h"
+
+// Polish localization file
+
+namespace i2p
+{
+namespace i18n
+{
+namespace polish // language namespace
+{
+ // language name in lowercase
+ static std::string language = "polish";
+
+ // See for language plural forms here:
+ // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
+ static int plural (int n) {
+ return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
+ }
+
+ static std::map<std::string, std::string> strings
+ {
+ {"building", "Kompilowanie"},
+ {"failed", "nieudane"},
+ {"expiring", "wygasający"},
+ {"established", "ustanowiony"},
+ {"Main page", "Strona główna"},
+ {"Router commands", "Komendy routera"},
+ {"Tunnels", "Tunele"},
+ {"OK", "Ok"},
+ {"Uptime", "Czas pracy"},
+ {"Sent", "Wysłane"},
+ {"", ""},
+ };
+
+ static std::map<std::string, std::vector<std::string>> plurals
+ {
+ {"", {"", "", ""}},
+ };
+
+ std::shared_ptr<const i2p::i18n::Locale> GetLocale()
+ {
+ return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
+ }
+
+} // language
+} // i18n
+} // i2p
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Portuguese.cpp
^
|
@@ -0,0 +1,219 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*/
+
+#include <map>
+#include <vector>
+#include <string>
+#include <memory>
+#include "I18N.h"
+
+// Portuguese localization file
+
+namespace i2p
+{
+namespace i18n
+{
+namespace portuguese // language namespace
+{
+ // language name in lowercase
+ static std::string language = "portuguese";
+
+ // See for language plural forms here:
+ // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
+ static int plural (int n) {
+ return n != 1 ? 1 : 0;
+ }
+
+ static std::map<std::string, std::string> strings
+ {
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
+ {"building", "construindo"},
+ {"failed", "falhou"},
+ {"expiring", "expirando"},
+ {"established", "estabelecido"},
+ {"unknown", "desconhecido"},
+ {"exploratory", "exploratório"},
+ {"Purple I2P Webconsole", "Webconsole Purple I2P"},
+ {"<b>i2pd</b> webconsole", "webconsole <b>i2pd</b>"},
+ {"Main page", "Página Principal"},
+ {"Router commands", "Comandos do Roteador"},
+ {"Local Destinations", "Destinos Locais"},
+ {"LeaseSets", "LeaseSets"},
+ {"Tunnels", "Túneis"},
+ {"Transit Tunnels", "Túneis de Trânsito"},
+ {"Transports", "Transportes"},
+ {"I2P tunnels", "Túneis I2P"},
+ {"SAM sessions", "Sessões do SAM"},
+ {"ERROR", "ERRO"},
+ {"OK", "OK"},
+ {"Testing", "Testando"},
+ {"Firewalled", "Sob Firewall"},
+ {"Unknown", "Desconhecido"},
+ {"Proxy", "Proxy"},
+ {"Mesh", "Malha"},
+ {"Clock skew", "Defasagem do Relógio"},
+ {"Offline", "Desligado"},
+ {"Symmetric NAT", "NAT Simétrico"},
+ {"Full cone NAT", "Full cone NAT"},
+ {"No Descriptors", "Sem Descritores"},
+ {"Uptime", "Tempo Ativo"},
+ {"Network status", "Estado da rede"},
+ {"Network status v6", "Estado da rede v6"},
+ {"Stopping in", "Parando em"},
+ {"Family", "Família"},
+ {"Tunnel creation success rate", "Taxa de sucesso na criação de túneis"},
+ {"Received", "Recebido"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
+ {"Sent", "Enviado"},
+ {"Transit", "Trânsito"},
+ {"Data path", "Diretório dos dados"},
+ {"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."},
+ {"Router Ident", "Identidade do Roteador"},
+ {"Router Family", "Família do Roteador"},
+ {"Router Caps", "Limites do Roteador"},
+ {"Version", "Versão"},
+ {"Our external address", "Nosso endereço externo"},
+ {"supported", "suportado"},
+ {"Routers", "Roteadores"},
+ {"Floodfills", "Modo Inundação"},
+ {"Client Tunnels", "Túneis de Clientes"},
+ {"Services", "Serviços"},
+ {"Enabled", "Ativado"},
+ {"Disabled", "Desativado"},
+ {"Encrypted B33 address", "Endereço B33 criptografado"},
+ {"Address registration line", "Linha de cadastro de endereço"},
+ {"Domain", "Domínio"},
+ {"Generate", "Gerar"},
+ {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b> Nota: </b>A string resultante só pode ser usada para registrar domínios 2LD (exemplo.i2p). Para registrar subdomínios por favor utilize o i2pd-tools."},
+ {"Address", "Endereço"},
+ {"Type", "Tipo"},
+ {"EncType", "Tipo de Criptografia"},
+ {"Inbound tunnels", "Túneis de Entrada"},
+ {"%dms", "%dms"},
+ {"Outbound tunnels", "Túneis de Saída"},
+ {"Tags", "Etiquetas"},
+ {"Incoming", "Entradas"},
+ {"Outgoing", "Saídas"},
+ {"Destination", "Destinos"},
+ {"Amount", "Quantidade"},
+ {"Incoming Tags", "Etiquetas de Entrada"},
+ {"Tags sessions", "Sessões de etiquetas"},
+ {"Status", "Estado"},
+ {"Local Destination", "Destinos Locais"},
+ {"Streams", "Fluxos"},
+ {"Close stream", "Fechar fluxo"},
+ {"I2CP session not found", "Sessão do I2CP não encontrada"},
+ {"I2CP is not enabled", "I2CP não está ativado"},
+ {"Invalid", "Inválido"},
+ {"Store type", "Tipo de armazenamento"},
+ {"Expires", "Expira em"},
+ {"Non Expired Leases", "Sessões não expiradas"},
+ {"Gateway", "Gateway"},
+ {"TunnelID", "TunnelID"},
+ {"EndDate", "Data final"},
+ {"floodfill mode is disabled", "Mode de inundação está desativado"},
+ {"Queue size", "Tamanho da fila"},
+ {"Run peer test", "Executar teste de peers"},
+ {"Reload tunnels configuration", "Recarregar a configuração dos túneis"},
+ {"Decline transit tunnels", "Negar túneis de trânsito"},
+ {"Accept transit tunnels", "Aceitar túneis de trânsito"},
+ {"Cancel graceful shutdown", "Cancelar desligamento gracioso"},
+ {"Start graceful shutdown", "Iniciar desligamento gracioso"},
+ {"Force shutdown", "Forçar desligamento"},
+ {"Reload external CSS styles", "Recarregar estilos CSS externos"},
+ {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b> Nota: </b> Qualquer ação feita aqui não será permanente e não altera os seus arquivos de configuração."},
+ {"Logging level", "Nível de registro"},
+ {"Transit tunnels limit", "Limite de túneis de trânsito"},
+ {"Change", "Mudar"},
+ {"Change language", "Trocar idioma"},
+ {"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"},
+ {"SAM disabled", "SAM desativado"},
+ {"no sessions currently running", "Nenhuma sessão funcionando no momento"},
+ {"SAM session not found", "Nenhuma sessão do SAM encontrada"},
+ {"SAM Session", "Sessão do SAM"},
+ {"Server Tunnels", "Túneis de Servidor"},
+ {"Client Forwards", "Túneis de Cliente"},
+ {"Server Forwards", "Encaminhamentos de Servidor"},
+ {"Unknown page", "Página desconhecida"},
+ {"Invalid token", "Token Inválido"},
+ {"SUCCESS", "SUCESSO"},
+ {"Stream closed", "Fluxo fechado"},
+ {"Stream not found or already was closed", "Fluxo não encontrado ou já encerrado"},
+ {"Destination not found", "Destino não encontrado"},
+ {"StreamID can't be null", "StreamID não pode ser nulo"},
+ {"Return to destination page", "Retornar para à página de destino"},
+ {"You will be redirected in %d seconds", "Você será redirecionado em %d segundos"},
+ {"Transit tunnels count must not exceed %d", "A contagem de túneis de trânsito não deve exceder %d"},
+ {"Back to commands list", "Voltar para a lista de comandos"},
+ {"Register at reg.i2p", "Registrar na reg.i2p"},
+ {"Description", "Descrição"},
+ {"A bit information about service on domain", "Algumas informações sobre o serviço no domínio"},
+ {"Submit", "Enviar"},
+ {"Domain can't end with .b32.i2p", "O domínio não pode terminar com .b32.i2p"},
+ {"Domain must end with .i2p", "O domínio não pode terminar com .i2p"},
+ {"Such destination is not found", "Tal destino não foi encontrado"},
+ {"Unknown command", "Comando desconhecido"},
+ {"Command accepted", "Comando aceito"},
+ {"Proxy error", "Erro no proxy"},
+ {"Proxy info", "Informações do proxy"},
+ {"Proxy error: Host not found", "Erro no proxy: Host não encontrado"},
+ {"Remote host not found in router's addressbook", "O host remoto não foi encontrado no livro de endereços do roteador"},
+ {"You may try to find this host on jump services below", "Você pode tentar encontrar este host nos jump services abaixo"},
+ {"Invalid request", "Requisição inválida"},
+ {"Proxy unable to parse your request", "O proxy foi incapaz de processar a sua requisição"},
+ {"Addresshelper is not supported", "O Auxiliar de Endereços não é suportado"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador</font>. <b>Cuidado: a fonte desta URL pode ser perigosa!</b> Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
+ {"Addresshelper forced update rejected", "A atualização forçada do Auxiliar de Endereços foi rejeitada"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Para adicionar o host <b> %s </b> ao catálogo de endereços do roteador, clique aqui: <a href='%s%s%s'>Continuar </a>."},
+ {"Addresshelper request", "Requisição do Auxiliar de Endereços"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "O host %s foi adicionado ao catálogo de endereços do roteador por um auxiliar. Clique aqui para proceder: <a href='%s'> Continuar </a>."},
+ {"Addresshelper adding", "Auxiliar de Endereço adicionando"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "O host %s já <font color=red>está no catálogo de endereços do roteador </font>. Clique aqui para atualizar o registro: <a href=\"%s%s%s&update=true\">Continuar</a>."},
+ {"Addresshelper update", "Atualização do Auxiliar de Endereços"},
+ {"Invalid request URI", "A URI de requisição é inválida"},
+ {"Can't detect destination host from request", "Incapaz de detectar o host de destino da requisição"},
+ {"Outproxy failure", "Falha no outproxy"},
+ {"Bad outproxy settings", "Configurações ruins de outproxy"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "O host %s não está dentro da rede I2P, mas o outproxy não está ativado"},
+ {"Unknown outproxy URL", "URL de outproxy desconhecida"},
+ {"Cannot resolve upstream proxy", "Não é possível resolver o proxy de entrada"},
+ {"Hostname is too long", "O hostname é muito longo"},
+ {"Cannot connect to upstream SOCKS proxy", "Não é possível se conectar ao proxy SOCKS de entrada"},
+ {"Cannot negotiate with SOCKS proxy", "Não é possível negociar com o proxy SOCKS"},
+ {"CONNECT error", "Erro de CONEXÃO"},
+ {"Failed to connect", "Falha ao conectar"},
+ {"SOCKS proxy error", "Erro no proxy SOCKS"},
+ {"Failed to send request to upstream", "Falha ao enviar requisição para o fluxo de entrada"},
+ {"No reply from SOCKS proxy", "Sem resposta do proxy SOCKS"},
+ {"Cannot connect", "Impossível conectar"},
+ {"HTTP out proxy not implemented", "proxy de saída HTTP não implementado"},
+ {"Cannot connect to upstream HTTP proxy", "Não é possível conectar ao proxy HTTP de entrada"},
+ {"Host is down", "Host está desligado"},
+ {"Can't create connection to requested host, it may be down. Please try again later.", "Não é possível se conectar ao host requisitado, talvez ele esteja for do ar. Por favor, tente novamente mais tarde."},
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Russian.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "КиБ"},
- {"MiB", "МиБ"},
- {"GiB", "ГиБ"},
+ {"%.2f KiB", "%.2f КиБ"},
+ {"%.2f MiB", "%.2f МиБ"},
+ {"%.2f GiB", "%.2f ГиБ"},
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"unknown", "неизвестно"},
{"exploratory", "исследовательский"},
+ {"Purple I2P Webconsole", "Веб-консоль Purple I2P"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
@@ -57,18 +58,20 @@
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
- {"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
+ {"Full cone NAT", "Full cone NAT"},
+ {"No Descriptors", "Нет дескрипторов"},
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
+ {"Total tunnel creation success rate", "Общий процент успешно построенных туннелей"},
{"Received", "Получено"},
- {"KiB/s", "КиБ/с"},
+ {"%.2f KiB/s", "%.2f КиБ/с"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"Data path", "Путь к данным"},
@@ -93,8 +96,9 @@
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
+ {"Expire LeaseSet", "Просрочить Лизсет"},
{"Inbound tunnels", "Входящие туннели"},
- {"ms", "мс"},
+ {"%dms", "%dмс"},
{"Outbound tunnels", "Исходящие туннели"},
{"Tags", "Теги"},
{"Incoming", "Входящие"},
@@ -107,6 +111,7 @@
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
+ {"Such destination is not found", "Такая точка назначения не найдена"},
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
{"Invalid", "Некорректный"},
@@ -116,9 +121,10 @@
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
- {"not floodfill", "не флудфил"},
+ {"floodfill mode is disabled", "режим флудфила отключен"},
{"Queue size", "Размер очереди"},
{"Run peer test", "Запустить тестирование"},
+ {"Reload tunnels configuration", "Перезагрузить конфигурацию туннелей"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
@@ -146,8 +152,10 @@
{"Destination not found", "Точка назначения не найдена"},
{"StreamID can't be null", "StreamID не может быть пустым"},
{"Return to destination page", "Вернуться на страницу точки назначения"},
- {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
- {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
+ {"You will be redirected in %d seconds", "Вы будете переадресованы через %d секунд"},
+ {"LeaseSet expiration time updated", "Время действия LeaseSet обновлено"},
+ {"LeaseSet is not found or already expired", "Лизсет не найден или время действия уже истекло"},
+ {"Transit tunnels count must not exceed %d", "Число транзитных туннелей не должно превышать %d"},
{"Back to commands list", "Вернуться к списку команд"},
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
@@ -155,7 +163,6 @@
{"Submit", "Отправить"},
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
- {"Such destination is not found", "Такая точка назначения не найдена"},
{"Unknown command", "Неизвестная команда"},
{"Command accepted", "Команда принята"},
{"Proxy error", "Ошибка прокси"},
@@ -165,32 +172,33 @@
{"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"},
{"Invalid request", "Некорректный запрос"},
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
- {"addresshelper is not supported", "addresshelper не поддерживается"},
- {"Host", "Узел"},
- {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
- {"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"},
- {"Continue", "Продолжить"},
- {"Addresshelper found", "Найден addresshelper"},
- {"already in router's addressbook", "уже в адресной книге роутера"},
- {"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"},
- {"invalid request uri", "некорректный URI запроса"},
+ {"Addresshelper is not supported", "Addresshelper не поддерживается"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. <b>Будьте осторожны: источник данной ссылки может быть вредоносным!</b> Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
+ {"Addresshelper forced update rejected", "Принудительное обновление через Addresshelper отклонено"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Чтобы добавить узел <b>%s</b> в адресную книгу роутера, нажмите здесь: <a href=\"%s%s%s\">Продолжить</a>."},
+ {"Addresshelper request", "Запрос добавления Addresshelper"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Узел %s добавлен в адресную книгу роутера через хелпер. Нажмите здесь, чтобы продолжить: <a href=\"%s\">Продолжить</a>."},
+ {"Addresshelper adding", "Добавление 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>.", "Узел %s <font color=red>уже в адресной книге роутера</font>. Нажмите здесь, чтобы обновить запись: <a href=\"%s%s%s&update=true\">Продолжить</a>."},
+ {"Addresshelper update", "Обновление записи через Addresshelper"},
+ {"Invalid request URI", "Некорректный URI запроса"},
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
{"Outproxy failure", "Ошибка внешнего прокси"},
- {"bad outproxy settings", "некорректные настройки внешнего прокси"},
- {"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
- {"unknown outproxy url", "неизвестный URL внешнего прокси"},
- {"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"},
- {"hostname too long", "имя хоста слишком длинное"},
- {"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
- {"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
+ {"Bad outproxy settings", "Некорректные настройки внешнего прокси"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Узел %s не в I2P сети, но внешний прокси не включен"},
+ {"Unknown outproxy URL", "Неизвестный URL внешнего прокси"},
+ {"Cannot resolve upstream proxy", "Не удается определить вышестоящий прокси"},
+ {"Hostname is too long", "Имя хоста слишком длинное"},
+ {"Cannot connect to upstream SOCKS proxy", "Не удалось подключиться к вышестоящему SOCKS прокси серверу"},
+ {"Cannot negotiate with SOCKS proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
{"CONNECT error", "Ошибка CONNECT запроса"},
- {"Failed to Connect", "Не удалось подключиться"},
- {"socks proxy error", "ошибка SOCKS прокси"},
- {"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
- {"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
- {"cannot connect", "не удалось подключиться"},
- {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
- {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
+ {"Failed to connect", "Не удалось соединиться"},
+ {"SOCKS proxy error", "Ошибка SOCKS прокси"},
+ {"Failed to send request to upstream", "Не удалось отправить запрос вышестоящему прокси серверу"},
+ {"No reply from SOCKS proxy", "Нет ответа от SOCKS прокси сервера"},
+ {"Cannot connect", "Не удалось подключиться"},
+ {"HTTP out proxy not implemented", "Поддержка внешнего HTTP прокси сервера не реализована"},
+ {"Cannot connect to upstream HTTP proxy", "Не удалось подключиться к вышестоящему HTTP прокси серверу"},
{"Host is down", "Узел недоступен"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
{"", ""},
@@ -198,10 +206,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"день", "дня", "дней"}},
- {"hours", {"час", "часа", "часов"}},
- {"minutes", {"минуту", "минуты", "минут"}},
- {"seconds", {"секунду", "секунды", "секунд"}},
+ {"%d days", {"%d день", "%d дня", "%d дней"}},
+ {"%d hours", {"%d час", "%d часа", "%d часов"}},
+ {"%d minutes", {"%d минуту", "%d минуты", "%d минут"}},
+ {"%d seconds", {"%d секунду", "%d секунды", "%d секунд"}},
{"", {"", "", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Spanish.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,9 +31,9 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "pendiente"},
{"failed", "fallido"},
{"expiring", "expiró"},
@@ -58,7 +58,6 @@
{"Unknown", "Desconocido"},
{"Proxy", "Proxy"},
{"Mesh", "Malla"},
- {"Error", "Error"},
{"Clock skew", "Reloj desfasado"},
{"Offline", "Desconectado"},
{"Symmetric NAT", "NAT simétrico"},
@@ -69,7 +68,7 @@
{"Family", "Familia"},
{"Tunnel creation success rate", "Tasa de éxito de creación de túneles"},
{"Received", "Recibido"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Enviado"},
{"Transit", "Tránsito"},
{"Data path", "Ruta de datos"},
@@ -95,7 +94,7 @@
{"Type", "Tipo"},
{"EncType", "TipoEncrip"},
{"Inbound tunnels", "Túneles entrantes"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Túneles salientes"},
{"Tags", "Etiquetas"},
{"Incoming", "Entrante"},
@@ -117,7 +116,6 @@
{"Gateway", "Puerta de enlace"},
{"TunnelID", "TunnelID"},
{"EndDate", "FechaVenc"},
- {"not floodfill", "no inundado"},
{"Queue size", "Tamaño de cola"},
{"Run peer test", "Ejecutar prueba de par"},
{"Decline transit tunnels", "Rechazar túneles de tránsito"},
@@ -147,8 +145,6 @@
{"Destination not found", "Destino no encontrado"},
{"StreamID can't be null", "StreamID no puede ser nulo"},
{"Return to destination page", "Volver a la página de destino"},
- {"You will be redirected in 5 seconds", "Serás redirigido en 5 segundos"},
- {"Transit tunnels count must not exceed 65535", "La cantidad de túneles de tránsito no puede exceder 65535"},
{"Back to commands list", "Volver a lista de comandos"},
{"Register at reg.i2p", "Registrar en reg.i2p"},
{"Description", "Descripción"},
@@ -166,32 +162,24 @@
{"You may try to find this host on jump services below", "Puede intentar encontrar este dominio en los siguientes servicios de salto"},
{"Invalid request", "Solicitud inválida"},
{"Proxy unable to parse your request", "Proxy no puede procesar su solicitud"},
- {"addresshelper is not supported", "ayudante de dirección no soportado"},
- {"Host", "Dominio"},
- {"added to router's addressbook from helper", "añadido a la libreta de direcciones desde el ayudante"},
- {"Click here to proceed:", "Haga clic aquí para continuar:"},
- {"Continue", "Continuar"},
- {"Addresshelper found", "Se encontró ayudante de dirección"},
- {"already in router's addressbook", "ya se encontró en libreta de direcciones"},
- {"Click here to update record:", "Haga clic aquí para actualizar el registro:"},
- {"invalid request uri", "uri de solicitud inválida"},
+ {"Invalid request URI", "URI de solicitud inválida"},
{"Can't detect destination host from request", "No se puede detectar el host de destino de la solicitud"},
{"Outproxy failure", "Fallo en el proxy saliente"},
- {"bad outproxy settings", "configuración de outproxy incorrecta"},
- {"not inside I2P network, but outproxy is not enabled", "no está dentro de la red I2P, pero el proxy de salida no está activado"},
- {"unknown outproxy url", "url de proxy outproxy desconocido"},
- {"cannot resolve upstream proxy", "no se puede resolver el proxy de upstream"},
- {"hostname too long", "nombre de dominio muy largo"},
- {"cannot connect to upstream socks proxy", "no se puede conectar al proxy socks principal"},
- {"Cannot negotiate with socks proxy", "No se puede negociar con el proxy socks"},
+ {"Bad outproxy settings", "Configuración de outproxy incorrecta"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Dominio %s no está dentro de la red I2P, pero el proxy de salida no está activado"},
+ {"Unknown outproxy URL", "URL de proxy outproxy desconocido"},
+ {"Cannot resolve upstream proxy", "No se puede resolver el proxy de upstream"},
+ {"Hostname is too long", "Nombre de dominio muy largo"},
+ {"Cannot connect to upstream SOCKS proxy", "No se puede conectar al proxy SOCKS principal"},
+ {"Cannot negotiate with SOCKS proxy", "No se puede negociar con el proxy SOCKS"},
{"CONNECT error", "Error de CONNECT"},
- {"Failed to Connect", "Error al Conectar"},
- {"socks proxy error", "error de proxy socks"},
- {"failed to send request to upstream", "no se pudo enviar petición al principal"},
- {"No Reply From socks proxy", "Sin respuesta del proxy socks"},
- {"cannot connect", "no se puede conectar"},
- {"http out proxy not implemented", "proxy externo http no implementado"},
- {"cannot connect to upstream http proxy", "no se puede conectar al proxy http principal"},
+ {"Failed to connect", "Error al conectar"},
+ {"SOCKS proxy error", "Error de proxy SOCKS"},
+ {"Failed to send request to upstream", "No se pudo enviar petición al principal"},
+ {"No reply from SOCKS proxy", "Sin respuesta del proxy SOCKS"},
+ {"Cannot connect", "No se puede conectar"},
+ {"HTTP out proxy not implemented", "Proxy externo HTTP no implementado"},
+ {"Cannot connect to upstream HTTP proxy", "No se puede conectar al proxy HTTP principal"},
{"Host is down", "Servidor caído"},
{"Can't create connection to requested host, it may be down. Please try again later.", "No se puede crear la conexión al servidor solicitado, puede estar caído. Intente de nuevo más tarde."},
{"", ""},
@@ -199,10 +187,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"día", "días"}},
- {"hours", {"hora", "horas"}},
- {"minutes", {"minuto", "minutos"}},
- {"seconds", {"segundo", "segundos"}},
+ {"%d days", {"%d día", "%d días"}},
+ {"%d hours", {"%d hora", "%d horas"}},
+ {"%d minutes", {"%d minuto", "%d minutos"}},
+ {"%d seconds", {"%d segundo", "%d segundos"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Swedish.cpp
^
|
@@ -0,0 +1,220 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*/
+
+#include <map>
+#include <vector>
+#include <string>
+#include <memory>
+#include "I18N.h"
+
+// Swedish localization file
+
+namespace i2p
+{
+namespace i18n
+{
+namespace swedish // language namespace
+{
+ // language name in lowercase
+ static std::string language = "swedish";
+
+ // See for language plural forms here:
+ // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
+ static int plural (int n) {
+ return n != 1 ? 1 : 0;
+ }
+
+ static std::map<std::string, std::string> strings
+ {
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
+ {"building", "bygger"},
+ {"failed", "misslyckad"},
+ {"expiring", "utgår"},
+ {"established", "upprättad"},
+ {"unknown", "okänt"},
+ {"exploratory", "utforskande"},
+ {"Purple I2P Webconsole", "Purple I2P Webbkonsoll"},
+ {"<b>i2pd</b> webconsole", "<b>i2pd</b>-Webbkonsoll"},
+ {"Main page", "Huvudsida"},
+ {"Router commands", "Routerkommandon"},
+ {"Local Destinations", "Lokala Platser"},
+ {"LeaseSets", "Hyresuppsättningar"},
+ {"Tunnels", "Tunnlar"},
+ {"Transit Tunnels", "Förmedlande Tunnlar"},
+ {"Transports", "Transporter"},
+ {"I2P tunnels", "I2P-tunnlar"},
+ {"SAM sessions", "SAM-perioder"},
+ {"ERROR", "FEL"},
+ {"OK", "OK"},
+ {"Testing", "Prövar"},
+ {"Firewalled", "Bakom Brandvägg"},
+ {"Unknown", "Okänt"},
+ {"Proxy", "Proxy"},
+ {"Mesh", "Mesh"},
+ {"Clock skew", "Tidsförskjutning"},
+ {"Offline", "Nedkopplad"},
+ {"Symmetric NAT", "Symmetrisk NAT"},
+ {"Full cone NAT", "Full kon NAT"},
+ {"No Descriptors", "Inga Beskrivningar"},
+ {"Uptime", "Upptid"},
+ {"Network status", "Nätverkstillstånd"},
+ {"Network status v6", "Nätverkstillstånd v6"},
+ {"Stopping in", "Avstängd om"},
+ {"Family", "Familj"},
+ {"Tunnel creation success rate", "Andel framgångsrika tunnlar"},
+ {"Received", "Mottaget"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
+ {"Sent", "Skickat"},
+ {"Transit", "Förmedlat"},
+ {"Data path", "Sökväg"},
+ {"Hidden content. Press on text to see.", "Dolt innehåll. Tryck för att visa."},
+ {"Router Ident", "Routeridentitet"},
+ {"Router Family", "Routerfamilj"},
+ {"Router Caps", "Routerbegränsningar"},
+ {"Version", "Version"},
+ {"Our external address", "Vår externa adress"},
+ {"supported", "stöds"},
+ {"Routers", "Routrar"},
+ {"Floodfills", "Översvämningsfyllare"},
+ {"Client Tunnels", "Klienttunnlar"},
+ {"Services", "Tjänster"},
+ {"Enabled", "Påslaget"},
+ {"Disabled", "Avslaget"},
+ {"Encrypted B33 address", "Krypterad B33-Adress"},
+ {"Address registration line", "Adressregistreringsrad"},
+ {"Domain", "Domän"},
+ {"Generate", "Skapa"},
+ {"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Uppmärksamma:</b> den resulterande strängen kan enbart användas för att registrera 2LD-domäner (exempel.i2p). För att registrera underdomäner, vänligen använd i2pd-tools."},
+ {"Address", "Adress"},
+ {"Type", "Typ"},
+ {"EncType", "EncTyp"},
+ {"Inbound tunnels", "Ingående Tunnlar"},
+ {"%dms", "%dms"},
+ {"Outbound tunnels", "Utgående Tunnlar"},
+ {"Tags", "Taggar"},
+ {"Incoming", "Ingående"},
+ {"Outgoing", "Utgående"},
+ {"Destination", "Plats"},
+ {"Amount", "Mängd"},
+ {"Incoming Tags", "Ingående Taggar"},
+ {"Tags sessions", "Tagg-perioder"},
+ {"Status", "Tillstånd"},
+ {"Local Destination", "Lokal Plats"},
+ {"Streams", "Strömmar"},
+ {"Close stream", "Stäng strömmen"},
+ {"Such destination is not found", "En sådan plats hittas ej"},
+ {"I2CP session not found", "I2CP-period hittades inte"},
+ {"I2CP is not enabled", "I2CP är inte påslaget"},
+ {"Invalid", "Ogiltig"},
+ {"Store type", "Lagringstyp"},
+ {"Expires", "Utgångsdatum"},
+ {"Non Expired Leases", "Ickeutgångna Hyresuppsättningar"},
+ {"Gateway", "Gateway"},
+ {"TunnelID", "TunnelID"},
+ {"EndDate", "EndDate"},
+ {"floodfill mode is disabled", "Floodfill läget är inaktiverat"},
+ {"Queue size", "Köstorlek"},
+ {"Run peer test", "Utför utsiktstest"},
+ {"Reload tunnels configuration", "Ladda om tunnelkonfiguration"},
+ {"Decline transit tunnels", "Avvisa förmedlande tunnlar"},
+ {"Accept transit tunnels", "Tillåt förmedlande tunnlar"},
+ {"Cancel graceful shutdown", "Avbryt välvillig avstängning"},
+ {"Start graceful shutdown", "Påbörja välvillig avstängning"},
+ {"Force shutdown", "Tvingad avstängning"},
+ {"Reload external CSS styles", "Ladda om externa CSS-stilar"},
+ {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Uppmärksamma:</b> inga ändringar här är beständiga eller påverkar dina inställningsfiler."},
+ {"Logging level", "Protokollförningsnivå"},
+ {"Transit tunnels limit", "Begränsa förmedlande tunnlar"},
+ {"Change", "Ändra"},
+ {"Change language", "Ändra språk"},
+ {"no transit tunnels currently built", "inga förmedlande tunnlar har byggts"},
+ {"SAM disabled", "SAM avslaget"},
+ {"no sessions currently running", "inga perioder igång"},
+ {"SAM session not found", "SAM-perioder hittades ej"},
+ {"SAM Session", "SAM-period"},
+ {"Server Tunnels", "Värdtunnlar"},
+ {"Client Forwards", "Klientförpassningar"},
+ {"Server Forwards", "Värdförpassningar"},
+ {"Unknown page", "Okänd sida"},
+ {"Invalid token", "Ogiltig polett"},
+ {"SUCCESS", "FRAMGÅNG"},
+ {"Stream closed", "Ström stängd"},
+ {"Stream not found or already was closed", "Strömmen hittades inte eller var redan avslutad"},
+ {"Destination not found", "Plats hittades ej"},
+ {"StreamID can't be null", "Ström-ID kan inte vara null"},
+ {"Return to destination page", "Återvänd till platssidan"},
+ {"You will be redirected in %d seconds", "Du omdirigeras inom %d sekunder"},
+ {"Transit tunnels count must not exceed %d", "Förmedlande tunnlar får inte överstiga %d"},
+ {"Back to commands list", "Tillbaka till kommandolistan"},
+ {"Register at reg.i2p", "Registrera vid reg.i2p"},
+ {"Description", "Beskrivning"},
+ {"A bit information about service on domain", "Ett stycke information om domänens tjänst"},
+ {"Submit", "Skicka"},
+ {"Domain can't end with .b32.i2p", "Domänen får inte sluta med .b32.i2p"},
+ {"Domain must end with .i2p", "Domänen måste sluta med .i2p"},
+ {"Unknown command", "Okänt kommando"},
+ {"Command accepted", "Kommando accepterades"},
+ {"Proxy error", "Proxyfel"},
+ {"Proxy info", "Proxyinfo"},
+ {"Proxy error: Host not found", "Proxyfel: Värden hittades ej"},
+ {"Remote host not found in router's addressbook", "Främmande värd hittades inte i routerns adressbok"},
+ {"You may try to find this host on jump services below", "Du kan försöka att hitta värden genom hopptjänsterna nedan"},
+ {"Invalid request", "Ogiltig förfrågan"},
+ {"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"},
+ {"Addresshelper is not supported", "Adresshjälparen stöds ej"},
+ {"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>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. <b>Var försiktig: källan till denna URL kan vara skadlig!</b> Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
+ {"Addresshelper forced update rejected", "Tvingad uppdatering av adresshjälparen nekad"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "För att lägga till värd <b>%s</b> i routerns adressbok, klicka här: <a href=\"%s%s%s\">Fortsätt</a>."},
+ {"Addresshelper request", "Adresshjälpare förfrågan"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Värd %s tillagd i routerns adressbok från hjälparen. Klicka här för att fortsätta: <a href=\"%s\">Fortsätt</a>."},
+ {"Addresshelper adding", "Adresshjälpare tilläggning"},
+ {"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>.", "Värd %s är <font color=red>redan i routerns adressbok</font>. Klicka här för att uppdatera registreringen: <a href=\"%s%s%s&update=true\">Fortsätt</a>."},
+ {"Addresshelper update", "Adresshjälpare uppdatering"},
+ {"Invalid request URI", "Ogiltig förfrågnings-URI"},
+ {"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"},
+ {"Outproxy failure", "Utproxyfel"},
+ {"Bad outproxy settings", "Ogiltig utproxyinställning"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Värd %s är inte inom I2P-näverket, men utproxy är inte påslaget"},
+ {"Unknown outproxy URL", "okänt Utproxy-URL"},
+ {"Cannot resolve upstream proxy", "Hittar inte uppströmsproxyt"},
+ {"Hostname is too long", "Värdnamnet är för långt"},
+ {"Cannot connect to upstream SOCKS proxy", "Kan inte ansluta till uppström SOCKS-proxy"},
+ {"Cannot negotiate with SOCKS proxy", "Kan inte förhandla med SOCKSproxyt"},
+ {"CONNECT error", "CONNECT-fel"},
+ {"Failed to connect", "Anslutningen misslyckades"},
+ {"SOCKS proxy error", "SOCKSproxyfel"},
+ {"Failed to send request to upstream", "Förfrågan uppströms kunde ej skickas"},
+ {"No reply from SOCKS proxy", "Fick inget svar från SOCKSproxyt"},
+ {"Cannot connect", "Kan inte ansluta"},
+ {"HTTP out proxy not implemented", "HTTP-Utproxy ej implementerat"},
+ {"Cannot connect to upstream HTTP proxy", "Kan inte ansluta till uppströms HTTP-proxy"},
+ {"Host is down", "Värden är nere"},
+ {"Can't create connection to requested host, it may be down. Please try again later.", "Kan inte ansluta till värden, den kan vara nere. Vänligen försök senare."},
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Turkish.cpp
^
|
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*/
+
+#include <map>
+#include <vector>
+#include <string>
+#include <memory>
+#include "I18N.h"
+
+// Turkish localization file
+
+namespace i2p
+{
+namespace i18n
+{
+namespace turkish // language namespace
+{
+ // language name in lowercase
+ static std::string language = "turkish";
+
+ // See for language plural forms here:
+ // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
+ static int plural (int n) {
+ return n != 1 ? 1 : 0;
+ }
+
+ static std::map<std::string, std::string> strings
+ {
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
+ {"building", "kuruluyor"},
+ {"failed", "başarısız"},
+ {"expiring", "süresi geçiyor"},
+ {"established", "kurulmuş"},
+ {"unknown", "bilinmeyen"},
+ {"Purple I2P Webconsole", "Mor I2P Webkonsolu"},
+ {"<b>i2pd</b> webconsole", "<b>i2pd</b> webkonsolu"},
+ {"Main page", "Ana sayfa"},
+ {"Router commands", "Router komutları"},
+ {"Local Destinations", "Yerel Hedefler"},
+ {"Tunnels", "Tüneller"},
+ {"Transit Tunnels", "Transit Tünelleri"},
+ {"Transports", "Taşıma"},
+ {"I2P tunnels", "I2P tünelleri"},
+ {"SAM sessions", "SAM oturumları"},
+ {"ERROR", "HATA"},
+ {"OK", "TAMAM"},
+ {"Testing", "Test ediliyor"},
+ {"Firewalled", "Güvenlik Duvarı Kısıtlaması"},
+ {"Unknown", "Bilinmeyen"},
+ {"Proxy", "Proxy"},
+ {"Clock skew", "Saat sorunu"},
+ {"Offline", "Çevrimdışı"},
+ {"Symmetric NAT", "Simetrik NAT"},
+ {"Full cone NAT", "Full cone NAT"},
+ {"No Descriptors", "Tanımlayıcı Yok"},
+ {"Uptime", "Bağlantı süresi"},
+ {"Network status", "Ağ durumu"},
+ {"Network status v6", "Ağ durumu v6"},
+ {"Family", "Aile"},
+ {"Tunnel creation success rate", "Tünel oluşturma başarı oranı"},
+ {"Received", "Alındı"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
+ {"Sent", "Gönderildi"},
+ {"Transit", "Transit"},
+ {"Data path", "Veri yolu"},
+ {"Hidden content. Press on text to see.", "Gizlenmiş içerik. Görmek için yazıya tıklayınız."},
+ {"Router Family", "Router Familyası"},
+ {"Decline transit tunnels", "Transit tünellerini reddet"},
+ {"Accept transit tunnels", "Transit tünellerini kabul et"},
+ {"Cancel graceful shutdown", "Düzgün durdurmayı iptal Et"},
+ {"Start graceful shutdown", "Düzgün durdurmayı başlat"},
+ {"Force shutdown", "Durdurmaya zorla"},
+ {"Reload external CSS styles", "Harici CSS stilini yeniden yükle"},
+ {"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Not:</b> burada yapılan ayarların hiçbiri kalıcı değildir ve ayar dosyalarınızı değiştirmez."},
+ {"Logging level", "Kayıt tutma seviyesi"},
+ {"Transit tunnels limit", "Transit tünel limiti"},
+ {"Change", "Değiştir"},
+ {"Change language", "Dil değiştir"},
+ {"no transit tunnels currently built", "kurulmuş bir transit tüneli bulunmamakta"},
+ {"SAM disabled", "SAM devre dışı"},
+ {"no sessions currently running", "hiçbir oturum şu anda çalışmıyor"},
+ {"SAM session not found", "SAM oturumu bulunamadı"},
+ {"SAM Session", "SAM oturumu"},
+ {"Server Tunnels", "Sunucu Tünelleri"},
+ {"Unknown page", "Bilinmeyen sayfa"},
+ {"Invalid token", "Geçersiz token"},
+ {"SUCCESS", "BAŞARILI"},
+ {"", ""},
+ };
+
+ static std::map<std::string, std::vector<std::string>> plurals
+ {
+ {"%d days", {"%d gün", "%d gün"}},
+ {"%d hours", {"%d saat", "%d saat"}},
+ {"%d minutes", {"%d dakika", "%d dakika"}},
+ {"%d seconds", {"%d saniye", "%d saniye"}},
+ {"", {"", ""}},
+ };
+
+ std::shared_ptr<const i2p::i18n::Locale> GetLocale()
+ {
+ return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
+ }
+
+} // language
+} // i18n
+} // i2p
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Turkmen.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021-2022, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "bina"},
{"failed", "şowsuz"},
{"expiring", "möhleti gutarýar"},
{"established", "işleýär"},
{"unknown", "näbelli"},
{"exploratory", "gözleg"},
+ {"Purple I2P Webconsole", "Web konsoly Purple I2P"},
{"<b>i2pd</b> webconsole", "Web konsoly <b>i2pd</b>"},
{"Main page", "Esasy sahypa"},
{"Router commands", "Marşrutizator buýruklary"},
@@ -57,7 +58,6 @@
{"Unknown", "Näbelli"},
{"Proxy", "Proksi"},
{"Mesh", "MESH-tor"},
- {"Error", "Ýalňyşlyk"},
{"Clock skew", "Takyk wagt däl"},
{"Offline", "Awtonom"},
{"Symmetric NAT", "Simmetriklik NAT"},
@@ -68,7 +68,7 @@
{"Family", "Maşgala"},
{"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"},
{"Received", "Alnan"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Ýerleşdirildi"},
{"Transit", "Tranzit"},
{"Data path", "Maglumat ýoly"},
@@ -94,7 +94,7 @@
{"Type", "Görnüş"},
{"EncType", "Şifrlemek görnüşi"},
{"Inbound tunnels", "Gelýän tuneller"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Çykýan tuneller"},
{"Tags", "Bellikler"},
{"Incoming", "Gelýän"},
@@ -116,7 +116,6 @@
{"Gateway", "Derweze"},
{"TunnelID", "Tuneliň ID"},
{"EndDate", "Gutarýar"},
- {"not floodfill", "fludfil däl"},
{"Queue size", "Nobatyň ululygy"},
{"Run peer test", "Synag başlaň"},
{"Decline transit tunnels", "Tranzit tunellerini ret ediň"},
@@ -146,8 +145,6 @@
{"Destination not found", "Niýetlenen ýeri tapylmady"},
{"StreamID can't be null", "StreamID boş bolup bilmez"},
{"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"},
- {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"},
- {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"},
{"Back to commands list", "Topar sanawyna dolan"},
{"Register at reg.i2p", "Reg.i2P-de hasaba duruň"},
{"Description", "Beýany"},
@@ -165,32 +162,24 @@
{"You may try to find this host on jump services below", "Aşakdaky böküş hyzmatlarynda bu öý eýesini tapmaga synanyşyp bilersiňiz"},
{"Invalid request", "Nädogry haýyş"},
{"Proxy unable to parse your request", "Proksi haýyşyňyzy derňäp bilmeýär"},
- {"addresshelper is not supported", "Salgylandyryjy goldanok"},
- {"Host", "Adres"},
- {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"},
- {"Click here to proceed:", "Dowam etmek bu ýerde basyň:"},
- {"Continue", "Dowam et"},
- {"Addresshelper found", "Forgelper tapyldy"},
- {"already in router's addressbook", "marşruteriň adres kitaby"},
- {"Click here to update record:", "Recordazgyny täzelemek üçin bu ýerde basyň:"},
- {"invalid request uri", "nädogry haýyş URI"},
+ {"Invalid request URI", "Nädogry haýyş URI"},
{"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"},
{"Outproxy failure", "Daşarky proksi ýalňyşlyk"},
- {"bad outproxy settings", "daşarky daşarky proksi sazlamalary nädogry"},
- {"not inside I2P network, but outproxy is not enabled", "I2P torunda däl, ýöne daşarky proksi goşulmaýar"},
- {"unknown outproxy url", "näbelli daşarky proksi URL"},
- {"cannot resolve upstream proxy", "has ýokary proksi kesgitläp bilmeýär"},
- {"hostname too long", "hoster eýesi ady gaty uzyn"},
- {"cannot connect to upstream socks proxy", "ýokary jorap SOCKS proksi bilen birigip bolmaýar"},
- {"Cannot negotiate with socks proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"},
+ {"Bad outproxy settings", "Daşarky Daşarky proksi sazlamalary nädogry"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Adres %s I2P torunda däl, ýöne daşarky proksi goşulmaýar"},
+ {"Unknown outproxy URL", "Näbelli daşarky proksi URL"},
+ {"Cannot resolve upstream proxy", "Has ýokary proksi kesgitläp bilmeýär"},
+ {"Hostname is too long", "Hoster eýesi ady gaty uzyn"},
+ {"Cannot connect to upstream SOCKS proxy", "Ýokary jorap SOCKS proksi bilen birigip bolmaýar"},
+ {"Cannot negotiate with SOCKS proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"},
{"CONNECT error", "Bagyr haýyşy säwligi"},
- {"Failed to Connect", "Birikdirip bilmedi"},
- {"socks proxy error", "socks proksi ýalňyşlygy"},
- {"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"},
- {"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"},
- {"cannot connect", "birikdirip bilmedi"},
- {"http out proxy not implemented", "daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"},
- {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"},
+ {"Failed to connect", "Birikdirip bilmedi"},
+ {"SOCKS proxy error", "SOCKS proksi ýalňyşlygy"},
+ {"Failed to send request to upstream", "Öý eýesi proksi üçin haýyş iberip bilmedi"},
+ {"No reply from SOCKS proxy", "Jorap SOCKS proksi serwerinden hiç hili jogap ýok"},
+ {"Cannot connect", "Birikdirip bilmedi"},
+ {"HTTP out proxy not implemented", "Daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"},
+ {"Cannot connect to upstream HTTP proxy", "Ýokary jorap HTTP proksi bilen birigip bolmaýar"},
{"Host is down", "Salgy elýeterli däl"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."},
{"", ""},
@@ -198,10 +187,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"gün", "gün"}},
- {"hours", {"sagat", "sagat"}},
- {"minutes", {"minut", "minut"}},
- {"seconds", {"sekunt", "sekunt"}},
+ {"%d days", {"%d gün", "%d gün"}},
+ {"%d hours", {"%d sagat", "%d sagat"}},
+ {"%d minutes", {"%d minut", "%d minut"}},
+ {"%d seconds", {"%d sekunt", "%d sekunt"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Ukrainian.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "КіБ"},
- {"MiB", "МіБ"},
- {"GiB", "ГіБ"},
+ {"%.2f KiB", "%.2f КіБ"},
+ {"%.2f MiB", "%.2f МіБ"},
+ {"%.2f GiB", "%.2f ГіБ"},
{"building", "будується"},
{"failed", "невдалий"},
{"expiring", "завершується"},
{"established", "працює"},
{"unknown", "невідомо"},
{"exploratory", "дослідницький"},
+ {"Purple I2P Webconsole", "Веб-консоль Purple I2P"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Головна"},
{"Router commands", "Команди маршрутизатора"},
@@ -57,10 +58,11 @@
{"Unknown", "Невідомо"},
{"Proxy", "Проксі"},
{"Mesh", "MESH-мережа"},
- {"Error", "Помилка"},
{"Clock skew", "Неточний час"},
{"Offline", "Офлайн"},
{"Symmetric NAT", "Симетричний NAT"},
+ {"Full cone NAT", "Повний NAT"},
+ {"No Descriptors", "Немає Описів"},
{"Uptime", "У мережі"},
{"Network status", "Мережевий статус"},
{"Network status v6", "Мережевий статус v6"},
@@ -68,7 +70,7 @@
{"Family", "Сімейство"},
{"Tunnel creation success rate", "Успішно побудованих тунелів"},
{"Received", "Отримано"},
- {"KiB/s", "КіБ/с"},
+ {"%.2f KiB/s", "%.2f КіБ/с"},
{"Sent", "Відправлено"},
{"Transit", "Транзит"},
{"Data path", "Шлях до даних"},
@@ -94,7 +96,7 @@
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Inbound tunnels", "Вхідні тунелі"},
- {"ms", "мс"},
+ {"%dms", "%dмс"},
{"Outbound tunnels", "Вихідні тунелі"},
{"Tags", "Теги"},
{"Incoming", "Вхідні"},
@@ -116,9 +118,10 @@
{"Gateway", "Шлюз"},
{"TunnelID", "ID тунеля"},
{"EndDate", "Закінчується"},
- {"not floodfill", "не флудфіл"},
+ {"floodfill mode is disabled", "режим floodfill вимкнено"},
{"Queue size", "Розмір черги"},
{"Run peer test", "Запустити тестування"},
+ {"Reload tunnels configuration", "Перезавантажити налаштування тунелів"},
{"Decline transit tunnels", "Відхиляти транзитні тунелі"},
{"Accept transit tunnels", "Ухвалювати транзитні тунелі"},
{"Cancel graceful shutdown", "Скасувати плавну зупинку"},
@@ -146,8 +149,8 @@
{"Destination not found", "Точка призначення не знайдена"},
{"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"},
{"Return to destination page", "Повернутися на сторінку точки призначення"},
- {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"},
- {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"},
+ {"You will be redirected in %d seconds", "Ви будете переадресовані через %d секунд"},
+ {"Transit tunnels count must not exceed %d", "Кількість транзитних тунелів не повинна перевищувати %d"},
{"Back to commands list", "Повернутися до списку команд"},
{"Register at reg.i2p", "Зареєструвати на reg.i2p"},
{"Description", "Опис"},
@@ -165,32 +168,33 @@
{"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"},
{"Invalid request", "Некоректний запит"},
{"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"},
- {"addresshelper is not supported", "addresshelper не підтримується"},
- {"Host", "Адреса"},
- {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"},
- {"Click here to proceed:", "Натисніть тут щоб продовжити:"},
- {"Continue", "Продовжити"},
- {"Addresshelper found", "Знайдено addresshelper"},
- {"already in router's addressbook", "вже в адресній книзі маршрутизатора"},
- {"Click here to update record:", "Натисніть тут щоб оновити запис:"},
- {"invalid request uri", "некоректний URI запиту"},
+ {"Addresshelper is not supported", "Адресна книга не підтримується"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Хост %s <font color=red>вже в адресній книзі маршрутизатора</font>. <b>Будьте обережні: джерело цієї адреси може зашкодити!</b> Натисніть тут, щоб оновити запис: <a href=\"%s%s%s&update=true\">Продовжити</a>."},
+ {"Addresshelper forced update rejected", "Адресна книга відхилила примусове оновлення"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Щоб додати хост <b>%s</b> в адресі маршрутизатора, натисніть тут: <a href=\"%s%s%s\">Продовжити</a>."},
+ {"Addresshelper request", "Запит на адресну сторінку"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Хост %s доданий в адресну книгу маршрутизатора від помічника. Натисніть тут, щоб продовжити: <a href=\"%s\">Продовжити</a>."},
+ {"Addresshelper adding", "Адреса додана"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "Хост %s <font color=red>вже в адресній книзі маршрутизатора</font>. Натисніть тут, щоб оновити запис: <a href=\"%s%s%s&update=true\">Продовжити</a>."},
+ {"Addresshelper update", "Оновлення адресної книги"},
+ {"Invalid request URI", "Некоректний URI запиту"},
{"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"},
{"Outproxy failure", "Помилка зовнішнього проксі"},
- {"bad outproxy settings", "некоректні налаштування зовнішнього проксі"},
- {"not inside I2P network, but outproxy is not enabled", "не в I2P мережі, але зовнішній проксі не включений"},
- {"unknown outproxy url", "невідомий URL зовнішнього проксі"},
- {"cannot resolve upstream proxy", "не вдається визначити висхідний проксі"},
- {"hostname too long", "ім'я вузла надто довге"},
- {"cannot connect to upstream socks proxy", "не вдається підключитися до висхідного SOCKS проксі"},
- {"Cannot negotiate with socks proxy", "Не вдається домовитися з висхідним SOCKS проксі"},
+ {"Bad outproxy settings", "Некоректні налаштування зовнішнього проксі"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Адрес %s не в I2P мережі, але зовнішній проксі не включений"},
+ {"Unknown outproxy URL", "Невідомий URL зовнішнього проксі"},
+ {"Cannot resolve upstream proxy", "Не вдається визначити висхідний проксі"},
+ {"Hostname is too long", "Ім'я вузла надто довге"},
+ {"Cannot connect to upstream SOCKS proxy", "Не вдалося підключитися до висхідного SOCKS проксі сервера"},
+ {"Cannot negotiate with SOCKS proxy", "Не вдається домовитися з висхідним SOCKS проксі"},
{"CONNECT error", "Помилка CONNECT запиту"},
- {"Failed to Connect", "Не вдалося підключитися"},
- {"socks proxy error", "помилка SOCKS проксі"},
- {"failed to send request to upstream", "не вдалося відправити запит висхідному проксі"},
- {"No Reply From socks proxy", "Немає відповіді від SOCKS проксі сервера"},
- {"cannot connect", "не вдалося підключитися"},
- {"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"},
- {"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"},
+ {"Failed to connect", "Не вдалося підключитися"},
+ {"SOCKS proxy error", "Помилка SOCKS проксі"},
+ {"Failed to send request to upstream", "Не вдалося відправити запит висхідному проксі"},
+ {"No reply from SOCKS proxy", "Немає відповіді від SOCKS проксі сервера"},
+ {"Cannot connect", "Не вдалося підключитися"},
+ {"HTTP out proxy not implemented", "Підтримка зовнішнього HTTP проксі сервера не реалізована"},
+ {"Cannot connect to upstream HTTP proxy", "Не вдалося підключитися до висхідного HTTP проксі сервера"},
{"Host is down", "Вузол недоступний"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."},
{"", ""},
@@ -198,10 +202,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"день", "дня", "днів"}},
- {"hours", {"годину", "години", "годин"}},
- {"minutes", {"хвилину", "хвилини", "хвилин"}},
- {"seconds", {"секунду", "секунди", "секунд"}},
+ {"%d days", {"%d день", "%d дня", "%d днів"}},
+ {"%d hours", {"%d годину", "%d години", "%d годин"}},
+ {"%d minutes", {"%d хвилину", "%d хвилини", "%d хвилин"}},
+ {"%d seconds", {"%d секунду", "%d секунди", "%d секунд"}},
{"", {"", "", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/i18n/Uzbek.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2021-2022, The PurpleI2P Project
+* Copyright (c) 2021-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -31,15 +31,16 @@
static std::map<std::string, std::string> strings
{
- {"KiB", "KiB"},
- {"MiB", "MiB"},
- {"GiB", "GiB"},
+ {"%.2f KiB", "%.2f KiB"},
+ {"%.2f MiB", "%.2f MiB"},
+ {"%.2f GiB", "%.2f GiB"},
{"building", "yaratilmoqda"},
{"failed", "muvaffaqiyatsiz"},
{"expiring", "muddati tugaydi"},
{"established", "aloqa o'rnatildi"},
{"unknown", "noma'lum"},
{"exploratory", "tadqiqiy"},
+ {"Purple I2P Webconsole", "Veb-konsoli Purple I2P"},
{"<b>i2pd</b> webconsole", "<b>i2pd</b> veb-konsoli"},
{"Main page", "Asosiy sahifa"},
{"Router commands", "Router buyruqlari"},
@@ -57,10 +58,11 @@
{"Unknown", "Notanish"},
{"Proxy", "Proksi"},
{"Mesh", "Mesh To'r"},
- {"Error", "Xato"},
{"Clock skew", "Aniq vaqt emas"},
{"Offline", "Oflayn"},
{"Symmetric NAT", "Simmetrik NAT"},
+ {"Full cone NAT", "Full cone NAT"},
+ {"No Descriptors", "Deskriptorlar yo'q"},
{"Uptime", "Ish vaqti"},
{"Network status", "Tarmoq holati"},
{"Network status v6", "Tarmoq holati v6"},
@@ -68,7 +70,7 @@
{"Family", "Oila"},
{"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"},
{"Received", "Qabul qilindi"},
- {"KiB/s", "KiB/s"},
+ {"%.2f KiB/s", "%.2f KiB/s"},
{"Sent", "Yuborilgan"},
{"Transit", "Tranzit"},
{"Data path", "Ma'lumotlar joylanishi"},
@@ -94,7 +96,7 @@
{"Type", "Turi"},
{"EncType", "ShifrlashTuri"},
{"Inbound tunnels", "Kirish tunnellari"},
- {"ms", "ms"},
+ {"%dms", "%dms"},
{"Outbound tunnels", "Chiquvchi tunnellar"},
{"Tags", "Teglar"},
{"Incoming", "Kiruvchi"},
@@ -116,9 +118,10 @@
{"Gateway", "Kirish yo'li"},
{"TunnelID", "TunnelID"},
{"EndDate", "Tugash Sanasi"},
- {"not floodfill", "floodfill emas"},
+ {"floodfill mode is disabled", "floodfill rejimi o'chirilgan"},
{"Queue size", "Navbat hajmi"},
{"Run peer test", "Sinovni boshlang"},
+ {"Reload tunnels configuration", "Tunnel konfiguratsiyasini qayta yuklash"},
{"Decline transit tunnels", "Tranzit tunnellarini rad etish"},
{"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"},
{"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qilish"},
@@ -146,8 +149,8 @@
{"Destination not found", "Yo'nalish topilmadi"},
{"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"},
{"Return to destination page", "Manzilgoh sahifasiga qaytish"},
- {"You will be redirected in 5 seconds", "Siz 5 soniya ichida qayta yo'naltirilasiz"},
- {"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"},
+ {"You will be redirected in %d seconds", "Siz %d soniyadan so‘ng boshqa yo‘nalishga yo‘naltirilasiz"},
+ {"Transit tunnels count must not exceed %d", "Tranzit tunnellar soni %d dan oshmasligi kerak"},
{"Back to commands list", "Buyruqlar ro'yxatiga qaytish"},
{"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"},
{"Description", "Tavsif"},
@@ -165,32 +168,33 @@
{"You may try to find this host on jump services below", "Siz xost quyida o'tish xizmatlari orqali topishga harakat qilishingiz mumkin"},
{"Invalid request", "Noto‘g‘ri so‘rov"},
{"Proxy unable to parse your request", "Proksi sizning so'rovingizni aniqlab ololmayapti"},
- {"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"},
- {"Host", "Xost"},
- {"added to router's addressbook from helper", "'helper'dan routerning 'addressbook'ga qo'shildi"},
- {"Click here to proceed:", "Davom etish uchun shu yerni bosing:"},
- {"Continue", "Davom etish"},
- {"Addresshelper found", "Addresshelper topildi"},
- {"already in router's addressbook", "allaqachon 'addressbook'da yozilgan"},
- {"Click here to update record:", "Yozuvni yangilash uchun shu yerni bosing:"},
- {"invalid request uri", "noto'g'ri URI so'rovi"},
+ {"Addresshelper is not supported", "Addresshelper qo'llab-quvvatlanmaydi"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. <b>Be careful: source of this URL may be harmful!</b> Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "%s xosti <font color=red>allaqachon routerning manzillar kitobida</font>. <b>Ehtiyot bo'ling: bu URL manbasi zararli bo'lishi mumkin!</b> Yozuvni yangilash uchun bu yerni bosing: <a href=\"%s%s%s&update=true\">Davom etish</a>."},
+ {"Addresshelper forced update rejected", "Addresshelperni majburiy yangilash rad etildi"},
+ {"To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.", "Routerning manzillar kitobiga <b>%s</b> xostini qo'shish uchun bu yerni bosing: <a href=\"%s%s%s\">Davom etish</a>."},
+ {"Addresshelper request", "Addresshelper so'rovi"},
+ {"Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.", "Yordamchidan router manzillar kitobiga %s xost qo‘shildi. Davom etish uchun bu yerga bosing: <a href=\"%s\">Davom etish</a>."},
+ {"Addresshelper adding", "Addresshelperni qo'shish"},
+ {"Host %s is <font color=red>already in router's addressbook</font>. Click here to update record: <a href=\"%s%s%s&update=true\">Continue</a>.", "%s xosti <font color=red>allaqachon routerning manzillar kitobida</font>. Yozuvni yangilash uchun shu yerni bosing: <a href=\"%s%s%s&update=true\">Davom etish</a>."},
+ {"Addresshelper update", "Addresshelperni yangilash"},
+ {"Invalid request URI", "Noto'g'ri URI so'rovi"},
{"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"},
{"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"},
- {"bad outproxy settings", "noto'g'ri tashqi proksi-server sozlamalari"},
- {"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"},
- {"unknown outproxy url", "noma'lum outproxy url"},
- {"cannot resolve upstream proxy", "yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"},
- {"hostname too long", "xost nomi juda uzun"},
- {"cannot connect to upstream socks proxy", "yuqori 'socks proxy'ga ulanib bo'lmayapti"},
- {"Cannot negotiate with socks proxy", "'Socks proxy' bilan muzokara olib bo'lmaydi"},
+ {"Bad outproxy settings", "Noto'g'ri tashqi proksi-server sozlamalari"},
+ {"Host %s is not inside I2P network, but outproxy is not enabled", "Xost %s I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"},
+ {"Unknown outproxy URL", "Noma'lum outproxy URL"},
+ {"Cannot resolve upstream proxy", "Yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"},
+ {"Hostname is too long", "Xost nomi juda uzun"},
+ {"Cannot connect to upstream SOCKS proxy", "Yuqori 'SOCKS proxy'ga ulanib bo'lmayapti"},
+ {"Cannot negotiate with SOCKS proxy", "'SOCKS proxy' bilan muzokara olib bo'lmaydi"},
{"CONNECT error", "CONNECT xatosi"},
- {"Failed to Connect", "Ulanib bo'lmayapti"},
- {"socks proxy error", "'socks proxy' xatosi"},
- {"failed to send request to upstream", "yuqori http proksi-serveriga so'rovni uborib bo'lmadi"},
- {"No Reply From socks proxy", "'Socks proxy'dan javob yo'q"},
- {"cannot connect", "ulanib bo'lmaydi"},
- {"http out proxy not implemented", "tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"},
- {"cannot connect to upstream http proxy", "yuqori http 'proxy-server'iga ulanib bo'lmayapti"},
+ {"Failed to connect", "Ulanib bo'lmayapti"},
+ {"SOCKS proxy error", "'SOCKS proxy' xatosi"},
+ {"Failed to send request to upstream", "Yuqori proksi-serveriga so'rovni uborib bo'lmadi"},
+ {"No reply from SOCKS proxy", "'SOCKS proxy'dan javob yo'q"},
+ {"Cannot connect", "Ulanib bo'lmaydi"},
+ {"HTTP out proxy not implemented", "Tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"},
+ {"Cannot connect to upstream HTTP proxy", "Yuqori 'HTTP proxy'ga ulanib bo'lmayapti"},
{"Host is down", "Xost ishlamayapti"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Talab qilingan xost bilan aloqa o'rnatilmadi, u ishlamay qolishi mumkin. Iltimos keyinroq qayta urinib ko'ring."},
{"", ""},
@@ -198,10 +202,10 @@
static std::map<std::string, std::vector<std::string>> plurals
{
- {"days", {"kun", "kun"}},
- {"hours", {"soat", "soat"}},
- {"minutes", {"daqiqa", "daqiqa"}},
- {"seconds", {"soniya", "soniya"}},
+ {"%d days", {"%d kun", "%d kun"}},
+ {"%d hours", {"%d soat", "%d soat"}},
+ {"%d minutes", {"%d daqiqa", "%d daqiqa"}},
+ {"%d seconds", {"%d soniya", "%d soniya"}},
{"", {"", ""}},
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Config.cpp
^
|
@@ -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
*
@@ -45,7 +45,7 @@
("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)")
("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
- ("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
+ ("host", value<std::string>()->default_value(""), "External IP")
("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
@@ -78,6 +78,7 @@
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
("limits.transittunnels", value<uint16_t>()->default_value(5000), "Maximum active transit tunnels (default:5000)")
+ ("limits.zombies", value<double>()->default_value(0), "Minimum percentage of successfully created tunnels under which tunnel cleanup is paused (default [%]: 0.00)")
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")
@@ -95,6 +96,7 @@
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
("http.lang", value<std::string>()->default_value("english"), "WebUI language (default: english )")
+ ("http.showTotalTCSR", value<bool>()->default_value(false), "Show additional value with total TCSR since router's start (default: false)")
;
options_description httpproxy("HTTP Proxy options");
@@ -148,7 +150,8 @@
sam.add_options()
("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.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")
;
@@ -214,10 +217,11 @@
"https://reseed.onion.im/,"
"https://i2pseed.creativecowpat.net:8443/,"
"https://reseed.i2pgit.org/,"
- "https://i2p.novg.net/,"
"https://banana.incognet.io/,"
"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.yggurls", value<std::string>()->default_value(
"http://[324:71e:281a:9ed3::ace]:7070/,"
@@ -284,7 +288,7 @@
options_description nettime("Time sync options");
nettime.add_options()
- ("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
+ ("nettime.enabled", value<bool>()->default_value(false), "Enable NTP time sync (default: disabled)")
("nettime.ntpservers", value<std::string>()->default_value(
"0.pool.ntp.org,"
"1.pool.ntp.org,"
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Crypto.cpp
^
|
@@ -555,7 +555,7 @@
}
// AES
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
#define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \
@@ -580,7 +580,7 @@
"movaps %%xmm3, "#round1"(%[sched]) \n"
#endif
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
{
__asm__
@@ -621,7 +621,7 @@
#endif
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
#define EncryptAES256(sched) \
"pxor (%["#sched"]), %%xmm0 \n" \
"aesenc 16(%["#sched"]), %%xmm0 \n" \
@@ -642,7 +642,7 @@
void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -660,7 +660,7 @@
}
}
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
#define DecryptAES256(sched) \
"pxor 224(%["#sched"]), %%xmm0 \n" \
"aesdec 208(%["#sched"]), %%xmm0 \n" \
@@ -681,7 +681,7 @@
void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -699,7 +699,7 @@
}
}
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
#define CallAESIMC(offset) \
"movaps "#offset"(%[shed]), %%xmm0 \n" \
"aesimc %%xmm0, %%xmm0 \n" \
@@ -708,7 +708,7 @@
void ECBEncryption::SetKey (const AESKey& key)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
ExpandKey (key);
@@ -722,7 +722,7 @@
void ECBDecryption::SetKey (const AESKey& key)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
ExpandKey (key); // expand encryption key first
@@ -754,7 +754,7 @@
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -799,7 +799,7 @@
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -823,7 +823,7 @@
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -869,7 +869,7 @@
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -893,7 +893,7 @@
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
@@ -934,7 +934,7 @@
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
-#ifdef __AES__
+#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
if(i2p::cpu::aesni)
{
__asm__
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Datagram.cpp
^
|
@@ -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
*
@@ -425,7 +425,7 @@
if (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();
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Destination.cpp
^
|
@@ -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
*
@@ -108,7 +108,7 @@
if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
m_AuthType = authType;
else
- LogPrint (eLogError, "Destination: Unknown auth type ", authType);
+ LogPrint (eLogError, "Destination: Unknown auth type: ", authType);
}
}
it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY);
@@ -117,7 +117,7 @@
m_LeaseSetPrivKey.reset (new i2p::data::Tag<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);
}
}
@@ -262,17 +262,6 @@
return nullptr;
}
}
- else
- {
- auto ls = i2p::data::netdb.FindLeaseSet (ident);
- if (ls && !ls->IsExpired ())
- {
- ls->PopulateLeases (); // since we don't store them in netdb
- std::lock_guard<std::mutex> _lock(m_RemoteLeaseSetsMutex);
- m_RemoteLeaseSets[ident] = ls;
- return ls;
- }
- }
return nullptr;
}
@@ -399,6 +388,11 @@
void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len)
{
+ if (len < DATABASE_STORE_HEADER_SIZE)
+ {
+ LogPrint (eLogError, "Destination: Database store msg is too short ", len);
+ return;
+ }
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
size_t offset = DATABASE_STORE_HEADER_SIZE;
if (replyToken)
@@ -406,6 +400,11 @@
LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore");
offset += 36;
}
+ if (offset > len || len > i2p::data::MAX_LS_BUFFER_SIZE + offset)
+ {
+ LogPrint (eLogError, "Destination: Database store message is too long ", len);
+ return;
+ }
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
switch (buf[DATABASE_STORE_TYPE_OFFSET])
@@ -467,12 +466,15 @@
{
auto ls2 = std::make_shared<i2p::data::LeaseSet2> (buf + offset, len - offset,
it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ());
- if (ls2->IsValid ())
+ if (ls2->IsValid () && !ls2->IsExpired ())
{
+ leaseSet = ls2;
+ std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key
m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup
- leaseSet = ls2;
}
+ else
+ LogPrint (eLogError, "Destination: New remote encrypted LeaseSet2 failed");
}
else
LogPrint (eLogInfo, "Destination: Couldn't find request for encrypted LeaseSet2");
@@ -622,7 +624,7 @@
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
shared_from_this (), std::placeholders::_1));
- outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg);
+ outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, msg);
m_LastSubmissionTime = ts;
}
@@ -763,9 +765,17 @@
request->requestTime = ts;
if (!SendLeaseSetRequest (dest, floodfill, request))
{
- // request failed
- m_LeaseSetRequests.erase (ret.first);
- if (requestComplete) requestComplete (nullptr);
+ // try another
+ LogPrint (eLogWarning, "Destination: Couldn't send LeaseSet request to ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another");
+ request->excluded.insert (floodfill->GetIdentHash ());
+ floodfill = i2p::data::netdb.GetClosestFloodfill (dest, request->excluded);
+ if (!SendLeaseSetRequest (dest, floodfill, request))
+ {
+ // request failed
+ LogPrint (eLogWarning, "Destination: LeaseSet request for ", dest.ToBase32 (), " was not sent");
+ m_LeaseSetRequests.erase (ret.first);
+ if (requestComplete) requestComplete (nullptr);
+ }
}
}
else // duplicate
@@ -792,11 +802,11 @@
std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request)
{
if (!request->replyTunnel || !request->replyTunnel->IsEstablished ())
- request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true));
- if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found");
+ request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); // outbound from floodfill
+ if (!request->replyTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible inbound tunnels found");
if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ())
- request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false));
- if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found");
+ request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); // inbound from floodfill
+ if (!request->outboundTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible outbound tunnels found");
if (request->replyTunnel && request->outboundTunnel)
{
@@ -814,7 +824,7 @@
AddSessionKey (replyKey, replyTag);
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
- request->outboundTunnel->SendTunnelDataMsg (
+ request->outboundTunnel->SendTunnelDataMsgs (
{
i2p::tunnel::TunnelMessageBlock
{
@@ -909,7 +919,7 @@
bool isPublic, const std::map<std::string, std::string> * params):
LeaseSetDestination (service, isPublic, params),
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
- m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS),
+ m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), m_LastPort (0),
m_DatagramDestination (nullptr), m_RefCounter (0),
m_ReadyChecker(service)
{
@@ -979,7 +989,7 @@
m_StreamingAckDelay = std::stoi(it->second);
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
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)
{
@@ -993,12 +1003,12 @@
else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params);
else
- LogPrint (eLogError, "Destination: Unexpected auth type ", authType);
+ LogPrint (eLogError, "Destination: Unexpected auth type: ", authType);
if (m_AuthKeys->size ())
LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read");
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;
}
}
@@ -1007,7 +1017,7 @@
}
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());
}
}
@@ -1026,22 +1036,30 @@
void ClientDestination::Stop ()
{
+ LogPrint(eLogDebug, "Destination: Stopping destination ", GetIdentHash().ToBase32(), ".b32.i2p");
LeaseSetDestination::Stop ();
m_ReadyChecker.cancel();
+ LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination");
m_StreamingDestination->Stop ();
//m_StreamingDestination->SetOwner (nullptr);
m_StreamingDestination = nullptr;
+
+ LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination by ports");
for (auto& it: m_StreamingDestinationsByPorts)
{
it.second->Stop ();
//it.second->SetOwner (nullptr);
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Destination.h
^
|
@@ -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
*
@@ -14,6 +14,7 @@
#include <mutex>
#include <memory>
#include <map>
+#include <unordered_map>
#include <set>
#include <string>
#include <functional>
@@ -184,8 +185,8 @@
boost::asio::io_service& m_Service;
mutable std::mutex m_RemoteLeaseSetsMutex;
- std::map<i2p::data::IdentHash, std::shared_ptr<i2p::data::LeaseSet> > m_RemoteLeaseSets;
- std::map<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> > m_LeaseSetRequests;
+ std::unordered_map<i2p::data::IdentHash, std::shared_ptr<i2p::data::LeaseSet> > m_RemoteLeaseSets;
+ std::unordered_map<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> > m_LeaseSetRequests;
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
std::mutex m_LeaseSetMutex;
@@ -241,15 +242,15 @@
int GetRefCounter () const { return m_RefCounter; };
// streaming
- std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (int port, bool gzip = true); // additional
- std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (int port = 0) const;
- std::shared_ptr<i2p::stream::StreamingDestination> RemoveStreamingDestination (int port);
+ std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (uint16_t port, bool gzip = true); // additional
+ std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (uint16_t port = 0) const;
+ std::shared_ptr<i2p::stream::StreamingDestination> RemoveStreamingDestination (uint16_t port);
// following methods operate with default streaming destination
- void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0);
- void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port = 0);
- std::shared_ptr<i2p::stream::Stream> CreateStream (const i2p::data::IdentHash& dest, int port = 0); // sync
- std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port = 0); // sync
- std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
+ void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, uint16_t port = 0);
+ void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port = 0);
+ std::shared_ptr<i2p::stream::Stream> CreateStream (const i2p::data::IdentHash& dest, uint16_t port = 0); // sync
+ std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, uint16_t port = 0); // sync
+ std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, uint16_t port = 0);
void SendPing (const i2p::data::IdentHash& to);
void SendPing (std::shared_ptr<const i2p::data::BlindedPublicKey> to);
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
@@ -285,7 +286,7 @@
void ReadAuthKey (const std::string& group, const std::map<std::string, std::string> * params);
template<typename Dest>
- std::shared_ptr<i2p::stream::Stream> CreateStreamSync (const Dest& dest, int port);
+ std::shared_ptr<i2p::stream::Stream> CreateStreamSync (const Dest& dest, uint16_t port);
private:
@@ -297,6 +298,7 @@
bool m_IsStreamingAnswerPings;
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
+ std::shared_ptr<i2p::stream::StreamingDestination> m_LastStreamingDestination; uint16_t m_LastPort; // for server tunnels
i2p::datagram::DatagramDestination * m_DatagramDestination;
int m_RefCounter; // how many clients(tunnels) use this destination
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/ECIESX25519AEADRatchetSession.cpp
^
|
@@ -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
*
@@ -335,7 +335,8 @@
case eECIESx25519BlkAckRequest:
{
LogPrint (eLogDebug, "Garlic: Ack request");
- m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index});
+ if (receiveTagset)
+ m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index});
break;
}
case eECIESx25519BlkTermination:
@@ -1149,7 +1150,7 @@
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)
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
size_t offset = 0;
@@ -1175,7 +1176,7 @@
// Noise_N, we are Alice, routerPublicKey is Bob's
i2p::crypto::NoiseSymmetricState noiseState;
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)
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
size_t offset = 0;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Ed25519.cpp
^
|
@@ -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
*
@@ -413,7 +413,7 @@
BIGNUM * y = BN_new ();
BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y);
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
BIGNUM * z = BN_new (), * t = BN_new ();
BN_one (z); BN_mod_mul (t, x, y, q, ctx); // pre-calculate t
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Family.cpp
^
|
@@ -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
*
@@ -88,7 +88,7 @@
}
EVP_PKEY_free (pkey);
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);
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Garlic.cpp
^
|
@@ -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
*
@@ -588,7 +588,7 @@
auto it = m_ECIESx25519Tags.find (tag);
if (it != m_ECIESx25519Tags.end ())
{
- if (it->second.tagset->HandleNextMessage (buf, len, it->second.index))
+ if (it->second.tagset && it->second.tagset->HandleNextMessage (buf, len, it->second.index))
m_LastTagset = it->second.tagset;
else
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message");
@@ -709,7 +709,7 @@
else
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
if (tunnel) // we have sent it through an outbound tunnel
- tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
+ tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, msg);
else
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
}
@@ -1075,7 +1075,7 @@
{
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
if (tunnel)
- tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID));
+ tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID));
else
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Gzip.cpp
^
|
@@ -139,7 +139,7 @@
if (m_IsDirty) deflateReset (&m_Deflator);
m_IsDirty = true;
size_t offset = 0;
- int err;
+ int err = 0;
for (const auto& it: bufs)
{
m_Deflator.next_in = const_cast<uint8_t *>(it.first);
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/HTTP.cpp
^
|
@@ -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
*
@@ -93,15 +93,18 @@
std::size_t pos_c = 0; /* < work position */
if(url.at(0) != '/' || pos_p > 0) {
std::size_t pos_s = 0;
+
/* schema */
pos_c = url.find("://");
if (pos_c != std::string::npos) {
schema = url.substr(0, pos_c);
pos_p = pos_c + 3;
}
+
/* user[:pass] */
pos_s = url.find('/', pos_p); /* find first slash */
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)) {
std::size_t delim = url.find(':', pos_p);
if (delim && delim != std::string::npos && delim < pos_c) {
@@ -113,21 +116,28 @@
}
pos_p = pos_c + 1;
}
+
/* hostname[:port][/path] */
- if (url[pos_p] == '[') // ipv6
+ if (url.at(pos_p) == '[') // ipv6
{
auto pos_b = url.find(']', pos_p);
if (pos_b == std::string::npos) return false;
+ ipv6 = true;
pos_c = url.find_first_of(":/", pos_b);
}
else
pos_c = url.find_first_of(":/", pos_p);
+
if (pos_c == std::string::npos) {
/* 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;
} 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] */
pos_p = pos_c + 1;
pos_c = url.find('/', pos_p);
@@ -147,7 +157,9 @@
pos_p = pos_c;
} else {
/* 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;
}
}
@@ -160,6 +172,7 @@
return true;
} else if (url.at(pos_c) == '?') {
/* found query part */
+ hasquery = true;
path = url.substr(pos_p, pos_c - pos_p);
pos_p = pos_c + 1;
pos_c = url.find('#', pos_p);
@@ -211,15 +224,25 @@
} else if (user != "") {
out += user + "@";
}
- if (port) {
- out += host + ":" + std::to_string(port);
+ if (ipv6) {
+ if (port) {
+ out += "[" + host + "]:" + std::to_string(port);
+ } else {
+ out += "[" + host + "]";
+ }
} else {
- out += host;
+ if (port) {
+ out += host + ":" + std::to_string(port);
+ } else {
+ out += host;
+ }
}
}
out += path;
+ if (hasquery) // add query even if it was empty
+ out += "?";
if (query != "")
- out += "?" + query;
+ out += query;
if (frag != "")
out += "#" + frag;
return out;
@@ -347,6 +370,14 @@
return "";
}
+ size_t HTTPReq::GetNumHeaders (const std::string& name) const
+ {
+ size_t num = 0;
+ for (auto& it : headers)
+ if (it.first == name) num++;
+ return num;
+ }
+
bool HTTPRes::is_chunked() const
{
auto it = headers.find("Transfer-Encoding");
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/HTTP.h
^
|
@@ -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
*
@@ -33,10 +33,12 @@
std::string host;
unsigned short int port;
std::string path;
+ bool hasquery;
std::string query;
std::string frag;
+ bool ipv6;
- URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), query(""), frag("") {};
+ URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag(""), ipv6(false) {};
/**
* @brief Tries to parse url from string
@@ -101,6 +103,8 @@
void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt
void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); };
std::string GetHeader (const std::string& name) const;
+ size_t GetNumHeaders (const std::string& name) const;
+ size_t GetNumHeaders () const { return headers.size (); };
};
struct HTTPRes : HTTPMsg {
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/I2NPProtocol.cpp
^
|
@@ -36,6 +36,11 @@
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)
{
return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint);
@@ -43,7 +48,10 @@
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)
@@ -126,7 +134,8 @@
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
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 ();
memcpy (buf, key, 32); // key
buf += 32;
@@ -147,7 +156,6 @@
if (excludedPeers)
{
- int cnt = excludedPeers->size ();
htobe16buf (buf, cnt);
buf += 2;
for (auto& it: *excludedPeers)
@@ -353,21 +361,6 @@
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)
{
for (int i = 0; i < num; i++)
@@ -379,10 +372,7 @@
if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false;
uint8_t retCode = 0;
// replace record to reply
- if (i2p::context.AcceptsTunnels () &&
- i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels &&
- !i2p::transport::transports.IsBandwidthExceeded () &&
- !i2p::transport::transports.IsTransitBandwidthExceeded ())
+ if (i2p::context.AcceptsTunnels () && !i2p::context.IsHighCongestion ())
{
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
@@ -434,6 +424,11 @@
{
int num = buf[0];
LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records");
+ if (num > i2p::tunnel::MAX_NUM_RECORDS)
+ {
+ LogPrint (eLogError, "I2NP: Too many records in VaribleTunnelBuild message ", num);
+ return;
+ }
if (len < num*TUNNEL_BUILD_RECORD_SIZE + 1)
{
LogPrint (eLogError, "I2NP: VaribleTunnelBuild message of ", num, " records is too short ", len);
@@ -487,6 +482,11 @@
{
int num = buf[0];
LogPrint (eLogDebug, "I2NP: TunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID);
+ if (num > i2p::tunnel::MAX_NUM_RECORDS)
+ {
+ LogPrint (eLogError, "I2NP: Too many records in TunnelBuildReply message ", num);
+ return;
+ }
size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE;
if (len < num*recordSize + 1)
{
@@ -518,6 +518,11 @@
{
int num = buf[0];
LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records");
+ if (num > i2p::tunnel::MAX_NUM_RECORDS)
+ {
+ LogPrint (eLogError, "I2NP: Too many records in ShortTunnelBuild message ", num);
+ return;
+ }
if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1)
{
LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len);
@@ -576,11 +581,8 @@
// check if we accept this tunnel
uint8_t retCode = 0;
- if (!i2p::context.AcceptsTunnels () ||
- i2p::tunnel::tunnels.GetTransitTunnels ().size () > g_MaxNumTransitTunnels ||
- i2p::transport::transports.IsBandwidthExceeded () ||
- i2p::transport::transports.IsTransitBandwidthExceeded ())
- retCode = 30;
+ if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ())
+ retCode = 30;
if (!retCode)
{
// create new transit tunnel
@@ -746,46 +748,38 @@
return l;
}
- void HandleI2NPMessage (uint8_t * msg, size_t len)
+ void HandleTunnelBuildI2NPMessage (std::shared_ptr<I2NPMessage> msg)
{
- if (len < I2NP_HEADER_SIZE)
+ if (msg)
{
- LogPrint (eLogError, "I2NP: Message length ", len, " is smaller than header");
- return;
- }
- uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
- uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
- LogPrint (eLogDebug, "I2NP: Msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
- uint8_t * buf = msg + I2NP_HEADER_SIZE;
- auto size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
- len -= I2NP_HEADER_SIZE;
- if (size > len)
- {
- LogPrint (eLogError, "I2NP: Payload size ", size, " exceeds buffer length ", len);
- size = len;
- }
- switch (typeID)
- {
- case eI2NPVariableTunnelBuild:
- HandleVariableTunnelBuildMsg (msgID, buf, size);
- break;
- case eI2NPShortTunnelBuild:
- HandleShortTunnelBuildMsg (msgID, buf, size);
- break;
- case eI2NPVariableTunnelBuildReply:
- HandleTunnelBuildReplyMsg (msgID, buf, size, false);
- break;
- case eI2NPShortTunnelBuildReply:
- HandleTunnelBuildReplyMsg (msgID, buf, size, true);
- break;
- case eI2NPTunnelBuild:
- HandleTunnelBuildMsg (buf, size);
- break;
- case eI2NPTunnelBuildReply:
- // TODO:
- break;
- default:
- LogPrint (eLogWarning, "I2NP: Unexpected message ", (int)typeID);
+ uint8_t typeID = msg->GetTypeID();
+ uint32_t msgID = msg->GetMsgID();
+ LogPrint (eLogDebug, "I2NP: Handling tunnel build message with len=", msg->GetLength(),", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
+ uint8_t * payload = msg->GetPayload();
+ auto size = msg->GetPayloadLength();
+ switch (typeID)
+ {
+ case eI2NPVariableTunnelBuild:
+ HandleVariableTunnelBuildMsg (msgID, payload, size);
+ break;
+ case eI2NPShortTunnelBuild:
+ HandleShortTunnelBuildMsg (msgID, payload, size);
+ break;
+ case eI2NPVariableTunnelBuildReply:
+ HandleTunnelBuildReplyMsg (msgID, payload, size, false);
+ break;
+ case eI2NPShortTunnelBuildReply:
+ HandleTunnelBuildReplyMsg (msgID, payload, size, true);
+ break;
+ case eI2NPTunnelBuild:
+ HandleTunnelBuildMsg (payload, size);
+ break;
+ case eI2NPTunnelBuildReply:
+ // TODO:
+ break;
+ default:
+ LogPrint (eLogError, "I2NP: Unexpected message with type", (int)typeID, " during handling TBM; skipping");
+ }
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/I2NPProtocol.h
^
|
@@ -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
*
@@ -140,6 +140,7 @@
const size_t I2NP_MAX_MESSAGE_SIZE = 62708;
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_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
@@ -262,6 +263,7 @@
std::shared_ptr<I2NPMessage> NewI2NPMessage ();
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
+ std::shared_ptr<I2NPMessage> NewI2NPMediumMessage ();
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len);
@@ -293,7 +295,7 @@
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg);
size_t GetI2NPMessageLength (const uint8_t * msg, size_t len);
- void HandleI2NPMessage (uint8_t * msg, size_t len);
+ void HandleTunnelBuildI2NPMessage (std::shared_ptr<I2NPMessage> msg);
void HandleI2NPMessage (std::shared_ptr<I2NPMessage> msg);
class I2NPMessagesHandler
@@ -308,10 +310,6 @@
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
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/I2PEndian.h
^
|
@@ -36,6 +36,23 @@
#define le64toh(x) OSSwapLittleToHostInt64(x)
#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 htole16(x) (x)
#define be16toh(x) __builtin_bswap16(x)
@@ -50,6 +67,7 @@
#define htole64(x) (x)
#define be64toh(x) __builtin_bswap64(x)
#define le64toh(x) (x)
+#endif
#else
#define NEEDS_LOCAL_ENDIAN
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Identity.cpp
^
|
@@ -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
*
@@ -187,7 +187,6 @@
IdentityEx::~IdentityEx ()
{
- delete m_Verifier;
}
IdentityEx& IdentityEx::operator=(const IdentityEx& other)
@@ -201,9 +200,8 @@
if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE;
memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen);
}
-
- delete m_Verifier;
m_Verifier = nullptr;
+ CreateVerifier ();
return *this;
}
@@ -212,11 +210,10 @@
{
m_StandardIdentity = standard;
m_IdentHash = m_StandardIdentity.Hash ();
-
m_ExtendedLen = 0;
- delete m_Verifier;
m_Verifier = nullptr;
+ CreateVerifier ();
return *this;
}
@@ -249,8 +246,8 @@
m_ExtendedLen = 0;
SHA256(buf, GetFullLen (), m_IdentHash);
- delete m_Verifier;
m_Verifier = nullptr;
+ CreateVerifier ();
return GetFullLen ();
}
@@ -286,7 +283,6 @@
size_t IdentityEx::GetSigningPublicKeyLen () const
{
- if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetPublicKeyLen ();
return 128;
@@ -301,7 +297,6 @@
size_t IdentityEx::GetSigningPrivateKeyLen () const
{
- if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetPrivateKeyLen ();
return GetSignatureLen ()/2;
@@ -309,14 +304,12 @@
size_t IdentityEx::GetSignatureLen () const
{
- if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetSignatureLen ();
return i2p::crypto::DSA_SIGNATURE_LENGTH;
}
bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
- if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->Verify (buf, len, signature);
return false;
@@ -373,52 +366,29 @@
return nullptr;
}
- void IdentityEx::CreateVerifier () const
+ void IdentityEx::CreateVerifier ()
{
- if (m_Verifier) return; // don't create again
- auto verifier = CreateVerifier (GetSigningKeyType ());
- if (verifier)
+ if (!m_Verifier)
{
- auto keyLen = verifier->GetPublicKeyLen ();
- if (keyLen <= 128)
- verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen);
- else
+ auto verifier = CreateVerifier (GetSigningKeyType ());
+ if (verifier)
{
- // for P521
- 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;
+ auto keyLen = verifier->GetPublicKeyLen ();
+ if (keyLen <= 128)
+ verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen);
+ else
+ {
+ // for P521
+ 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)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Identity.h
^
|
@@ -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
*
@@ -13,9 +13,7 @@
#include <string.h>
#include <string>
#include <memory>
-#include <atomic>
#include <vector>
-#include <mutex>
#include "Base.h"
#include "Signature.h"
#include "CryptoKey.h"
@@ -118,7 +116,6 @@
SigningKeyType GetSigningKeyType () const;
bool IsRSA () const; // signing key type
CryptoKeyType GetCryptoKeyType () const;
- void DropVerifier () const; // to save memory
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
void RecalculateIdentHash(uint8_t * buff=nullptr);
@@ -128,15 +125,13 @@
private:
- void CreateVerifier () const;
- void UpdateVerifier (i2p::crypto::Verifier * verifier) const;
-
+ void CreateVerifier ();
+
private:
Identity m_StandardIdentity;
IdentHash m_IdentHash;
- mutable i2p::crypto::Verifier * m_Verifier = nullptr;
- mutable std::mutex m_VerifierMutex;
+ std::unique_ptr<i2p::crypto::Verifier> m_Verifier;
size_t m_ExtendedLen;
uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE];
};
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/KadDHT.cpp
^
|
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*
+*/
+
+#include "KadDHT.h"
+
+namespace i2p
+{
+namespace data
+{
+ DHTNode::DHTNode ():
+ zero (nullptr), one (nullptr)
+ {
+ }
+
+ DHTNode::~DHTNode ()
+ {
+ if (zero) delete zero;
+ if (one) delete one;
+ }
+
+ void DHTNode::MoveRouterUp (bool fromOne)
+ {
+ DHTNode *& side = fromOne ? one : zero;
+ if (side)
+ {
+ if (router) router = nullptr; // shouldn't happen
+ router = side->router;
+ side->router = nullptr;
+ delete side;
+ side = nullptr;
+ }
+ }
+
+ DHTTable::DHTTable ():
+ m_Size (0)
+ {
+ m_Root = new DHTNode;
+ }
+
+ DHTTable::~DHTTable ()
+ {
+ delete m_Root;
+ }
+
+ void DHTTable::Clear ()
+ {
+ m_Size = 0;
+ delete m_Root;
+ m_Root = new DHTNode;
+ }
+
+ void DHTTable::Insert (const std::shared_ptr<RouterInfo>& r)
+ {
+ if (!r) return;
+ return Insert (r, m_Root, 0);
+ }
+
+ void DHTTable::Insert (const std::shared_ptr<RouterInfo>& r, DHTNode * root, int level)
+ {
+ if (root->router)
+ {
+ if (root->router->GetIdentHash () == r->GetIdentHash ())
+ {
+ root->router = r; // replace
+ return;
+ }
+ auto r2 = root->router;
+ root->router = nullptr; m_Size--;
+ int bit1, bit2;
+ do
+ {
+ bit1 = r->GetIdentHash ().GetBit (level);
+ bit2 = r2->GetIdentHash ().GetBit (level);
+ if (bit1 == bit2)
+ {
+ if (bit1)
+ {
+ if (root->one) return; // something wrong
+ root->one = new DHTNode;
+ root = root->one;
+ }
+ else
+ {
+ if (root->zero) return; // something wrong
+ root->zero = new DHTNode;
+ root = root->zero;
+ }
+ level++;
+ }
+ }
+ while (bit1 == bit2);
+
+ if (!root->zero)
+ root->zero = new DHTNode;
+ if (!root->one)
+ root->one = new DHTNode;
+ if (bit1)
+ {
+ Insert (r2, root->zero, level + 1);
+ Insert (r, root->one, level + 1);
+ }
+ else
+ {
+ Insert (r2, root->one, level + 1);
+ Insert (r, root->zero, level + 1);
+ }
+ }
+ else
+ {
+ if (!root->zero && !root->one)
+ {
+ root->router = r; m_Size++;
+ return;
+ }
+ int bit = r->GetIdentHash ().GetBit (level);
+ if (bit)
+ {
+ if (!root->one)
+ root->one = new DHTNode;
+ Insert (r, root->one, level + 1);
+ }
+ else
+ {
+ if (!root->zero)
+ root->zero = new DHTNode;
+ Insert (r, root->zero, level + 1);
+ }
+ }
+ }
+
+ bool DHTTable::Remove (const IdentHash& h)
+ {
+ return Remove (h, m_Root, 0);
+ }
+
+ bool DHTTable::Remove (const IdentHash& h, DHTNode * root, int level)
+ {
+ if (root)
+ {
+ if (root->router && root->router->GetIdentHash () == h)
+ {
+ root->router = nullptr;
+ m_Size--;
+ return true;
+ }
+ int bit = h.GetBit (level);
+ if (bit)
+ {
+ if (root->one && Remove (h, root->one, level + 1))
+ {
+ if (root->one->IsEmpty ())
+ {
+ delete root->one;
+ root->one = nullptr;
+ if (root->zero && root->zero->router)
+ root->MoveRouterUp (false);
+ }
+ else if (root->one->router && !root->zero)
+ root->MoveRouterUp (true);
+ return true;
+ }
+ }
+ else
+ {
+ if (root->zero && Remove (h, root->zero, level + 1))
+ {
+ if (root->zero->IsEmpty ())
+ {
+ delete root->zero;
+ root->zero = nullptr;
+ if (root->one && root->one->router)
+ root->MoveRouterUp (true);
+ }
+ else if (root->zero->router && !root->one)
+ root->MoveRouterUp (false);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, const Filter& filter) const
+ {
+ if (filter) m_Filter = filter;
+ auto r = FindClosest (h, m_Root, 0);
+ m_Filter = nullptr;
+ return r;
+ }
+
+ std::shared_ptr<RouterInfo> DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) const
+ {
+ bool split = false;
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/KadDHT.h
^
|
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2023, The PurpleI2P Project
+*
+* This file is part of Purple i2pd project and licensed under BSD3
+*
+* See full license text in LICENSE file at top of project tree
+*
+*/
+
+#ifndef KADDHT_H__
+#define KADDHT_H__
+
+#include <memory>
+#include <vector>
+#include <sstream>
+#include <functional>
+#include "RouterInfo.h"
+
+// Kademlia DHT (XOR distance)
+
+namespace i2p
+{
+namespace data
+{
+ struct DHTNode
+ {
+ DHTNode * zero, * one;
+ std::shared_ptr<RouterInfo> router;
+
+ DHTNode ();
+ ~DHTNode ();
+
+ bool IsEmpty () const { return !zero && !one && !router; };
+ void MoveRouterUp (bool fromOne);
+ };
+
+ class DHTTable
+ {
+ typedef std::function<bool (const std::shared_ptr<RouterInfo>&)> Filter;
+ public:
+
+ DHTTable ();
+ ~DHTTable ();
+
+ void Insert (const std::shared_ptr<RouterInfo>& r);
+ bool Remove (const IdentHash& h);
+ 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) const;
+
+ void Print (std::stringstream& s);
+ size_t GetSize () const { return m_Size; };
+ void Clear ();
+ void Cleanup (const Filter& filter);
+
+ private:
+
+ void Insert (const std::shared_ptr<RouterInfo>& r, DHTNode * root, int level); // recursive
+ bool Remove (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) const;
+ void Cleanup (DHTNode * root);
+ void Print (std::stringstream& s, DHTNode * root, int level);
+
+ private:
+
+ DHTNode * m_Root;
+ size_t m_Size;
+ // transient
+ mutable Filter m_Filter;
+ };
+}
+}
+
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/LeaseSet.cpp
^
|
@@ -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
*
@@ -50,7 +50,7 @@
void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature)
{
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 ();
if (size + 256 > m_BufferLen)
{
@@ -76,7 +76,7 @@
LogPrint (eLogDebug, "LeaseSet: Read num=", (int)num);
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;
return;
}
@@ -315,9 +315,9 @@
{
// standard LS2 header
std::shared_ptr<const IdentityEx> identity;
- if (readIdentity)
+ if (readIdentity || !GetIdentity ())
{
- identity = std::make_shared<IdentityEx>(buf, len);
+ identity = netdb.NewIdentity (buf, len);
SetIdentity (identity);
}
else
@@ -366,6 +366,8 @@
VerifySignature (identity, buf, len, offset);
SetIsValid (verified);
}
+ else
+ SetIsValid (true);
offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen ();
if (offset > len) {
LogPrint (eLogWarning, "LeaseSet2: short buffer: wanted ", int(offset), "bytes, have ", int(len));
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/LeaseSet.h
^
|
@@ -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
*
@@ -96,6 +96,9 @@
void Encrypt (const uint8_t * data, uint8_t * encrypted) const;
bool IsDestination () const { return true; };
+ // used in webconsole
+ void ExpireLease () { m_ExpirationTime = i2p::util::GetSecondsSinceEpoch (); };
+
protected:
void UpdateLeasesBegin ();
@@ -145,6 +148,7 @@
{
public:
+ LeaseSet2 (uint8_t storeType): LeaseSet (true), m_StoreType (storeType) {}; // for update
LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL);
LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); // store type 5, called from local netdb only
uint8_t GetStoreType () const { return m_StoreType; };
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Log.cpp
^
|
@@ -20,11 +20,12 @@
*/
static const char *g_LogLevelStr[eNumLogLevels] =
{
- "none", // eLogNone
- "error", // eLogError
- "warn", // eLogWarning
- "info", // eLogInfo
- "debug" // eLogDebug
+ "none", // eLogNone
+ "critical", // eLogCritical
+ "error", // eLogError
+ "warn", // eLogWarning
+ "info", // eLogInfo
+ "debug" // eLogDebug
};
/**
@@ -32,10 +33,11 @@
* @note Using ISO 6429 (ANSI) color sequences
*/
#ifdef _WIN32
- static const char *LogMsgColors[] = { "", "", "", "", "", "" };
+ static const char *LogMsgColors[] = { "", "", "", "", "", "", "" };
#else /* UNIX */
static const char *LogMsgColors[] = {
"\033[1;32m", /* none: green */
+ "\033[1;41m", /* critical: red background */
"\033[1;31m", /* error: red */
"\033[1;33m", /* warning: yellow */
"\033[1;36m", /* info: cyan */
@@ -53,6 +55,7 @@
int priority = LOG_DEBUG;
switch (l) {
case eLogNone : priority = LOG_CRIT; break;
+ case eLogCritical: priority = LOG_CRIT; break;
case eLogError : priority = LOG_ERR; break;
case eLogWarning : priority = LOG_WARNING; break;
case eLogInfo : priority = LOG_INFO; break;
@@ -123,13 +126,14 @@
void Log::SetLogLevel (const std::string& level_) {
std::string level=str_tolower(level_);
- if (level == "none") { m_MinLevel = eLogNone; }
- else if (level == "error") { m_MinLevel = eLogError; }
- else if (level == "warn") { m_MinLevel = eLogWarning; }
- else if (level == "info") { m_MinLevel = eLogInfo; }
- else if (level == "debug") { m_MinLevel = eLogDebug; }
+ if (level == "none") { m_MinLevel = eLogNone; }
+ else if (level == "critical") { m_MinLevel = eLogCritical; }
+ else if (level == "error") { m_MinLevel = eLogError; }
+ else if (level == "warn") { m_MinLevel = eLogWarning; }
+ else if (level == "info") { m_MinLevel = eLogInfo; }
+ else if (level == "debug") { m_MinLevel = eLogDebug; }
else {
- LogPrint(eLogError, "Log: Unknown loglevel: ", level);
+ LogPrint(eLogCritical, "Log: Unknown loglevel: ", level);
return;
}
LogPrint(eLogInfo, "Log: Logging level set to ", level);
@@ -212,7 +216,7 @@
m_LogStream = os;
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) {
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Log.h
^
|
@@ -27,6 +27,7 @@
enum LogLevel
{
eLogNone = 0,
+ eLogCritical,
eLogError,
eLogWarning,
eLogInfo,
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/NTCP2.cpp
^
|
@@ -452,6 +452,7 @@
{
m_Establisher->CreateSessionRequestMessage ();
// 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 (),
std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
@@ -529,6 +530,7 @@
{
m_Establisher->CreateSessionCreatedMessage ();
// 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 (),
std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
@@ -542,6 +544,7 @@
}
else
{
+ m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred);
uint16_t paddingLen = 0;
if (m_Establisher->ProcessSessionCreatedMessage (paddingLen))
@@ -563,7 +566,11 @@
SendSessionConfirmed ();
}
else
+ {
+ if (GetRemoteIdentity ())
+ i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key
Terminate ();
+ }
}
}
@@ -646,6 +653,7 @@
}
else
{
+ m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
LogPrint (eLogDebug, "NTCP2: SessionConfirmed received");
// part 1
uint8_t nonce[12];
@@ -693,10 +701,20 @@
SendTerminationAndTerminate (eNTCP2Message3Error);
return;
}
- auto addr = ri.GetNTCP2AddressWithStaticKey (m_Establisher->m_RemoteStaticKey);
- if (!addr)
+ auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri.GetNTCP2V4Address () :
+ (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri.GetYggdrasilAddress () : ri.GetNTCP2V6Address ());
+ if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32))
+ {
+ LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed");
+ Terminate ();
+ return;
+ }
+ if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host &&
+ (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ?
+ memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet
+ memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address
{
- LogPrint (eLogError, "NTCP2: No NTCP2 address with static key found in SessionConfirmed");
+ LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ());
Terminate ();
return;
}
@@ -874,8 +892,20 @@
switch (blk)
{
case eNTCP2BlkDateTime:
+ {
LogPrint (eLogDebug, "NTCP2: Datetime");
- break;
+ if (m_IsEstablished)
+ {
+ uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
+ uint64_t tsA = bufbe32toh (frame + offset);
+ if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
+ {
+ LogPrint (eLogWarning, "NTCP2: Established session time difference ", (int)(ts - tsA), " exceeds clock skew");
+ SendTerminationAndTerminate (eNTCP2ClockSkew);
+ }
+ }
+ break;
+ }
case eNTCP2BlkOptions:
LogPrint (eLogDebug, "NTCP2: Options");
break;
@@ -1120,12 +1150,17 @@
{
if (!IsEstablished ()) return;
auto riLen = i2p::context.GetRouterInfo ().GetBufferLen ();
- size_t payloadLen = riLen + 4; // 3 bytes block header + 1 byte RI flag
+ size_t payloadLen = riLen + 3 + 1 + 7; // 3 bytes block header + 1 byte RI flag + 7 bytes DateTime
m_NextSendBuffer = new uint8_t[payloadLen + 16 + 2 + 64]; // up to 64 bytes padding
- m_NextSendBuffer[2] = eNTCP2BlkRouterInfo;
- htobe16buf (m_NextSendBuffer + 3, riLen + 1); // size
- m_NextSendBuffer[5] = 0; // flag
- memcpy (m_NextSendBuffer + 6, i2p::context.GetRouterInfo ().GetBuffer (), riLen);
+ // DateTime block
+ m_NextSendBuffer[2] = eNTCP2BlkDateTime;
+ htobe16buf (m_NextSendBuffer + 3, 4);
+ htobe32buf (m_NextSendBuffer + 5, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000);
+ // RouterInfo block
+ m_NextSendBuffer[9] = eNTCP2BlkRouterInfo;
+ htobe16buf (m_NextSendBuffer + 10, riLen + 1); // size
+ m_NextSendBuffer[12] = 0; // flag
+ memcpy (m_NextSendBuffer + 13, i2p::context.GetRouterInfo ().GetBuffer (), riLen);
// padding block
auto paddingSize = CreatePaddingBlock (payloadLen, m_NextSendBuffer + 2 + payloadLen, 64);
payloadLen += paddingSize;
@@ -1211,7 +1246,7 @@
boost::system::error_code e;
auto itr = m_Resolver.resolve(q, e);
if(e)
- LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message());
+ LogPrint(eLogCritical, "NTCP2: Failed to resolve proxy ", e.message());
else
{
m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr));
@@ -1239,7 +1274,7 @@
}
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 ());
continue;
}
@@ -1282,7 +1317,7 @@
}
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 ());
continue;
}
@@ -1430,7 +1465,7 @@
void NTCP2Server::HandleAccept (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error)
{
- if (!error)
+ if (!error && conn)
{
boost::system::error_code ec;
auto ep = conn->GetSocket ().remote_endpoint(ec);
@@ -1439,17 +1474,14 @@
LogPrint (eLogDebug, "NTCP2: Connected from ", ep);
if (!i2p::util::net::IsInReservedRange(ep.address ()))
{
- if (conn)
+ if (m_PendingIncomingSessions.emplace (ep.address (), conn).second)
{
- if (m_PendingIncomingSessions.emplace (ep.address (), conn).second)
- {
- conn->SetRemoteEndpoint (ep);
- conn->ServerLogin ();
- conn = nullptr;
- }
- else
- LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending");
+ conn->SetRemoteEndpoint (ep);
+ conn->ServerLogin ();
+ conn = nullptr;
}
+ else
+ LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending");
}
else
LogPrint (eLogError, "NTCP2: Incoming connection from invalid IP ", ep.address ());
@@ -1480,7 +1512,7 @@
void NTCP2Server::HandleAcceptV6 (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error)
{
- if (!error)
+ if (!error && conn)
{
boost::system::error_code ec;
auto ep = conn->GetSocket ().remote_endpoint(ec);
@@ -1490,17 +1522,14 @@
if (!i2p::util::net::IsInReservedRange(ep.address ()) ||
i2p::util::net::IsYggdrasilAddress (ep.address ()))
{
- if (conn)
+ if (m_PendingIncomingSessions.emplace (ep.address (), conn).second)
{
- if (m_PendingIncomingSessions.emplace (ep.address (), conn).second)
- {
- conn->SetRemoteEndpoint (ep);
- conn->ServerLogin ();
- conn = nullptr;
- }
- else
- LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending");
+ conn->SetRemoteEndpoint (ep);
+ conn->ServerLogin ();
+ conn = nullptr;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/NetDb.cpp
^
|
@@ -36,7 +36,7 @@
{
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 @@
Load ();
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 ();
}
@@ -66,13 +66,13 @@
if (it != m_RouterInfos.end ())
{
// remove own router
- m_Floodfills.remove (it->second);
+ m_Floodfills.Remove (it->second->GetIdentHash ());
m_RouterInfos.erase (it);
}
// insert own router
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ());
if (i2p::context.IsFloodfill ())
- m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ());
+ m_Floodfills.Insert (i2p::context.GetSharedRouterInfo ());
i2p::config::GetOption("persist.profiles", m_PersistProfiles);
@@ -85,11 +85,10 @@
if (m_IsRunning)
{
if (m_PersistProfiles)
- for (auto& it: m_RouterInfos)
- it.second->SaveProfile ();
+ SaveProfiles ();
DeleteObsoleteProfiles ();
m_RouterInfos.clear ();
- m_Floodfills.clear ();
+ m_Floodfills.Clear ();
if (m_Thread)
{
m_IsRunning = false;
@@ -107,7 +106,7 @@
{
i2p::util::SetThreadName("NetDB");
- uint64_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
+ uint64_t lastManage = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
int16_t profilesCleanupVariance = 0;
@@ -133,9 +132,6 @@
case eI2NPDatabaseLookup:
HandleDatabaseLookupMsg (msg);
break;
- case eI2NPDeliveryStatus:
- HandleDeliveryStatusMsg (msg);
- break;
case eI2NPDummyMsg:
// plain RouterInfo from NTCP2 with flags for now
HandleNTCP2RouterInfoMsg (msg);
@@ -153,62 +149,39 @@
if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
- if (ts - lastManageRequest >= 15) // manage requests every 15 seconds
+ if (ts - lastManageRequest >= 15 || ts + 15 < lastManageRequest) // manage requests every 15 seconds
{
m_Requests.ManageRequests ();
lastManageRequest = ts;
}
- if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
+ if (ts - lastManage >= 60 || ts + 60 < lastManage) // manage routers and leasesets every minute
{
- if (lastSave)
+ if (lastManage)
{
- SaveUpdated ();
+ ManageRouterInfos ();
ManageLeaseSets ();
}
- lastSave = ts;
+ lastManage = ts;
}
- if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
+ if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT ||
+ ts + i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT < lastDestinationCleanup)
{
i2p::context.CleanupDestination ();
lastDestinationCleanup = ts;
}
- if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance))
+ if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) ||
+ ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup)
{
+ if (m_PersistProfiles) PersistProfiles ();
DeleteObsoleteProfiles ();
lastProfilesCleanup = ts;
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)
- {
- // 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) // exploratory every 30 seconds
+ if (ts - lastExploratory >= 30 || ts + 30 < lastExploratory) // exploratory every 30 seconds
{
auto numRouters = m_RouterInfos.size ();
if (!numRouters)
@@ -221,7 +194,7 @@
if (numRouters < 1) numRouters = 1;
if (numRouters > 9) numRouters = 9;
m_Requests.ManageRequests ();
- if(!m_HiddenMode)
+ if(!i2p::context.IsHidden ())
Explore (numRouters);
lastExploratory = ts;
}
@@ -234,12 +207,6 @@
}
}
- 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)
{
bool updated;
@@ -273,7 +240,24 @@
bool wasFloodfill = r->IsFloodfill ();
{
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
- r->Update (buf, len);
+ if (!r->Update (buf, len))
+ {
+ updated = false;
+ m_Requests.RequestComplete (ident, r);
+ return r;
+ }
+ if (r->IsUnreachable ())
+ {
+ // delete router as invalid after update
+ m_RouterInfos.erase (ident);
+ if (wasFloodfill)
+ {
+ std::unique_lock<std::mutex> l(m_FloodfillsMutex);
+ m_Floodfills.Remove (r->GetIdentHash ());
+ }
+ m_Requests.RequestComplete (ident, nullptr);
+ return nullptr;
+ }
}
LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64());
if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated
@@ -281,9 +265,14 @@
LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64());
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
if (wasFloodfill)
- m_Floodfills.remove (r);
+ m_Floodfills.Remove (r->GetIdentHash ());
else if (r->IsEligibleFloodfill ())
- m_Floodfills.push_back (r);
+ {
+ if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ())
+ m_Floodfills.Insert (r);
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/NetDb.hpp
^
|
@@ -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
*
@@ -12,7 +12,6 @@
#include <inttypes.h>
#include <set>
#include <unordered_map>
-#include <list>
#include <string>
#include <thread>
#include <mutex>
@@ -31,6 +30,7 @@
#include "Family.h"
#include "version.h"
#include "util.h"
+#include "KadDHT.h"
namespace i2p
{
@@ -38,18 +38,14 @@
{
const int NETDB_MIN_ROUTERS = 90;
const int NETDB_MIN_FLOODFILLS = 5;
- const int NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE = 8; // in percents
+ const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1500;
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds
- const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days
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, 36); // 0.9.36
- const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38
+ 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_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
/** function for visiting a leaseset stored in a floodfill */
@@ -86,31 +82,28 @@
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
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 (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
std::shared_ptr<const RouterInfo> GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
std::shared_ptr<const RouterInfo> GetRandomSSU2Introducer (bool v4, const std::set<IdentHash>& excluded) const;
- std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
+ std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily (FamilyID fam) const;
void SetUnreachable (const IdentHash& ident, bool unreachable);
+ void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports);
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 ();
Families& GetFamilies () { return m_Families; };
// for web interface
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 (); };
/** visit all lease sets we currently store */
@@ -124,7 +117,7 @@
void ClearRouterInfos () { m_RouterInfos.clear (); };
std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
- void PopulateRouterInfoBuffer (std::shared_ptr<RouterInfo> r);
+ bool PopulateRouterInfoBuffer (std::shared_ptr<RouterInfo> r);
std::shared_ptr<RouterInfo::Address> NewRouterInfoAddress () { return m_RouterInfoAddressesPool.AcquireSharedMt (); };
boost::shared_ptr<RouterInfo::Addresses> NewRouterInfoAddresses ()
{
@@ -134,6 +127,7 @@
&m_RouterInfoAddressVectorsPool, std::placeholders::_1));
};
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; };
@@ -144,8 +138,8 @@
void SaveUpdated ();
void Run (); // exploratory thread
void Explore (int numDestinations);
- void Publish ();
void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg);
+ void ManageRouterInfos ();
void ManageLeaseSets ();
void ManageRequests ();
@@ -164,7 +158,7 @@
mutable std::mutex m_RouterInfosMutex;
std::unordered_map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
mutable std::mutex m_FloodfillsMutex;
- std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
+ DHTTable m_Floodfills;
bool m_IsRunning;
std::thread * m_Thread;
@@ -183,9 +177,6 @@
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
- /** true if in hidden mode */
- bool m_HiddenMode;
-
std::set<IdentHash> m_PublishExcluded;
uint32_t m_PublishReplyToken = 0;
@@ -193,6 +184,7 @@
i2p::util::MemoryPoolMt<RouterInfo::Address> m_RouterInfoAddressesPool;
i2p::util::MemoryPoolMt<RouterInfo::Addresses> m_RouterInfoAddressVectorsPool;
i2p::util::MemoryPoolMt<Lease> m_LeasesPool;
+ i2p::util::MemoryPoolMt<IdentityEx> m_IdentitiesPool;
};
extern NetDb netdb;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/NetDbRequests.cpp
^
|
@@ -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
*
@@ -137,7 +137,7 @@
auto inbound = pool->GetNextInboundTunnel ();
auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
if (nextFloodfill && outbound && inbound)
- outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0,
+ outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0,
dest->CreateRequestMessage (nextFloodfill, inbound));
else
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Profiling.cpp
^
|
@@ -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
*
@@ -7,34 +7,42 @@
*/
#include <sys/stat.h>
+#include <unordered_map>
+#include <list>
+#include <thread>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "Base.h"
#include "FS.h"
#include "Log.h"
+#include "Timestamp.h"
#include "Profiling.h"
namespace i2p
{
namespace data
{
- i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
+ static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
+ static std::unordered_map<i2p::data::IdentHash, std::shared_ptr<RouterProfile> > g_Profiles;
+ static std::mutex g_ProfilesMutex;
- RouterProfile::RouterProfile ():
- m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
- m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
- m_NumTimesTaken (0), m_NumTimesRejected (0)
+ static boost::posix_time::ptime GetTime ()
{
+ return boost::posix_time::second_clock::local_time();
}
- boost::posix_time::ptime RouterProfile::GetTime () const
+ RouterProfile::RouterProfile ():
+ m_LastUpdateTime (GetTime ()), m_IsUpdated (false),
+ m_LastDeclineTime (0), m_LastUnreachableTime (0),
+ m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
+ m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false)
{
- return boost::posix_time::second_clock::local_time();
}
void RouterProfile::UpdateTime ()
{
m_LastUpdateTime = GetTime ();
+ m_IsUpdated = true;
}
void RouterProfile::Save (const IdentHash& identHash)
@@ -47,15 +55,18 @@
boost::property_tree::ptree usage;
usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken);
usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected);
+ usage.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected);
// fill property tree
boost::property_tree::ptree pt;
pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime));
+ if (m_LastUnreachableTime)
+ pt.put (PEER_PROFILE_LAST_UNREACHABLE_TIME, m_LastUnreachableTime);
pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation);
pt.put_child (PEER_PROFILE_SECTION_USAGE, usage);
// save to file
std::string ident = identHash.ToBase64 ();
- std::string path = m_ProfilesStorage.Path(ident);
+ std::string path = g_ProfilesStorage.Path(ident);
try {
boost::property_tree::write_ini (path, pt);
@@ -68,7 +79,7 @@
void RouterProfile::Load (const IdentHash& identHash)
{
std::string ident = identHash.ToBase64 ();
- std::string path = m_ProfilesStorage.Path(ident);
+ std::string path = g_ProfilesStorage.Path(ident);
boost::property_tree::ptree pt;
if (!i2p::fs::Exists(path))
@@ -94,6 +105,7 @@
m_LastUpdateTime = boost::posix_time::time_from_string (t);
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT)
{
+ m_LastUnreachableTime = pt.get (PEER_PROFILE_LAST_UNREACHABLE_TIME, 0);
try
{
// read participations
@@ -112,6 +124,7 @@
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
+ m_HasConnected = usage.get (PEER_PROFILE_USAGE_CONNECTED, false);
}
catch (boost::property_tree::ptree_bad_path& ex)
{
@@ -131,14 +144,36 @@
{
UpdateTime ();
if (ret > 0)
+ {
m_NumTunnelsDeclined++;
+ m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch ();
+ }
else
- m_NumTunnelsAgreed++;
+ {
+ m_NumTunnelsAgreed++;
+ m_LastDeclineTime = 0;
+ }
}
void RouterProfile::TunnelNonReplied ()
{
- m_NumTunnelsNonReplied++;
+ m_NumTunnelsNonReplied++;
+ UpdateTime ();
+ if (m_NumTunnelsNonReplied > 2*m_NumTunnelsAgreed && m_NumTunnelsNonReplied > 3)
+ {
+ m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch ();
+ }
+ }
+
+ void RouterProfile::Unreachable ()
+ {
+ m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch ();
+ UpdateTime ();
+ }
+
+ void RouterProfile::Connected ()
+ {
+ m_HasConnected = true;
UpdateTime ();
}
@@ -153,8 +188,19 @@
return m_NumTunnelsNonReplied > 10*(total + 1);
}
+ bool RouterProfile::IsDeclinedRecently ()
+ {
+ if (!m_LastDeclineTime) return false;
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
+ if (ts > m_LastDeclineTime + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL ||
+ ts + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL < m_LastDeclineTime)
+ m_LastDeclineTime = 0;
+ return (bool)m_LastDeclineTime;
+ }
+
bool RouterProfile::IsBad ()
{
+ if (IsDeclinedRecently () || IsUnreachable ()) return true;
auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/;
if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1))
{
@@ -168,32 +214,103 @@
return isBad;
}
+ bool RouterProfile::IsUnreachable ()
+ {
+ if (!m_LastUnreachableTime) return false;
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
+ if (ts > m_LastUnreachableTime + PEER_PROFILE_UNREACHABLE_INTERVAL ||
+ ts + PEER_PROFILE_UNREACHABLE_INTERVAL < m_LastUnreachableTime)
+ m_LastUnreachableTime = 0;
+ return (bool)m_LastUnreachableTime;
+ }
+
+ bool RouterProfile::IsUseful() const
+ {
+ return IsReal () || m_NumTunnelsNonReplied >= PEER_PROFILE_USEFUL_THRESHOLD;
+ }
+
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
{
+ {
+ std::unique_lock<std::mutex> l(g_ProfilesMutex);
+ auto it = g_Profiles.find (identHash);
+ if (it != g_Profiles.end ())
+ return it->second;
+ }
auto profile = std::make_shared<RouterProfile> ();
profile->Load (identHash); // if possible
+ std::unique_lock<std::mutex> l(g_ProfilesMutex);
+ g_Profiles.emplace (identHash, profile);
return profile;
}
void InitProfilesStorage ()
{
- m_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
- m_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64);
+ g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Profiling.h
^
|
@@ -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
*
@@ -22,15 +22,21 @@
const char PEER_PROFILE_SECTION_USAGE[] = "usage";
// params
const char PEER_PROFILE_LAST_UPDATE_TIME[] = "lastupdatetime";
+ const char PEER_PROFILE_LAST_UNREACHABLE_TIME[] = "lastunreachabletime";
const char PEER_PROFILE_PARTICIPATION_AGREED[] = "agreed";
const char PEER_PROFILE_PARTICIPATION_DECLINED[] = "declined";
const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied";
const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
-
- const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
- const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day)
- const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours)
+ const char PEER_PROFILE_USAGE_CONNECTED[] = "connected";
+
+ const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days)
+ const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours)
+ const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour)
+ const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes)
+ const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes)
+ const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours)
+ const int PEER_PROFILE_USEFUL_THRESHOLD = 3;
class RouterProfile
{
@@ -43,22 +49,34 @@
void Load (const IdentHash& identHash);
bool IsBad ();
+ bool IsUnreachable ();
+ bool IsReal () const { return m_HasConnected || m_NumTunnelsAgreed > 0 || m_NumTunnelsDeclined > 0; }
void TunnelBuildResponse (uint8_t ret);
void TunnelNonReplied ();
+ void Unreachable ();
+ void Connected ();
+
+ boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; };
+ bool IsUpdated () const { return m_IsUpdated; };
+
+ bool IsUseful() const;
+
private:
- boost::posix_time::ptime GetTime () const;
void UpdateTime ();
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
bool IsLowPartcipationRate () const;
bool IsLowReplyRate () const;
+ bool IsDeclinedRecently ();
private:
- boost::posix_time::ptime m_LastUpdateTime;
+ boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono
+ bool m_IsUpdated;
+ uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds
// participation
uint32_t m_NumTunnelsAgreed;
uint32_t m_NumTunnelsDeclined;
@@ -66,11 +84,14 @@
// usage
uint32_t m_NumTimesTaken;
uint32_t m_NumTimesRejected;
+ bool m_HasConnected; // successful trusted(incoming or NTCP2) connection
};
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
void InitProfilesStorage ();
void DeleteObsoleteProfiles ();
+ void SaveProfiles ();
+ void PersistProfiles ();
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Reseed.cpp
^
|
@@ -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
*
@@ -153,7 +153,7 @@
return ProcessSU3Stream (s);
else
{
- LogPrint (eLogError, "Reseed: Can't open file ", filename);
+ LogPrint (eLogCritical, "Reseed: Can't open file ", filename);
return 0;
}
}
@@ -170,7 +170,7 @@
}
else
{
- LogPrint (eLogError, "Reseed: Can't open file ", filename);
+ LogPrint (eLogCritical, "Reseed: Can't open file ", filename);
return 0;
}
}
@@ -278,7 +278,7 @@
if (verify) // not verified
{
- LogPrint (eLogError, "Reseed: SU3 verification failed");
+ LogPrint (eLogCritical, "Reseed: SU3 verification failed");
return 0;
}
@@ -320,7 +320,7 @@
uint16_t fileNameLength, extraFieldLength;
s.read ((char *)&fileNameLength, 2);
fileNameLength = le16toh (fileNameLength);
- if ( fileNameLength > 255 ) {
+ if ( fileNameLength >= 255 ) {
// too big
LogPrint(eLogError, "Reseed: SU3 fileNameLength too large: ", fileNameLength);
return numFiles;
@@ -492,7 +492,7 @@
SSL_free (ssl);
}
else
- LogPrint (eLogError, "Reseed: Can't open certificate file ", filename);
+ LogPrint (eLogCritical, "Reseed: Can't open certificate file ", filename);
SSL_CTX_free (ctx);
}
@@ -534,17 +534,17 @@
}
// check for valid proxy url schema
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
- LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy);
+ LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy);
return "";
}
} else {
- LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy);
+ LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy);
return "";
}
}
i2p::http::URL url;
if (!url.parse(address)) {
- LogPrint(eLogError, "Reseed: Failed to parse url: ", address);
+ LogPrint(eLogCritical, "Reseed: Failed to parse url: ", address);
return "";
}
url.schema = "https";
@@ -687,12 +687,23 @@
while (it != end)
{
boost::asio::ip::tcp::endpoint ep = *it;
- if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
- (ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
+ if (
+ (
+ !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);
if (!ecode)
{
+ LogPrint (eLogDebug, "Reseed: Resolved to ", ep.address ());
connected = true;
break;
}
@@ -780,17 +791,45 @@
boost::asio::io_service service;
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
- if (url.host.length () < 2) return ""; // assume []
- auto host = url.host.substr (1, url.host.length () - 2);
- 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);
+ auto it = boost::asio::ip::tcp::resolver(service).resolve (
+ boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
+
+ if (!ecode)
+ {
+ 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: Connected to Yggdrasil ", url.host, ":", url.port);
+ LogPrint (eLogDebug, "Reseed: Yggdrasil: Connected to ", url.host, ":", url.port);
return ReseedRequest (s, url.to_string());
}
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 "";
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/RouterContext.cpp
^
|
@@ -20,6 +20,8 @@
#include "Log.h"
#include "Family.h"
#include "ECIESX25519AEADRatchetSession.h"
+#include "Transports.h"
+#include "Tunnel.h"
#include "RouterContext.h"
namespace i2p
@@ -29,7 +31,8 @@
RouterContext::RouterContext ():
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
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 @@
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 ()
{
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
@@ -85,96 +116,103 @@
bool ssu2Published = false;
if (ssu2)
i2p::config::GetOption("ssu2.published", ssu2Published);
- uint8_t caps = 0, addressCaps = 0;
+ uint8_t caps = 0;
if (ipv4)
{
- std::string host = "127.0.0.1";
- if (!i2p::config::IsDefault("host"))
- i2p::config::GetOption("host", host);
- else if (!nat)
- {
+ std::string host;
+ if (!nat)
// we have no NAT so set external address from local address
- std::string address4; i2p::config::GetOption("address4", address4);
- if (!address4.empty ()) host = address4;
- }
+ i2p::config::GetOption("address4", host);
+ if (host.empty ()) i2p::config::GetOption("host", host);
if (ntcp2)
{
- if (ntcp2Published)
- routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port);
- else // add non-published NTCP2 address
+ uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
+ if (!ntcp2Port) ntcp2Port = port;
+ if (ntcp2Published && ntcp2Port)
{
- addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
- routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
+ boost::asio::ip::address addr;
+ if (!host.empty ())
+ addr = boost::asio::ip::address::from_string (host);
+ if (!addr.is_v4())
+ addr = boost::asio::ip::address_v4 ();
+ routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port);
+ }
+ else
+ {
+ // add non-published NTCP2 address
+ uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
+ if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
+ routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, addressCaps);
}
}
if (ssu2)
{
- if (ssu2Published)
- {
- uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
- if (!ssu2Port) ssu2Port = port;
- routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), ssu2Port);
+ uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
+ if (!ssu2Port) ssu2Port = port;
+ if (ssu2Published && ssu2Port)
+ {
+ boost::asio::ip::address addr;
+ if (!host.empty ())
+ addr = boost::asio::ip::address::from_string (host);
+ if (!addr.is_v4())
+ addr = boost::asio::ip::address_v4 ();
+ routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port);
}
else
{
- addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
- routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
+ uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
+ if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
+ routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, addressCaps);
}
}
}
if (ipv6)
{
- std::string host;
- if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only
- i2p::config::GetOption("host", host);
- else
- {
- std::string address6; i2p::config::GetOption("address6", address6);
- if (!address6.empty ()) host = address6;
- }
+ std::string host; i2p::config::GetOption("address6", host);
+ if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented
if (ntcp2)
{
- bool added = false;
- if (ntcp2Published)
+ uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
+ if (!ntcp2Port) ntcp2Port = port;
+ if (ntcp2Published && ntcp2Port)
{
std::string ntcp2Host;
if (!i2p::config::IsDefault ("ntcp2.addressv6"))
i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
else
ntcp2Host = host;
- if (!ntcp2Host.empty () && port)
- {
- routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port);
- added = true;
- }
+ boost::asio::ip::address addr;
+ if (!ntcp2Host.empty ())
+ addr = boost::asio::ip::address::from_string (ntcp2Host);
+ if (!addr.is_v6())
+ addr = boost::asio::ip::address_v6 ();
+ routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port);
}
- if (!added)
+ else
{
if (!ipv4) // no other ntcp2 addresses yet
- routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
- addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
+ routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV6);
}
}
if (ssu2)
{
- bool added = false;
- if (ssu2Published)
- {
- uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
- if (!ssu2Port) ssu2Port = port;
- if (!host.empty () && ssu2Port)
- {
- routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), ssu2Port);
- added = true;
- }
+ uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
+ if (!ssu2Port) ssu2Port = port;
+ if (ssu2Published && ssu2Port)
+ {
+ boost::asio::ip::address addr;
+ if (!host.empty ())
+ addr = boost::asio::ip::address::from_string (host);
+ if (!addr.is_v6())
+ addr = boost::asio::ip::address_v6 ();
+ routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port);
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/RouterContext.h
^
|
@@ -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
*
@@ -12,12 +12,13 @@
#include <inttypes.h>
#include <string>
#include <memory>
-#include <mutex>
#include <chrono>
+#include <set>
#include <boost/asio.hpp>
#include "Identity.h"
#include "RouterInfo.h"
#include "Garlic.h"
+#include "util.h"
namespace i2p
{
@@ -30,7 +31,13 @@
const char ROUTER_KEYS[] = "router.keys";
const char NTCP2_KEYS[] = "ntcp2.keys";
const char SSU2_KEYS[] = "ssu2.keys";
- const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
+ const int ROUTER_INFO_UPDATE_INTERVAL = 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
{
@@ -70,11 +77,23 @@
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:
RouterContext ();
void Init ();
-
+ void Start ();
+ void Stop ();
+
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
i2p::data::LocalRouterInfo& GetRouterInfo () { return m_RouterInfo; };
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo ()
@@ -116,11 +135,9 @@
bool DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data);
void UpdatePort (int port); // called from Daemon
- void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
+ void UpdateAddress (const boost::asio::ip::address& host); // called from SSU2 or Daemon
void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg);
- void UpdateNTCP2Address (bool enable);
void PublishSSU2Address (int port, bool publish, bool v4, bool v6);
- void UpdateSSU2Address (bool enable);
bool AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4);
void RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4);
void ClearSSU2Introducers (bool v4);
@@ -136,6 +153,7 @@
void SetShareRatio (int percents); // 0 - 100
bool AcceptsTunnels () const { return m_AcceptsTunnels; };
void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
+ bool IsHighCongestion () const;
bool SupportsV6 () const { return m_RouterInfo.IsV6 (); };
bool SupportsV4 () const { return m_RouterInfo.IsV4 (); };
bool SupportsMesh () const { return m_RouterInfo.IsMesh (); };
@@ -143,6 +161,8 @@
void SetSupportsV4 (bool supportsV4);
void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host);
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; };
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove
@@ -177,13 +197,27 @@
void UpdateRouterInfo ();
void NewNTCP2Keys ();
void NewSSU2Keys ();
- bool IsSSU2Only () const; // SSU2 and no SSU
+ void UpdateNTCP2Keys ();
+ void UpdateSSU2Keys ();
bool Load ();
void SaveKeys ();
uint16_t SelectRandomPort () 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);
+ 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:
i2p::data::LocalRouterInfo m_RouterInfo;
@@ -198,12 +232,17 @@
RouterStatus m_Status, m_StatusV6;
RouterError m_Error, m_ErrorV6;
int m_NetID;
- std::mutex m_GarlicMutex;
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
// for ECIESx25519
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;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/RouterInfo.cpp
^
|
@@ -43,7 +43,7 @@
RouterInfo::RouterInfo (const std::string& fullPath):
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
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_Buffer = NewBuffer (); // always RouterInfo's
@@ -53,7 +53,7 @@
RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
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)
{
@@ -79,13 +79,12 @@
{
}
- void RouterInfo::Update (const uint8_t * buf, size_t len)
+ bool RouterInfo::Update (const uint8_t * buf, size_t len)
{
if (len > MAX_RI_BUFFER_SIZE)
{
- LogPrint (eLogError, "RouterInfo: Buffer is too long ", len);
- m_IsUnreachable = true;
- return;
+ LogPrint (eLogWarning, "RouterInfo: Updated buffer is too long ", len, ". Not changed");
+ return false;
}
// verify signature since we have identity already
int l = len - m_RouterIdentity->GetSignatureLen ();
@@ -99,20 +98,21 @@
m_Caps = 0;
// don't clean up m_Addresses, it will be replaced in ReadFromStream
ClearProperties ();
- // copy buffer
- UpdateBuffer (buf, len);
// skip identity
size_t identityLen = m_RouterIdentity->GetFullLen ();
// read new RI
- std::stringstream str (std::string ((char *)m_Buffer->data () + identityLen, m_BufferLen - identityLen));
+ std::stringstream str (std::string ((char *)buf + identityLen, len - identityLen));
ReadFromStream (str);
+ if (!m_IsUnreachable)
+ UpdateBuffer (buf, len); // save buffer
// don't delete buffer until saved to the file
}
else
- {
- LogPrint (eLogError, "RouterInfo: Signature verification failed");
- m_IsUnreachable = true;
- }
+ {
+ LogPrint (eLogWarning, "RouterInfo: Updated signature verification failed. Not changed");
+ return false;
+ }
+ return true;
}
void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
@@ -161,7 +161,7 @@
m_IsUnreachable = true;
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 ();
if (identityLen >= m_BufferLen)
{
@@ -186,7 +186,6 @@
m_IsUnreachable = true;
return;
}
- m_RouterIdentity->DropVerifier ();
}
// parse RI
std::stringstream str;
@@ -202,7 +201,7 @@
void RouterInfo::ReadFromStream (std::istream& s)
{
if (!s) return;
- m_Caps = 0;
+ m_Caps = 0; m_Congestion = eLowCongestion;
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
m_Timestamp = be64toh (m_Timestamp);
// read addresses
@@ -252,7 +251,15 @@
{
boost::system::error_code ecode;
address->host = boost::asio::ip::address::from_string (value, ecode);
- if (!ecode && !address->host.is_unspecified ()) isHost = true;
+ if (!ecode && !address->host.is_unspecified ())
+ {
+ if (!i2p::util::net::IsInReservedRange (address->host) ||
+ i2p::util::net::IsYggdrasilAddress (address->host))
+ isHost = true;
+ else
+ // we consider such address as invalid
+ address->transportStyle = eTransportUnknown;
+ }
}
else if (!strcmp (key, "port"))
{
@@ -286,7 +293,8 @@
else if (!strcmp (key, "s")) // ntcp2 or ssu2 static key
{
Base64ToByteStream (value, strlen (value), address->s, 32);
- isStaticKey = true;
+ if (!(address->s[31] & 0x80)) // check if x25519 public key
+ isStaticKey = true;
}
else if (!strcmp (key, "i")) // ntcp2 iv or ssu2 intro
{
@@ -328,11 +336,7 @@
address->ssu->introducers.resize (index + 1);
}
Introducer& introducer = address->ssu->introducers.at (index);
- if (!strcmp (key, "ihost"))
- introducer.isH = false; // SSU1
- else if (!strcmp (key, "iport"))
- introducer.isH = false; // SSU1
- else if (!strcmp (key, "itag"))
+ if (!strcmp (key, "itag"))
{
try
{
@@ -344,10 +348,7 @@
}
}
else if (!strcmp (key, "ih"))
- {
Base64ToByteStream (value, strlen (value), introducer.iH, 32);
- introducer.isH = true;
- }
else if (!strcmp (key, "iexp"))
{
try
@@ -362,11 +363,12 @@
}
if (!s) return;
}
+
if (address->transportStyle == eTransportNTCP2)
{
if (isStaticKey)
{
- if (isHost)
+ if (isHost && address->port)
{
if (address->host.is_v6 ())
supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
@@ -374,8 +376,9 @@
supportedTransports |= eNTCP2V4;
m_ReachableTransports |= supportedTransports;
}
- else if (!address->published)
+ else
{
+ address->published = false;
if (address->caps)
{
if (address->caps & AddressCaps::eV4) supportedTransports |= eNTCP2V4;
@@ -386,11 +389,11 @@
}
}
}
- else if (address->transportStyle == eTransportSSU2 && isV2)
+ else if (address->transportStyle == eTransportSSU2 && isV2 && isStaticKey)
{
if (address->IsV4 ()) supportedTransports |= eSSU2V4;
if (address->IsV6 ()) supportedTransports |= eSSU2V6;
- if (address->port)
+ if (isHost && address->port)
{
if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4;
if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6;
@@ -400,18 +403,9 @@
{
// exclude invalid introducers
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
- int numValid = 0;
- for (auto& it: address->ssu->introducers)
- {
- if (it.iTag && ts < it.iExp && it.isH)
- numValid++;
- else
- it.iTag = 0;
- }
- if (numValid)
+ UpdateIntroducers (address, ts);
+ if (!address->ssu->introducers.empty ()) // still has something
m_ReachableTransports |= supportedTransports;
- else
- address->ssu->introducers.resize (0);
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/RouterInfo.h
^
|
@@ -44,7 +44,11 @@
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_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_V6 = '6';
const char CAPS_FLAG_SSU2_TESTING = 'B';
@@ -56,6 +60,9 @@
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 int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes
+ const int INTRODUCER_UPDATE_INTERVAL = 20*60*1000; // in milliseconds, 20 minutes
+
class RouterInfo: public RoutingDestination
{
public:
@@ -93,6 +100,14 @@
eUnreachable = 0x20
};
+ enum Congestion
+ {
+ eLowCongestion = 0,
+ eMediumCongestion,
+ eHighCongestion,
+ eRejectAll
+ };
+
enum AddressCaps
{
eV4 = 0x01,
@@ -110,11 +125,10 @@
struct Introducer
{
- Introducer (): iTag (0), iExp (0), isH (false) {};
+ Introducer (): iTag (0), iExp (0) {};
IdentHash iH;
uint32_t iTag;
uint32_t iExp;
- bool isH; // TODO: remove later
};
struct SSUExt
@@ -189,8 +203,8 @@
virtual void SetProperty (const std::string& key, const std::string& value) {};
virtual void ClearProperties () {};
boost::shared_ptr<Addresses> GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr
- std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
- std::shared_ptr<const Address> GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const;
+ std::shared_ptr<const Address> GetNTCP2V4Address () const;
+ std::shared_ptr<const Address> GetNTCP2V6Address () const;
std::shared_ptr<const Address> GetPublishedNTCP2V4Address () const;
std::shared_ptr<const Address> GetPublishedNTCP2V6Address () const;
std::shared_ptr<const Address> GetYggdrasilAddress () const;
@@ -198,15 +212,19 @@
std::shared_ptr<const Address> GetSSU2V6Address () const;
std::shared_ptr<const Address> GetSSU2Address (bool v4) const;
+ void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,int port, uint8_t caps); // non published
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
- const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0);
- void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps = 0); // non published
+ const boost::asio::ip::address& host, int port); // published
+ void RemoveNTCP2Address (bool v4);
+ void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, int port, uint8_t caps); // non published
void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
const boost::asio::ip::address& host, int port); // published
+ void RemoveSSU2Address (bool v4);
void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
void UpdateSupportedTransports ();
+ void UpdateIntroducers (uint64_t ts); // ts in seconds
bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
- bool IsReachable () const { return m_Caps & Caps::eReachable; };
+ void ResetFlooldFill () { m_Caps &= ~Caps::eFloodfill; };
bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
bool IsNTCP2 (bool v4only = true) const;
bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; };
@@ -230,16 +248,21 @@
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
bool IsEligibleFloodfill () const;
+ bool IsPublished (bool v4) const;
bool IsSSU2PeerTesting (bool v4) const;
bool IsSSU2Introducer (bool v4) const;
+ bool IsHighCongestion (bool highBandwidth) const;
uint8_t GetCaps () const { return m_Caps; };
void SetCaps (uint8_t caps) { m_Caps = caps; };
+ Congestion GetCongestion () const { return m_Congestion; };
+
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
bool IsUnreachable () const { return m_IsUnreachable; };
+ void ExcludeReachableTransports (CompatibleTransports transports) { m_ReachableTransports &= ~transports; };
- const uint8_t * GetBuffer () const { return m_Buffer->data (); };
+ const uint8_t * GetBuffer () const { return m_Buffer ? m_Buffer->data () : nullptr; };
const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary
size_t GetBufferLen () const { return m_BufferLen; };
@@ -248,9 +271,9 @@
bool SaveToFile (const std::string& fullPath);
std::shared_ptr<RouterProfile> GetProfile () const;
- void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
+ void DropProfile () { m_Profile = nullptr; };
- void Update (const uint8_t * buf, size_t len);
+ bool Update (const uint8_t * buf, size_t len);
void DeleteBuffer () { m_Buffer = nullptr; };
bool IsNewer (const uint8_t * buf, size_t len) const;
@@ -272,7 +295,8 @@
void RefreshTimestamp ();
CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; };
void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; };
-
+ void SetCongestion (Congestion c) { m_Congestion = c; };
+
private:
bool LoadFile (const std::string& fullPath);
@@ -282,11 +306,13 @@
size_t ReadString (char* str, size_t len, std::istream& s) const;
void ExtractCaps (const char * value);
uint8_t ExtractAddressCaps (const char * value) const;
+ void UpdateIntroducers (std::shared_ptr<Address> address, uint64_t ts);
template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const;
virtual std::shared_ptr<Buffer> NewBuffer () const;
virtual std::shared_ptr<Address> NewAddress () const;
virtual boost::shared_ptr<Addresses> NewAddresses () const;
+ virtual std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const;
private:
@@ -294,12 +320,13 @@
std::shared_ptr<const IdentityEx> m_RouterIdentity;
std::shared_ptr<Buffer> m_Buffer;
size_t m_BufferLen;
- uint64_t m_Timestamp;
+ uint64_t m_Timestamp; // in milliseconds
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
bool m_IsUpdated, m_IsUnreachable;
CompatibleTransports m_SupportedTransports, m_ReachableTransports;
uint8_t m_Caps;
int m_Version;
+ Congestion m_Congestion;
mutable std::shared_ptr<RouterProfile> m_Profile;
};
@@ -308,9 +335,9 @@
public:
LocalRouterInfo () = default;
- LocalRouterInfo (const std::string& fullPath): RouterInfo (fullPath) {};
void CreateBuffer (const PrivateKeys& privateKeys);
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 DeleteProperty (const std::string& key);
@@ -328,6 +355,7 @@
std::shared_ptr<Buffer> NewBuffer () const override;
std::shared_ptr<Address> NewAddress () const override;
boost::shared_ptr<Addresses> NewAddresses () const override;
+ std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const override;
private:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/SSU2.cpp
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -22,7 +22,7 @@
RunnableServiceWithWork ("SSU2"), m_ReceiveService ("SSU2r"),
m_SocketV4 (m_ReceiveService.GetService ()), m_SocketV6 (m_ReceiveService.GetService ()),
m_AddressV4 (boost::asio::ip::address_v4()), m_AddressV6 (boost::asio::ip::address_v6()),
- m_TerminationTimer (GetService ()), m_ResendTimer (GetService ()),
+ m_TerminationTimer (GetService ()), m_CleanupTimer (GetService ()), m_ResendTimer (GetService ()),
m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()),
m_IsPublished (true), m_IsSyncClockFromPeers (true), m_IsThroughProxy (false)
{
@@ -78,6 +78,7 @@
if (address->IsV4 ())
{
found = true;
+ LogPrint (eLogDebug, "SSU2: Opening IPv4 socket at Start");
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port));
m_ReceiveService.GetService ().post(
[this]()
@@ -89,6 +90,7 @@
if (address->IsV6 ())
{
found = true;
+ LogPrint (eLogDebug, "SSU2: Opening IPv6 socket at Start");
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port));
m_ReceiveService.GetService ().post(
[this]()
@@ -99,7 +101,7 @@
}
}
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)
@@ -109,6 +111,7 @@
m_ReceiveService.Start ();
}
ScheduleTermination ();
+ ScheduleCleanup ();
ScheduleResend (false);
}
}
@@ -118,6 +121,7 @@
if (IsRunning ())
{
m_TerminationTimer.cancel ();
+ m_CleanupTimer.cancel ();
m_ResendTimer.cancel ();
m_IntroducersUpdateTimer.cancel ();
m_IntroducersUpdateTimerV6.cancel ();
@@ -210,6 +214,8 @@
boost::asio::ip::udp::socket& socket = localEndpoint.address ().is_v6 () ? m_SocketV6 : m_SocketV4;
try
{
+ if (socket.is_open ())
+ socket.close ();
socket.open (localEndpoint.protocol ());
if (localEndpoint.address ().is_v6 ())
socket.set_option (boost::asio::ip::v6_only (true));
@@ -220,7 +226,7 @@
}
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 ());
}
return socket;
@@ -239,10 +245,12 @@
if (!ecode
|| ecode == boost::asio::error::connection_refused
|| ecode == boost::asio::error::connection_reset
+ || ecode == boost::asio::error::network_reset
|| ecode == boost::asio::error::network_unreachable
|| ecode == boost::asio::error::host_unreachable
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
+ || ecode.value() == boost::winapi::WSAENETRESET_ // 10052
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
#endif
@@ -299,7 +307,7 @@
else
{
auto ep = socket.local_endpoint ();
- socket.close ();
+ LogPrint (eLogCritical, "SSU2: Reopening socket in HandleReceivedFrom: code ", ecode.value(), ": ", ecode.message ());
OpenSocket (ep);
Receive (socket);
}
@@ -554,16 +562,25 @@
SendThroughProxy (header, headerLen, nullptr, 0, payload, payloadLen, to);
return;
}
+
std::vector<boost::asio::const_buffer> bufs
{
boost::asio::buffer (header, headerLen),
boost::asio::buffer (payload, payloadLen)
};
+
boost::system::error_code ec;
if (to.address ().is_v6 ())
+ {
+ if (!m_SocketV6.is_open ()) return;
m_SocketV6.send_to (bufs, to, 0, ec);
+ }
else
+ {
+ if (!m_SocketV4.is_open ()) return;
m_SocketV4.send_to (bufs, to, 0, ec);
+ }
+
if (!ec)
i2p::transport::transports.UpdateSentBytes (headerLen + payloadLen);
else
@@ -578,17 +595,25 @@
SendThroughProxy (header, headerLen, headerX, headerXLen, payload, payloadLen, to);
return;
}
+
std::vector<boost::asio::const_buffer> bufs
{
boost::asio::buffer (header, headerLen),
boost::asio::buffer (headerX, headerXLen),
boost::asio::buffer (payload, payloadLen)
};
+
boost::system::error_code ec;
if (to.address ().is_v6 ())
+ {
+ if (!m_SocketV6.is_open ()) return;
m_SocketV6.send_to (bufs, to, 0, ec);
+ }
else
+ {
+ if (!m_SocketV4.is_open ()) return;
m_SocketV4.send_to (bufs, to, 0, ec);
+ }
if (!ec)
i2p::transport::transports.UpdateSentBytes (headerLen + headerXLen + payloadLen);
@@ -807,6 +832,22 @@
it++;
}
+ ScheduleTermination ();
+ }
+ }
+
+ void SSU2Server::ScheduleCleanup ()
+ {
+ m_CleanupTimer.expires_from_now (boost::posix_time::seconds(SSU2_CLEANUP_INTERVAL));
+ m_CleanupTimer.async_wait (std::bind (&SSU2Server::HandleCleanupTimer,
+ this, std::placeholders::_1));
+ }
+
+ void SSU2Server::HandleCleanupTimer (const boost::system::error_code& ecode)
+ {
+ if (ecode != boost::asio::error::operation_aborted)
+ {
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_Relays.begin (); it != m_Relays.begin ();)
{
if (it->second && it->second->GetState () == eSSU2SessionStateTerminated)
@@ -833,7 +874,9 @@
m_PacketsPool.CleanUpMt ();
m_SentPacketsPool.CleanUp ();
- ScheduleTermination ();
+ m_IncompleteMessagesPool.CleanUp ();
+ m_FragmentsPool.CleanUp ();
+ ScheduleCleanup ();
}
}
@@ -896,7 +939,7 @@
}
uint64_t token;
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;
}
@@ -905,7 +948,7 @@
m_IncomingTokens.erase (ep); // drop previous
uint64_t token;
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);
return ret;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/SSU2.h
^
|
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022, The PurpleI2P Project
+* Copyright (c) 2022-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -18,7 +18,8 @@
{
namespace transport
{
- const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // in seconds
+ const int SSU2_TERMINATION_CHECK_TIMEOUT = 25; // in seconds
+ const int SSU2_CLEANUP_INTERVAL = 72; // in seconds
const int SSU2_RESEND_CHECK_TIMEOUT = 400; // in milliseconds
const int SSU2_RESEND_CHECK_TIMEOUT_VARIANCE = 100; // in milliseconds
const int SSU2_RESEND_CHECK_MORE_TIMEOUT = 10; // in milliseconds
@@ -97,6 +98,8 @@
void RescheduleIntroducersUpdateTimerV6 ();
i2p::util::MemoryPool<SSU2SentPacket>& GetSentPacketsPool () { return m_SentPacketsPool; };
+ i2p::util::MemoryPool<SSU2IncompleteMessage>& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; };
+ i2p::util::MemoryPool<SSU2IncompleteMessage::Fragment>& GetFragmentsPool () { return m_FragmentsPool; };
private:
@@ -111,6 +114,9 @@
void ScheduleTermination ();
void HandleTerminationTimer (const boost::system::error_code& ecode);
+ void ScheduleCleanup ();
+ void HandleCleanupTimer (const boost::system::error_code& ecode);
+
void ScheduleResend (bool more);
void HandleResendTimer (const boost::system::error_code& ecode);
@@ -147,7 +153,9 @@
std::list<i2p::data::IdentHash> m_Introducers, m_IntroducersV6; // introducers we are connected to
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
i2p::util::MemoryPool<SSU2SentPacket> m_SentPacketsPool;
- boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer,
+ i2p::util::MemoryPool<SSU2IncompleteMessage> m_IncompleteMessagesPool;
+ i2p::util::MemoryPool<SSU2IncompleteMessage::Fragment> m_FragmentsPool;
+ boost::asio::deadline_timer m_TerminationTimer, m_CleanupTimer, m_ResendTimer,
m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6;
std::shared_ptr<SSU2Session> m_LastSession;
bool m_IsPublished; // if we maintain introducers
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/SSU2Session.cpp
^
|
@@ -23,7 +23,7 @@
if (msg->len + fragmentSize > msg->maxLen)
{
LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough");
- auto newMsg = NewI2NPMessage ();
+ auto newMsg = NewI2NPMessage (msg->len + fragmentSize);
*newMsg = *msg;
msg = newMsg;
}
@@ -32,15 +32,60 @@
nextFragmentNum++;
}
+ bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments ()
+ {
+ bool isLast = false;
+ while (outOfSequenceFragments)
+ {
+ if (outOfSequenceFragments->fragmentNum == nextFragmentNum)
+ {
+ AttachNextFragment (outOfSequenceFragments->buf, outOfSequenceFragments->len);
+ isLast = outOfSequenceFragments->isLast;
+ if (isLast)
+ outOfSequenceFragments = nullptr;
+ else
+ outOfSequenceFragments = outOfSequenceFragments->next;
+ }
+ else
+ break;
+ }
+ return isLast;
+ }
+
+ void SSU2IncompleteMessage::AddOutOfSequenceFragment (std::shared_ptr<SSU2IncompleteMessage::Fragment> fragment)
+ {
+ if (!fragment || !fragment->fragmentNum) return; // fragment 0 not allowed
+ if (fragment->fragmentNum < nextFragmentNum) return; // already processed
+ if (!outOfSequenceFragments)
+ outOfSequenceFragments = fragment;
+ else
+ {
+ auto frag = outOfSequenceFragments;
+ std::shared_ptr<Fragment> prev;
+ do
+ {
+ if (fragment->fragmentNum < frag->fragmentNum) break; // found
+ if (fragment->fragmentNum == frag->fragmentNum) return; // duplicate
+ prev = frag; frag = frag->next;
+ }
+ while (frag);
+ fragment->next = frag;
+ if (prev)
+ prev->next = fragment;
+ else
+ outOfSequenceFragments = fragment;
+ }
+ lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
+ }
SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT),
m_Server (server), m_Address (addr), m_RemoteTransports (0),
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
- m_SendPacketNum (0), m_ReceivePacketNum (0), 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_SendPacketNum (0), m_ReceivePacketNum (0), m_LastDatetimeSentPacketNum (0),
+ 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_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose),
m_MaxPayloadSize (SSU2_MIN_PACKET_SIZE - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - 32) // min size
{
@@ -563,7 +608,7 @@
* payload = m_SentHandshakePacket->payload;
// fill packet
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.flags[0] = 2; // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
@@ -591,7 +636,7 @@
m_EphemeralKeys->Agree (m_Address->s, sharedSecret);
m_NoiseState->MixKey (sharedSecret);
// 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);
payloadSize += 16;
header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
@@ -603,6 +648,7 @@
if (m_State == eSSU2SessionStateTokenReceived || m_Server.AddPendingOutgoingSession (shared_from_this ()))
{
m_State = eSSU2SessionStateSessionRequestSent;
+ m_HandshakeInterval = ts;
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
}
else
@@ -676,7 +722,7 @@
uint8_t * headerX = m_SentHandshakePacket->headerX,
* payload = m_SentHandshakePacket->payload;
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.flags[0] = 2; // ver
header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID
@@ -715,7 +761,7 @@
m_EphemeralKeys->Agree (X, sharedSecret);
m_NoiseState->MixKey (sharedSecret);
// 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);
payloadSize += 16;
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || encrypted Noise payload from Session Created)
@@ -725,6 +771,7 @@
m_State = eSSU2SessionStateSessionCreatedSent;
m_SentHandshakePacket->payloadSize = payloadSize;
// send
+ m_HandshakeInterval = ts;
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
}
@@ -745,6 +792,7 @@
LogPrint (eLogWarning, "SSU2: SessionCreated message too short ", len);
return false;
}
+ m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
const uint8_t nonce[12] = {0};
uint8_t headerX[48];
i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX);
@@ -761,6 +809,8 @@
m_NoiseState->m_CK + 32, nonce, decryptedPayload.data (), decryptedPayload.size (), false))
{
LogPrint (eLogWarning, "SSU2: SessionCreated AEAD verification failed ");
+ if (GetRemoteIdentity ())
+ i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key
return false;
}
m_NoiseState->MixHash (payload, len - 64); // h = SHA256(h || encrypted payload from SessionCreated) for SessionConfirmed
@@ -787,7 +837,7 @@
// fill packet
Header& header = m_SentHandshakePacket->header;
header.h.connID = m_DestConnID; // dest id
- header.h.packetNum = 0;
+ header.h.packetNum = 0; // always zero
header.h.type = eSSU2SessionConfirmed;
memset (header.h.flags, 0, 3);
header.h.flags[0] = 1; // frag, total fragments always 1
@@ -810,7 +860,7 @@
// Encrypt part 1
uint8_t * part1 = m_SentHandshakePacket->headerX;
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);
m_NoiseState->MixHash (part1, 48); // h = SHA256(h || ciphertext);
// KDF for Session Confirmed part 2
@@ -818,7 +868,7 @@
i2p::context.GetSSU2StaticKeys ().Agree (Y, sharedSecret);
m_NoiseState->MixKey (sharedSecret);
// 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);
payloadSize += 16;
m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || ciphertext);
@@ -875,6 +925,12 @@
// TODO: queue up
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
uint8_t numFragments = header.h.flags[0] & 0x0F;
if (numFragments > 1)
@@ -944,6 +1000,7 @@
if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr);
return false;
}
+ m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval;
// KDF for Session Confirmed part 1
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
// decrypt part1
@@ -996,10 +1053,18 @@
LogPrint (eLogError, "SSU2: SessionConfirmed malformed RouterInfo block");
return false;
}
- m_Address = ri->GetSSU2AddressWithStaticKey (S, m_RemoteEndpoint.address ().is_v6 ());
- if (!m_Address)
+ m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address ();
+ if (!m_Address || memcmp (S, m_Address->s, 32))
{
- LogPrint (eLogError, "SSU2: No SSU2 address with static key found in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ()));
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/SSU2Session.h
^
|
@@ -48,9 +48,12 @@
const size_t SSU2_MAX_RTO = 2500; // in milliseconds
const float SSU2_kAPPA = 1.8;
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_ACK_PACKETS = 511; // ackthrough + acnt + 1 range
const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send
const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64;
-
+ const int SSU2_SEND_DATETIME_NUM_PACKETS = 256;
+
// flags
const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01;
@@ -171,15 +174,19 @@
{
uint8_t buf[SSU2_MAX_PACKET_SIZE];
size_t len;
+ int fragmentNum;
bool isLast;
+ std::shared_ptr<Fragment> next;
};
std::shared_ptr<I2NPMessage> msg;
int nextFragmentNum;
uint32_t lastFragmentInsertTime; // in seconds
- std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
+ std::shared_ptr<Fragment> outOfSequenceFragments; // #1 and more
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
+ bool ConcatOutOfSequenceFragments (); // true if message complete
+ void AddOutOfSequenceFragment (std::shared_ptr<Fragment> fragment);
};
struct SSU2SentPacket
@@ -306,13 +313,12 @@
bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate
void HandleFirstFragment (const uint8_t * buf, size_t len);
void HandleFollowOnFragment (const uint8_t * buf, size_t len);
- bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
void HandleRelayRequest (const uint8_t * buf, size_t len);
void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0);
void HandleRelayResponse (const uint8_t * buf, size_t len);
void HandlePeerTest (const uint8_t * buf, size_t len);
void HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg);
-
+
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
size_t CreateAckBlock (uint8_t * buf, size_t len);
@@ -339,10 +345,10 @@
uint64_t m_DestConnID, m_SourceConnID;
SSU2SessionState m_State;
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
- uint32_t m_SendPacketNum, m_ReceivePacketNum;
+ uint32_t m_SendPacketNum, m_ReceivePacketNum, m_LastDatetimeSentPacketNum;
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
std::map<uint32_t, std::shared_ptr<SSU2SentPacket> > m_SentPackets; // packetNum -> packet
- std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
+ std::unordered_map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // msgID -> I2NP
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_PeerTests; // same as for relay sessions
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Streaming.cpp
^
|
@@ -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
*
@@ -51,8 +51,8 @@
{
// partially
rem = len - offset;
- memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset);
- nextBuffer->offset += (len - offset);
+ memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem);
+ nextBuffer->offset += rem;
offset = len; // break
}
}
@@ -139,14 +139,22 @@
{
m_NumReceivedBytes += packet->GetLength ();
if (!m_SendStreamID)
+ {
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
ProcessAck (packet);
int32_t receivedSeqn = packet->GetSeqn ();
- bool isSyn = packet->IsSYN ();
- if (!receivedSeqn && !isSyn)
+ if (!receivedSeqn && !packet->GetFlags ())
{
// plain ack
LogPrint (eLogDebug, "Streaming: Plain ACK received");
@@ -188,7 +196,7 @@
shared_from_this (), std::placeholders::_1));
}
}
- else if (isSyn)
+ else if (packet->IsSYN ())
// we have to send SYN back to incoming connection
SendBuffer (); // also sets m_IsOpen
}
@@ -384,7 +392,7 @@
memset (p.buf, 0, 22); // minimal header all zeroes
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
- ssize_t payloadLen = packet->len - (packet->GetPayload () - packet->buf);
+ auto payloadLen = int(packet->len) - (packet->GetPayload () - packet->buf);
if (payloadLen > 0)
memcpy (p.buf + 22, packet->GetPayload (), payloadLen);
else
@@ -560,8 +568,19 @@
else
htobe32buf (packet + size, m_LastReceivedSequenceNumber);
size += 4; // ack Through
- packet[size] = 0;
- size++; // NACK count
+ if (m_Status == eStreamStatusNew && !m_SendStreamID && m_RemoteIdentity)
+ {
+ // 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;
size++; // resend delay
if (m_Status == eStreamStatusNew)
@@ -906,7 +925,7 @@
});
m_NumSentBytes += it->GetLength ();
}
- m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs);
+ m_CurrentOutboundTunnel->SendTunnelDataMsgs (msgs);
}
else
{
@@ -1428,7 +1447,7 @@
const uint8_t * payload, size_t len, uint16_t toPort, bool checksum, bool gzip)
{
size_t size;
- auto msg = m_I2NPMsgsPool.AcquireShared ();
+ auto msg = (len <= STREAMING_MTU_RATCHETS) ? m_I2NPMsgsPool.AcquireShared () : NewI2NPMessage ();
uint8_t * buf = msg->GetPayload ();
buf += 4; // reserve for lengthlength
msg->len += 4;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Streaming.h
^
|
@@ -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
*
@@ -80,6 +80,7 @@
uint32_t GetAckThrough () const { return bufbe32toh (buf + 12); };
uint8_t GetNACKCount () const { return buf[16]; };
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
uint16_t GetFlags () const { return bufbe16toh (GetOption () - 2); };
uint16_t GetOptionSize () const { return bufbe16toh (GetOption ()); };
@@ -312,7 +313,7 @@
std::unordered_map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
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:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Tag.h
^
|
@@ -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
*
@@ -80,6 +80,13 @@
return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
}
+ uint8_t GetBit (int i) const
+ {
+ int pos = i >> 3; // /8
+ if (pos >= (int)sz) return 0;
+ return m_Buf[pos] & (0x80 >> (i & 0x07));
+ }
+
private:
union // 8 bytes aligned
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/TransitTunnel.h
^
|
@@ -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
*
@@ -34,9 +34,9 @@
virtual size_t GetNumTransmittedBytes () const { return 0; };
// implements TunnelBase
- void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
- void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
- void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
+ void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
+ void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
+ void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
private:
i2p::crypto::AESKey m_LayerKey, m_IVKey;
@@ -54,9 +54,9 @@
layerKey, ivKey), m_NumTransmittedBytes (0) {};
~TransitTunnelParticipant ();
- size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; };
- void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg);
- void FlushTunnelDataMsgs ();
+ size_t GetNumTransmittedBytes () const override { return m_NumTransmittedBytes; };
+ void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
+ void FlushTunnelDataMsgs () override;
private:
@@ -74,9 +74,9 @@
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
layerKey, ivKey), m_Gateway(this) {};
- void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
- void FlushTunnelDataMsgs ();
- size_t GetNumTransmittedBytes () const { return m_Gateway.GetNumSentBytes (); };
+ void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
+ void FlushTunnelDataMsgs () override;
+ size_t GetNumTransmittedBytes () const override { return m_Gateway.GetNumSentBytes (); };
private:
@@ -94,10 +94,10 @@
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey),
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);
- size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }
+ void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
+ size_t GetNumTransmittedBytes () const override { return m_Endpoint.GetNumReceivedBytes (); }
private:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/TransportSession.h
^
|
@@ -69,6 +69,8 @@
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
{
public:
@@ -76,7 +78,8 @@
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> router, int terminationTimeout):
m_NumSentBytes (0), m_NumReceivedBytes (0), m_SendQueueSize (0),
m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
- m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ())
+ m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()),
+ m_HandshakeInterval (0)
{
if (router)
m_RemoteIdentity = router->GetRouterIdentity ();
@@ -103,11 +106,16 @@
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
size_t GetSendQueueSize () const { return m_SendQueueSize; };
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; };
void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; };
bool IsTerminationTimeoutExpired (uint64_t ts) const
- { return ts >= m_LastActivityTimestamp + GetTerminationTimeout (); };
+ {
+ return ts >= m_LastActivityTimestamp + GetTerminationTimeout () ||
+ ts + GetTerminationTimeout () < m_LastActivityTimestamp;
+ };
uint32_t GetCreationTime () const { return m_CreationTime; };
void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers
@@ -126,6 +134,7 @@
int m_TerminationTimeout;
uint64_t m_LastActivityTimestamp;
uint32_t m_CreationTime; // seconds since epoch
+ int64_t m_HandshakeInterval; // in milliseconds between SessionRequest->SessionCreated or SessionCreated->SessionConfirmed
};
// SOCKS5 proxy
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Transports.cpp
^
|
@@ -200,10 +200,10 @@
i2p::context.SetStatusV6 (eRouterStatusProxy);
}
else
- LogPrint(eLogError, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy);
+ LogPrint(eLogCritical, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy);
}
else
- LogPrint(eLogError, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy);
+ LogPrint(eLogCritical, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy);
}
else
m_NTCP2Server = new NTCP2Server ();
@@ -225,10 +225,10 @@
i2p::context.SetStatusV6 (eRouterStatusProxy);
}
else
- LogPrint(eLogError, "Transports: Can't set SSU2 proxy ", ssu2proxy);
+ LogPrint(eLogCritical, "Transports: Can't set SSU2 proxy ", ssu2proxy);
}
else
- LogPrint(eLogError, "Transports: Invalid SSU2 proxy URL ", ssu2proxy);
+ LogPrint(eLogCritical, "Transports: Invalid SSU2 proxy URL ", ssu2proxy);
}
}
@@ -458,8 +458,20 @@
it->second.sessions.front ()->SendI2NPMessages (msgs);
else
{
- if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES)
+ auto sz = it->second.delayedMessages.size ();
+ if (sz < MAX_NUM_DELAYED_MESSAGES)
{
+ if (sz < CHECK_PROFILE_NUM_DELAYED_MESSAGES && sz + msgs.size () >= CHECK_PROFILE_NUM_DELAYED_MESSAGES)
+ {
+ auto profile = i2p::data::GetRouterProfile (ident);
+ if (profile && profile->IsUnreachable ())
+ {
+ LogPrint (eLogWarning, "Transports: Peer profile for ", ident.ToBase64 (), " reports unreachable. Dropped");
+ std::unique_lock<std::mutex> l(m_PeersMutex);
+ m_Peers.erase (it);
+ return;
+ }
+ }
for (auto& it1: msgs)
it->second.delayedMessages.push_back (it1);
}
@@ -476,7 +488,7 @@
bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer)
{
if (!peer.router) // reconnect
- peer.router = netdb.FindRouter (ident); // try to get new one from netdb
+ peer.SetRouter (netdb.FindRouter (ident)); // try to get new one from netdb
if (peer.router) // we have RI already
{
if (peer.priority.empty ())
@@ -539,7 +551,8 @@
}
LogPrint (eLogInfo, "Transports: No compatible addresses available");
- i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
+ if (peer.router->IsReachableFrom (i2p::context.GetRouterInfo ()))
+ i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed but router claimed them
peer.Done ();
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident);
@@ -578,7 +591,7 @@
peer.router->GetCompatibleTransports (true);
peer.numAttempts = 0;
peer.priority.clear ();
- bool ssu2 = rand () & 1;
+ bool ssu2 = peer.router->GetProfile ()->IsReal () ? (rand () & 1) : false; // try NTCP2 if router is not confirmed real
const auto& priority = ssu2 ? ssu2Priority : ntcp2Priority;
for (auto transport: priority)
if (transport & compatibleTransports)
@@ -598,7 +611,7 @@
if (r)
{
LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect");
- it->second.router = r;
+ it->second.SetRouter (r);
ConnectToPeer (ident, it->second);
}
else
@@ -687,6 +700,24 @@
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{
+ if (it->second.numAttempts > 1)
+ {
+ // exclude failed transports
+ i2p::data::RouterInfo::CompatibleTransports transports = 0;
+ int numExcluded = it->second.numAttempts - 1;
+ if (numExcluded > (int)it->second.priority.size ()) numExcluded = it->second.priority.size ();
+ for (int i = 0; i < numExcluded; i++)
+ transports |= it->second.priority[i];
+ i2p::data::netdb.ExcludeReachableTransports (ident, transports);
+ }
+ if (it->second.router && it->second.numAttempts)
+ {
+ auto transport = it->second.priority[it->second.numAttempts-1];
+ if (transport == i2p::data::RouterInfo::eNTCP2V4 ||
+ transport == i2p::data::RouterInfo::eNTCP2V6 || transport == i2p::data::RouterInfo::eNTCP2V6Mesh)
+ it->second.router->GetProfile ()->Connected (); // outgoing NTCP2 connection if always real
+ }
+ it->second.numAttempts = 0;
it->second.router = nullptr; // we don't need RouterInfo after successive connect
bool sendDatabaseStore = true;
if (it->second.delayedMessages.size () > 0)
@@ -705,7 +736,7 @@
session->SendI2NPMessages (it->second.delayedMessages);
it->second.delayedMessages.clear ();
}
- else // incoming connection
+ else // incoming connection or peer test
{
if(RoutesRestricted() && ! IsRestrictedPeer(ident)) {
// not trusted
@@ -713,11 +744,15 @@
session->Done();
return;
}
- session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
+ if (!session->IsOutgoing ()) // incoming
+ session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
+ auto r = i2p::data::netdb.FindRouter (ident); // router should be in netdb after SessionConfirmed
+ if (r) r->GetProfile ()->Connected ();
auto ts = i2p::util::GetSecondsSinceEpoch ();
std::unique_lock<std::mutex> l(m_PeersMutex);
- auto it = m_Peers.insert (std::make_pair (ident, Peer{ nullptr, ts })).first;
+ auto it = m_Peers.insert (std::make_pair (ident, Peer{ r, ts })).first;
it->second.sessions.push_back (session);
+ it->second.router = nullptr;
}
});
}
@@ -774,11 +809,12 @@
if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT)
{
LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds");
- auto profile = i2p::data::GetRouterProfile(it->first);
- if (profile)
- {
- profile->TunnelNonReplied();
- }
+ /* if (!it->second.router)
+ {
+ // if router for ident not found mark it unreachable
+ auto profile = i2p::data::GetRouterProfile (it->first);
+ if (profile) profile->Unreachable ();
+ } */
std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.erase (it);
}
@@ -815,20 +851,102 @@
}
}
- std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
+ template<typename Filter>
+ std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer (Filter filter) const
{
- if (m_Peers.empty ()) return nullptr;
+ if (m_Peers.empty()) return nullptr;
+ bool found = false;
i2p::data::IdentHash ident;
{
+ uint16_t inds[3];
+ RAND_bytes ((uint8_t *)inds, sizeof (inds));
std::unique_lock<std::mutex> l(m_PeersMutex);
+ inds[0] %= m_Peers.size ();
auto it = m_Peers.begin ();
- std::advance (it, rand () % m_Peers.size ());
- if (it == m_Peers.end () || it->second.router || it->second.sessions.empty () ||
- it->second.sessions.front ()->GetSendQueueSize () > PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE)
- return nullptr; // not connected or overloaded
- ident = it->first;
+ std::advance (it, inds[0]);
+ // try random peer
+ if (it != m_Peers.end () && filter (it->second))
+ {
+ ident = it->first;
+ found = true;
+ }
+ else
+ {
+ // try some peers around
+ auto it1 = m_Peers.begin ();
+ if (inds[0])
+ {
+ // before
+ inds[1] %= inds[0];
+ std::advance (it1, (inds[1] + inds[0])/2);
+ }
+ else
+ it1 = it;
+ auto it2 = it;
+ if (inds[0] < m_Peers.size () - 1)
+ {
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Transports.h
^
|
@@ -72,11 +72,18 @@
uint64_t creationTime, nextRouterInfoUpdateTime;
std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages;
std::vector<i2p::data::RouterInfo::SupportedTransports> priority;
+ bool isHighBandwidth, isReachable;
Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts):
numAttempts (0), router (r), creationTime (ts),
- nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL)
+ nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL),
+ isHighBandwidth (false), isReachable (false)
{
+ if (router)
+ {
+ isHighBandwidth = router->IsHighBandwidth ();
+ isReachable = (bool)router->GetCompatibleTransports (true);
+ }
}
void Done ()
@@ -84,11 +91,22 @@
for (auto& it: sessions)
it->Done ();
}
+
+ void SetRouter (std::shared_ptr<const i2p::data::RouterInfo> r)
+ {
+ router = r;
+ if (router)
+ {
+ isHighBandwidth = router->IsHighBandwidth ();
+ isReachable = (bool)router->GetCompatibleTransports (true);
+ }
+ }
};
const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds
const int PEER_TEST_INTERVAL = 71; // in minutes
const int MAX_NUM_DELAYED_MESSAGES = 150;
+ const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after
class Transports
{
public:
@@ -131,7 +149,7 @@
bool IsBandwidthExceeded () const;
bool IsTransitBandwidthExceeded () const;
size_t GetNumPeers () const { return m_Peers.size (); };
- std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer () const;
+ std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer (bool isHighBandwidth) const;
/** get a trusted first hop for restricted routes */
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;
@@ -163,6 +181,9 @@
void DetectExternalIP ();
+ template<typename Filter>
+ std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer (Filter filter) const;
+
private:
volatile bool m_IsOnline;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Tunnel.cpp
^
|
@@ -103,7 +103,7 @@
if (msg1) msg = msg1;
}
}
- outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg);
+ outboundTunnel->SendTunnelDataMsgTo (GetNextIdentHash (), 0, msg);
}
else
{
@@ -266,7 +266,7 @@
}
}
- 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;
if (gwHash)
@@ -284,10 +284,10 @@
block.deliveryType = eDeliveryTypeLocal;
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);
for (auto& it : msgs)
@@ -306,7 +306,7 @@
{
}
- void ZeroHopsOutboundTunnel::SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs)
+ void ZeroHopsOutboundTunnel::SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs)
{
for (auto& msg : msgs)
{
@@ -331,13 +331,15 @@
Tunnels tunnels;
- Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr),
- m_NumSuccesiveTunnelCreations (0), m_NumFailedTunnelCreations (0)
+ Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_MaxNumTransitTunnels (DEFAULT_MAX_NUM_TRANSIT_TUNNELS),
+ m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal average
+ m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0)
{
}
Tunnels::~Tunnels ()
{
+ DeleteTunnelPool(m_ExploratoryPool);
}
std::shared_ptr<TunnelBase> Tunnels::GetTunnel (uint32_t tunnelID)
@@ -438,11 +440,11 @@
if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second)
m_TransitTunnels.push_back (tunnel);
else
- {
+ {
LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists");
- return false;
- }
- return true;
+ return false;
+ }
+ return true;
}
void Tunnels::Start ()
@@ -514,7 +516,7 @@
case eI2NPShortTunnelBuildReply:
case eI2NPTunnelBuild:
case eI2NPTunnelBuildReply:
- HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
+ HandleTunnelBuildI2NPMessage (msg);
break;
default:
LogPrint (eLogWarning, "Tunnel: Unexpected message type ", (int) typeID);
@@ -536,17 +538,20 @@
if (i2p::transport::transports.IsOnline())
{
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
- if (ts - lastTs >= TUNNEL_MANAGE_INTERVAL) // manage tunnels every 15 seconds
+ if (ts - lastTs >= TUNNEL_MANAGE_INTERVAL || // manage tunnels every 15 seconds
+ ts + TUNNEL_MANAGE_INTERVAL < lastTs)
{
- ManageTunnels ();
+ ManageTunnels (ts);
lastTs = ts;
}
- if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL) // manage pools every 5 seconds
+ if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 seconds
+ ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs)
{
ManageTunnelPools (ts);
lastPoolsTs = ts;
}
- if (ts - lastMemoryPoolTs >= TUNNEL_MEMORY_POOL_MANAGE_INTERVAL) // manage memory pool every 2 minutes
+ if (ts - lastMemoryPoolTs >= TUNNEL_MEMORY_POOL_MANAGE_INTERVAL ||
+ ts + TUNNEL_MEMORY_POOL_MANAGE_INTERVAL < lastMemoryPoolTs) // manage memory pool every 2 minutes
{
m_I2NPTunnelEndpointMessagesMemoryPool.CleanUpMt ();
m_I2NPTunnelMessagesMemoryPool.CleanUpMt ();
@@ -581,39 +586,46 @@
auto typeID = msg->GetTypeID ();
LogPrint (eLogDebug, "Tunnel: Gateway of ", (int) len, " bytes for tunnel ", tunnel->GetTunnelID (), ", msg type ", (int)typeID);
- if (IsRouterInfoMsg (msg) || typeID == eI2NPDatabaseSearchReply)
- // transit DatabaseStore my contain new/updated RI
- // or DatabaseSearchReply with new routers
+ if (typeID == eI2NPDatabaseSearchReply)
+ // DatabaseSearchReply with new routers
i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg));
+ else if (IsRouterInfoMsg (msg))
+ {
+ // transit DatabaseStore might contain new/updated RI
+ auto m = CopyI2NPMessage (msg);
+ if (bufbe32toh (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET))
+ memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply
+ i2p::data::netdb.PostI2NPMsg (m);
+ }
tunnel->SendTunnelDataMsg (msg);
}
- void Tunnels::ManageTunnels ()
+ void Tunnels::ManageTunnels (uint64_t ts)
{
- ManagePendingTunnels ();
- ManageInboundTunnels ();
- ManageOutboundTunnels ();
- ManageTransitTunnels ();
+ ManagePendingTunnels (ts);
+ ManageInboundTunnels (ts);
+ ManageOutboundTunnels (ts);
+ ManageTransitTunnels (ts);
}
- void Tunnels::ManagePendingTunnels ()
+ void Tunnels::ManagePendingTunnels (uint64_t ts)
{
- ManagePendingTunnels (m_PendingInboundTunnels);
- ManagePendingTunnels (m_PendingOutboundTunnels);
+ ManagePendingTunnels (m_PendingInboundTunnels, ts);
+ ManagePendingTunnels (m_PendingOutboundTunnels, ts);
}
template<class PendingTunnels>
- void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels)
+ void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts)
{
// check pending tunnel. delete failed or timeout
- uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();)
{
auto tunnel = it->second;
switch (tunnel->GetState ())
{
case eTunnelStatePending:
- if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
+ if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT ||
+ ts + TUNNEL_CREATION_TIMEOUT < tunnel->GetCreationTime ())
{
LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " timeout, deleted");
// update stats
@@ -634,7 +646,7 @@
}
// delete
it = pendingTunnels.erase (it);
- m_NumFailedTunnelCreations++;
+ FailedTunnelCreation();
}
else
++it;
@@ -642,7 +654,7 @@
case eTunnelStateBuildFailed:
LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " failed, deleted");
it = pendingTunnels.erase (it);
- m_NumFailedTunnelCreations++;
+ FailedTunnelCreation();
break;
case eTunnelStateBuildReplyReceived:
// intermediate state, will be either established of build failed
@@ -651,52 +663,49 @@
default:
// success
it = pendingTunnels.erase (it);
- m_NumSuccesiveTunnelCreations++;
+ SuccesiveTunnelCreation();
}
}
}
- void Tunnels::ManageOutboundTunnels ()
+ void Tunnels::ManageOutboundTunnels (uint64_t ts)
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/Tunnel.h
^
|
@@ -41,6 +41,7 @@
const int MAX_NUM_RECORDS = 8;
const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds
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_POOLS_MANAGE_INTERVAL = 5; // in seconds
const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds
@@ -48,6 +49,9 @@
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 double TCSR_SMOOTHING_CONSTANT = 0.0005; // smoothing constant in exponentially weighted moving average
+ const double TCSR_START_VALUE = 0.1; // start value of tunnel creation success rate
+
enum TunnelState
{
eTunnelStatePending,
@@ -99,8 +103,8 @@
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
// implements TunnelBase
- void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
- void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
+ void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
+ void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
/** @brief add latency sample */
void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; }
@@ -134,15 +138,15 @@
OutboundTunnel (std::shared_ptr<const TunnelConfig> config):
Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {};
- void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
- virtual void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
+ void SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
+ virtual void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
// 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:
@@ -156,12 +160,12 @@
public:
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 (); };
- bool IsInbound() const { return true; }
+ bool IsInbound() const override { return true; }
// override TunnelBase
- void Cleanup () { m_Endpoint.Cleanup (); };
+ void Cleanup () override { m_Endpoint.Cleanup (); };
private:
@@ -173,8 +177,8 @@
public:
ZeroHopsInboundTunnel ();
- void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
- size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
+ void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
+ size_t GetNumReceivedBytes () const override { return m_NumReceivedBytes; };
private:
@@ -186,8 +190,8 @@
public:
ZeroHopsOutboundTunnel ();
- void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs);
- size_t GetNumSentBytes () const { return m_NumSentBytes; };
+ void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs) override;
+ size_t GetNumSentBytes () const override { return m_NumSentBytes; };
private:
@@ -226,6 +230,10 @@
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:
template<class TTunnel>
@@ -238,18 +246,36 @@
void HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg);
void Run ();
- void ManageTunnels ();
- void ManageOutboundTunnels ();
- void ManageInboundTunnels ();
- void ManageTransitTunnels ();
- void ManagePendingTunnels ();
+ void ManageTunnels (uint64_t ts);
+ void ManageOutboundTunnels (uint64_t ts);
+ void ManageInboundTunnels (uint64_t ts);
+ void ManageTransitTunnels (uint64_t ts);
+ void ManagePendingTunnels (uint64_t ts);
template<class PendingTunnels>
- void ManagePendingTunnels (PendingTunnels& pendingTunnels);
+ void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);
void ManageTunnelPools (uint64_t ts);
std::shared_ptr<ZeroHopsInboundTunnel> CreateZeroHopsInboundTunnel (std::shared_ptr<TunnelPool> pool);
std::shared_ptr<ZeroHopsOutboundTunnel> CreateZeroHopsOutboundTunnel (std::shared_ptr<TunnelPool> pool);
+ // Calculating of tunnel creation success rate
+ void SuccesiveTunnelCreation()
+ {
+ // total TCSR
+ m_TotalNumSuccesiveTunnelCreations++;
+ // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity
+ double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum;
+ m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate;
+
+ }
+ void FailedTunnelCreation()
+ {
+ m_TotalNumFailedTunnelCreations++;
+
+ double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum;
+ m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate;
+ }
+
private:
bool m_IsRunning;
@@ -266,9 +292,11 @@
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_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
-
- // some stats
- int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations;
+ uint16_t m_MaxNumTransitTunnels;
+ // count of tunnels for total TCSR algorithm
+ int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
+ double m_TunnelCreationSuccessRate;
+ int m_TunnelCreationAttemptsNum;
public:
@@ -282,10 +310,12 @@
size_t CountOutboundTunnels() const;
int GetQueueSize () { return m_Queue.GetSize (); };
- int GetTunnelCreationSuccessRate () const // in percents
+ int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents
+ double GetPreciseTunnelCreationSuccessRate () const { return m_TunnelCreationSuccessRate * 100; } // in percents
+ int GetTotalTunnelCreationSuccessRate () const // in percents
{
- int totalNum = m_NumSuccesiveTunnelCreations + m_NumFailedTunnelCreations;
- return totalNum ? m_NumSuccesiveTunnelCreations*100/totalNum : 0;
+ int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations;
+ return totalNum ? m_TotalNumSuccesiveTunnelCreations*100/totalNum : 0;
}
};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/TunnelEndpoint.cpp
^
|
@@ -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
*
@@ -208,7 +208,7 @@
if (msg.data->len + size > msg.data->maxLen)
{
// 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);
msg.data = newMsg;
}
@@ -297,11 +297,11 @@
if (msg.data->len + size > msg.data->maxLen)
{
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);
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);
if (it->second->isLastFragment)
// message complete
@@ -323,11 +323,7 @@
}
uint8_t typeID = msg.data->GetTypeID ();
LogPrint (eLogDebug, "TunnelMessage: Handle fragment of ", msg.data->GetLength (), " bytes, msg type ", (int)typeID);
- // catch RI or reply with new list of routers
- if ((IsRouterInfoMsg (msg.data) || typeID == eI2NPDatabaseSearchReply) &&
- !m_IsInbound && msg.deliveryType != eDeliveryTypeLocal)
- i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg.data));
-
+
switch (msg.deliveryType)
{
case eDeliveryTypeLocal:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/TunnelPool.cpp
^
|
@@ -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
*
@@ -383,7 +383,7 @@
std::unique_lock<std::mutex> l(m_TestsMutex);
m_Tests[msgID] = std::make_pair (*it1, *it2);
}
- (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
+ (*it1)->SendTunnelDataMsgTo ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
CreateDeliveryStatusMsg (msgID));
++it1; ++it2;
}
@@ -480,7 +480,7 @@
return hop;
}
- bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop)
+ bool TunnelPool::StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop)
{
int start = 0;
std::shared_ptr<const i2p::data::RouterInfo> prevHop = i2p::context.GetSharedRouterInfo ();
@@ -496,9 +496,9 @@
else if (i2p::transport::transports.GetNumPeers () > 100 ||
(inbound && i2p::transport::transports.GetNumPeers () > 25))
{
- auto r = i2p::transport::transports.GetRandomPeer ();
+ auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ());
if (r && r->IsECIES () && !r->GetProfile ()->IsBad () &&
- (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable
+ (numHops > 1 || (r->IsV4 () && (!inbound || r->IsPublished (true))))) // first inbound must be published ipv4
{
prevHop = r;
path.Add (r);
@@ -512,7 +512,7 @@
if (!hop && !i) // if no suitable peer found for first hop, try already connected
{
LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected");
- hop = i2p::transport::transports.GetRandomPeer ();
+ hop = i2p::transport::transports.GetRandomPeer (false);
if (hop && !hop->IsECIES ()) hop = nullptr;
}
if (!hop)
@@ -520,8 +520,7 @@
LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ());
return false;
}
- if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4
- (inbound && !hop->IsReachable ()))) // IBGW is not reachable
+ if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && !hop->IsPublished (true)))) // IBGW is not published ipv4
{
auto hop1 = nextHop (prevHop, true);
if (hop1) hop = hop1;
@@ -638,8 +637,13 @@
outboundTunnel = tunnels.GetNextOutboundTunnel ();
LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel...");
std::shared_ptr<TunnelConfig> config;
- if (m_NumInboundHops > 0 && tunnel->GetPeers().size())
- config = std::make_shared<TunnelConfig>(tunnel->GetPeers (), tunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ());
+ if (m_NumInboundHops > 0)
+ {
+ auto peers = tunnel->GetPeers();
+ if (peers.size ()&& ValidatePeers (peers))
+ config = std::make_shared<TunnelConfig>(tunnel->GetPeers (),
+ tunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ());
+ }
if (!m_NumInboundHops || config)
{
auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel);
@@ -703,10 +707,12 @@
{
LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel...");
std::shared_ptr<TunnelConfig> config;
- if (m_NumOutboundHops > 0 && tunnel->GetPeers().size())
+ if (m_NumOutboundHops > 0)
{
- config = std::make_shared<TunnelConfig>(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (),
- inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ());
+ auto peers = tunnel->GetPeers();
+ if (peers.size () && ValidatePeers (peers))
+ config = std::make_shared<TunnelConfig>(peers, inboundTunnel->GetNextTunnelID (),
+ inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ());
}
if (!m_NumOutboundHops || config)
{
@@ -747,6 +753,21 @@
return m_CustomPeerSelector != nullptr;
}
+ bool TunnelPool::ValidatePeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers) const
+ {
+ bool highBandwidth = !IsExploratory ();
+ for (auto it: peers)
+ {
+ auto r = i2p::data::netdb.FindRouter (it->GetIdentHash ());
+ if (r)
+ {
+ if (r->IsHighCongestion (highBandwidth)) return false;
+ it = r->GetIdentity (); // use identity from updated RouterInfo
+ }
+ }
+ return true;
+ }
+
std::shared_ptr<InboundTunnel> TunnelPool::GetLowestLatencyInboundTunnel(std::shared_ptr<InboundTunnel> exclude) const
{
std::shared_ptr<InboundTunnel> tun = nullptr;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/TunnelPool.h
^
|
@@ -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
*
@@ -54,12 +54,9 @@
virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0;
};
-
- typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
- bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
-
class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination
{
+ typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
public:
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
@@ -116,6 +113,7 @@
// for overriding tunnel peer selection
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop, bool reverse) const;
+ bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
private:
@@ -128,6 +126,7 @@
typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const;
bool SelectPeers (Path& path, bool isInbound);
bool SelectExplicitPeers (Path& path, bool isInbound);
+ bool ValidatePeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers) const;
private:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/api.cpp
^
|
@@ -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
*
@@ -67,11 +67,15 @@
i2p::transport::transports.Start();
LogPrint(eLogInfo, "API: Starting Tunnels");
i2p::tunnel::tunnels.Start();
+ LogPrint(eLogInfo, "API: Starting Router context");
+ i2p::context.Start();
}
void StopI2P ()
{
LogPrint(eLogInfo, "API: Shutting down");
+ LogPrint(eLogInfo, "API: Stopping Router context");
+ i2p::context.Stop();
LogPrint(eLogInfo, "API: Stopping Tunnels");
i2p::tunnel::tunnels.Stop();
LogPrint(eLogInfo, "API: Stopping Transports");
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/util.cpp
^
|
@@ -8,13 +8,14 @@
#include <cstdlib>
#include <string>
+#include <unordered_set>
#include <boost/asio.hpp>
#include "util.h"
#include "Log.h"
#include "I2PEndian.h"
-#if not defined (__FreeBSD__)
+#if !defined (__FreeBSD__) && !defined(_MSC_VER)
#include <pthread.h>
#endif
@@ -36,6 +37,19 @@
#include <iphlpapi.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 FREE(x) HeapFree(GetProcessHeap(), 0, (x))
@@ -74,7 +88,8 @@
ZeroMemory(&ss, sizeof(ss));
ss.ss_family = af;
- switch(af) {
+ switch (af)
+ {
case AF_INET:
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
break;
@@ -160,7 +175,23 @@
#elif defined(__NetBSD__)
pthread_setname_np(pthread_self(), "%s", (void *)name);
#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);
+ #endif
#endif
}
@@ -170,7 +201,7 @@
int GetMTUWindowsIpv4 (sockaddr_in inputAddress, int fallback)
{
typedef const char *(* IPN)(int af, const void *src, char *dst, socklen_t size);
- IPN inetntop = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop");
+ IPN inetntop = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop");
if (!inetntop) inetntop = inet_ntop_xp; // use own implementation if not found
ULONG outBufLen = 0;
@@ -178,7 +209,7 @@
PIP_ADAPTER_ADDRESSES pCurrAddresses = 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)
{
FREE(pAddresses);
@@ -189,7 +220,7 @@
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");
FREE(pAddresses);
@@ -197,19 +228,17 @@
}
pCurrAddresses = pAddresses;
- while(pCurrAddresses)
+ while (pCurrAddresses)
{
- PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
-
pUnicast = pCurrAddresses->FirstUnicastAddress;
- if(pUnicast == nullptr)
+ if (pUnicast == nullptr)
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;
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];
inetntop(AF_INET, &(((struct sockaddr_in *)localInterfaceAddress)->sin_addr), addr, INET_ADDRSTRLEN);
@@ -233,7 +262,7 @@
int GetMTUWindowsIpv6 (sockaddr_in6 inputAddress, int fallback)
{
typedef const char *(* IPN)(int af, const void *src, char *dst, socklen_t size);
- IPN inetntop = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop");
+ IPN inetntop = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop");
if (!inetntop) inetntop = inet_ntop_xp; // use own implementation if not found
ULONG outBufLen = 0;
@@ -263,12 +292,11 @@
pCurrAddresses = pAddresses;
while (pCurrAddresses)
{
- PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
pUnicast = pCurrAddresses->FirstUnicastAddress;
if (pUnicast == nullptr)
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;
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
@@ -313,16 +341,16 @@
#endif
typedef int (* IPN)(int af, const char *src, void *dst);
- IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
+ IPN inetpton = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found
- if(localAddress.is_v4())
+ if (localAddress.is_v4())
{
sockaddr_in inputAddress;
inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr));
return GetMTUWindowsIpv4(inputAddress, fallback);
}
- else if(localAddress.is_v6())
+ else if (localAddress.is_v6())
{
sockaddr_in6 inputAddress;
inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr));
@@ -338,7 +366,7 @@
int GetMTUUnix (const boost::asio::ip::address& localAddress, int fallback)
{
ifaddrs* ifaddr, *ifa = nullptr;
- if(getifaddrs(&ifaddr) == -1)
+ if (getifaddrs(&ifaddr) == -1)
{
LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno));
return fallback;
@@ -346,34 +374,34 @@
int family = 0;
// 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;
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;
- 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
}
- else if(family == AF_INET6 && localAddress.is_v6())
+ else if (family == AF_INET6 && localAddress.is_v6())
{
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
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/util.h
^
|
@@ -224,6 +224,7 @@
bool IsLocalAddress (const boost::asio::ip::address& addr);
bool IsInReservedRange (const boost::asio::ip::address& host);
bool IsYggdrasilAddress (const boost::asio::ip::address& addr);
+ bool IsPortInReservedRange (const uint16_t port) noexcept;
}
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd/version.h
^
|
@@ -11,16 +11,18 @@
#define CODENAME "Purple"
+#define XSTRINGIZE(x) STRINGIZE(x)
#define STRINGIZE(x) #x
+
#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 I2PD_VERSION_MAJOR 2
-#define I2PD_VERSION_MINOR 45
-#define I2PD_VERSION_MICRO 1
+#define I2PD_VERSION_MINOR 48
+#define I2PD_VERSION_MICRO 0
#define I2PD_VERSION_PATCH 0
#ifdef GITVER
- #define I2PD_VERSION GITVER
+ #define I2PD_VERSION XSTRINGIZE(GITVER)
#else
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
#endif
@@ -31,7 +33,7 @@
#define I2P_VERSION_MAJOR 0
#define I2P_VERSION_MINOR 9
-#define I2P_VERSION_MICRO 57
+#define I2P_VERSION_MICRO 59
#define I2P_VERSION_PATCH 0
#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)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/AddressBook.cpp
^
|
@@ -661,7 +661,7 @@
this, std::placeholders::_1));
}
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 ()
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/BOB.cpp
^
|
@@ -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
*
@@ -127,7 +127,7 @@
connection->I2PConnect (receiver->data, receiver->dataLen);
}
- BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, int port,
+ BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, uint16_t port,
std::shared_ptr<ClientDestination> localDestination, bool quiet): BOBI2PTunnel (localDestination),
m_Endpoint (boost::asio::ip::address::from_string (outhost), port), m_IsQuiet (quiet)
{
@@ -164,7 +164,7 @@
BOBDestination::BOBDestination (std::shared_ptr<ClientDestination> localDestination,
const std::string &nickname, const std::string &inhost, const std::string &outhost,
- const int inport, const int outport, const bool quiet):
+ const uint16_t inport, const uint16_t outport, const bool quiet):
m_LocalDestination (localDestination),
m_OutboundTunnel (nullptr), m_InboundTunnel (nullptr),
m_Nickname(nickname), m_InHost(inhost), m_OutHost(outhost),
@@ -209,7 +209,7 @@
}
}
- void BOBDestination::CreateInboundTunnel (int port, const std::string& inhost)
+ void BOBDestination::CreateInboundTunnel (uint16_t port, const std::string& inhost)
{
if (!m_InboundTunnel)
{
@@ -230,7 +230,7 @@
}
}
- void BOBDestination::CreateOutboundTunnel (const std::string& outhost, int port, bool quiet)
+ void BOBDestination::CreateOutboundTunnel (const std::string& outhost, uint16_t port, bool quiet)
{
if (!m_OutboundTunnel)
{
@@ -595,9 +595,12 @@
LogPrint (eLogDebug, "BOB: outport ", operand);
if (*operand)
{
- m_OutPort = std::stoi(operand);
- if (m_OutPort >= 0)
+ int port = std::stoi(operand);
+ if (port >= 0 && port < 65536)
+ {
+ m_OutPort = port;
SendReplyOK ("outbound port set");
+ }
else
SendReplyError ("port out of range");
}
@@ -622,9 +625,12 @@
LogPrint (eLogDebug, "BOB: inport ", operand);
if (*operand)
{
- m_InPort = std::stoi(operand);
- if (m_InPort >= 0)
+ int port = std::stoi(operand);
+ if (port >= 0 && port < 65536)
+ {
+ m_InPort = port;
SendReplyOK ("inbound port set");
+ }
else
SendReplyError ("port out of range");
}
@@ -814,7 +820,7 @@
}
}
- BOBCommandChannel::BOBCommandChannel (const std::string& address, int port):
+ BOBCommandChannel::BOBCommandChannel (const std::string& address, uint16_t port):
RunnableService ("BOB"),
m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port))
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/BOB.h
^
|
@@ -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
*
@@ -124,7 +124,7 @@
{
public:
- BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr<ClientDestination> localDestination, bool quiet);
+ BOBI2POutboundTunnel (const std::string& outhost, uint16_t port, std::shared_ptr<ClientDestination> localDestination, bool quiet);
void Start ();
void Stop ();
@@ -149,19 +149,19 @@
BOBDestination (std::shared_ptr<ClientDestination> localDestination,
const std::string &nickname, const std::string &inhost, const std::string &outhost,
- const int inport, const int outport, const bool quiet);
+ const uint16_t inport, const uint16_t outport, const bool quiet);
~BOBDestination ();
void Start ();
void Stop ();
void StopTunnels ();
- void CreateInboundTunnel (int port, const std::string& inhost);
- void CreateOutboundTunnel (const std::string& outhost, int port, bool quiet);
+ void CreateInboundTunnel (uint16_t port, const std::string& inhost);
+ void CreateOutboundTunnel (const std::string& outhost, uint16_t port, bool quiet);
const std::string& GetNickname() const { return m_Nickname; }
const std::string& GetInHost() const { return m_InHost; }
const std::string& GetOutHost() const { return m_OutHost; }
- int GetInPort() const { return m_InPort; }
- int GetOutPort() const { return m_OutPort; }
+ uint16_t GetInPort() const { return m_InPort; }
+ uint16_t GetOutPort() const { return m_OutPort; }
bool GetQuiet() const { return m_Quiet; }
bool IsRunning() const { return m_IsRunning; }
const i2p::data::PrivateKeys& GetKeys () const { return m_LocalDestination->GetPrivateKeys (); };
@@ -175,7 +175,7 @@
std::string m_Nickname;
std::string m_InHost, m_OutHost;
- int m_InPort, m_OutPort;
+ uint16_t m_InPort, m_OutPort;
bool m_Quiet;
bool m_IsRunning;
};
@@ -237,7 +237,7 @@
boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer;
bool m_IsOpen, m_IsQuiet, m_IsActive;
std::string m_Nickname, m_InHost, m_OutHost;
- int m_InPort, m_OutPort;
+ uint16_t m_InPort, m_OutPort;
i2p::data::PrivateKeys m_Keys;
std::map<std::string, std::string> m_Options;
BOBDestination * m_CurrentDestination;
@@ -248,7 +248,7 @@
{
public:
- BOBCommandChannel (const std::string& address, int port);
+ BOBCommandChannel (const std::string& address, uint16_t port);
~BOBCommandChannel ();
void Start ();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/ClientContext.cpp
^
|
@@ -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
*
@@ -63,18 +63,19 @@
if (sam)
{
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);
- LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":", samPort);
+ LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP, "]");
try
{
- m_SamBridge = new SAMBridge (samAddr, samPort, singleThread);
+ m_SamBridge = new SAMBridge (samAddr, samPortTCP, samPortUDP, singleThread);
m_SamBridge->Start ();
}
catch (std::exception& e)
{
- LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what());
- ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ());
+ LogPrint(eLogCritical, "Clients: Exception in SAM bridge: ", e.what());
+ ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP,"]: ", e.what ());
}
}
@@ -91,7 +92,7 @@
}
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 ());
}
}
@@ -111,7 +112,7 @@
}
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 ());
}
}
@@ -185,22 +186,30 @@
LogPrint(eLogInfo, "Clients: Stopping AddressBook");
m_AddressBook.Stop ();
+ LogPrint(eLogInfo, "Clients: Stopping UDP Tunnels");
{
std::lock_guard<std::mutex> lock(m_ForwardsMutex);
m_ServerForwards.clear();
m_ClientForwards.clear();
}
+ LogPrint(eLogInfo, "Clients: Stopping UDP Tunnels timers");
if (m_CleanupUDPTimer)
{
m_CleanupUDPTimer->cancel ();
m_CleanupUDPTimer = nullptr;
}
- for (auto& it: m_Destinations)
- it.second->Stop ();
- m_Destinations.clear ();
+ {
+ LogPrint(eLogInfo, "Clients: Stopping Destinations");
+ std::lock_guard<std::mutex> lock(m_DestinationsMutex);
+ for (auto& it: m_Destinations)
+ it.second->Stop ();
+ LogPrint(eLogInfo, "Clients: Stopping Destinations - Clear");
+ m_Destinations.clear ();
+ }
+ LogPrint(eLogInfo, "Clients: Stopping SharedLocalDestination");
m_SharedLocalDestination->Release ();
m_SharedLocalDestination = nullptr;
}
@@ -278,7 +287,7 @@
s.read ((char *)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;
}
else
@@ -287,7 +296,7 @@
}
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);
std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out);
size_t len = keys.GetFullLen ();
@@ -568,12 +577,12 @@
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
- int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
+ uint16_t port = section.second.get<uint16_t> (I2P_CLIENT_TUNNEL_PORT);
// optional params
- bool matchTunnels = section.second.get(I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false);
- std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "transient");
- std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
- int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
+ bool matchTunnels = section.second.get (I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false);
+ std::string keys = section.second.get<std::string> (I2P_CLIENT_TUNNEL_KEYS, "transient");
+ std::string address = section.second.get<std::string> (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
+ uint16_t destinationPort = section.second.get<uint16_t> (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
// I2CP
@@ -711,22 +720,22 @@
{
// mandatory params
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
- int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
+ uint16_t port = section.second.get<uint16_t> (I2P_SERVER_TUNNEL_PORT);
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS);
// optional params
- int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
- std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
+ uint16_t inPort = section.second.get<uint16_t> (I2P_SERVER_TUNNEL_INPORT, port);
+ std::string accessList = section.second.get<std::string> (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
if(accessList == "")
- accessList=section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, "");
- std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
+ accessList = section.second.get<std::string> (I2P_SERVER_TUNNEL_WHITE_LIST, "");
+ std::string hostOverride = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, false);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "");
- bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
- bool ssl = section.second.get(I2P_SERVER_TUNNEL_SSL, false);
+ bool isUniqueLocal = section.second.get (I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
+ bool ssl = section.second.get (I2P_SERVER_TUNNEL_SSL, false);
// I2CP
std::map<std::string, std::string> options;
@@ -850,7 +859,7 @@
}
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 ());
}
}
@@ -882,7 +891,7 @@
if (localDestination) localDestination->Acquire ();
}
else
- LogPrint(eLogError, "Clients: Failed to load HTTP Proxy key");
+ LogPrint(eLogCritical, "Clients: Failed to load HTTP Proxy key");
}
try
{
@@ -891,7 +900,7 @@
}
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 ());
}
}
@@ -929,7 +938,7 @@
if (localDestination) localDestination->Acquire ();
}
else
- LogPrint(eLogError, "Clients: Failed to load SOCKS Proxy key");
+ LogPrint(eLogCritical, "Clients: Failed to load SOCKS Proxy key");
}
try
{
@@ -939,7 +948,7 @@
}
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 ());
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/HTTPProxy.cpp
^
|
@@ -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
*
@@ -113,7 +113,7 @@
i2p::http::URL m_ProxyURL;
i2p::http::URL m_RequestURL;
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::HTTPReq m_ClientRequest;
i2p::http::HTTPRes m_ClientResponse;
@@ -238,9 +238,33 @@
std::string value = params["i2paddresshelper"];
len += value.length();
b64 = i2p::http::UrlDecode(value);
+
// if we need update exists, request formed with update param
- if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; }
- if (pos != 0 && url.query[pos-1] == '&') { pos--; len++; } // if helper is not only one query option
+ if (params["update"] == "true")
+ {
+ len += std::strlen("&update=true");
+ confirm = true;
+ }
+
+ // if helper is not only one query option and it placed after user's query
+ if (pos != 0 && url.query[pos-1] == '&')
+ {
+ pos--;
+ len++;
+ }
+ // if helper is not only one query option and it placed before user's query
+ else if (pos == 0 && url.query.length () > len && url.query[len] == '&')
+ {
+ // we don't touch the '?' but remove the trailing '&'
+ len++;
+ }
+ else
+ {
+ // there is no more query options, resetting hasquery flag
+ url.hasquery = false;
+ }
+
+ // reset hasquery flag and remove addresshelper from URL
url.query.replace(pos, len, "");
return true;
}
@@ -321,7 +345,7 @@
if (!m_Addresshelper)
{
LogPrint(eLogWarning, "HTTPProxy: Addresshelper request rejected");
- GenericProxyError(tr("Invalid request"), tr("addresshelper is not supported"));
+ GenericProxyError(tr("Invalid request"), tr("Addresshelper is not supported"));
return true;
}
@@ -333,24 +357,51 @@
}
else if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm)
{
+ const std::string referer_raw = m_ClientRequest.GetHeader("Referer");
+ i2p::http::URL referer_url;
+ if (!referer_raw.empty ())
+ {
+ referer_url.parse (referer_raw);
+ }
+ if (m_RequestURL.host != referer_url.host)
+ {
+ if (m_Confirm) // Attempt to forced overwriting by link with "&update=true" from harmful URL
+ {
+ LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful", ")");
+ std::string full_url = m_RequestURL.to_string();
+ std::stringstream ss;
+ ss << tr("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>.",
+ m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str());
+ GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str());
+ }
+ else // Preventing unauthorized additions to the address book
+ {
+ LogPrint (eLogDebug, "HTTPProxy: Adding address from addresshelper for ", m_RequestURL.host, " (generate refer-base page)");
+ std::string full_url = m_RequestURL.to_string();
+ std::stringstream ss;
+ ss << tr("To add host <b>%s</b> in router's addressbook, click here: <a href=\"%s%s%s\">Continue</a>.",
+ m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str());
+ GenericProxyInfo(tr("Addresshelper request"), ss.str());
+ }
+ return true; /* request processed */
+ }
+
i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, jump);
LogPrint (eLogInfo, "HTTPProxy: Added address from addresshelper for ", m_RequestURL.host);
std::string full_url = m_RequestURL.to_string();
std::stringstream ss;
- ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". ";
- ss << tr("Click here to proceed:") << " <a href=\"" << full_url << "\">" << tr("Continue") << "</a>.";
- GenericProxyInfo(tr("Addresshelper found"), ss.str());
+ ss << tr("Host %s added to router's addressbook from helper. Click here to proceed: <a href=\"%s\">Continue</a>.",
+ m_RequestURL.host.c_str(), full_url.c_str());
+ GenericProxyInfo(tr("Addresshelper adding"), ss.str());
return true; /* request processed */
}
else
{
std::string full_url = m_RequestURL.to_string();
std::stringstream ss;
- ss << tr("Host") << " " << m_RequestURL.host << " <font color=red>" << tr("already in router's addressbook") << "</font>. ";
- ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" );
- ss << " <a href=\"" << full_url << (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper=");
- ss << jump << "&update=true\">" << tr("Continue") << "</a>.";
- GenericProxyInfo(tr("Addresshelper found"), ss.str());
+ ss << tr("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>.",
+ m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str());
+ GenericProxyInfo(tr("Addresshelper update"), ss.str());
return true; /* request processed */
}
}
@@ -363,7 +414,7 @@
auto pos = uri.find(":");
if(pos == std::string::npos || pos == uri.size() - 1)
{
- GenericProxyError(tr("Invalid request"), tr("invalid request uri"));
+ GenericProxyError(tr("Invalid request"), tr("Invalid request URI"));
return true;
}
else
@@ -423,10 +474,10 @@
if(m_ProxyURL.parse(m_OutproxyUrl))
ForwardToUpstreamProxy();
else
- GenericProxyError(tr("Outproxy failure"), tr("bad outproxy settings"));
+ GenericProxyError(tr("Outproxy failure"), tr("Bad outproxy settings"));
} else {
LogPrint (eLogWarning, "HTTPProxy: Outproxy failure for ", dest_host, ": no outproxy enabled");
- std::stringstream ss; ss << tr("Host") << " " << dest_host << " " << tr("not inside I2P network, but outproxy is not enabled");
+ std::stringstream ss; ss << tr("Host %s is not inside I2P network, but outproxy is not enabled", dest_host.c_str());
GenericProxyError(tr("Outproxy failure"), ss.str());
}
return true;
@@ -515,13 +566,13 @@
else
{
/* unknown type, complain */
- GenericProxyError(tr("unknown outproxy url"), m_ProxyURL.to_string());
+ GenericProxyError(tr("Unknown outproxy URL"), m_ProxyURL.to_string());
}
}
void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler)
{
- if(ec) GenericProxyError(tr("cannot resolve upstream proxy"), ec.message());
+ if(ec) GenericProxyError(tr("Cannot resolve upstream proxy"), ec.message());
else handler(*it);
}
@@ -529,7 +580,7 @@
{
if(!ec) {
if(m_RequestURL.host.size() > 255) {
- GenericProxyError(tr("hostname too long"), m_RequestURL.host);
+ GenericProxyError(tr("Hostname is too long"), m_RequestURL.host);
return;
}
uint16_t port = m_RequestURL.port;
@@ -556,13 +607,13 @@
reqsize += host.size();
m_socks_buf[++reqsize] = 0;
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2));
- } else GenericProxyError(tr("cannot connect to upstream socks proxy"), ec.message());
+ } else GenericProxyError(tr("Cannot connect to upstream SOCKS proxy"), ec.message());
}
void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred)
{
LogPrint(eLogDebug, "HTTPProxy: Upstream SOCKS handshake sent");
- if(ec) GenericProxyError(tr("Cannot negotiate with socks proxy"), ec.message());
+ if(ec) GenericProxyError(tr("Cannot negotiate with SOCKS proxy"), ec.message());
else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2));
}
@@ -604,7 +655,7 @@
}
else
{
- GenericProxyError(tr("CONNECT error"), tr("Failed to Connect"));
+ GenericProxyError(tr("CONNECT error"), tr("Failed to connect"));
}
}
@@ -615,7 +666,7 @@
m_send_buf = m_ClientResponse.to_string();
boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred)
{
- if(ec) GenericProxyError(tr("socks proxy error"), ec.message());
+ if(ec) GenericProxyError(tr("SOCKS proxy error"), ec.message());
else HandoverToUpstreamProxy();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/HTTPProxy.h
^
|
@@ -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
*
@@ -15,8 +15,8 @@
{
public:
- HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr<i2p::client::ClientDestination> localDestination);
- HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
+ HTTPProxy(const std::string& name, const std::string& address, uint16_t port, const std::string & outproxy, bool addresshelper, std::shared_ptr<i2p::client::ClientDestination> localDestination);
+ HTTPProxy(const std::string& name, const std::string& address, uint16_t port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
HTTPProxy(name, address, port, "", true, localDestination) {} ;
~HTTPProxy() {};
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2CP.cpp
^
|
@@ -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
*
@@ -230,7 +230,7 @@
remoteLease->tunnelGateway, remoteLease->tunnelID,
garlic
});
- outboundTunnel->SendTunnelDataMsg (msgs);
+ outboundTunnel->SendTunnelDataMsgs (msgs);
return true;
}
else
@@ -936,7 +936,7 @@
}
}
- I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread):
+ I2CPServer::I2CPServer (const std::string& interface, uint16_t port, bool isSingleThread):
RunnableService ("I2CP"), m_IsSingleThread (isSingleThread),
m_Acceptor (GetIOService (),
boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port))
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2CP.h
^
|
@@ -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
*
@@ -210,7 +210,7 @@
{
public:
- I2CPServer (const std::string& interface, int port, bool isSingleThread);
+ I2CPServer (const std::string& interface, uint16_t port, bool isSingleThread);
~I2CPServer ();
void Start ();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2PService.cpp
^
|
@@ -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
*
@@ -107,7 +107,7 @@
m_ReadyTimerTriggered = false;
}
- void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) {
+ void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, uint16_t port) {
assert(streamRequestComplete);
auto address = i2p::client::context.GetAddressBook ().GetAddress (dest);
if (address)
@@ -119,7 +119,7 @@
}
}
- void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr<const Address> address, int port)
+ void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr<const Address> address, uint16_t port)
{
if(m_ConnectTimeout && !m_LocalDestination->IsReady())
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2PService.h
^
|
@@ -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
*
@@ -59,8 +59,8 @@
if (dest) dest->Acquire ();
m_LocalDestination = dest;
}
- void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0);
- void CreateStream(StreamRequestComplete complete, std::shared_ptr<const Address> address, int port);
+ void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, uint16_t port = 0);
+ void CreateStream(StreamRequestComplete complete, std::shared_ptr<const Address> address, uint16_t port);
inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); }
virtual void Start () = 0;
@@ -155,11 +155,11 @@
{
public:
- TCPIPAcceptor (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
+ TCPIPAcceptor (const std::string& address, uint16_t port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
I2PService(localDestination),
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
m_Timer (GetService ()) {}
- TCPIPAcceptor (const std::string& address, int port, i2p::data::SigningKeyType kt) :
+ TCPIPAcceptor (const std::string& address, uint16_t port, i2p::data::SigningKeyType kt) :
I2PService(kt),
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
m_Timer (GetService ()) {}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2PTunnel.cpp
^
|
@@ -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
*
@@ -31,7 +31,7 @@
}
I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
- std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port):
+ std::shared_ptr<const i2p::data::LeaseSet> leaseSet, uint16_t port):
I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()),
m_IsQuiet (true)
{
@@ -346,7 +346,12 @@
}
}
else
+ {
+ // insert incomplete line back
+ m_InHeader.clear ();
+ m_InHeader << line;
break;
+ }
}
if (endOfHeader)
@@ -392,7 +397,8 @@
while (!endOfHeader)
{
std::getline(m_InHeader, line);
- if (!m_InHeader.fail ())
+ if (m_InHeader.fail ()) break;
+ if (!m_InHeader.eof ())
{
if (line == "\r") endOfHeader = true;
else
@@ -409,7 +415,7 @@
matched = true;
break;
}
- if (matched) break;
+ if (matched) continue;
// replace some headers
if (!m_Host.empty () && boost::iequals (line.substr (0, 5), "Host:"))
@@ -428,7 +434,12 @@
}
}
else
+ {
+ // insert incomplete line back
+ m_InHeader.clear ();
+ m_InHeader << line;
break;
+ }
}
if (endOfHeader)
@@ -475,7 +486,8 @@
while (!endOfHeader)
{
std::getline(m_InHeader, line);
- if (!m_InHeader.fail ())
+ if (m_InHeader.fail ()) break;
+ if (!m_InHeader.eof ())
{
if (line == "\r") endOfHeader = true;
else
@@ -496,7 +508,12 @@
}
}
else
+ {
+ // insert incomplete line back
+ m_InHeader.clear ();
+ m_InHeader << line;
break;
+ }
}
if (endOfHeader)
@@ -564,7 +581,7 @@
{
public:
I2PClientTunnelHandler (I2PClientTunnel * parent, std::shared_ptr<const Address> address,
- int destinationPort, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
+ uint16_t destinationPort, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
I2PServiceHandler(parent), m_Address(address),
m_DestinationPort (destinationPort), m_Socket(socket) {};
void Handle();
@@ -572,7 +589,7 @@
private:
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
std::shared_ptr<const Address> m_Address;
- int m_DestinationPort;
+ uint16_t m_DestinationPort;
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
};
@@ -613,7 +630,7 @@
}
I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination,
- const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort):
+ const std::string& address, uint16_t port, std::shared_ptr<ClientDestination> localDestination, uint16_t destinationPort):
TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination),
m_DestinationPort (destinationPort), m_KeepAliveInterval (0)
{
@@ -688,10 +705,12 @@
}
I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address,
- int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip):
+ uint16_t port, std::shared_ptr<ClientDestination> localDestination, uint16_t inport, bool gzip):
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);
+ m_PortDestination = localDestination->GetStreamingDestination (inport);
+ if (!m_PortDestination) // default destination
+ m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip);
}
void I2PServerTunnel::Start ()
@@ -850,8 +869,8 @@
}
I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address,
- int port, std::shared_ptr<ClientDestination> localDestination,
- const std::string& host, int inport, bool gzip):
+ uint16_t port, std::shared_ptr<ClientDestination> localDestination,
+ const std::string& host, uint16_t inport, bool gzip):
I2PServerTunnel (name, address, port, localDestination, inport, gzip),
m_Host (host)
{
@@ -863,8 +882,8 @@
}
I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address,
- int port, std::shared_ptr<ClientDestination> localDestination,
- const std::string& webircpass, int inport, bool gzip):
+ uint16_t port, std::shared_ptr<ClientDestination> localDestination,
+ const std::string& webircpass, uint16_t inport, bool gzip):
I2PServerTunnel (name, address, port, localDestination, inport, gzip),
m_WebircPass (webircpass)
{
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/I2PTunnel.h
^
|
@@ -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
*
@@ -41,7 +41,7 @@
public:
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
- std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
+ std::shared_ptr<const i2p::data::LeaseSet> leaseSet, uint16_t port = 0); // to I2P
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<i2p::stream::Stream> stream); // to I2P using simplified API
I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
@@ -154,7 +154,7 @@
public:
I2PClientTunnel (const std::string& name, const std::string& destination,
- const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
+ const std::string& address, uint16_t port, std::shared_ptr<ClientDestination> localDestination, uint16_t destinationPort = 0);
~I2PClientTunnel () {}
void Start ();
@@ -174,7 +174,7 @@
std::string m_Name, m_Destination;
std::shared_ptr<const Address> m_Address;
- int m_DestinationPort;
+ uint16_t m_DestinationPort;
uint32_t m_KeepAliveInterval;
std::unique_ptr<boost::asio::deadline_timer> m_KeepAliveTimer;
};
@@ -183,8 +183,8 @@
{
public:
- I2PServerTunnel (const std::string& name, const std::string& address, int port,
- std::shared_ptr<ClientDestination> localDestination, int inport = 0, bool gzip = true);
+ I2PServerTunnel (const std::string& name, const std::string& address, uint16_t port,
+ std::shared_ptr<ClientDestination> localDestination, uint16_t inport = 0, bool gzip = true);
void Start ();
void Stop ();
@@ -200,7 +200,7 @@
void SetLocalAddress (const std::string& localAddress);
const std::string& GetAddress() const { return m_Address; }
- int GetPort () const { return m_Port; };
+ uint16_t GetPort () const { return m_Port; };
uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); };
const boost::asio::ip::tcp::endpoint& GetEndpoint () const { return m_Endpoint; }
@@ -219,7 +219,7 @@
bool m_IsUniqueLocal;
std::string m_Name, m_Address;
- int m_Port;
+ uint16_t m_Port;
boost::asio::ip::tcp::endpoint m_Endpoint;
std::shared_ptr<i2p::stream::StreamingDestination> m_PortDestination;
std::set<i2p::data::IdentHash> m_AccessList;
@@ -232,9 +232,9 @@
{
public:
- I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port,
+ I2PServerTunnelHTTP (const std::string& name, const std::string& address, uint16_t port,
std::shared_ptr<ClientDestination> localDestination, const std::string& host,
- int inport = 0, bool gzip = true);
+ uint16_t inport = 0, bool gzip = true);
private:
@@ -249,9 +249,9 @@
{
public:
- I2PServerTunnelIRC (const std::string& name, const std::string& address, int port,
+ I2PServerTunnelIRC (const std::string& name, const std::string& address, uint16_t port,
std::shared_ptr<ClientDestination> localDestination, const std::string& webircpass,
- int inport = 0, bool gzip = true);
+ uint16_t inport = 0, bool gzip = true);
private:
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/MatchedDestination.cpp
^
|
@@ -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
*
@@ -72,7 +72,7 @@
bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound)
{
auto pool = GetTunnelPool();
- if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound,
+ if(!pool || !pool->StandardSelectPeers(path, hops, inbound,
std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2)))
return false;
// more here for outbound tunnels
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/SAM.cpp
^
|
@@ -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
*
@@ -440,18 +440,23 @@
{
if (ecode != boost::asio::error::operation_aborted)
{
- auto session = m_Owner.FindSession(m_ID);
- if(session)
+ if (m_Socket.is_open ())
{
- if (session->GetLocalDestination ()->IsReady ())
- SendSessionCreateReplyOk ();
- else
+ auto session = m_Owner.FindSession(m_ID);
+ if(session)
{
- m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
- m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
- shared_from_this (), std::placeholders::_1));
+ if (session->GetLocalDestination ()->IsReady ())
+ SendSessionCreateReplyOk ();
+ else
+ {
+ m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
+ m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
+ shared_from_this (), std::placeholders::_1));
+ }
}
}
+ else
+ Terminate ("SAM: session socket closed");
}
}
@@ -1212,7 +1217,7 @@
subsessions.clear ();
}
- SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, int port):
+ SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, uint16_t port):
SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port)
{
if (Type == eSAMSessionTypeStream)
@@ -1239,10 +1244,10 @@
// TODO: implement datagrams
}
- SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread):
+ SAMBridge::SAMBridge (const std::string& address, uint16_t portTCP, uint16_t portUDP, bool singleThread):
RunnableService ("SAM"), m_IsSingleThread (singleThread),
- m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
- m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint),
+ 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), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint),
m_SignatureTypes
{
{"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1},
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/SAM.h
^
|
@@ -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
*
@@ -30,7 +30,7 @@
{
const size_t SAM_SOCKET_BUFFER_SIZE = 8192;
const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds
- const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
+ const int SAM_SESSION_READINESS_CHECK_INTERVAL = 3; // in seconds
const char SAM_HANDSHAKE[] = "HELLO VERSION";
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n";
@@ -221,9 +221,9 @@
struct SAMSubSession: public SAMSession
{
std::shared_ptr<SAMMasterSession> masterSession;
- int inPort;
+ uint16_t inPort;
- SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, int port);
+ SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, uint16_t port);
// implements SAMSession
std::shared_ptr<ClientDestination> GetLocalDestination ();
void StopLocalDestination ();
@@ -233,7 +233,7 @@
{
public:
- SAMBridge (const std::string& address, int port, bool singleThread);
+ SAMBridge (const std::string& address, uint16_t portTCP, uint16_t portUDP, bool singleThread);
~SAMBridge ();
void Start ();
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/SOCKS.cpp
^
|
@@ -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
*
@@ -66,6 +66,11 @@
GET5_IPV6,
GET5_HOST_SIZE,
GET5_HOST,
+ GET5_USERPASSWD,
+ GET5_USER_SIZE,
+ GET5_USER,
+ GET5_PASSWD_SIZE,
+ GET5_PASSWD,
READY,
UPSTREAM_RESOLVE,
UPSTREAM_CONNECT,
@@ -129,6 +134,7 @@
boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port);
boost::asio::const_buffers_1 GenerateUpstreamRequest();
bool Socks5ChooseAuth();
+ void Socks5UserPasswdResponse ();
void SocksRequestFailed(errTypes error);
void SocksRequestSuccess();
void SentSocksFailed(const boost::system::error_code & ecode);
@@ -324,6 +330,15 @@
}
}
+ void SOCKSHandler::Socks5UserPasswdResponse ()
+ {
+ m_response[0] = 5; // Version
+ m_response[1] = 0; // Response code
+ LogPrint(eLogDebug, "SOCKS: v5 user/password response");
+ boost::asio::async_write(*m_sock, boost::asio::const_buffers_1(m_response, 2),
+ std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1));
+ }
+
/* All hope is lost beyond this point */
void SOCKSHandler::SocksRequestFailed(SOCKSHandler::errTypes error)
{
@@ -438,10 +453,15 @@
m_parseleft --;
if (*sock_buff == AUTH_NONE)
m_authchosen = AUTH_NONE;
+ else if (*sock_buff == AUTH_USERPASSWD)
+ m_authchosen = AUTH_USERPASSWD;
if ( m_parseleft == 0 )
{
if (!Socks5ChooseAuth()) return false;
- EnterState(GET5_REQUESTV);
+ if (m_authchosen == AUTH_USERPASSWD)
+ EnterState(GET5_USERPASSWD);
+ else
+ EnterState(GET5_REQUESTV);
}
break;
case GET_COMMAND:
@@ -557,6 +577,35 @@
m_parseleft--;
if (m_parseleft == 0) EnterState(GET_PORT);
break;
+ case GET5_USERPASSWD:
+ if (*sock_buff != 1)
+ {
+ LogPrint(eLogError,"SOCKS: v5 rejected invalid username/password subnegotiation: ", ((int)*sock_buff));
+ SocksRequestFailed(SOCKS5_GEN_FAIL);
+ return false;
+ }
+ EnterState(GET5_USER_SIZE);
+ break;
+ case GET5_USER_SIZE:
+ EnterState(GET5_USER, *sock_buff);
+ break;
+ case GET5_USER:
+ // skip user for now
+ m_parseleft--;
+ if (m_parseleft == 0) EnterState(GET5_PASSWD_SIZE);
+ break;
+ case GET5_PASSWD_SIZE:
+ EnterState(GET5_PASSWD, *sock_buff);
+ break;
+ case GET5_PASSWD:
+ // skip passwd for now
+ m_parseleft--;
+ if (m_parseleft == 0)
+ {
+ Socks5UserPasswdResponse ();
+ EnterState(GET5_REQUESTV);
+ }
+ break;
default:
LogPrint(eLogError, "SOCKS: Parse state?? ", m_state);
Terminate();
@@ -788,7 +837,7 @@
shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
- SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, int port,
+ SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, uint16_t port,
bool outEnable, const std::string& outAddress, uint16_t outPort,
std::shared_ptr<i2p::client::ClientDestination> localDestination) :
TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/libi2pd_client/SOCKS.h
^
|
@@ -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
*
@@ -23,7 +23,7 @@
{
public:
- SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort,
+ SOCKSServer(const std::string& name, const std::string& address, uint16_t port, bool outEnable, const std::string& outAddress, uint16_t outPort,
std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
~SOCKSServer() {};
|
[-]
[+]
|
Added |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/.gitignore
^
|
@@ -0,0 +1,12 @@
+/test-http-merge_chunked
+/test-http-req
+/test-http-res
+/test-http-url
+/test-http-url_decode
+/test-gost
+/test-gost-sig
+/test-base-64
+/test-x25519
+/test-aeadchacha20poly1305
+/test-blinding
+/test-elligator
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/CMakeLists.txt
^
|
@@ -4,9 +4,9 @@
# Compiler flags:
if(APPLE)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -Wl,-undefined,dynamic_lookup")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -Wl,-undefined,dynamic_lookup")
else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -D_GLIBCXX_USE_NANOSLEEP=1 -Wl,--unresolved-symbols=ignore-in-object-files")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -Wl,--unresolved-symbols=ignore-in-object-files")
endif()
set(TEST_PATH ${CMAKE_CURRENT_BINARY_DIR})
@@ -18,80 +18,50 @@
)
set(test-http-merge_chunked_SRCS
- ../libi2pd/HTTP.cpp
test-http-merge_chunked.cpp
)
set(test-http-req_SRCS
- ../libi2pd/HTTP.cpp
test-http-req.cpp
)
set(test-http-res_SRCS
- ../libi2pd/HTTP.cpp
test-http-res.cpp
)
set(test-http-url_decode_SRCS
- ../libi2pd/HTTP.cpp
test-http-url_decode.cpp
)
set(test-http-url_SRCS
- ../libi2pd/HTTP.cpp
test-http-url.cpp
)
set(test-base-64_SRCS
- ../libi2pd/Base.cpp
test-base-64.cpp
)
set(test-gost_SRCS
- ../libi2pd/Gost.cpp
- ../libi2pd/I2PEndian.cpp
test-gost.cpp
)
set(test-gost-sig_SRCS
- ../libi2pd/Gost.cpp
- ../libi2pd/I2PEndian.cpp
- ../libi2pd/Crypto.cpp
- ../libi2pd/Log.cpp
test-gost-sig.cpp
)
set(test-x25519_SRCS
- ../libi2pd/Ed25519.cpp
- ../libi2pd/I2PEndian.cpp
- ../libi2pd/Log.cpp
- ../libi2pd/Crypto.cpp
test-x25519.cpp
)
set(test-aeadchacha20poly1305_SRCS
- ../libi2pd/Crypto.cpp
- ../libi2pd/ChaCha20.cpp
- ../libi2pd/Poly1305.cpp
test-aeadchacha20poly1305.cpp
)
set(test-blinding_SRCS
- ../libi2pd/Crypto.cpp
- ../libi2pd/Blinding.cpp
- ../libi2pd/Ed25519.cpp
- ../libi2pd/I2PEndian.cpp
- ../libi2pd/Log.cpp
- ../libi2pd/util.cpp
- ../libi2pd/Identity.cpp
- ../libi2pd/Signature.cpp
- ../libi2pd/Timestamp.cpp
test-blinding.cpp
)
SET(test-elligator_SRCS
- ../libi2pd/Elligator.cpp
- ../libi2pd/Crypto.cpp
test-elligator.cpp
)
@@ -109,15 +79,23 @@
add_executable(test-elligator ${test-elligator_SRCS})
set(LIBS
+ libi2pd
${Boost_LIBRARIES}
- ${CHECK_LDFLAGS}
- ${CMAKE_REQUIRED_LIBRARIES}
OpenSSL::SSL
OpenSSL::Crypto
+ ZLIB::ZLIB
Threads::Threads
+ ${CHECK_LDFLAGS}
+ ${CMAKE_REQUIRED_LIBRARIES}
)
-target_link_libraries(test-gost OpenSSL::Crypto Threads::Threads)
+target_link_libraries(test-http-merge_chunked ${LIBS})
+target_link_libraries(test-http-req ${LIBS})
+target_link_libraries(test-http-res ${LIBS})
+target_link_libraries(test-http-url_decode ${LIBS})
+target_link_libraries(test-http-url ${LIBS})
+target_link_libraries(test-base-64 ${LIBS})
+target_link_libraries(test-gost ${LIBS})
target_link_libraries(test-gost-sig ${LIBS})
target_link_libraries(test-x25519 ${LIBS})
target_link_libraries(test-aeadchacha20poly1305 ${LIBS})
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/Makefile
^
|
@@ -1,36 +1,62 @@
-CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files
+SYS := $(shell $(CXX) -dumpmachine)
+
+CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -DOPENSSL_SUPPRESS_DEPRECATED -pthread -Wl,--unresolved-symbols=ignore-in-object-files
INCFLAGS += -I../libi2pd
-TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator
+LIBI2PD = ../libi2pd.a
+
+TESTS = \
+ test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \
+ test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator
+
+ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
+ CXXFLAGS += -DWIN32_LEAN_AND_MEAN
+ LDFLAGS += -mwindows -static
+ BOOST_SUFFIX = -mt
+ NEEDED_LDLIBS = -lwsock32 -lws2_32 -lgdi32 -liphlpapi -lole32
+endif
+
+LDLIBS = \
+ -lboost_filesystem$(BOOST_SUFFIX) \
+ -lboost_program_options$(BOOST_SUFFIX) \
+ -lssl \
+ -lcrypto \
+ -lz \
+ $(NEEDED_LDLIBS) \
+ -lpthread
+
all: $(TESTS) run
-test-http-%: ../libi2pd/HTTP.cpp test-http-%.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
+$(LIBI2PD):
+ @echo "Building libi2pd.a ..." && cd .. && $(MAKE) libi2pd.a
+
+test-http-%: test-http-%.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-base-%: ../libi2pd/Base.cpp test-base-%.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
+test-base-%: test-base-%.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-gost: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp test-gost.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto
+test-gost: test-gost.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-gost-sig: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Crypto.cpp ../libi2pd/Log.cpp test-gost-sig.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
+test-gost-sig: test-gost-sig.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/Crypto.cpp test-x25519.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
+test-x25519: test-x25519.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
+test-aeadchacha20poly1305: test-aeadchacha20poly1305.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
+test-blinding: test-blinding.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
-test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp
- $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
+test-elligator: test-elligator.cpp $(LIBI2PD)
+ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
run: $(TESTS)
- @for TEST in $(TESTS); do ./$$TEST ; done
+ @for TEST in $(TESTS); do echo Running $$TEST; ./$$TEST ; done
clean:
rm -f $(TESTS)
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-aeadchacha20poly1305.cpp
^
|
@@ -7,28 +7,28 @@
char text[] = "Ladies and Gentlemen of the class of '99: If I could offer you "
"only one tip for the future, sunscreen would be it."; // 114 bytes
-uint8_t key[32] =
+uint8_t key[32] =
{
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
};
-uint8_t ad[12] =
+uint8_t ad[12] =
{
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7
};
-uint8_t nonce[12] =
+uint8_t nonce[12] =
{
0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
};
-uint8_t tag[16] =
+uint8_t tag[16] =
{
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
};
-uint8_t encrypted[114] =
+uint8_t encrypted[114] =
{
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
@@ -53,7 +53,7 @@
assert (memcmp (buf1, text, 114) == 0);
// test encryption of multiple buffers
memcpy (buf, text, 114);
- std::vector<std::pair<uint8_t*, std::size_t> > bufs{ std::make_pair (buf, 20), std::make_pair (buf + 20, 10), std::make_pair (buf + 30, 70), std::make_pair (buf + 100, 14) };
+ std::vector<std::pair<uint8_t*, std::size_t> > bufs{ std::make_pair (buf, 20), std::make_pair (buf + 20, 10), std::make_pair (buf + 30, 70), std::make_pair (buf + 100, 14) };
i2p::crypto::AEADChaCha20Poly1305Encrypt (bufs, key, nonce, buf + 114);
i2p::crypto::AEADChaCha20Poly1305 (buf, 114, nullptr, 0, key, nonce, buf1, 114, false);
assert (memcmp (buf1, text, 114) == 0);
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-blinding.cpp
^
|
@@ -13,12 +13,12 @@
{
auto keys = PrivateKeys::CreateRandomKeys (sigType);
BlindedPublicKey blindedKey (keys.GetPublic ());
- auto timestamp = GetSecondsSinceEpoch ();
+ auto timestamp = GetSecondsSinceEpoch ();
char date[9];
GetDateString (timestamp, date);
- uint8_t blindedPriv[32], blindedPub[32];
+ uint8_t blindedPriv[32], blindedPub[32];
auto publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub);
- uint8_t blindedPub1[32];
+ uint8_t blindedPub1[32];
blindedKey.GetBlindedKey (date, blindedPub1);
// check if public key produced from private blinded key matches blided public key
assert (!memcmp (blindedPub, blindedPub1, publicKeyLen));
@@ -26,16 +26,16 @@
std::unique_ptr<Signer> blindedSigner (PrivateKeys::CreateSigner (blindedKey.GetBlindedSigType (), blindedPriv));
uint8_t buf[100], signature[64];
memset (buf, 1, 100);
- blindedSigner->Sign (buf, 100, signature);
+ blindedSigner->Sign (buf, 100, signature);
std::unique_ptr<Verifier> blindedVerifier (IdentityEx::CreateVerifier (blindedKey.GetBlindedSigType ()));
blindedVerifier->SetPublicKey (blindedPub);
- assert (blindedVerifier->Verify (buf, 100, signature));
+ assert (blindedVerifier->Verify (buf, 100, signature));
}
int main ()
{
- // EdDSA test
+ // EdDSA test
BlindTest (SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
- // RedDSA test
+ // RedDSA test
BlindTest (SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519);
}
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-elligator.cpp
^
|
@@ -4,19 +4,19 @@
#include "Elligator.h"
-const uint8_t key[32] =
+const uint8_t key[32] =
{
0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, 0x78, 0x06, 0x3c, 0xcf, 0xd0, 0x34, 0x8a, 0xf4,
0x21, 0x50, 0xca, 0x16, 0xd2, 0x64, 0x6f, 0x2c, 0x58, 0x56, 0xe8, 0x33, 0x83, 0x77, 0xd8, 0x80
};
-const uint8_t encoded_key[32] =
+const uint8_t encoded_key[32] =
{
0x28, 0x20, 0xb6, 0xb2, 0x41, 0xe0, 0xf6, 0x8a, 0x6c, 0x4a, 0x7f, 0xee, 0x3d, 0x97, 0x82, 0x28,
0xef, 0x3a, 0xe4, 0x55, 0x33, 0xcd, 0x41, 0x0a, 0xa9, 0x1a, 0x41, 0x53, 0x31, 0xd8, 0x61, 0x2d
};
-const uint8_t encoded_key_high_y[32] =
+const uint8_t encoded_key_high_y[32] =
{
0x3c, 0xfb, 0x87, 0xc4, 0x6c, 0x0b, 0x45, 0x75, 0xca, 0x81, 0x75, 0xe0, 0xed, 0x1c, 0x0a, 0xe9,
0xda, 0xe7, 0x9d, 0xb7, 0x8d, 0xf8, 0x69, 0x97, 0xc4, 0x84, 0x7b, 0x9f, 0x20, 0xb2, 0x77, 0x18
@@ -28,7 +28,7 @@
0x14, 0x50, 0x95, 0x89, 0x28, 0x84, 0x57, 0x99, 0x5a, 0x2b, 0x4c, 0xa3, 0x49, 0x0a, 0xa2, 0x07
};
-const uint8_t key1[32] =
+const uint8_t key1[32] =
{
0x1e, 0x8a, 0xff, 0xfe, 0xd6, 0xbf, 0x53, 0xfe, 0x27, 0x1a, 0xd5, 0x72, 0x47, 0x32, 0x62, 0xde,
0xd8, 0xfa, 0xec, 0x68, 0xe5, 0xe6, 0x7e, 0xf4, 0x5e, 0xbb, 0x82, 0xee, 0xba, 0x52, 0x60, 0x4f
@@ -40,7 +40,7 @@
0xd9, 0x03, 0x65, 0xf2, 0x4a, 0x38, 0xaa, 0x7a, 0xef, 0x1b, 0x97, 0xe2, 0x39, 0x54, 0x10, 0x1b
};
-const uint8_t key2[32] =
+const uint8_t key2[32] =
{
0x79, 0x4f, 0x05, 0xba, 0x3e, 0x3a, 0x72, 0x95, 0x80, 0x22, 0x46, 0x8c, 0x88, 0x98, 0x1e, 0x0b,
0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63
@@ -52,7 +52,7 @@
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
};
-const uint8_t key3[32] =
+const uint8_t key3[32] =
{
0x9c, 0xdb, 0x52, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-http-req.cpp
^
|
@@ -22,13 +22,13 @@
assert(req->version == "HTTP/1.0");
assert(req->method == "GET");
assert(req->uri == "/");
- assert(req->headers.size() == 3);
- assert(req->headers.count("Host") == 1);
- assert(req->headers.count("Accept") == 1);
- assert(req->headers.count("User-Agent") == 1);
- assert(req->headers.find("Host")->second == "inr.i2p");
- assert(req->headers.find("Accept")->second == "*/*");
- assert(req->headers.find("User-Agent")->second == "curl/7.26.0");
+ assert(req->GetNumHeaders () == 3);
+ assert(req->GetNumHeaders("Host") == 1);
+ assert(req->GetNumHeaders("Accept") == 1);
+ assert(req->GetNumHeaders("User-Agent") == 1);
+ assert(req->GetHeader("Host") == "inr.i2p");
+ assert(req->GetHeader("Accept") == "*/*");
+ assert(req->GetHeader("User-Agent") == "curl/7.26.0");
delete req;
/* test: parsing request without body */
@@ -41,7 +41,7 @@
assert(req->version == "HTTP/1.0");
assert(req->method == "GET");
assert(req->uri == "/");
- assert(req->headers.size() == 0);
+ assert(req->GetNumHeaders () == 0);
delete req;
/* test: parsing request without body */
@@ -74,13 +74,13 @@
assert((ret = req->parse(buf, len)) == len); /* no host header */
assert(req->method == "GET");
assert(req->uri == "http://inr.i2p");
- assert(req->headers.size() == 3);
- assert(req->headers.count("Host") == 1);
- assert(req->headers.count("Accept") == 1);
- assert(req->headers.count("Accept-Encoding") == 1);
- assert(req->headers["Host"] == "stats.i2p");
- assert(req->headers["Accept"] == "*/*");
- assert(req->headers["Accept-Encoding"] == "");
+ assert(req->GetNumHeaders () == 3);
+ assert(req->GetNumHeaders("Host") == 1);
+ assert(req->GetNumHeaders("Accept") == 1);
+ assert(req->GetNumHeaders("Accept-Encoding") == 1);
+ assert(req->GetHeader("Host") == "stats.i2p");
+ assert(req->GetHeader("Accept") == "*/*");
+ assert(req->GetHeader("Accept-Encoding") == "");
delete req;
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-http-url.cpp
^
|
@@ -15,6 +15,7 @@
assert(url->host == "127.0.0.1");
assert(url->port == 7070);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "12345");
assert(url->to_string() == "https://127.0.0.1:7070/asdasd?12345");
delete url;
@@ -27,6 +28,7 @@
assert(url->host == "site.com");
assert(url->port == 8080);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "123456");
delete url;
@@ -38,6 +40,7 @@
assert(url->host == "site.com");
assert(url->port == 0);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "name=value");
delete url;
@@ -49,6 +52,7 @@
assert(url->host == "site.com");
assert(url->port == 0);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "name=value1&name=value2");
delete url;
@@ -60,6 +64,7 @@
assert(url->host == "site.com");
assert(url->port == 0);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "name1=value1&name2&name3=value2");
assert(url->parse_query(params));
assert(params.size() == 3);
@@ -79,6 +84,7 @@
assert(url->host == "site.com");
assert(url->port == 800);
assert(url->path == "/asdasd");
+ assert(url->hasquery == true);
assert(url->query == "");
delete url;
@@ -90,6 +96,7 @@
assert(url->host == "site.com");
assert(url->port == 17);
assert(url->path == "");
+ assert(url->hasquery == false);
assert(url->query == "");
delete url;
@@ -101,6 +108,7 @@
assert(url->host == "site.com");
assert(url->port == 0);
assert(url->path == "");
+ assert(url->hasquery == false);
assert(url->query == "");
delete url;
@@ -112,6 +120,7 @@
assert(url->host == "site.com");
assert(url->port == 84);
assert(url->path == "/asdasd/@17");
+ assert(url->hasquery == false);
assert(url->query == "");
assert(url->frag == "frag");
delete url;
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd-2.48.0+git1.tar.gz/upstream/tests/test-x25519.cpp
^
|
@@ -4,21 +4,21 @@
#include "Ed25519.h"
-const uint8_t k[32] =
+const uint8_t k[32] =
{
0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4
};
-const uint8_t u[32] =
+const uint8_t u[32] =
{
0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c
};
-uint8_t p[32] =
+uint8_t p[32] =
{
0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
@@ -36,4 +36,3 @@
assert(memcmp (buf, p, 32) == 0);
#endif
}
-
|
[-]
[+]
|
Changed |
_service:tar_git:i2pd.yaml
^
|
@@ -1,6 +1,6 @@
Name: i2pd
Summary: End-to-End encrypted and anonymous Internet daemon
-Version: 2.45.1
+Version: 2.48.0
Release: 1
Group: Applications/Internet
License: BSD-3-Clause
|