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

pull/1669/head
idk 3 years ago
commit 739d1aa9e9
No known key found for this signature in database
GPG Key ID: D75C03B39B5E14E1

@ -38,3 +38,51 @@ jobs:
cd build
cmake -DWITH_UPNP=${{ matrix.with_upnp }} .
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 }}

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

@ -68,15 +68,15 @@ Build instructions:
**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/)
* 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)
* Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/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 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/)
* Snap
* FreeBSD
* Android
* 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)
* iOS
Using i2pd

@ -1,4 +1,4 @@
FROM alpine:latest
FROM alpine:3.13
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
# 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.
# 2. strip binaries.
# 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 \
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
&& cd i2pd \

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

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

@ -138,18 +138,18 @@ namespace http {
int num;
if ((num = seconds / 86400) > 0) {
s << num << " " << tr("days", num) << ", ";
s << num << " " << tr("day", "days", num) << ", ";
seconds -= num * 86400;
}
if ((num = seconds / 3600) > 0) {
s << num << " " << tr("hours", num) << ", ";
s << num << " " << tr("hour", "hours", num) << ", ";
seconds -= num * 3600;
}
if ((num = seconds / 60) > 0) {
s << num << " " << tr("minutes", num) << ", ";
s << num << " " << tr("minute", "minutes", num) << ", ";
seconds -= num * 60;
}
s << seconds << " " << tr("seconds", seconds);
s << seconds << " " << tr("second", "seconds", seconds);
}
static void ShowTraffic (std::stringstream& s, uint64_t bytes)
@ -691,7 +691,7 @@ namespace http {
if (Daemon.gracefulShutdownInterval)
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
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)
if (i2p::util::DaemonWin32::Instance().isGraceful)
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
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
Standards-Version: 3.9.6
Standards-Version: 3.9.8
Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd
Architecture: any
Pre-Depends: adduser
Pre-Depends: ${misc:Pre-Depends}, adduser
Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base,
Description: Full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.
.
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
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/*
Copyright: 2013-2015 Kill Your TV <killyourtv@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
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+
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

4
debian/docs vendored

@ -1,5 +1 @@
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

@ -1,5 +1,5 @@
i2pd usr/sbin/
contrib/i2pd.conf etc/i2pd/
contrib/i2pd.conf etc/i2pd/
contrib/tunnels.conf etc/i2pd/
contrib/subscriptions.txt etc/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.
if getent passwd $I2PDUSER > /dev/null 2>&1; then
groupadd -f $I2PDUSER || true
usermod -s "/bin/false" -e 1 $I2PDUSER > /dev/null || true
else
adduser --system --quiet --group --home $I2PDHOME $I2PDUSER
fi
@ -23,7 +22,7 @@ case "$1" in
chmod 640 $LOGFILE
chown -f ${I2PDUSER}:adm $LOGFILE
mkdir -p -m0750 $I2PDHOME
chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
chown -f -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
;;
abort-upgrade|abort-remove|abort-deconfigure)
echo "Aborting upgrade"

26
debian/rules vendored

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

6
debian/watch vendored

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

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

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

@ -17,7 +17,9 @@ namespace i18n
{
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());
else if (!lang.compare("turkmen"))
i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale());
@ -32,9 +34,9 @@ namespace i18n
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
} // i2p

@ -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);
if (it == m_Plurals.end())
const auto it = m_Plurals.find(arg2);
if (it == m_Plurals.end()) // not found, fallback to english
{
return arg;
return n == 1 ? arg : arg2;
}
else
{
@ -56,9 +56,10 @@ namespace i18n
};
// Add localization here with language name as namespace
namespace english { 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 afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { 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 (); }
} // i18n

@ -61,7 +61,7 @@ namespace turkmen // language
{"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"},
{"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"},
{"Host is down", "Salgy elýeterli däl"},
{"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"},
{"LeaseSets", "Lizset"},
{"Tunnels", "Tuneller"},
{"Transit tunnels", "Tranzit Tunels"},
{"Transit tunnels", "Tranzit tunels"},
{"Transports", "Daşamak"},
{"I2P tunnels", "I2P tuneller"},
{"SAM sessions", "SAM Sessiýasy"},
@ -108,7 +108,7 @@ namespace turkmen // language
{"Uptime", "Onlaýn onlaýn sözlügi"},
{"Network status", "Tor ýagdaýy"},
{"Network status v6", "Tor ýagdaýy v6"},
{"Stopping in", "soň duruň"},
{"Stopping in", "Soň duruň"},
{"Family", "Maşgala"},
{"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"},
{"Received", "Alnan"},
@ -122,10 +122,9 @@ namespace turkmen // language
{"Router Caps", "Baýdaklar marşruteri"},
{"Version", "Wersiýasy"},
{"Our external address", "Daşarky salgymyz"},
{"supported", "Goldanýar"},
{"supported", "goldanýar"},
{"Routers", "Marşrutizatorlar"},
{"Floodfills", "Fludfillar"},
{"LeaseSets", "Lizsetllar"},
{"Client Tunnels", "Müşderi tunelleri"},
{"Transit Tunnels", "Tranzit Tunelleri"},
{"Services", "Hyzmatlar"},
@ -150,7 +149,7 @@ namespace turkmen // language
{"Destination", "Maksat"},
{"Amount", "Sany"},
{"Incoming Tags", "Gelýän bellikler"},
{"Tags sessions", "Sapaklar Tag."},
{"Tags sessions", "Sapaklar bellikler"},
{"Status", "Ýagdaýy"},
// ShowLocalDestination
{"Local Destination", "Ýerli maksat"},
@ -178,7 +177,7 @@ namespace turkmen // language
{"Start graceful shutdown", "Tekiz durmak"},
{"Force shutdown", "Mejbury duralga"},
{"<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"},
{"Transit tunnels limit", "Tranzit tunelleriniň çägi"},
{"Change", "Üýtgetmek"},
@ -217,7 +216,7 @@ namespace turkmen // language
{"Description", "Beýany"},
{"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"},
{"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"},
{"Such destination is not found", "Bu barmaly ýer tapylmady"},
{"", ""},

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

@ -221,7 +221,7 @@ namespace config {
("addressbook.defaulturl", value<std::string>()->default_value(
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
), "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");
options_description trust("Trust options");

@ -1109,21 +1109,22 @@ namespace garlic
bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len)
{
if (!GetOwner ()) return false;
i2p::crypto::NoiseSymmetricState state (GetNoiseState ());
m_CurrentNoiseState = GetNoiseState ();
// we are Bob
state.MixHash (buf, 32);
m_CurrentNoiseState.MixHash (buf, 32);
uint8_t sharedSecret[32];
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");
return false;
}
state.MixKey (sharedSecret);
m_CurrentNoiseState.MixKey (sharedSecret);
buf += 32; len -= 32;
uint8_t nonce[12];
CreateNonce (0, nonce);
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");
return false;

@ -249,6 +249,11 @@ namespace garlic
RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState);
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);

@ -426,8 +426,8 @@ namespace i2p
uint8_t nonce[12];
memset (nonce, 0, 12);
auto& noiseState = i2p::context.GetCurrentNoiseState ();
if (!noiseState || !i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
noiseState->m_H, 32, noiseState->m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
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
{
LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed");
return false;
@ -611,13 +611,8 @@ namespace i2p
return;
}
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)
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 (
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
@ -653,7 +648,7 @@ namespace i2p
otbrm->len += (payload - otbrm->GetPayload ());
otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET));
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;
memcpy (&tag, replyKeys + 32, 8);
// send garlic to reply tunnel
@ -674,14 +669,14 @@ namespace i2p
{
// TODO: fill reply
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");
return;
}
}
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;
}
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET,

@ -1170,7 +1170,7 @@ namespace transport
if (!address) continue;
if (address->IsPublishedNTCP2 () && address->port)
{
if (address->host.is_v4())
if (address->IsV4())
{
try
{
@ -1189,7 +1189,7 @@ namespace transport
auto conn = std::make_shared<NTCP2Session>(*this);
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 ()));
try
@ -1201,7 +1201,11 @@ namespace transport
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
#if (BOOST_VERSION >= 105500)
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));
}
#endif

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

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

@ -125,7 +125,7 @@ namespace garlic
void SetSupportsV4 (bool supportsV4);
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; };
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 UpdateStats ();
@ -185,7 +185,7 @@ namespace garlic
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
// for ECIESx25519
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
// i18n
std::shared_ptr<const i2p::i18n::Locale> m_Language;

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

@ -204,7 +204,8 @@ namespace data
void EnableMesh ();
void DisableMesh ();
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 IsHidden () const { return m_Caps & eHidden; };
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };

@ -70,7 +70,11 @@ namespace transport
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
#if (BOOST_VERSION >= 105500)
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));
}
#endif

@ -383,7 +383,7 @@ namespace transport
{
// tell out peer to now assign relay tag
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
htobe16buf (payload, flags);
payload += 2;
@ -1073,7 +1073,10 @@ namespace transport
LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob");
auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest
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
break;
}
@ -1093,9 +1096,12 @@ namespace transport
if (port)
{
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
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
{

@ -401,7 +401,7 @@ namespace transport
try
{
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);
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;
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 ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -457,7 +457,7 @@ namespace transport
}
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 ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -485,7 +485,7 @@ namespace transport
std::shared_ptr<const RouterInfo::Address> address;
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 ();
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
@ -495,7 +495,7 @@ namespace transport
}
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);
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))

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

Loading…
Cancel
Save