Browse Source

Merge branch 'c-wrapper-libi2pd-api' of github.com:eyedeekay/i2pd into c-wrapper-libi2pd-api

pull/1669/head
idk 3 years ago
parent
commit
739d1aa9e9
No known key found for this signature in database
GPG Key ID: D75C03B39B5E14E1
  1. 48
      .github/workflows/build.yml
  2. 63
      .github/workflows/docker.yml
  3. 12
      README.md
  4. 5
      contrib/docker/Dockerfile
  5. 724
      contrib/i18n/English.po
  6. 7
      contrib/i18n/regex.txt
  7. 0
      contrib/openrc/i2pd.openrc
  8. 0
      contrib/upstart/i2pd.upstart
  9. 10
      daemon/HTTPServer.cpp
  10. 2
      debian/compat
  11. 18
      debian/control
  12. 29
      debian/copyright
  13. 4
      debian/docs
  14. 2
      debian/i2pd.dirs
  15. 2
      debian/i2pd.install
  16. 3
      debian/postinst
  17. 26
      debian/rules
  18. 6
      debian/watch
  19. 73
      i18n/Afrikaans.cpp
  20. 5
      i18n/English.cpp
  21. 8
      i18n/I18N.h
  22. 15
      i18n/I18N_langs.h
  23. 15
      i18n/Turkmen.cpp
  24. 11
      i18n/Ukrainian.cpp
  25. 2
      libi2pd/Config.cpp
  26. 9
      libi2pd/ECIESX25519AEADRatchetSession.cpp
  27. 5
      libi2pd/ECIESX25519AEADRatchetSession.h
  28. 17
      libi2pd/I2NPProtocol.cpp
  29. 8
      libi2pd/NTCP2.cpp
  30. 4
      libi2pd/NetDb.cpp
  31. 25
      libi2pd/RouterContext.cpp
  32. 4
      libi2pd/RouterContext.h
  33. 64
      libi2pd/RouterInfo.cpp
  34. 3
      libi2pd/RouterInfo.h
  35. 4
      libi2pd/SSU.cpp
  36. 14
      libi2pd/SSUSession.cpp
  37. 10
      libi2pd/Transports.cpp
  38. 12
      libi2pd/TunnelPool.cpp

48
.github/workflows/build.yml

@ -38,3 +38,51 @@ jobs:
cd build cd build
cmake -DWITH_UPNP=${{ matrix.with_upnp }} . cmake -DWITH_UPNP=${{ matrix.with_upnp }} .
make -j3 make -j3
build-deb-stretch:
name: Build package for stretch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-stretch" -M --distribution stretch "trunk build"
- uses: singingwolfboy/build-dpkg-stretch@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}
build-deb-buster:
name: Build package for buster
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: change debian changelog
run: |
sudo apt-get update
sudo apt-get install devscripts
debchange -v "`git describe --tags`-buster" -M --distribution buster "trunk build"
- uses: singingwolfboy/build-dpkg-buster@v1
id: build
with:
args: --unsigned-source --unsigned-changes -b
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename }}
path: ${{ steps.build.outputs.filename }}
- uses: actions/upload-artifact@v1
with:
name: ${{ steps.build.outputs.filename-dbgsym }}
path: ${{ steps.build.outputs.filename-dbgsym }}

63
.github/workflows/docker.yml

@ -0,0 +1,63 @@
name: Build containers
on: [push]
jobs:
docker:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push trunk container
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386
push: true
tags: |
purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:latest
- name: Set env
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Build and push release container
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: docker/build-push-action@v2
with:
context: ./contrib/docker
file: ./contrib/docker/Dockerfile
platforms: linux/amd64,linux/386
push: true
tags: |
purplei2p/i2pd:latest
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
ghcr.io/purplei2p/i2pd:latest
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}

12
README.md

@ -68,15 +68,15 @@ Build instructions:
**Supported systems:** **Supported systems:**
* GNU/Linux - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) * GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml)
* CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
* Windows - [![Build status](https://ci.appveyor.com/api/projects/status/1908qe4p48ff1x23?svg=true)](https://ci.appveyor.com/project/PurpleI2P/i2pd) * 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 Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) * 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/) * Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/)
* Snap * 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 * 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 - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
* iOS * iOS
Using i2pd Using i2pd

5
contrib/docker/Dockerfile

@ -1,4 +1,4 @@
FROM alpine:latest FROM alpine:3.13
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>" LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
# Expose git branch, tag and URL variables as arguments # Expose git branch, tag and URL variables as arguments
@ -25,7 +25,8 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
# 1. install deps, clone and build. # 1. install deps, clone and build.
# 2. strip binaries. # 2. strip binaries.
# 3. Purge all dependencies and other unrelated packages, including build directory. # 3. Purge all dependencies and other unrelated packages, including build directory.
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \ RUN apk update \
&& apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \
&& mkdir -p /tmp/build \ && mkdir -p /tmp/build \
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
&& cd i2pd \ && cd i2pd \

724
contrib/i18n/English.po

@ -0,0 +1,724 @@
# i2pd
# Copyright (C) 2021 PurpleI2P team
# This file is distributed under the same license as the i2pd package.
# R4SAS <r4sas@i2pmail.org>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: i2pd\n"
"Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n"
"POT-Creation-Date: 2021-06-15 17:40\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.0\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-KeywordsList: ;tr\n"
"X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n"
"X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n"
#: daemon/HTTPServer.cpp:85
msgid "Disabled"
msgstr ""
#: daemon/HTTPServer.cpp:86
msgid "Enabled"
msgstr ""
#: daemon/HTTPServer.cpp:141
msgid "day"
msgid_plural "days"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:145
msgid "hour"
msgid_plural "hours"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:149
msgid "minute"
msgid_plural "minutes"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:152
msgid "second"
msgid_plural "seconds"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188
msgid "KiB"
msgstr ""
#: daemon/HTTPServer.cpp:162
msgid "MiB"
msgstr ""
#: daemon/HTTPServer.cpp:164
msgid "GiB"
msgstr ""
#: daemon/HTTPServer.cpp:181
msgid "building"
msgstr ""
#: daemon/HTTPServer.cpp:182
msgid "failed"
msgstr ""
#: daemon/HTTPServer.cpp:183
msgid "expiring"
msgstr ""
#: daemon/HTTPServer.cpp:184
msgid "established"
msgstr ""
#: daemon/HTTPServer.cpp:185
msgid "unknown"
msgstr ""
#: daemon/HTTPServer.cpp:187
msgid "exploratory"
msgstr ""
#: daemon/HTTPServer.cpp:223
msgid "<b>i2pd</b> webconsole"
msgstr ""
#: daemon/HTTPServer.cpp:226
msgid "Main page"
msgstr ""
#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683
msgid "Router commands"
msgstr ""
#: daemon/HTTPServer.cpp:228
msgid "Local destinations"
msgstr ""
#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:382
#: daemon/HTTPServer.cpp:463 daemon/HTTPServer.cpp:469
#: daemon/HTTPServer.cpp:599 daemon/HTTPServer.cpp:642
#: daemon/HTTPServer.cpp:646
msgid "LeaseSets"
msgstr ""
#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652
msgid "Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727
#: daemon/HTTPServer.cpp:743
msgid "Transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792
msgid "Transports"
msgstr ""
#: daemon/HTTPServer.cpp:235
msgid "I2P tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854
#: daemon/HTTPServer.cpp:864
msgid "SAM sessions"
msgstr ""
#: daemon/HTTPServer.cpp:253 daemon/HTTPServer.cpp:1254
#: daemon/HTTPServer.cpp:1257 daemon/HTTPServer.cpp:1260
#: daemon/HTTPServer.cpp:1274 daemon/HTTPServer.cpp:1319
#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1325
msgid "ERROR"
msgstr ""
#: daemon/HTTPServer.cpp:260
msgid "OK"
msgstr ""
#: daemon/HTTPServer.cpp:261
msgid "Testing"
msgstr ""
#: daemon/HTTPServer.cpp:262
msgid "Firewalled"
msgstr ""
#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284
#: daemon/HTTPServer.cpp:370
msgid "Unknown"
msgstr ""
#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394
#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922
#: daemon/HTTPServer.cpp:931
msgid "Proxy"
msgstr ""
#: daemon/HTTPServer.cpp:265
msgid "Mesh"
msgstr ""
#: daemon/HTTPServer.cpp:268
msgid "Error"
msgstr ""
#: daemon/HTTPServer.cpp:272
msgid "Clock skew"
msgstr ""
#: daemon/HTTPServer.cpp:275
msgid "Offline"
msgstr ""
#: daemon/HTTPServer.cpp:278
msgid "Symmetric NAT"
msgstr ""
#: daemon/HTTPServer.cpp:290
msgid "Uptime"
msgstr ""
#: daemon/HTTPServer.cpp:293
msgid "Network status"
msgstr ""
#: daemon/HTTPServer.cpp:298
msgid "Network status v6"
msgstr ""
#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311
msgid "Stopping in"
msgstr ""
#: daemon/HTTPServer.cpp:318
msgid "Family"
msgstr ""
#: daemon/HTTPServer.cpp:319
msgid "Tunnel creation success rate"
msgstr ""
#: daemon/HTTPServer.cpp:320
msgid "Received"
msgstr ""
#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325
#: daemon/HTTPServer.cpp:328
msgid "KiB/s"
msgstr ""
#: daemon/HTTPServer.cpp:323
msgid "Sent"
msgstr ""
#: daemon/HTTPServer.cpp:326
msgid "Transit"
msgstr ""
#: daemon/HTTPServer.cpp:329
msgid "Data path"
msgstr ""
#: daemon/HTTPServer.cpp:332
msgid "Hidden content. Press on text to see."
msgstr ""
#: daemon/HTTPServer.cpp:335
msgid "Router Ident"
msgstr ""
#: daemon/HTTPServer.cpp:337
msgid "Router Family"
msgstr ""
#: daemon/HTTPServer.cpp:338
msgid "Router Caps"
msgstr ""
#: daemon/HTTPServer.cpp:339
msgid "Version"
msgstr ""
#: daemon/HTTPServer.cpp:340
msgid "Our external address"
msgstr ""
#: daemon/HTTPServer.cpp:348
msgid "supported"
msgstr ""
#: daemon/HTTPServer.cpp:380
msgid "Routers"
msgstr ""
#: daemon/HTTPServer.cpp:381
msgid "Floodfills"
msgstr ""
#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908
msgid "Client Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:389
msgid "Transit Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:393
msgid "Services"
msgstr ""
#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419
msgid "Local Destinations"
msgstr ""
#: daemon/HTTPServer.cpp:442
msgid "Encrypted B33 address"
msgstr ""
#: daemon/HTTPServer.cpp:451
msgid "Address registration line"
msgstr ""
#: daemon/HTTPServer.cpp:456
msgid "Domain"
msgstr ""
#: daemon/HTTPServer.cpp:457
msgid "Generate"
msgstr ""
#: daemon/HTTPServer.cpp:458
msgid ""
"<b>Note:</b> result string can be used only for registering 2LD domains "
"(example.i2p). For registering subdomains please use i2pd-tools."
msgstr ""
#: daemon/HTTPServer.cpp:464
msgid "Address"
msgstr ""
#: daemon/HTTPServer.cpp:464
msgid "Type"
msgstr ""
#: daemon/HTTPServer.cpp:464
msgid "EncType"
msgstr ""
#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657
msgid "Inbound tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489
#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672
#: Means milliseconds
msgid "ms"
msgstr ""
#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667
msgid "Outbound tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:496
msgid "Tags"
msgstr ""
#: daemon/HTTPServer.cpp:496
msgid "Incoming"
msgstr ""
#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506
msgid "Outgoing"
msgstr ""
#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520
msgid "Destination"
msgstr ""
#: daemon/HTTPServer.cpp:504
msgid "Amount"
msgstr ""
#: daemon/HTTPServer.cpp:511
msgid "Incoming Tags"
msgstr ""
#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522
msgid "Tags sessions"
msgstr ""
#: daemon/HTTPServer.cpp:520
msgid "Status"
msgstr ""
#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584
msgid "Local Destination"
msgstr ""
#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887
msgid "Streams"
msgstr ""
#: daemon/HTTPServer.cpp:560
msgid "Close stream"
msgstr ""
#: daemon/HTTPServer.cpp:589
msgid "I2CP session not found"
msgstr ""
#: daemon/HTTPServer.cpp:592
msgid "I2CP is not enabled"
msgstr ""
#: daemon/HTTPServer.cpp:618
msgid "Invalid"
msgstr ""
#: daemon/HTTPServer.cpp:621
msgid "Store type"
msgstr ""
#: daemon/HTTPServer.cpp:622
msgid "Expires"
msgstr ""
#: daemon/HTTPServer.cpp:627
msgid "Non Expired Leases"
msgstr ""
#: daemon/HTTPServer.cpp:630
msgid "Gateway"
msgstr ""
#: daemon/HTTPServer.cpp:631
msgid "TunnelID"
msgstr ""
#: daemon/HTTPServer.cpp:632
msgid "EndDate"
msgstr ""
#: daemon/HTTPServer.cpp:642
msgid "not floodfill"
msgstr ""
#: daemon/HTTPServer.cpp:653
msgid "Queue size"
msgstr ""
#: daemon/HTTPServer.cpp:684
msgid "Run peer test"
msgstr ""
#: daemon/HTTPServer.cpp:687
msgid "Decline transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:689
msgid "Accept transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697
msgid "Cancel graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699
msgid "Start graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:701
msgid "Force shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:704
msgid ""
"<b>Note:</b> any action done here are not persistent and not changes your "
"config files."
msgstr ""
#: daemon/HTTPServer.cpp:706
msgid "Logging level"
msgstr ""
#: daemon/HTTPServer.cpp:714
msgid "Transit tunnels limit"
msgstr ""
#: daemon/HTTPServer.cpp:719
msgid "Change"
msgstr ""
#: daemon/HTTPServer.cpp:743
msgid "no transit tunnels currently built"
msgstr ""
#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871
msgid "SAM disabled"
msgstr ""
#: daemon/HTTPServer.cpp:864
msgid "no sessions currently running"
msgstr ""
#: daemon/HTTPServer.cpp:877
msgid "SAM session not found"
msgstr ""
#: daemon/HTTPServer.cpp:882
msgid "SAM Session"
msgstr ""
#: daemon/HTTPServer.cpp:939
msgid "Server Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:955
msgid "Client Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:969
msgid "Server Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:1175
msgid "Unknown page"
msgstr ""
#: daemon/HTTPServer.cpp:1194
msgid "Invalid token"
msgstr ""
#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309
#: daemon/HTTPServer.cpp:1337
msgid "SUCCESS"
msgstr ""
#: daemon/HTTPServer.cpp:1252
msgid "Stream closed"
msgstr ""
#: daemon/HTTPServer.cpp:1254
msgid "Stream not found or already was closed"
msgstr ""
#: daemon/HTTPServer.cpp:1257
msgid "Destination not found"
msgstr ""
#: daemon/HTTPServer.cpp:1260
msgid "StreamID can't be null"
msgstr ""
#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327
msgid "Return to destination page"
msgstr ""
#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276
msgid "You will be redirected back in 5 seconds"
msgstr ""
#: daemon/HTTPServer.cpp:1274
msgid "Transit tunnels count must not exceed 65535"
msgstr ""
#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338
msgid "Back to commands list"
msgstr ""
#: daemon/HTTPServer.cpp:1311
msgid "Register at reg.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1312
msgid "Description"
msgstr ""
#: daemon/HTTPServer.cpp:1312
msgid "A bit information about service on domain"
msgstr ""
#: daemon/HTTPServer.cpp:1313
msgid "Submit"
msgstr ""
#: daemon/HTTPServer.cpp:1319
msgid "Domain can't end with .b32.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1322
msgid "Domain must end with .i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1325
msgid "Such destination is not found"
msgstr ""
#: daemon/HTTPServer.cpp:1333
msgid "Unknown command"
msgstr ""
#: daemon/HTTPServer.cpp:1337
msgid "Command accepted"
msgstr ""
#: daemon/HTTPServer.cpp:1339
msgid "You will be redirected in 5 seconds"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:157
msgid "Proxy error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:165
msgid "Proxy info"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:173
msgid "Proxy error: Host not found"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:174
msgid "Remote host not found in router's addressbook"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:175
msgid "You may try to find this host on jump services below"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288
#: libi2pd_client/HTTPProxy.cpp:365
msgid "Invalid request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:273
msgid "Proxy unable to parse your request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:288
msgid "addresshelper is not supported"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:297 libi2pd_client/HTTPProxy.cpp:306
#: libi2pd_client/HTTPProxy.cpp:385
msgid "Host"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:297
msgid "added to router's addressbook from helper"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:307
msgid "Click"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:308
msgid "here"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:298
msgid "to proceed"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:299 libi2pd_client/HTTPProxy.cpp:309
msgid "Addresshelper found"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:306
msgid "already in router's addressbook"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:308
msgid "to update record"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:322
msgid "Invalid Request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:322
msgid "invalid request uri"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:365
msgid "Can't detect destination host from request"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:382 libi2pd_client/HTTPProxy.cpp:386
msgid "Outproxy failure"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:382
msgid "bad outproxy settings"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:385
msgid "not inside I2P network, but outproxy is not enabled"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:474
msgid "unknown outproxy url"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:480
msgid "cannot resolve upstream proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:488
msgid "hostname too long"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:515
msgid "cannot connect to upstream socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:521
msgid "Cannot negotiate with socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:563
msgid "CONNECT error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:563
msgid "Failed to Connect"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:574 libi2pd_client/HTTPProxy.cpp:600
msgid "socks proxy error"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:582
msgid "failed to send request to upstream"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:603
msgid "No Reply From socks proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:610
msgid "cannot connect"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:610
msgid "http out proxy not implemented"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:611
msgid "cannot connect to upstream http proxy"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:644
msgid "Host is down"
msgstr ""
#: libi2pd_client/HTTPProxy.cpp:644
msgid ""
"Can't create connection to requested host, it may be down. Please try again "
"later."
msgstr ""

7
contrib/i18n/regex.txt

@ -0,0 +1,7 @@
Regex for transforming gettext translations to our format
msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)?
#{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n
msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
{"$1", "$2"},\n

0
debian/i2pd.openrc → contrib/openrc/i2pd.openrc

0
debian/i2pd.upstart → contrib/upstart/i2pd.upstart

10
daemon/HTTPServer.cpp

@ -138,18 +138,18 @@ namespace http {
int num; int num;
if ((num = seconds / 86400) > 0) { if ((num = seconds / 86400) > 0) {
s << num << " " << tr("days", num) << ", "; s << num << " " << tr("day", "days", num) << ", ";
seconds -= num * 86400; seconds -= num * 86400;
} }
if ((num = seconds / 3600) > 0) { if ((num = seconds / 3600) > 0) {
s << num << " " << tr("hours", num) << ", "; s << num << " " << tr("hour", "hours", num) << ", ";
seconds -= num * 3600; seconds -= num * 3600;
} }
if ((num = seconds / 60) > 0) { if ((num = seconds / 60) > 0) {
s << num << " " << tr("minutes", num) << ", "; s << num << " " << tr("minute", "minutes", num) << ", ";
seconds -= num * 60; seconds -= num * 60;
} }
s << seconds << " " << tr("seconds", seconds); s << seconds << " " << tr("second", "seconds", seconds);
} }
static void ShowTraffic (std::stringstream& s, uint64_t bytes) static void ShowTraffic (std::stringstream& s, uint64_t bytes)
@ -691,7 +691,7 @@ namespace http {
if (Daemon.gracefulShutdownInterval) if (Daemon.gracefulShutdownInterval)
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n"; s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
else else
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n"; s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
#elif defined(WIN32_APP) #elif defined(WIN32_APP)
if (i2p::util::DaemonWin32::Instance().isGraceful) if (i2p::util::DaemonWin32::Instance().isGraceful)
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n"; s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";

2
debian/compat vendored

@ -1 +1 @@
10 9

18
debian/control vendored

@ -3,30 +3,16 @@ Section: net
Priority: optional Priority: optional
Maintainer: r4sas <r4sas@i2pmail.org> Maintainer: r4sas <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
Standards-Version: 3.9.6 Standards-Version: 3.9.8
Homepage: http://i2pd.website/ Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd Package: i2pd
Architecture: any Architecture: any
Pre-Depends: adduser Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client. Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses. don't reveal their real IP addresses.
.
This package contains the full-featured C++ implementation of I2P router.
Package: i2pd-dbg
Architecture: any
Priority: extra
Section: debug
Depends: i2pd (= ${binary:Version}), ${misc:Depends}
Description: i2pd debugging symbols
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.
.
This package contains symbols required for debugging.

29
debian/copyright vendored

@ -6,13 +6,6 @@ Files: *
Copyright: 2013-2020 PurpleI2P Copyright: 2013-2020 PurpleI2P
License: BSD-3-clause License: BSD-3-clause
Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl
qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java
Copyright: 2011-2013 BogDan Vatra <bogdan@kde.org>
License: BSD-2-Clause
Files: debian/* Files: debian/*
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org> Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
2014-2016 hagen <hagen@i2pmail.org> 2014-2016 hagen <hagen@i2pmail.org>
@ -49,28 +42,6 @@ License: BSD-3-clause
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: GPL-2+ License: GPL-2+
This package is free software; you can redistribute it and/or modify This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

4
debian/docs vendored

@ -1,5 +1 @@
README.md README.md
contrib/i2pd.conf
contrib/subscriptions.txt
contrib/tunnels.conf
contrib/tunnels.d

2
debian/i2pd.dirs vendored

@ -1,2 +0,0 @@
etc/i2pd
var/lib/i2pd

2
debian/i2pd.install vendored

@ -1,5 +1,5 @@
i2pd usr/sbin/ i2pd usr/sbin/
contrib/i2pd.conf etc/i2pd/ contrib/i2pd.conf etc/i2pd/
contrib/tunnels.conf etc/i2pd/ contrib/tunnels.conf etc/i2pd/
contrib/subscriptions.txt etc/i2pd/ contrib/subscriptions.txt etc/i2pd/
contrib/certificates/ usr/share/i2pd/ contrib/certificates/ usr/share/i2pd/

3
debian/postinst vendored

@ -12,7 +12,6 @@ case "$1" in
# Create user and group as a system user. # Create user and group as a system user.
if getent passwd $I2PDUSER > /dev/null 2>&1; then if getent passwd $I2PDUSER > /dev/null 2>&1; then
groupadd -f $I2PDUSER || true groupadd -f $I2PDUSER || true
usermod -s "/bin/false" -e 1 $I2PDUSER > /dev/null || true
else else
adduser --system --quiet --group --home $I2PDHOME $I2PDUSER adduser --system --quiet --group --home $I2PDHOME $I2PDUSER
fi fi
@ -23,7 +22,7 @@ case "$1" in
chmod 640 $LOGFILE chmod 640 $LOGFILE
chown -f ${I2PDUSER}:adm $LOGFILE chown -f ${I2PDUSER}:adm $LOGFILE
mkdir -p -m0750 $I2PDHOME mkdir -p -m0750 $I2PDHOME
chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME} chown -f -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
;; ;;
abort-upgrade|abort-remove|abort-deconfigure) abort-upgrade|abort-remove|abort-deconfigure)
echo "Aborting upgrade" echo "Aborting upgrade"

26
debian/rules vendored

@ -1,22 +1,16 @@
#!/usr/bin/make -f #!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 #export DH_VERBOSE=1
DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow
#DPKG_EXPORT_BUILDFLAGS = 1
#include /usr/share/dpkg/buildflags.mk
#CXXFLAGS+=$(CPPFLAGS)
#PREFIX=/usr
%: export DEB_BUILD_MAINT_OPTIONS = hardening=+all
dh $@ --parallel
# dh_apparmor --profile-name=usr.sbin.i2pd -pi2pd
include /usr/share/dpkg/architecture.mk
override_dh_strip: export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic -O3
dh_strip --dbg-package=i2pd-dbg
## uncomment this if you have "missing info" problem when building package export DEB_LDFLAGS_MAINT_APPEND =
#override_dh_shlibdeps:
# dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
%:
dh $@ --parallel

6
debian/watch vendored

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

73
i18n/Afrikaans.cpp

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021, 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"
// Afrikaans localization file
namespace i2p
{
namespace i18n
{
namespace afrikaans // language
{
// 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
{
{"Disabled", "Gedeaktiveer"},
{"Enabled", "Geaktiveer"},
{"failed", "Het misluk"},
{"unknown", "onbekend"},
{"Tunnels", "Tonnels"},
{"Transit tunnels", "Deurgang tonnels"},
{"I2P tunnels", "I2P tonnels"},
{"SAM sessions", "SAM sessies"},
{"OK", "LEKKER"},
{"Testing", "Besig om te toets"},
{"Firewalled", "Vuurmuur'd"},
{"Unknown", "Onbekend"},
{"Error", "Fout"},
{"Offline", "Aflyn"},
{"Uptime", "Optyd"},
{"Network status", "Netwerk status"},
{"Network status v6", "Netwerk status v6"},
{"Family", "Familie"},
{"Received", "Ontvang"},
{"Sent", "Gestuur"},
{"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."},
{"Router Ident", "Router Ident"},
{"Router Family", "Router Familie"},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
{"days", {"dag", "dae"}},
{"hours", {"uur", "ure"}},
{"minutes", {"minuut", "minute"}},
{"seconds", {"seconde", "sekondes"}},
{"", {"", ""}},
};
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
}
} // language
} // i18n
} // i2p

5
i18n/English.cpp

@ -13,6 +13,7 @@
#include "I18N.h" #include "I18N.h"
// English localization file // English localization file
// This is an example translation file without strings in it.
namespace i2p namespace i2p
{ {
@ -33,10 +34,6 @@ namespace english // language
static std::map<std::string, std::vector<std::string>> plurals static std::map<std::string, std::vector<std::string>> plurals
{ {
{"days", {"day", "days"}},
{"hours", {"hour", "hours"}},
{"minutes", {"minute", "minutes"}},
{"seconds", {"second", "seconds"}},
{"", {"", ""}}, {"", {"", ""}},
}; };

8
i18n/I18N.h

@ -17,7 +17,9 @@ namespace i18n
{ {
inline void SetLanguage(const std::string &lang) inline void SetLanguage(const std::string &lang)
{ {
if (!lang.compare("russian")) if (!lang.compare("afrikaans"))
i2p::context.SetLanguage (i2p::i18n::afrikaans::GetLocale());
else if (!lang.compare("russian"))
i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); i2p::context.SetLanguage (i2p::i18n::russian::GetLocale());
else if (!lang.compare("turkmen")) else if (!lang.compare("turkmen"))
i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale()); i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale());
@ -32,9 +34,9 @@ namespace i18n
return i2p::context.GetLanguage ()->GetString (arg); return i2p::context.GetLanguage ()->GetString (arg);
} }
inline std::string translate (const std::string& arg, const int& n) inline std::string translate (const std::string& arg, const std::string& arg2, const int& n)
{ {
return i2p::context.GetLanguage ()->GetPlural (arg, n); return i2p::context.GetLanguage ()->GetPlural (arg, arg2, n);
} }
} // i18n } // i18n
} // i2p } // i2p

15
i18n/I18N_langs.h

@ -35,12 +35,12 @@ namespace i18n
} }
} }
std::string GetPlural (const std::string& arg, const int& n) const std::string GetPlural (const std::string& arg, const std::string& arg2, const int& n) const
{ {
const auto it = m_Plurals.find(arg); const auto it = m_Plurals.find(arg2);
if (it == m_Plurals.end()) if (it == m_Plurals.end()) // not found, fallback to english
{ {
return arg; return n == 1 ? arg : arg2;
} }
else else
{ {
@ -56,9 +56,10 @@ namespace i18n
}; };
// Add localization here with language name as namespace // Add localization here with language name as namespace
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); } namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
} // i18n } // i18n

15
i18n/Turkmen.cpp

@ -61,7 +61,7 @@ namespace turkmen // language
{"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"}, {"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"}, {"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"},
{"cannot connect", "birikdirip bilmedi"}, {"cannot connect", "birikdirip bilmedi"},
{"http out proxy not implemented", "daşarky http proksi serwerini goldamak amala aşyrylmaýar"}, {"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"}, {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"},
{"Host is down", "Salgy elýeterli däl"}, {"Host is down", "Salgy elýeterli däl"},
{"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.",
@ -89,7 +89,7 @@ namespace turkmen // language
{"Local destinations", "Ýerli ýerler"}, {"Local destinations", "Ýerli ýerler"},
{"LeaseSets", "Lizset"}, {"LeaseSets", "Lizset"},
{"Tunnels", "Tuneller"}, {"Tunnels", "Tuneller"},
{"Transit tunnels", "Tranzit Tunels"}, {"Transit tunnels", "Tranzit tunels"},
{"Transports", "Daşamak"}, {"Transports", "Daşamak"},
{"I2P tunnels", "I2P tuneller"}, {"I2P tunnels", "I2P tuneller"},
{"SAM sessions", "SAM Sessiýasy"}, {"SAM sessions", "SAM Sessiýasy"},
@ -108,7 +108,7 @@ namespace turkmen // language
{"Uptime", "Onlaýn onlaýn sözlügi"}, {"Uptime", "Onlaýn onlaýn sözlügi"},
{"Network status", "Tor ýagdaýy"}, {"Network status", "Tor ýagdaýy"},
{"Network status v6", "Tor ýagdaýy v6"}, {"Network status v6", "Tor ýagdaýy v6"},
{"Stopping in", "soň duruň"}, {"Stopping in", "Soň duruň"},
{"Family", "Maşgala"}, {"Family", "Maşgala"},
{"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"},
{"Received", "Alnan"}, {"Received", "Alnan"},
@ -122,10 +122,9 @@ namespace turkmen // language
{"Router Caps", "Baýdaklar marşruteri"}, {"Router Caps", "Baýdaklar marşruteri"},
{"Version", "Wersiýasy"}, {"Version", "Wersiýasy"},
{"Our external address", "Daşarky salgymyz"}, {"Our external address", "Daşarky salgymyz"},
{"supported", "Goldanýar"}, {"supported", "goldanýar"},
{"Routers", "Marşrutizatorlar"}, {"Routers", "Marşrutizatorlar"},
{"Floodfills", "Fludfillar"}, {"Floodfills", "Fludfillar"},
{"LeaseSets", "Lizsetllar"},
{"Client Tunnels", "Müşderi tunelleri"}, {"Client Tunnels", "Müşderi tunelleri"},
{"Transit Tunnels", "Tranzit Tunelleri"}, {"Transit Tunnels", "Tranzit Tunelleri"},
{"Services", "Hyzmatlar"}, {"Services", "Hyzmatlar"},
@ -150,7 +149,7 @@ namespace turkmen // language
{"Destination", "Maksat"}, {"Destination", "Maksat"},
{"Amount", "Sany"}, {"Amount", "Sany"},
{"Incoming Tags", "Gelýän bellikler"}, {"Incoming Tags", "Gelýän bellikler"},
{"Tags sessions", "Sapaklar Tag."}, {"Tags sessions", "Sapaklar bellikler"},
{"Status", "Ýagdaýy"}, {"Status", "Ýagdaýy"},
// ShowLocalDestination // ShowLocalDestination
{"Local Destination", "Ýerli maksat"}, {"Local Destination", "Ýerli maksat"},
@ -178,7 +177,7 @@ namespace turkmen // language
{"Start graceful shutdown", "Tekiz durmak"}, {"Start graceful shutdown", "Tekiz durmak"},
{"Force shutdown", "Mejbury duralga"}, {"Force shutdown", "Mejbury duralga"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", {"<b>Note:</b> any action done here are not persistent and not changes your config files.",
"<b>Bellik:</b> Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär.."}, "<b>Bellik:</b> Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär."},
{"Logging level", "Giriş derejesi"}, {"Logging level", "Giriş derejesi"},
{"Transit tunnels limit", "Tranzit tunelleriniň çägi"}, {"Transit tunnels limit", "Tranzit tunelleriniň çägi"},
{"Change", "Üýtgetmek"}, {"Change", "Üýtgetmek"},
@ -217,7 +216,7 @@ namespace turkmen // language
{"Description", "Beýany"}, {"Description", "Beýany"},
{"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"}, {"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"},
{"Submit", "Iber"}, {"Submit", "Iber"},
{"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez."}, {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez"},
{"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"}, {"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"},
{"Such destination is not found", "Bu barmaly ýer tapylmady"}, {"Such destination is not found", "Bu barmaly ýer tapylmady"},
{"", ""}, {"", ""},

11
i18n/Ukrainian.cpp

@ -86,17 +86,17 @@ namespace ukrainian // language
// ShowPageHead // ShowPageHead
{"Main page", "Головна"}, {"Main page", "Головна"},
{"Router commands", "Команди роутера"}, {"Router commands", "Команди роутера"},
{"Local destinations", "Локальні признач."}, {"Local destinations", "Локальні призначення"},
{"LeaseSets", "Лізсети"}, {"LeaseSets", "Лізсети"},
{"Tunnels", "Тунелі"}, {"Tunnels", "Тунелі"},
{"Transit tunnels", "Транзит. тунелі"}, {"Transit tunnels", "Транзитні тунелі"},
{"Transports", "Транспорти"}, {"Transports", "Транспорти"},
{"I2P tunnels", "I2P тунелі"}, {"I2P tunnels", "I2P тунелі"},
{"SAM sessions", "SAM сесії"}, {"SAM sessions", "SAM сесії"},
// Network Status // Network Status
{"OK", "OK"}, {"OK", "OK"},
{"Testing", "Тестування"}, {"Testing", "Тестування"},
{"Firewalled", "Файрвол"}, {"Firewalled", "Заблоковано ззовні"},
{"Unknown", "Невідомо"}, {"Unknown", "Невідомо"},
{"Proxy", "Проксі"}, {"Proxy", "Проксі"},
{"Mesh", "MESH-мережа"}, {"Mesh", "MESH-мережа"},
@ -125,7 +125,6 @@ namespace ukrainian // language
{"supported", "підтримується"}, {"supported", "підтримується"},
{"Routers", "Роутери"}, {"Routers", "Роутери"},
{"Floodfills", "Флудфіли"}, {"Floodfills", "Флудфіли"},
{"LeaseSets", "Лізсети"},
{"Client Tunnels", "Клієнтські Тунелі"}, {"Client Tunnels", "Клієнтські Тунелі"},
{"Transit Tunnels", "Транзитні Тунелі"}, {"Transit Tunnels", "Транзитні Тунелі"},
{"Services", "Сервіси"}, {"Services", "Сервіси"},
@ -153,7 +152,7 @@ namespace ukrainian // language
{"Tags sessions", "Сесії тегів"}, {"Tags sessions", "Сесії тегів"},
{"Status", "Статус"}, {"Status", "Статус"},
// ShowLocalDestination // ShowLocalDestination
{"Local Destination", "Локальне Призначення"}, {"Local Destination", "Локальні Призначення"},
{"Streams", "Потоки"}, {"Streams", "Потоки"},
{"Close stream", "Закрити потік"}, {"Close stream", "Закрити потік"},
// ShowI2CPLocalDestination // ShowI2CPLocalDestination
@ -197,7 +196,7 @@ namespace ukrainian // language
{"Unknown page", "Невідома сторінка"}, {"Unknown page", "Невідома сторінка"},
// HandleCommand, ShowError // HandleCommand, ShowError
{"Invalid token", "Невірний токен"}, {"Invalid token", "Невірний токен"},
{"SUCCESS", "ВДАЛО"}, {"SUCCESS", "УСПІШНО"},
{"ERROR", "ПОМИЛКА"}, {"ERROR", "ПОМИЛКА"},
{"Unknown command", "Невідома команда"}, {"Unknown command", "Невідома команда"},
{"Command accepted", "Команда прийнята"}, {"Command accepted", "Команда прийнята"},

2
libi2pd/Config.cpp

@ -221,7 +221,7 @@ namespace config {
("addressbook.defaulturl", value<std::string>()->default_value( ("addressbook.defaulturl", value<std::string>()->default_value(
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt" "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
), "AddressBook subscription URL for initial setup") ), "AddressBook subscription URL for initial setup")
("addressbook.subscriptions", value<std::string>()->default_value(""), "AddressBook subscriptions URLs, separated by comma") ("addressbook.subscriptions", value<std::string>()->default_value("http://reg.i2p/hosts.txt"), "AddressBook subscriptions URLs, separated by comma")
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format"); ("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
options_description trust("Trust options"); options_description trust("Trust options");

9
libi2pd/ECIESX25519AEADRatchetSession.cpp

@ -1109,21 +1109,22 @@ namespace garlic
bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len) bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len)
{ {
if (!GetOwner ()) return false; if (!GetOwner ()) return false;
i2p::crypto::NoiseSymmetricState state (GetNoiseState ()); m_CurrentNoiseState = GetNoiseState ();
// we are Bob // we are Bob
state.MixHash (buf, 32); m_CurrentNoiseState.MixHash (buf, 32);
uint8_t sharedSecret[32]; uint8_t sharedSecret[32];
if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
{ {
LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key"); LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key");
return false; return false;
} }
state.MixKey (sharedSecret); m_CurrentNoiseState.MixKey (sharedSecret);
buf += 32; len -= 32; buf += 32; len -= 32;
uint8_t nonce[12]; uint8_t nonce[12];
CreateNonce (0, nonce); CreateNonce (0, nonce);
std::vector<uint8_t> payload (len - 16); std::vector<uint8_t> payload (len - 16);
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, state.m_H, 32, state.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_CurrentNoiseState.m_H, 32,
m_CurrentNoiseState.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
{ {
LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed"); LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed");
return false; return false;

5
libi2pd/ECIESX25519AEADRatchetSession.h

@ -249,6 +249,11 @@ namespace garlic
RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState); RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState);
bool HandleNextMessage (const uint8_t * buf, size_t len); bool HandleNextMessage (const uint8_t * buf, size_t len);
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
private:
i2p::crypto::NoiseSymmetricState m_CurrentNoiseState;
}; };
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag); std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);

17
libi2pd/I2NPProtocol.cpp

@ -426,8 +426,8 @@ namespace i2p
uint8_t nonce[12]; uint8_t nonce[12];
memset (nonce, 0, 12); memset (nonce, 0, 12);
auto& noiseState = i2p::context.GetCurrentNoiseState (); auto& noiseState = i2p::context.GetCurrentNoiseState ();
if (!noiseState || !i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
noiseState->m_H, 32, noiseState->m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
{ {
LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed");
return false; return false;
@ -611,13 +611,8 @@ namespace i2p
return; return;
} }
auto& noiseState = i2p::context.GetCurrentNoiseState (); auto& noiseState = i2p::context.GetCurrentNoiseState ();
if (!noiseState)
{
LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption");
return;
}
uint8_t layerKeys[64]; // (layer key, iv key) uint8_t layerKeys[64]; // (layer key, iv key)
i2p::crypto::HKDF (noiseState->m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain i2p::crypto::HKDF (noiseState.m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain
auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
@ -653,7 +648,7 @@ namespace i2p
otbrm->len += (payload - otbrm->GetPayload ()); otbrm->len += (payload - otbrm->GetPayload ());
otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET));
uint8_t replyKeys[64]; // (reply key, tag) uint8_t replyKeys[64]; // (reply key, tag)
i2p::crypto::HKDF (noiseState->m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain
uint64_t tag; uint64_t tag;
memcpy (&tag, replyKeys + 32, 8); memcpy (&tag, replyKeys + 32, 8);
// send garlic to reply tunnel // send garlic to reply tunnel
@ -674,14 +669,14 @@ namespace i2p
{ {
// TODO: fill reply // TODO: fill reply
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16,
noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt noiseState.m_H, 32, noiseState.m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
{ {
LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed");
return; return;
} }
} }
else else
i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply);
reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; reply += SHORT_TUNNEL_BUILD_RECORD_SIZE;
} }
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET,

8
libi2pd/NTCP2.cpp

@ -1170,7 +1170,7 @@ namespace transport
if (!address) continue; if (!address) continue;
if (address->IsPublishedNTCP2 () && address->port) if (address->IsPublishedNTCP2 () && address->port)
{ {
if (address->host.is_v4()) if (address->IsV4())
{ {
try try
{ {
@ -1189,7 +1189,7 @@ namespace transport
auto conn = std::make_shared<NTCP2Session>(*this); auto conn = std::make_shared<NTCP2Session>(*this);
m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1));
} }
else if (address->host.is_v6() && (context.SupportsV6 () || context.SupportsMesh ())) else if (address->IsV6() && (context.SupportsV6 () || context.SupportsMesh ()))
{ {
m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ()));
try try
@ -1201,7 +1201,11 @@ namespace transport
if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address
{ {
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
#if (BOOST_VERSION >= 105500)
typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr; typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
#else
typedef boost::asio::detail::socket_option::integer<IPPROTO_IPV6, IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
#endif
m_NTCP2V6Acceptor->set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); m_NTCP2V6Acceptor->set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA));
} }
#endif #endif

4
libi2pd/NetDb.cpp

@ -1187,7 +1187,11 @@ namespace data
(reverse ? compatibleWith->IsReachableFrom (*router) : (reverse ? compatibleWith->IsReachableFrom (*router) :
router->IsReachableFrom (*compatibleWith)) && router->IsReachableFrom (*compatibleWith)) &&
(router->GetCaps () & RouterInfo::eHighBandwidth) && (router->GetCaps () & RouterInfo::eHighBandwidth) &&
#if defined(__x86_64__)
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION;
#else
router->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD;
#endif
}); });
} }

25
libi2pd/RouterContext.cpp

@ -45,10 +45,8 @@ namespace i2p
UpdateRouterInfo (); UpdateRouterInfo ();
if (IsECIES ()) if (IsECIES ())
{ {
auto initState = new i2p::crypto::NoiseSymmetricState (); i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ());
i2p::crypto::InitNoiseNState (*initState, GetIdentity ()->GetEncryptionPublicKey ()); m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
m_InitialNoiseState.reset (initState);
m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(*initState);
} }
} }
@ -486,11 +484,12 @@ namespace i2p
addr->ssu->introducers.clear (); addr->ssu->introducers.clear ();
port = addr->port; port = addr->port;
} }
// unpiblish NTCP2 addreeses // unpublish NTCP2 addreeses
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2) if (ntcp2)
PublishNTCP2Address (port, false, v4, v6, false); PublishNTCP2Address (port, false, v4, v6, false);
// update // update
m_RouterInfo.UpdateSupportedTransports ();
UpdateRouterInfo (); UpdateRouterInfo ();
} }
@ -530,6 +529,7 @@ namespace i2p
} }
} }
// update // update
m_RouterInfo.UpdateSupportedTransports ();
UpdateRouterInfo (); UpdateRouterInfo ();
} }
@ -679,7 +679,7 @@ namespace i2p
if (addr->IsPublishedNTCP2 ()) if (addr->IsPublishedNTCP2 ())
{ {
bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host); bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host);
if (addr->host.is_v6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1))) if (addr->IsV6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1)))
{ {
if (addr->host != host) if (addr->host != host)
{ {
@ -889,27 +889,26 @@ namespace i2p
bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize)
{ {
if (!m_InitialNoiseState || !m_TunnelDecryptor) return false;
// m_InitialNoiseState is h = SHA256(h || hepk) // m_InitialNoiseState is h = SHA256(h || hepk)
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); m_CurrentNoiseState = m_InitialNoiseState;
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk)
uint8_t sharedSecret[32]; uint8_t sharedSecret[32];
if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false))
{ {
LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
return false; return false;
} }
m_CurrentNoiseState->MixKey (sharedSecret); m_CurrentNoiseState.MixKey (sharedSecret);
encrypted += 32; encrypted += 32;
uint8_t nonce[12]; uint8_t nonce[12];
memset (nonce, 0, 12); memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState->m_H, 32, if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState.m_H, 32,
m_CurrentNoiseState->m_CK + 32, nonce, data, clearTextSize, false)) // decrypt m_CurrentNoiseState.m_CK + 32, nonce, data, clearTextSize, false)) // decrypt
{ {
LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed");
return false; return false;
} }
m_CurrentNoiseState->MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext) m_CurrentNoiseState.MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext)
return true; return true;
} }

4
libi2pd/RouterContext.h

@ -125,7 +125,7 @@ namespace garlic
void SetSupportsV4 (bool supportsV4); void SetSupportsV4 (bool supportsV4);
void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host);
bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
std::unique_ptr<i2p::crypto::NoiseSymmetricState>& GetCurrentNoiseState () { return m_CurrentNoiseState; }; i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove
void UpdateStats (); void UpdateStats ();
@ -185,7 +185,7 @@ namespace garlic
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys; std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys; std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
// for ECIESx25519 // for ECIESx25519
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState; i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
// i18n // i18n
std::shared_ptr<const i2p::i18n::Locale> m_Language; std::shared_ptr<const i2p::i18n::Locale> m_Language;

64
libi2pd/RouterInfo.cpp

@ -554,7 +554,7 @@ namespace data
if (address.IsNTCP2 ()) if (address.IsNTCP2 ())
{ {
WriteString ("NTCP2", s); WriteString ("NTCP2", s);
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified ()) if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
isPublished = true; isPublished = true;
else else
{ {
@ -971,10 +971,10 @@ namespace data
{ {
if (!IsV6 ()) if (!IsV6 ())
{ {
m_SupportedTransports |= eSSUV6 | eNTCP2V6;
uint8_t addressCaps = AddressCaps::eV6; uint8_t addressCaps = AddressCaps::eV6;
if (IsV4 ()) addressCaps |= AddressCaps::eV4; if (IsV4 ()) addressCaps |= AddressCaps::eV4;
SetUnreachableAddressesTransportCaps (addressCaps); SetUnreachableAddressesTransportCaps (addressCaps);
UpdateSupportedTransports ();
} }
} }
@ -982,10 +982,10 @@ namespace data
{ {
if (!IsV4 ()) if (!IsV4 ())
{ {
m_SupportedTransports |= eSSUV4 | eNTCP2V4;
uint8_t addressCaps = AddressCaps::eV4; uint8_t addressCaps = AddressCaps::eV4;
if (IsV6 ()) addressCaps |= AddressCaps::eV6; if (IsV6 ()) addressCaps |= AddressCaps::eV6;
SetUnreachableAddressesTransportCaps (addressCaps); SetUnreachableAddressesTransportCaps (addressCaps);
UpdateSupportedTransports ();
} }
} }
@ -994,16 +994,23 @@ namespace data
{ {
if (IsV6 ()) if (IsV6 ())
{ {
m_SupportedTransports &= ~(eSSUV6 | eNTCP2V6);
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
{ {
auto addr = *it; auto addr = *it;
addr->caps &= ~AddressCaps::eV6; if (addr->IsV6 ())
if (addr->host.is_v6 ()) {
it = m_Addresses->erase (it); if (addr->IsV4 ())
{
addr->caps &= ~AddressCaps::eV6;
++it;
}
else
it = m_Addresses->erase (it);
}
else else
++it; ++it;
} }
UpdateSupportedTransports ();
} }
} }
@ -1011,23 +1018,33 @@ namespace data
{ {
if (IsV4 ()) if (IsV4 ())
{ {
m_SupportedTransports &= ~(eSSUV4 | eNTCP2V4);
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
{ {
auto addr = *it; auto addr = *it;
addr->caps &= ~AddressCaps::eV4; if (addr->IsV4 ())
if (addr->host.is_v4 ()) {
it = m_Addresses->erase (it); if (addr->IsV6 ())
{
addr->caps &= ~AddressCaps::eV4;
++it;
}
else
it = m_Addresses->erase (it);
}
else else
++it; ++it;
} }
UpdateSupportedTransports ();
} }
} }
void RouterInfo::EnableMesh () void RouterInfo::EnableMesh ()
{ {
if (!IsMesh ()) if (!IsMesh ())
{
m_SupportedTransports |= eNTCP2V6Mesh; m_SupportedTransports |= eNTCP2V6Mesh;
m_ReachableTransports |= eNTCP2V6Mesh;
}
} }
void RouterInfo::DisableMesh () void RouterInfo::DisableMesh ()
@ -1035,6 +1052,7 @@ namespace data
if (IsMesh ()) if (IsMesh ())
{ {
m_SupportedTransports &= ~eNTCP2V6Mesh; m_SupportedTransports &= ~eNTCP2V6Mesh;
m_ReachableTransports &= ~eNTCP2V6Mesh;
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
{ {
auto addr = *it; auto addr = *it;
@ -1161,34 +1179,12 @@ namespace data
}); });
} }
bool RouterInfo::IsReachableFrom (const RouterInfo& other) const
{
auto commonTransports = m_SupportedTransports & other.m_SupportedTransports;
if (!commonTransports) return false;
if (commonTransports & eNTCP2V6Mesh) return true;
return (bool)GetAddress (
[commonTransports](std::shared_ptr<const RouterInfo::Address> address)->bool
{
if (address->IsPublishedNTCP2 ())
{
if ((commonTransports & eNTCP2V4) && address->IsV4 ()) return true;
if ((commonTransports & eNTCP2V6) && address->IsV6 ()) return true;
}
else if (address->IsReachableSSU ())
{
if ((commonTransports & eSSUV4) && address->IsV4 ()) return true;
if ((commonTransports & eSSUV6) && address->IsV6 ()) return true;
}
return false;
});
}
void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports) void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports)
{ {
for (auto& addr: *m_Addresses) for (auto& addr: *m_Addresses)
{ {
// TODO: implement SSU // TODO: implement SSU
if (addr->transportStyle == eTransportNTCP && (!addr->IsPublishedNTCP2 () || addr->port)) if (addr->transportStyle == eTransportNTCP && !addr->IsPublishedNTCP2 ())
{ {
addr->caps &= ~(eV4 | eV6); addr->caps &= ~(eV4 | eV6);
addr->caps |= transports; addr->caps |= transports;

3
libi2pd/RouterInfo.h

@ -204,7 +204,8 @@ namespace data
void EnableMesh (); void EnableMesh ();
void DisableMesh (); void DisableMesh ();
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
bool IsReachableFrom (const RouterInfo& other) const; bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; };
bool IsReachableBy (SupportedTransports transport) const { return m_ReachableTransports & transport; };
bool HasValidAddresses () const { return m_SupportedTransports; }; bool HasValidAddresses () const { return m_SupportedTransports; };
bool IsHidden () const { return m_Caps & eHidden; }; bool IsHidden () const { return m_Caps & eHidden; };
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };

4
libi2pd/SSU.cpp

@ -70,7 +70,11 @@ namespace transport
if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address
{ {
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
#if (BOOST_VERSION >= 105500)
typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr; typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
#else
typedef boost::asio::detail::socket_option::integer<IPPROTO_IPV6, IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
#endif
m_SocketV6.set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); m_SocketV6.set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA));
} }
#endif #endif

14
libi2pd/SSUSession.cpp

@ -383,7 +383,7 @@ namespace transport
{ {
// tell out peer to now assign relay tag // tell out peer to now assign relay tag
flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED;
*payload = 2; payload++; // 1 byte length *payload = 2; payload++; // 1 byte length
uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
htobe16buf (payload, flags); htobe16buf (payload, flags);
payload += 2; payload += 2;
@ -1073,7 +1073,10 @@ namespace transport
LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob"); LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob");
auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest
if (session && session->m_State == eSessionStateEstablished) if (session && session->m_State == eSessionStateEstablished)
session->Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Alice {
const auto& ep = session->GetRemoteEndpoint (); // Alice's endpoint as known to Bob
session->SendPeerTest (nonce, ep.address (), ep.port (), introKey, false, true); // send back to Alice
}
m_Server.RemovePeerTest (nonce); // nonce has been used m_Server.RemovePeerTest (nonce); // nonce has been used
break; break;
} }
@ -1093,9 +1096,12 @@ namespace transport
if (port) if (port)
{ {
LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie"); LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie");
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob
SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob if (!addr.is_unspecified () && !i2p::util::net::IsInReservedRange(addr))
{
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob
}
} }
else else
{ {

10
libi2pd/Transports.cpp

@ -401,7 +401,7 @@ namespace transport
try try
{ {
auto r = netdb.FindRouter (ident); auto r = netdb.FindRouter (ident);
if (!r || r->IsUnreachable () || !r->IsCompatible (i2p::context.GetRouterInfo ())) return; if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return;
{ {
std::unique_lock<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {}, it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
@ -447,7 +447,7 @@ namespace transport
std::shared_ptr<const RouterInfo::Address> address; std::shared_ptr<const RouterInfo::Address> address;
if (!peer.numAttempts) // NTCP2 ipv6 if (!peer.numAttempts) // NTCP2 ipv6
{ {
if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsNTCP2V6 ()) if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsReachableBy (RouterInfo::eNTCP2V6))
{ {
address = peer.router->GetPublishedNTCP2V6Address (); address = peer.router->GetPublishedNTCP2V6Address ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -457,7 +457,7 @@ namespace transport
} }
if (!address && peer.numAttempts == 1) // NTCP2 ipv4 if (!address && peer.numAttempts == 1) // NTCP2 ipv4
{ {
if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsNTCP2 (true) && !peer.router->IsUnreachable ()) if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsReachableBy (RouterInfo::eNTCP2V4))
{ {
address = peer.router->GetPublishedNTCP2V4Address (); address = peer.router->GetPublishedNTCP2V4Address ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -485,7 +485,7 @@ namespace transport
std::shared_ptr<const RouterInfo::Address> address; std::shared_ptr<const RouterInfo::Address> address;
if (peer.numAttempts == 2) // SSU ipv6 if (peer.numAttempts == 2) // SSU ipv6
{ {
if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsSSUV6 ()) if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsReachableBy (RouterInfo::eSSUV6))
{ {
address = peer.router->GetSSUV6Address (); address = peer.router->GetSSUV6Address ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -495,7 +495,7 @@ namespace transport
} }
if (!address && peer.numAttempts == 3) // SSU ipv4 if (!address && peer.numAttempts == 3) // SSU ipv4
{ {
if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsSSU (true)) if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsReachableBy (RouterInfo::eSSUV4))
{ {
address = peer.router->GetSSUAddress (true); address = peer.router->GetSSUAddress (true);
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))

12
libi2pd/TunnelPool.cpp

@ -142,16 +142,24 @@ namespace tunnel
{ {
std::vector<std::shared_ptr<InboundTunnel> > v; std::vector<std::shared_ptr<InboundTunnel> > v;
int i = 0; int i = 0;
std::shared_ptr<InboundTunnel> slowTunnel;
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex); std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (const auto& it : m_InboundTunnels) for (const auto& it : m_InboundTunnels)
{ {
if (i >= num) break; if (i >= num) break;
if (it->IsEstablished ()) if (it->IsEstablished ())
{ {
v.push_back (it); if (it->IsSlow () && !slowTunnel)
i++; slowTunnel = it;
else
{
v.push_back (it);
i++;
}
} }
} }
if (slowTunnel && (int)v.size () < (num/2+1))
v.push_back (slowTunnel);
return v; return v;
} }

Loading…
Cancel
Save