From ed53cbb7b7b544e7c593b9d2bde8d5159fdd36bd Mon Sep 17 00:00:00 2001 From: idk Date: Tue, 8 Jun 2021 16:25:45 -0400 Subject: [PATCH 001/186] OK that's my first working C wrapper, but I don't yet know how to do anything other than initialize, start, and stop a router --- libi2pd/capi.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ libi2pd/capi.h | 43 ++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 libi2pd/capi.cpp create mode 100644 libi2pd/capi.h diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp new file mode 100644 index 00000000..1decb717 --- /dev/null +++ b/libi2pd/capi.cpp @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2013-2020, 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 "capi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void C_InitI2P (int argc, char* argv[], const char * appName) +{ + return i2p::api::InitI2P(argc, argv, appName); +} + +void C_TerminateI2P () +{ + return i2p::api::TerminateI2P(); +} + +void C_StartI2P (std::shared_ptr logStream) +{ + return i2p::api::StartI2P(logStream); +} + +void C_StopI2P () +{ + return i2p::api::StopI2P(); +} + +void C_RunPeerTest () +{ + return i2p::api::RunPeerTest(); +} + +std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, + const std::map * params) +{ + return i2p::api::CreateLocalDestination(keys, isPublic, params); +} + +std::shared_ptr C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, + const std::map * params) +{ + return i2p::api::CreateLocalDestination(isPublic, sigType, params); +} + +void C_DestroyLocalDestination (std::shared_ptr dest) +{ + return i2p::api::DestroyLocalDestination(dest); +} + +void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote) +{ + return i2p::api::RequestLeaseSet(dest, remote); +} + +std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote) +{ + return i2p::api::CreateStream(dest, remote); +} + +void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) +{ + return i2p::api::AcceptStream(dest, acceptor); +} + +void C_DestroyStream (std::shared_ptr stream) +{ + return i2p::api::DestroyStream(stream); +} + +#ifdef __cplusplus +} +#endif + diff --git a/libi2pd/capi.h b/libi2pd/capi.h new file mode 100644 index 00000000..70b9228e --- /dev/null +++ b/libi2pd/capi.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef CAPI_H__ +#define CAPI_H__ + +#include "api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// initialization start and stop +void C_InitI2P (int argc, char* argv[], const char * appName); +void C_TerminateI2P (); +void C_StartI2P (std::shared_ptr logStream = nullptr); +// write system log to logStream, if not specified to .log in application's folder +void C_StopI2P (); +void C_RunPeerTest (); // should be called after UPnP + +// destinations +std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, + const std::map * params = nullptr); +std::shared_ptr C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, + const std::map * params = nullptr); // transient destinations usually not published +void C_DestroyLocalDestination (std::shared_ptr dest); + +// streams +void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote); +std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote); +void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); +void C_DestroyStream (std::shared_ptr stream); + +#ifdef __cplusplus +} +#endif + +#endif From b962a330ad863d7c5a8cbbdb7ab156902e8dc7d1 Mon Sep 17 00:00:00 2001 From: idk Date: Tue, 15 Jun 2021 12:02:57 -0400 Subject: [PATCH 002/186] Allow passing raw pointers to C wrapper functions, I think --- Makefile | 5 +++++ libi2pd/Destination.h | 8 ++++++++ libi2pd/capi.cpp | 38 ++++++++++++++++++++++---------------- libi2pd/capi.h | 17 +++++++++-------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 40e72918..7a033bf2 100644 --- a/Makefile +++ b/Makefile @@ -136,3 +136,8 @@ doxygen: .PHONY: mk_obj_dir .PHONY: install .PHONY: strip + +##TODO: delete this before a PR +testc: api api_client + g++ -Ii18n -c test.c -o test.o + g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 6695796d..f24e31ca 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -28,6 +28,10 @@ #include "Datagram.h" #include "util.h" +#ifdef __cplusplus +extern "C" { +#endif + namespace i2p { namespace client @@ -312,4 +316,8 @@ namespace client } } +#ifdef __cplusplus +} +#endif + #endif diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index 1decb717..b1f94d1f 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -22,9 +22,10 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P (std::shared_ptr logStream) +void C_StartI2P (std::ostream *logStream) { - return i2p::api::StartI2P(logStream); + std::shared_ptr cppLogStream(logStream); + return i2p::api::StartI2P(cppLogStream); } void C_StopI2P () @@ -37,41 +38,46 @@ void C_RunPeerTest () return i2p::api::RunPeerTest(); } -std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, +i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) { - return i2p::api::CreateLocalDestination(keys, isPublic, params); + return i2p::api::CreateLocalDestination(keys, isPublic, params).get(); } -std::shared_ptr C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, +i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, const std::map * params) { - return i2p::api::CreateLocalDestination(isPublic, sigType, params); + return i2p::api::CreateLocalDestination(isPublic, sigType, params).get(); } -void C_DestroyLocalDestination (std::shared_ptr dest) +void C_DestroyLocalDestination (i2p::client::ClientDestination *dest) { - return i2p::api::DestroyLocalDestination(dest); + std::shared_ptr cppDest(dest); + return i2p::api::DestroyLocalDestination(cppDest); } -void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote) +void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) { - return i2p::api::RequestLeaseSet(dest, remote); + std::shared_ptr cppDest(dest); + return i2p::api::RequestLeaseSet(cppDest, remote); } -std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote) +i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) { - return i2p::api::CreateStream(dest, remote); + std::shared_ptr cppDest(dest); + return i2p::api::CreateStream(cppDest, remote).get(); } -void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) +void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) { - return i2p::api::AcceptStream(dest, acceptor); + std::shared_ptr cppDest(dest); + return i2p::api::AcceptStream(cppDest, acceptor); } -void C_DestroyStream (std::shared_ptr stream) +void C_DestroyStream (i2p::stream::Stream *stream) { - return i2p::api::DestroyStream(stream); + std::shared_ptr cppStream(stream); + return i2p::api::DestroyStream(cppStream); } #ifdef __cplusplus diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 70b9228e..341cf39e 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -11,6 +11,7 @@ #include "api.h" + #ifdef __cplusplus extern "C" { #endif @@ -18,23 +19,23 @@ extern "C" { // initialization start and stop void C_InitI2P (int argc, char* argv[], const char * appName); void C_TerminateI2P (); -void C_StartI2P (std::shared_ptr logStream = nullptr); +void C_StartI2P (std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP // destinations -std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, +i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); -std::shared_ptr C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, +i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, const std::map * params = nullptr); // transient destinations usually not published -void C_DestroyLocalDestination (std::shared_ptr dest); +void C_DestroyLocalDestination (i2p::client::ClientDestination *dest); // streams -void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote); -std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote); -void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); -void C_DestroyStream (std::shared_ptr stream); +void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); +i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); +void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); +void C_DestroyStream (i2p::stream::Stream *stream); #ifdef __cplusplus } From a6af4908d55e11600e698a814bf731c5434799d6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Jun 2021 18:14:33 -0400 Subject: [PATCH 003/186] use m_ReachableTransports bitmask --- libi2pd/RouterContext.cpp | 2 ++ libi2pd/RouterInfo.cpp | 31 +++++++++---------------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 50dd6c59..c527aede 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -489,6 +489,7 @@ namespace i2p if (ntcp2) PublishNTCP2Address (port, false, v4, v6, false); // update + m_RouterInfo.UpdateSupportedTransports (); UpdateRouterInfo (); } @@ -528,6 +529,7 @@ namespace i2p } } // update + m_RouterInfo.UpdateSupportedTransports (); UpdateRouterInfo (); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index dcef9463..da456549 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -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,7 +994,6 @@ namespace data { if (IsV6 ()) { - m_SupportedTransports &= ~(eSSUV6 | eNTCP2V6); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -1011,6 +1010,7 @@ namespace data else ++it; } + UpdateSupportedTransports (); } } @@ -1018,7 +1018,6 @@ namespace data { if (IsV4 ()) { - m_SupportedTransports &= ~(eSSUV4 | eNTCP2V4); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -1035,13 +1034,17 @@ namespace data else ++it; } + UpdateSupportedTransports (); } } void RouterInfo::EnableMesh () { if (!IsMesh ()) + { m_SupportedTransports |= eNTCP2V6Mesh; + m_ReachableTransports |= eNTCP2V6Mesh; + } } void RouterInfo::DisableMesh () @@ -1049,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; @@ -1177,24 +1181,7 @@ 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 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; - }); + return m_ReachableTransports & other.m_SupportedTransports; } void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports) From 1dda832e39a5bed13a3d973267e1d9f702589d07 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:35:10 +0300 Subject: [PATCH 004/186] [gha] build docker containers Build docker containers and publish them to GitHub Container Registry --- .github/workflows/docker.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..d6afa613 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,28 @@ +name: Build Docker containers + +on: push + +jobs: + docker: + runs-on: ubuntu-latest + 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: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: contrib/docker/Dockerfile + platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + push: true + tags: ghcr.io/PurpleI2P/i2pd:latest From d058b9a5959d1c501442d96a5ee924a3341e7fcf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:38:38 +0300 Subject: [PATCH 005/186] [gha] fix repository name to lowercase --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d6afa613..9f15c30b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,4 +25,4 @@ jobs: file: contrib/docker/Dockerfile platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le push: true - tags: ghcr.io/PurpleI2P/i2pd:latest + tags: ghcr.io/purplei2p/i2pd:latest From 2ee7ed8dda5997c14228b9eb98191e5983d33dea Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:59:47 +0300 Subject: [PATCH 006/186] [gha] temporary build only amd64 container --- .github/workflows/docker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9f15c30b..51509008 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,6 +23,7 @@ jobs: with: context: . file: contrib/docker/Dockerfile - platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + platforms: linux/amd64 push: true tags: ghcr.io/purplei2p/i2pd:latest From 970f47ce3323ec7966885f1fce8c1f42a6f1207c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 11:03:30 +0300 Subject: [PATCH 007/186] [gha] remove context --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 51509008..50cfe2d2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,7 +21,6 @@ jobs: - name: Build and push uses: docker/build-push-action@v2 with: - context: . file: contrib/docker/Dockerfile # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le platforms: linux/amd64 From 3dc19bfd318e5d0bb093c41f0f7d0503d0e5bb70 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 11:07:56 +0300 Subject: [PATCH 008/186] [gha] docker - disable cache (test) --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 50cfe2d2..d0e5e28c 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,4 +25,5 @@ jobs: # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le platforms: linux/amd64 push: true + no-cache: true tags: ghcr.io/purplei2p/i2pd:latest From 08a82a0bcd95855c8e02b91b4377929226dc1729 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 12:12:06 -0400 Subject: [PATCH 009/186] don't try to connect to a router not reachable from us --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 1e40f88c..3aaa12ba 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -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 l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, From f56f75bb3f474d7a29c4c6efd85ca99cd90716da Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 17:37:47 +0100 Subject: [PATCH 010/186] [gha] add docker building (#1664) --- .github/workflows/docker.yml | 19 +++++++++++++------ contrib/docker/Dockerfile | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d0e5e28c..81c0fcfb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,29 +1,36 @@ -name: Build Docker containers +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: registry: ghcr.io - username: ${{ github.repository_owner }} + username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push uses: docker/build-push-action@v2 with: - file: contrib/docker/Dockerfile - # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le - platforms: linux/amd64 + context: ./contrib/docker + file: ./contrib/docker/Dockerfile + platforms: linux/amd64,linux/386 push: true - no-cache: true tags: ghcr.io/purplei2p/i2pd:latest diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index dc9f5501..71af141e 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -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 \ From a97d2bbb6393c161b5f51dba67d531fc312e7517 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 20:07:10 +0300 Subject: [PATCH 011/186] [gha] publish containers to docker hub --- .github/workflows/docker.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 81c0fcfb..0946b431 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,6 +20,12 @@ jobs: 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 @@ -33,4 +39,6 @@ jobs: file: ./contrib/docker/Dockerfile platforms: linux/amd64,linux/386 push: true - tags: ghcr.io/purplei2p/i2pd:latest + tags: | + purplei2p/i2pd:latest + ghcr.io/purplei2p/i2pd:latest From 3330d2bb0ca098067e39ac41aa4f27e44ab5f05e Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 13:24:19 -0400 Subject: [PATCH 012/186] Also Extern Identity, Destination, Streaming headers --- Makefile | 11 ++++++++++- libi2pd/capi.cpp | 9 +++++---- libi2pd/capi.h | 9 +++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 7a033bf2..0569ab7c 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,13 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) obj/%.o: %.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< +flags: + @echo $(CXXFLAGS) + @echo $(NEEDED_CXXFLAGS) + @echo $(INCFLAGS) + @echo $(LDFLAGS) + @echo $(LDLIBS) + # '-' is 'ignore if missing' on first run -include $(DEPS) @@ -139,5 +146,7 @@ doxygen: ##TODO: delete this before a PR testc: api api_client - g++ -Ii18n -c test.c -o test.o +# g++ -Ii18n -c test.c -o test.o + gcc -Ii18n -c _test.c -o test.o +# gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index b1f94d1f..d507f64e 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -6,6 +6,7 @@ * See full license text in LICENSE file at top of project tree */ +#include "api.h" #include "capi.h" #ifdef __cplusplus @@ -22,10 +23,10 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P (std::ostream *logStream) +void C_StartI2P ()//std::ostream *logStream) { - std::shared_ptr cppLogStream(logStream); - return i2p::api::StartI2P(cppLogStream); +// std::shared_ptr cppLogStream(logStream); + return i2p::api::StartI2P(nullptr); } void C_StopI2P () @@ -80,7 +81,7 @@ void C_DestroyStream (i2p::stream::Stream *stream) return i2p::api::DestroyStream(cppStream); } + #ifdef __cplusplus } #endif - diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 341cf39e..0ad92b49 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,17 +9,18 @@ #ifndef CAPI_H__ #define CAPI_H__ -#include "api.h" - - #ifdef __cplusplus extern "C" { #endif +#include "Identity.h" +#include "Destination.h" +#include "Streaming.h" + // initialization start and stop void C_InitI2P (int argc, char* argv[], const char * appName); void C_TerminateI2P (); -void C_StartI2P (std::ostream *logStream = nullptr); +void C_StartI2P (); //std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP From 45ef6cba9d07127d1001911c7072c01ba436efb4 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 13:46:57 -0400 Subject: [PATCH 013/186] Un-mangle Destination in case we need to somehow pass one to DestroyLocalDestination,RequestLeaseSet, etc --- Makefile | 2 +- libi2pd/Identity.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0569ab7c..29a03fc1 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,6 @@ doxygen: ##TODO: delete this before a PR testc: api api_client # g++ -Ii18n -c test.c -o test.o - gcc -Ii18n -c _test.c -o test.o + gcc -llibi2pd.so -c _test.c -o test.o # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index e9cf63ed..2e7cd32d 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -20,6 +20,10 @@ #include "Signature.h" #include "CryptoKey.h" +#ifdef __cplusplus +extern "C" { +#endif + namespace i2p { namespace data @@ -244,4 +248,8 @@ namespace data } } +#ifdef __cplusplus +} +#endif + #endif From 669720d8f5f0b84abdc97175dfccaf563a92c6e4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 21:37:48 +0300 Subject: [PATCH 014/186] [gha] build and publish release containers --- .github/workflows/docker.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0946b431..aced7f39 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,6 +1,6 @@ name: Build containers -on: push +on: [push] jobs: docker: @@ -32,7 +32,8 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push + - name: Build and push trunk container + if: ${{ !startsWith(github.ref, 'refs/tags/') }} uses: docker/build-push-action@v2 with: context: ./contrib/docker @@ -42,3 +43,21 @@ jobs: 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 }} From 82bb3a9b25f0eeddd59a0dcfdff53e66ab172fab Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 01:26:08 +0300 Subject: [PATCH 015/186] [i18n] remove comment line in afrikaans Signed-off-by: R4SAS --- i18n/Afrikaans.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 098c1105..d2b652b4 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -13,7 +13,6 @@ #include "I18N.h" // Afrikaans localization file -// This is an example translation file without strings in it. namespace i2p { From e14d3584205d20e232510a8b555ed5fab600bac9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 22:11:46 +0300 Subject: [PATCH 016/186] [docker] add debug commands Adding `g++ -dumpmachine` command on build stage to figure out why docker hub is unable to build container. --- contrib/docker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 71af141e..d8140412 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -31,6 +31,7 @@ RUN apk update \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ + && g++ -dumpmachine \ && make USE_UPNP=yes \ && cp -R contrib/certificates /i2pd_certificates \ && mkdir -p /usr/local/bin \ From 5e11a03f0aa4c9fe75f9a20fb953e2428c7ad5c0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 22:41:37 +0300 Subject: [PATCH 017/186] [docker] fallback to alpine 3.13 https://wiki.alpinelinux.org/wiki/Draft_Release_Notes_for_Alpine_3.14.0#faccessat2 --- contrib/docker/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index d8140412..6470e148 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:latest +FROM alpine:3.13 LABEL authors "Mikal Villa , Darknet Villain " # Expose git branch, tag and URL variables as arguments @@ -31,7 +31,6 @@ RUN apk update \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ - && g++ -dumpmachine \ && make USE_UPNP=yes \ && cp -R contrib/certificates /i2pd_certificates \ && mkdir -p /usr/local/bin \ From 5013ce56491131b824685efb9b83e07c23236d55 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 18:25:55 -0400 Subject: [PATCH 018/186] Try and figure out why the C Compiler thinks it needs to find iostream when the C++ library has already been compiled. Make the makefile aware of variables in the environment --- Makefile | 35 +++++++++++++++++++++-------------- libi2pd/api.swigcxx | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 libi2pd/api.swigcxx diff --git a/Makefile b/Makefile index 29a03fc1..97e75c15 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ DAEMON_SRC_DIR := daemon # import source files lists include filelist.mk -USE_AESNI := yes -USE_STATIC := no -USE_MESHNET := no -USE_UPNP := no -DEBUG := yes +USE_AESNI := $(or $(USE_AESNI),yes) +USE_STATIC := $(or $(USE_STATIC),no) +USE_MESHNET := $(or $(USE_MESHNET),no) +USE_UPNP := $(or $(USE_UPNP),no) +DEBUG := $(or $(DEBUG),yes) ifeq ($(DEBUG),yes) CXX_DEBUG = -g @@ -82,13 +82,6 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) obj/%.o: %.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< -flags: - @echo $(CXXFLAGS) - @echo $(NEEDED_CXXFLAGS) - @echo $(INCFLAGS) - @echo $(LDFLAGS) - @echo $(LDLIBS) - # '-' is 'ignore if missing' on first run -include $(DEPS) @@ -144,9 +137,23 @@ doxygen: .PHONY: install .PHONY: strip +flags: + @echo $(CXXFLAGS) + @echo $(NEEDED_CXXFLAGS) + @echo $(INCFLAGS) + @echo $(LDFLAGS) + @echo $(LDLIBS) + @echo $(USE_AESNI) + @echo $(USE_STATIC) + @echo $(USE_MESHNET) + @echo $(USE_UPNP) + @echo $(DEBUG) + ##TODO: delete this before a PR testc: api api_client # g++ -Ii18n -c test.c -o test.o - gcc -llibi2pd.so -c _test.c -o test.o +# gcc -llibi2pd.so -c _test.c -o test.o + $(CC) -g -Wall -o test.o _test.c libi2pd.a +# gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o - g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file +# g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx new file mode 100644 index 00000000..324967ee --- /dev/null +++ b/libi2pd/api.swigcxx @@ -0,0 +1,16 @@ +// See swig.org for more inteface options, +// e.g. map std::string to Go string + +%{ +#include "api.h" +//#include "Streaming.h" +#include "Destination.h" +//#include "Identity.h" +//#include "Tag.h" +%} + +%include "api.h" +//%include "Streaming.h" +//%include "Destination.h" +//%include "Identity.h" +//%include "Tag.h" \ No newline at end of file From 81c83f0d54aca38fb82d1a60e9108cd341ceb69f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 19:10:57 -0400 Subject: [PATCH 019/186] pick ECIES routers only for non-x64 --- libi2pd/NetDb.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index a1d97cba..5e93fabb 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -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 }); } From 2185019b59b3a54fb5280508f3130805a9b7f9e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 19:46:05 -0400 Subject: [PATCH 020/186] check if router is reachable by transport before obtaining address --- libi2pd/RouterInfo.cpp | 5 ----- libi2pd/RouterInfo.h | 3 ++- libi2pd/Transports.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index da456549..3f50a4b7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1179,11 +1179,6 @@ namespace data }); } - bool RouterInfo::IsReachableFrom (const RouterInfo& other) const - { - return m_ReachableTransports & other.m_SupportedTransports; - } - void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports) { for (auto& addr: *m_Addresses) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index bea83fda..89654757 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -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; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 3aaa12ba..c2bed2ab 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -447,7 +447,7 @@ namespace transport std::shared_ptr 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 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)) From 7bc2e74683307952c8c8dd442fffe73519c86882 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 23:12:22 -0400 Subject: [PATCH 021/186] Get it to build from go build --- Makefile | 39 +++++++++++++++++++++++++++++---------- libi2pd/Destination.h | 8 -------- libi2pd/Identity.h | 8 -------- libi2pd/api.go | 10 ++++++++++ libi2pd/api.swigcxx | 6 +++--- libi2pd/capi.cpp | 9 +++++---- libi2pd/capi.h | 11 ++++++----- 7 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 libi2pd/api.go diff --git a/Makefile b/Makefile index 97e75c15..62a64584 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ SYS := $(shell $(CXX) -dumpmachine) SHLIB := libi2pd.so ARLIB := libi2pd.a +SHLIB_LANG := libi2pdlang.so +ARLIB_LANG := libi2pdlang.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a I2PD := i2pd @@ -26,6 +28,12 @@ else LD_DEBUG = -s endif +ifeq ($(USE_STATIC),yes) + NEEDED_CXXFLAGS+= -static +else + +endif + ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) @@ -68,9 +76,10 @@ mk_obj_dir: @mkdir -p obj/$(LANG_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -88,22 +97,31 @@ obj/%.o: %.cpp $(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif -$(ARLIB): $(LIB_OBJS) +$(SHLIB_LANG): $(LANG_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ -$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_LANG): $(LANG_OBJS) + $(AR) -r $@ $^ + + clean: $(RM) -r obj $(RM) -r docs/generated @@ -151,9 +169,10 @@ flags: ##TODO: delete this before a PR testc: api api_client -# g++ -Ii18n -c test.c -o test.o + g++ -Ii18n -c _test.c -o test.o # gcc -llibi2pd.so -c _test.c -o test.o - $(CC) -g -Wall -o test.o _test.c libi2pd.a +# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -Ilibi2pd -Ilibi2pd_client -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so +# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so # gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o -# g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file + g++ test.o libi2pd.a libi2pdclient.a libi2pdlang.a -o test.main \ No newline at end of file diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f24e31ca..6695796d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -28,10 +28,6 @@ #include "Datagram.h" #include "util.h" -#ifdef __cplusplus -extern "C" { -#endif - namespace i2p { namespace client @@ -316,8 +312,4 @@ namespace client } } -#ifdef __cplusplus -} -#endif - #endif diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 2e7cd32d..e9cf63ed 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -20,10 +20,6 @@ #include "Signature.h" #include "CryptoKey.h" -#ifdef __cplusplus -extern "C" { -#endif - namespace i2p { namespace data @@ -248,8 +244,4 @@ namespace data } } -#ifdef __cplusplus -} -#endif - #endif diff --git a/libi2pd/api.go b/libi2pd/api.go new file mode 100644 index 00000000..d7a19bc9 --- /dev/null +++ b/libi2pd/api.go @@ -0,0 +1,10 @@ +package api + +/* +//void Go_InitI2P (int argc, char argv[], const char * appName){ + +//} +#cgo CPPFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +*/ +import "C" diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx index 324967ee..fbb1b95a 100644 --- a/libi2pd/api.swigcxx +++ b/libi2pd/api.swigcxx @@ -2,14 +2,14 @@ // e.g. map std::string to Go string %{ -#include "api.h" +#include "capi.h" //#include "Streaming.h" -#include "Destination.h" +//#include "Destination.h" //#include "Identity.h" //#include "Tag.h" %} -%include "api.h" +%include "capi.h" //%include "Streaming.h" //%include "Destination.h" //%include "Identity.h" diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index d507f64e..1a2498b6 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -13,9 +13,9 @@ extern "C" { #endif -void C_InitI2P (int argc, char* argv[], const char * appName) +void C_InitI2P (int argc, char argv[], const char * appName) { - return i2p::api::InitI2P(argc, argv, appName); + return i2p::api::InitI2P(argc, &argv, appName); } void C_TerminateI2P () @@ -25,8 +25,9 @@ void C_TerminateI2P () void C_StartI2P ()//std::ostream *logStream) { -// std::shared_ptr cppLogStream(logStream); - return i2p::api::StartI2P(nullptr); + std::shared_ptr logStream; + //cppLogStream(&out); + return i2p::api::StartI2P(logStream); } void C_StopI2P () diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 0ad92b49..8395cfca 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,16 +9,17 @@ #ifndef CAPI_H__ #define CAPI_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "Identity.h" #include "Destination.h" #include "Streaming.h" +#ifdef __cplusplus +extern "C" { +#endif + // initialization start and stop -void C_InitI2P (int argc, char* argv[], const char * appName); +void C_InitI2P (int argc, char argv[], const char * appName); +//void C_InitI2P (int argc, char** argv, const char * appName); void C_TerminateI2P (); void C_StartI2P (); //std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder From 5bfab0a79639924b666ce20647a8fe469838f0fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 06:38:10 +0300 Subject: [PATCH 022/186] add certsdir option (#1642) Signed-off-by: R4SAS --- contrib/i2pd.conf | 4 ++++ libi2pd/Config.cpp | 1 + libi2pd/Family.cpp | 9 ++++++++- libi2pd/Reseed.cpp | 9 ++++++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index f3cea2b5..7b85a61b 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -15,6 +15,10 @@ ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d # tunnelsdir = /var/lib/i2pd/tunnels.d +## Path to certificates used for verifying .su3, families +## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates +# certsdir = /var/lib/i2pd/certificates + ## Where to write pidfile (default: i2pd.pid, not used in Windows) # pidfile = /run/i2pd.pid diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index a80778a1..16d50e8c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -37,6 +37,7 @@ namespace config { ("conf", value()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)") ("tunconf", value()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)") ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") + ("certsdir", value()->default_value(""), "Path to certificates used for verifying .su3, families (default: ~/.i2pd/certificates or /var/lib/i2pd/certificates") ("pidfile", value()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)") ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index fbb7b9ee..baf846f6 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -98,7 +98,14 @@ namespace data void Families::LoadCertificates () { - std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + std::string certDir; + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + if (!i2p::config::IsDefault("certsdir")) + certDir = certsdir + i2p::fs::dirSep + "family"; + + if (certDir.empty() || !i2p::fs::Exists(certDir)) + std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 41111ecc..a78058cf 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -497,7 +497,14 @@ namespace data void Reseeder::LoadCertificates () { - std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::string certDir; + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + if (!i2p::config::IsDefault("certsdir")) + certDir = certsdir + i2p::fs::dirSep + "reseed"; + + if (certDir.empty() || !i2p::fs::Exists(certDir)) + std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::vector files; int numCertificates = 0; From d3a49e513c75ba4a78ac8d68a4def828feb6bfcb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 06:40:58 +0300 Subject: [PATCH 023/186] remove repeatable type definition, add include (#1642) Signed-off-by: R4SAS --- libi2pd/Family.cpp | 3 ++- libi2pd/Reseed.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index baf846f6..f37a5f54 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -13,6 +13,7 @@ #include "FS.h" #include "Log.h" #include "Family.h" +#include "Config.h" namespace i2p { @@ -104,7 +105,7 @@ namespace data certDir = certsdir + i2p::fs::dirSep + "family"; if (certDir.empty() || !i2p::fs::Exists(certDir)) - std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + certDir = i2p::fs::DataDirPath("certificates", "family"); std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index a78058cf..482506b2 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -503,7 +503,7 @@ namespace data certDir = certsdir + i2p::fs::dirSep + "reseed"; if (certDir.empty() || !i2p::fs::Exists(certDir)) - std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + certDir = i2p::fs::DataDirPath("certificates", "reseed"); std::vector files; int numCertificates = 0; From e8ad7b4f79292c8ccded1c22e80089ad9f6a501f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 10:04:48 +0300 Subject: [PATCH 024/186] rework of storing certificates path (#1642) Signed-off-by: R4SAS --- daemon/Daemon.cpp | 6 ++++++ libi2pd/FS.cpp | 20 ++++++++++++++++++++ libi2pd/FS.h | 18 +++++++++++++++++- libi2pd/Family.cpp | 8 +------- libi2pd/Reseed.cpp | 8 +------- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index f7f2ef2f..445c4dfd 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -94,6 +94,11 @@ namespace util i2p::config::GetOption("daemon", isDaemon); + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + i2p::fs::SetCertsDir(certsdir); + + certsdir = i2p::fs::GetCertsDir(); + std::string logs = ""; i2p::config::GetOption("log", logs); std::string logfile = ""; i2p::config::GetOption("logfile", logfile); std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); @@ -132,6 +137,7 @@ namespace util LogPrint(eLogNone, "i2pd v", VERSION, " starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); + LogPrint(eLogDebug, "FS: certificates directory: ", certsdir); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 6ac302b0..f6653e55 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -24,6 +24,7 @@ namespace i2p { namespace fs { std::string appName = "i2pd"; std::string dataDir = ""; + std::string certsDir = ""; #ifdef _WIN32 std::string dirSep = "\\"; #else @@ -42,6 +43,10 @@ namespace fs { return dataDir; } + const std::string & GetCertsDir () { + return certsDir; + } + const std::string GetUTF8DataDir () { #ifdef _WIN32 boost::filesystem::wpath path (dataDir); @@ -126,6 +131,21 @@ namespace fs { #endif } + void SetCertsDir(const std::string & cmdline_certsdir) { + if (cmdline_certsdir != "") + { + if (cmdline_certsdir[cmdline_certsdir.length()-1] == '/') + certsDir = cmdline_certsdir.substr(0, cmdline_certsdir.size()-1); // strip trailing slash + else + certsDir = cmdline_certsdir; + } + else + { + certsDir = i2p::fs::DataDirPath("certificates"); + } + return; + } + bool Init() { if (!boost::filesystem::exists(dataDir)) boost::filesystem::create_directory(dataDir); diff --git a/libi2pd/FS.h b/libi2pd/FS.h index f07ee35c..d51aa955 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -75,6 +75,9 @@ namespace fs { /** @brief Returns datadir path */ const std::string & GetDataDir(); + /** @brief Returns certsdir path */ + const std::string & GetCertsDir(); + /** @brief Returns datadir path in UTF-8 encoding */ const std::string GetUTF8DataDir(); @@ -90,7 +93,20 @@ namespace fs { * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/ * Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/ */ - void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); + void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); + + /** + * @brief Set certsdir either from cmdline option or using autodetection + * @param cmdline_param Value of cmdline parameter --certsdir= + * + * Examples of autodetected paths: + * + * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\certificates + * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\certificates + * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates + * Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates + */ + void SetCertsDir(const std::string & cmdline_certsdir); /** * @brief Create subdirectories inside datadir diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index f37a5f54..a6f0e2ee 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -99,13 +99,7 @@ namespace data void Families::LoadCertificates () { - std::string certDir; - std::string certsdir; i2p::config::GetOption("certsdir", certsdir); - if (!i2p::config::IsDefault("certsdir")) - certDir = certsdir + i2p::fs::dirSep + "family"; - - if (certDir.empty() || !i2p::fs::Exists(certDir)) - certDir = i2p::fs::DataDirPath("certificates", "family"); + std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "family"; std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 482506b2..aec683d4 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -497,13 +497,7 @@ namespace data void Reseeder::LoadCertificates () { - std::string certDir; - std::string certsdir; i2p::config::GetOption("certsdir", certsdir); - if (!i2p::config::IsDefault("certsdir")) - certDir = certsdir + i2p::fs::dirSep + "reseed"; - - if (certDir.empty() || !i2p::fs::Exists(certDir)) - certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "reseed"; std::vector files; int numCertificates = 0; From 8e5d2e1b73fa28133c0e51aa0455bd77155ecdf9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 17:26:18 +0300 Subject: [PATCH 025/186] [readme] add gha container build badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92a2f46f..37c4553a 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Build instructions: * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. * Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml) * 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/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml) * Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd) * FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml) * Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml) From 6ca28adcbb29df8fd94d1e735ae5791bbd2e5a54 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 18 Jun 2021 18:19:05 -0400 Subject: [PATCH 026/186] set address caps and available transports for new address --- libi2pd/RouterContext.cpp | 23 ++++++++++++++--------- libi2pd/RouterInfo.cpp | 16 ++++++++++++++-- libi2pd/RouterInfo.h | 3 ++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c527aede..adce291c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -568,16 +568,21 @@ namespace i2p { bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); - if (ntcp2 && ntcp2Published) + if (ntcp2) { - std::string ntcp2Host; - if (!i2p::config::IsDefault ("ntcp2.addressv6")) - i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); + if (ntcp2Published) + { + std::string ntcp2Host; + if (!i2p::config::IsDefault ("ntcp2.addressv6")) + i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); + else + ntcp2Host = "::1"; + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + } else - ntcp2Host = "::1"; - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); } } m_RouterInfo.EnableV6 (); @@ -632,7 +637,7 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port); } else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4); } } m_RouterInfo.EnableV4 (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3f50a4b7..a426d9b7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -840,21 +840,33 @@ namespace data for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; + m_ReachableTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; m_Addresses->push_back(std::move(addr)); } - void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port) + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, + const boost::asio::ip::address& host, int port, uint8_t caps) { auto addr = std::make_shared
(); addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP; - addr->caps = 0; + addr->caps = caps; addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); if (port) addr->published = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->iv, iv, 16); + if (addr->IsV4 ()) + { + m_SupportedTransports |= eNTCP2V4; + if (addr->published) m_ReachableTransports |= eNTCP2V4; + } + if (addr->IsV6 ()) + { + m_SupportedTransports |= eNTCP2V6; + if (addr->published) m_ReachableTransports |= eNTCP2V6; + } m_Addresses->push_back(std::move(addr)); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 89654757..f27a5d68 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -179,7 +179,8 @@ namespace data std::shared_ptr GetYggdrasilAddress () const; void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); - void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0); + void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, + const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0); bool AddIntroducer (const Introducer& introducer); bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only From f5e7d87f5b8b63424e544729fd475bfd41a4892e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Jun 2021 14:25:50 -0400 Subject: [PATCH 027/186] don't disable floodfill if still reachable by ipv6 --- libi2pd/RouterContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index adce291c..b2a19890 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -470,7 +470,8 @@ namespace i2p uint8_t caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eReachable; caps |= i2p::data::RouterInfo::eUnreachable; - caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill + if (v6 || !SupportsV6 ()) + caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill m_RouterInfo.SetCaps (caps); } uint16_t port = 0; From fed04c1a199c4d97f46ae3f64915fbf4e1217934 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Jun 2021 14:44:33 -0400 Subject: [PATCH 028/186] requsted router to send to if not in netdb --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c2bed2ab..181c3663 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -401,7 +401,7 @@ namespace transport try { auto r = netdb.FindRouter (ident); - if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return; + if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable { std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, From 84d987810f9a6f657ea854069754d979e648442a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 20 Jun 2021 09:36:14 +0300 Subject: [PATCH 029/186] add afrikaans in config example --- contrib/i2pd.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 7b85a61b..599a2081 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,7 +108,8 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), russian, turkmen and ukrainian languages +## Currently supported english (default), afrikaans, russian, turkmen and ukrainian languages + # lang = english [httpproxy] From 6971b1e9da863a7260b145dde29f5961c74feaf0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 20 Jun 2021 20:02:20 +0300 Subject: [PATCH 030/186] fix typo in config option description Kudos @iBicha https://github.com/PurpleI2P/i2pd/pull/1662#pullrequestreview-687850246 Signed-off-by: R4SAS --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 16d50e8c..e5640ad0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -285,7 +285,7 @@ namespace config { options_description meshnets("Meshnet transports options"); meshnets.add_options() - ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)") + ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)") ("meshnets.yggaddress", value()->default_value(""), "Yggdrasil address to publish") ; From 35ba16ff3b986749aaf1b1a2065196a1578c1be4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 20 Jun 2021 17:20:29 -0400 Subject: [PATCH 031/186] fixed #1665. cast to int64_t --- daemon/I2PControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 12602c99..73dde618 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -406,7 +406,7 @@ namespace client void I2PControlService::UptimeHandler (std::ostringstream& results) { - InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000); + InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL)); } void I2PControlService::VersionHandler (std::ostringstream& results) From 7d51b4c6ed83fe9e9edf0be04998df6404ff1be8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 21 Jun 2021 21:16:25 +0300 Subject: [PATCH 032/186] [i18n] pull ukrainian translation from crowdin (closes #1666) Signed-off-by: R4SAS --- contrib/i18n/regex.txt | 3 + i18n/Ukrainian.cpp | 299 +++++++++++++++++++---------------------- 2 files changed, 139 insertions(+), 163 deletions(-) diff --git a/contrib/i18n/regex.txt b/contrib/i18n/regex.txt index 768a4b01..e74f9d2d 100644 --- a/contrib/i18n/regex.txt +++ b/contrib/i18n/regex.txt @@ -5,3 +5,6 @@ msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"( msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n {"$1", "$2"},\n + +^#:(.*)$\n + diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 11878cde..5e856c52 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -28,23 +28,151 @@ namespace ukrainian // language static std::map strings { - // HTTP Proxy + {"Disabled", "Вимкнуто"}, + {"Enabled", "Увімкнуто"}, + {"KiB", "КіБ"}, + {"MiB", "МіБ"}, + {"GiB", "ГіБ"}, + {"building", "будується"}, + {"failed", "невдалий"}, + {"expiring", "завершується"}, + {"established", "працює"}, + {"unknown", "невідомо"}, + {"exploratory", "дослідницький"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + {"Main page", "Головна"}, + {"Router commands", "Команди маршрутизатора"}, + {"Local destinations", "Локальні призначення"}, + {"LeaseSets", "Лізсети"}, + {"Tunnels", "Тунелі"}, + {"Transit tunnels", "Транзитні тунелі"}, + {"Transports", "Транспорти"}, + {"I2P tunnels", "I2P тунелі"}, + {"SAM sessions", "SAM сесії"}, + {"ERROR", "ПОМИЛКА"}, + {"OK", "OK"}, + {"Testing", "Тестування"}, + {"Firewalled", "Заблоковано ззовні"}, + {"Unknown", "Невідомо"}, + {"Proxy", "Проксі"}, + {"Mesh", "MESH-мережа"}, + {"Error", "Помилка"}, + {"Clock skew", "Неточний час"}, + {"Offline", "Офлайн"}, + {"Symmetric NAT", "Симетричний NAT"}, + {"Uptime", "У мережі"}, + {"Network status", "Мережевий статус"}, + {"Network status v6", "Мережевий статус v6"}, + {"Stopping in", "Зупинка через"}, + {"Family", "Сімейство"}, + {"Tunnel creation success rate", "Успішно побудованих тунелів"}, + {"Received", "Отримано"}, + {"KiB/s", "КіБ/с"}, + {"Sent", "Відправлено"}, + {"Transit", "Транзит"}, + {"Data path", "Шлях до даних"}, + {"Hidden content. Press on text to see.", "Прихований вміст. Щоб відобразити, натисніть на текст."}, + {"Router Ident", "Ідентифікатор маршрутизатора"}, + {"Router Family", "Сімейство маршрутизатора"}, + {"Router Caps", "Прапорці маршрутизатора"}, + {"Version", "Версія"}, + {"Our external address", "Наша зовнішня адреса"}, + {"supported", "підтримується"}, + {"Routers", "Маршрутизатори"}, + {"Floodfills", "Флудфіли"}, + {"Client Tunnels", "Клієнтські Тунелі"}, + {"Transit Tunnels", "Транзитні Тунелі"}, + {"Services", "Сервіси"}, + {"Local Destinations", "Локальні Призначення"}, + {"Encrypted B33 address", "Шифровані B33 адреси"}, + {"Address registration line", "Рядок реєстрації адреси"}, + {"Domain", "Домен"}, + {"Generate", "Згенерувати"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Примітка: отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня (example.i2p). Для реєстрації піддоменів використовуйте i2pd-tools."}, + {"Address", "Адреса"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Вхідні тунелі"}, + {"ms", "мс"}, + {"Outbound tunnels", "Вихідні тунелі"}, + {"Tags", "Теги"}, + {"Incoming", "Вхідні"}, + {"Outgoing", "Вихідні"}, + {"Destination", "Призначення"}, + {"Amount", "Кількість"}, + {"Incoming Tags", "Вхідні Теги"}, + {"Tags sessions", "Сесії Тегів"}, + {"Status", "Статус"}, + {"Local Destination", "Локальні Призначення"}, + {"Streams", "Потоки"}, + {"Close stream", "Закрити потік"}, + {"I2CP session not found", "I2CP сесія не знайдена"}, + {"I2CP is not enabled", "I2CP не увікнуто"}, + {"Invalid", "Некоректний"}, + {"Store type", "Тип сховища"}, + {"Expires", "Завершується"}, + {"Non Expired Leases", "Не завершені Lease-и"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID тунеля"}, + {"EndDate", "Закінчується"}, + {"not floodfill", "не флудфіл"}, + {"Queue size", "Розмір черги"}, + {"Run peer test", "Запустити тестування"}, + {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, + {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, + {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, + {"Start graceful shutdown", "Запустити плавну зупинку"}, + {"Force shutdown", "Примусова зупинка"}, + {"Note: any action done here are not persistent and not changes your config files.", "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, + {"Logging level", "Рівень логування"}, + {"Transit tunnels limit", "Обмеження транзитних тунелів"}, + {"Change", "Змінити"}, + {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, + {"SAM disabled", "SAM вимкнуто"}, + {"no sessions currently running", "немає запущених сесій"}, + {"SAM session not found", "SAM сесія не знайдена"}, + {"SAM Session", "SAM сесія"}, + {"Server Tunnels", "Серверні Тунелі"}, + {"Client Forwards", "Клієнтські Переспрямування"}, + {"Server Forwards", "Серверні Переспрямування"}, + {"Unknown page", "Невідома сторінка"}, + {"Invalid token", "Невірний токен"}, + {"SUCCESS", "УСПІШНО"}, + {"Stream closed", "Потік зачинений"}, + {"Stream not found or already was closed", "Потік не знайдений або вже зачинений"}, + {"Destination not found", "Точка призначення не знайдена"}, + {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, + {"Return to destination page", "Повернутися на сторінку точки призначення"}, + {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, + {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, + {"Back to commands list", "Повернутися до списку команд"}, + {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, + {"Description", "Опис"}, + {"A bit information about service on domain", "Трохи інформації про сервіс на домені"}, + {"Submit", "Надіслати"}, + {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, + {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, + {"Such destination is not found", "Така точка призначення не знайдена"}, + {"Unknown command", "Невідома команда"}, + {"Command accepted", "Команда прийнята"}, + {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Proxy error", "Помилка проксі"}, {"Proxy info", "Інформація проксі"}, {"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"}, - {"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі роутера"}, + {"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі маршрутизатора"}, {"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"}, {"Invalid request", "Некоректний запит"}, {"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"}, {"addresshelper is not supported", "addresshelper не підтримується"}, {"Host", "Адреса"}, - {"added to router's addressbook from helper", "доданий в адресну книгу роутера через хелпер"}, - {"already in router's addressbook", "вже в адресній книзі роутера"}, + {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"}, {"Click", "Натисніть"}, {"here", "тут"}, {"to proceed", "щоб продовжити"}, - {"to update record", "щоб оновити запис"}, {"Addresshelper found", "Знайдено addresshelper"}, + {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, + {"to update record", "щоб оновити запис"}, + {"Invalid Request", "Некоректний Запит"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, @@ -64,169 +192,14 @@ namespace ukrainian // language {"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"}, {"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"}, {"Host is down", "Вузол недоступний"}, - {"Can't create connection to requested host, it may be down. Please try again later.", - "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, - - // Webconsole // - // cssStyles - {"Disabled", "Вимкнуто"}, - {"Enabled", "Увімкнуто"}, - // ShowTraffic - {"KiB", "КіБ"}, - {"MiB", "МіБ"}, - {"GiB", "ГіБ"}, - // ShowTunnelDetails - {"building", "будується"}, - {"failed", "невдалий"}, - {"expiring", "завершується"}, - {"established", "працює"}, - {"exploratory", "дослідницький"}, - {"unknown", "невідомо"}, - {"i2pd webconsole", "Веб-консоль i2pd"}, - // ShowPageHead - {"Main page", "Головна"}, - {"Router commands", "Команди роутера"}, - {"Local destinations", "Локальні призначення"}, - {"LeaseSets", "Лізсети"}, - {"Tunnels", "Тунелі"}, - {"Transit tunnels", "Транзитні тунелі"}, - {"Transports", "Транспорти"}, - {"I2P tunnels", "I2P тунелі"}, - {"SAM sessions", "SAM сесії"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Тестування"}, - {"Firewalled", "Заблоковано ззовні"}, - {"Unknown", "Невідомо"}, - {"Proxy", "Проксі"}, - {"Mesh", "MESH-мережа"}, - {"Error", "Помилка"}, - {"Clock skew", "Неточний час"}, - {"Offline", "Офлайн"}, - {"Symmetric NAT", "Симетричний NAT"}, - // Status - {"Uptime", "В мережі"}, - {"Network status", "Мережевий статус"}, - {"Network status v6", "Мережевий статус v6"}, - {"Stopping in", "Зупинка через"}, - {"Family", "Сімейство"}, - {"Tunnel creation success rate", "Успішно побудованих тунелів"}, - {"Received", "Отримано"}, - {"Sent", "Відправлено"}, - {"Transit", "Транзит"}, - {"KiB/s", "КіБ/с"}, - {"Data path", "Шлях до даних"}, - {"Hidden content. Press on text to see.", "Прихований вміст. Натисніть на текст щоб відобразити."}, - {"Router Ident", "Ідентифікатор Роутера"}, - {"Router Family", "Сімейство Роутера"}, - {"Router Caps", "Прапорці Роутера"}, - {"Version", "Версія"}, - {"Our external address", "Наша зовнішня адреса"}, - {"supported", "підтримується"}, - {"Routers", "Роутери"}, - {"Floodfills", "Флудфіли"}, - {"Client Tunnels", "Клієнтські Тунелі"}, - {"Transit Tunnels", "Транзитні Тунелі"}, - {"Services", "Сервіси"}, - // ShowLocalDestinations - {"Local Destinations", "Локальні Призначення"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Шифровані B33 адреси"}, - {"Address registration line", "Рядок реєстрації адреси"}, - {"Domain", "Домен"}, - {"Generate", "Згенерувати"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Примітка: отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня. Для реєстрації піддоменів використовуйте i2pd-tools."}, - {"Address", "Адреса"}, - {"Type", "Тип"}, - {"EncType", "ТипШифр"}, - {"Inbound tunnels", "Вхідні тунелі"}, - {"Outbound tunnels", "Вихідні тунелі"}, - {"ms", "мс"}, // milliseconds - {"Tags", "Теги"}, - {"Incoming", "Вхідні"}, - {"Outgoing", "Вихідні"}, - {"Destination", "Призначення"}, - {"Amount", "Кількість"}, - {"Incoming Tags", "Вхідні Теги"}, - {"Tags sessions", "Сесії тегів"}, - {"Status", "Статус"}, - // ShowLocalDestination - {"Local Destination", "Локальні Призначення"}, - {"Streams", "Потоки"}, - {"Close stream", "Закрити потік"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP сесія не знайдена"}, - {"I2CP is not enabled", "I2CP не увікнуто"}, - // ShowLeasesSets - {"Invalid", "Некоректний"}, - {"Store type", "Тип сховища"}, - {"Expires", "Завершується"}, - {"Non Expired Leases", "Не завершені Lease-и"}, - {"Gateway", "Шлюз"}, - {"TunnelID", "ID тунеля"}, - {"EndDate", "Закінчується"}, - {"not floodfill", "не флудфіл"}, - // ShowTunnels - {"Queue size", "Розмір черги"}, - // ShowCommands - {"Run peer test", "Запустити тестування"}, - {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, - {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, - {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, - {"Start graceful shutdown", "Запустити плавну зупинку"}, - {"Force shutdown", "Примусова зупинка"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, - {"Logging level", "Рівень логування"}, - {"Transit tunnels limit", "Обмеження транзитних тунелів"}, - {"Change", "Змінити"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM вимкнуто"}, - {"SAM session not found", "SAM сесія не знайдена"}, - {"no sessions currently running", "немає запущених сесій"}, - {"SAM Session", "SAM сесія"}, - // ShowI2PTunnels - {"Server Tunnels", "Серверні Тунелі"}, - {"Client Forwards", "Клієнтські Переспрямування"}, - {"Server Forwards", "Серверні Переспрямування"}, - // HandlePage - {"Unknown page", "Невідома сторінка"}, - // HandleCommand, ShowError - {"Invalid token", "Невірний токен"}, - {"SUCCESS", "УСПІШНО"}, - {"ERROR", "ПОМИЛКА"}, - {"Unknown command", "Невідома команда"}, - {"Command accepted", "Команда прийнята"}, - {"Back to commands list", "Повернутися до списку команд"}, - {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Потік зачинений"}, - {"Stream not found or already was closed", "Потік не знайдений або вже зачинений"}, - {"Destination not found", "Точка призначення не знайдена"}, - {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, - {"Return to destination page", "Повернутися на сторінку точки призначення"}, - {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, - {"Description", "Опис"}, - {"A bit information about service on domain", "Трохи інформації про сервіс на домені"}, - {"Submit", "Надіслати"}, - {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, - {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, - {"Such destination is not found", "Така точка призначення не знайдена"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, {"", ""}, }; static std::map> plurals { - // ShowUptime - {"days", {"день", "дня", "днів"}}, - {"hours", {"годину", "години", "годин"}}, + {"days", {"день", "дня", "днів"}}, + {"hours", {"годину", "години", "годин"}}, {"minutes", {"хвилину", "хвилини", "хвилин"}}, {"seconds", {"секунду", "секунди", "секунд"}}, {"", {"", "", ""}}, From f7f50d049b98366726a6fd2518c109930f23e997 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 22 Jun 2021 13:11:02 -0400 Subject: [PATCH 033/186] reduce short tunnel build record length --- libi2pd/I2NPProtocol.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index ee143734..cc7c94af 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -55,7 +55,7 @@ namespace i2p // TunnelBuild const size_t TUNNEL_BUILD_RECORD_SIZE = 528; - const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 236; + const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218; //BuildRequestRecordClearText const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; @@ -113,7 +113,7 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1; const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; - const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172; + const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; enum I2NPMessageType { From 3c076654794c619eed228adcac075e9c1dea732f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 22 Jun 2021 15:35:44 -0400 Subject: [PATCH 034/186] use unordered_map for incomplete messages --- libi2pd/TunnelEndpoint.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 43b836f1..6466df3a 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,6 +11,7 @@ #include #include +#include #include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -54,7 +55,7 @@ namespace tunnel private: - std::map m_IncompleteMessages; + std::unordered_map m_IncompleteMessages; std::map, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; From f5db34b98b4a081bdfac694c82eb5ebe4f3c171b Mon Sep 17 00:00:00 2001 From: idk Date: Wed, 23 Jun 2021 11:18:53 -0400 Subject: [PATCH 035/186] C_InitI2P is compatible with more things if it passes argv by reference, it would appear. So to pass arguments to InitI2P you need to turn them back into char* argv[] by tokenizing them and copying them into an array which you then pass to InitI2P from C_InitI2P. The Streaming and Destination Creation parts need to have wrappers for over Identity.h, Streaming.h to be useful so remove them. --- Makefile | 47 ++++--------------- libi2pd/api.go | 5 +-- libi2pd/api.swigcxx | 8 ---- libi2pd/capi.cpp | 107 ++++++++++++++++++++++++++------------------ libi2pd/capi.h | 17 ------- 5 files changed, 73 insertions(+), 111 deletions(-) diff --git a/Makefile b/Makefile index 62a64584..72e68118 100644 --- a/Makefile +++ b/Makefile @@ -28,12 +28,6 @@ else LD_DEBUG = -s endif -ifeq ($(USE_STATIC),yes) - NEEDED_CXXFLAGS+= -static -else - -endif - ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) @@ -76,9 +70,9 @@ mk_obj_dir: @mkdir -p obj/$(LANG_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -97,31 +91,30 @@ obj/%.o: %.cpp $(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif -$(SHLIB_LANG): $(LANG_OBJS) +$(SHLIB_LANG): $(LANG_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ -$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ -$(ARLIB_LANG): $(LANG_OBJS) +$(ARLIB_LANG): $(LANG_OBJS) $(AR) -r $@ $^ - clean: $(RM) -r obj $(RM) -r docs/generated @@ -154,25 +147,3 @@ doxygen: .PHONY: mk_obj_dir .PHONY: install .PHONY: strip - -flags: - @echo $(CXXFLAGS) - @echo $(NEEDED_CXXFLAGS) - @echo $(INCFLAGS) - @echo $(LDFLAGS) - @echo $(LDLIBS) - @echo $(USE_AESNI) - @echo $(USE_STATIC) - @echo $(USE_MESHNET) - @echo $(USE_UPNP) - @echo $(DEBUG) - -##TODO: delete this before a PR -testc: api api_client - g++ -Ii18n -c _test.c -o test.o -# gcc -llibi2pd.so -c _test.c -o test.o -# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -Ilibi2pd -Ilibi2pd_client -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so -# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so -# gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd -# gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o - g++ test.o libi2pd.a libi2pdclient.a libi2pdlang.a -o test.main \ No newline at end of file diff --git a/libi2pd/api.go b/libi2pd/api.go index d7a19bc9..48a41a4f 100644 --- a/libi2pd/api.go +++ b/libi2pd/api.go @@ -1,10 +1,7 @@ package api /* -//void Go_InitI2P (int argc, char argv[], const char * appName){ - -//} -#cgo CPPFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes #cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx index fbb1b95a..3ef6bd36 100644 --- a/libi2pd/api.swigcxx +++ b/libi2pd/api.swigcxx @@ -3,14 +3,6 @@ %{ #include "capi.h" -//#include "Streaming.h" -//#include "Destination.h" -//#include "Identity.h" -//#include "Tag.h" %} %include "capi.h" -//%include "Streaming.h" -//%include "Destination.h" -//%include "Identity.h" -//%include "Tag.h" \ No newline at end of file diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index 1a2498b6..55b1b051 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -8,6 +8,64 @@ #include "api.h" #include "capi.h" +#include +#include +#include +#include + + +// Uses the example from: https://stackoverflow.com/a/9210560 +// See also https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c/9210560# +// Does not handle consecutive delimiters, this is only for passing +// lists of arguments by value to InitI2P from C_InitI2P +char** str_split(char* a_str, const char a_delim) +{ + char** result = 0; + size_t count = 0; + char* tmp = a_str; + char* last_comma = 0; + char delim[2]; + delim[0] = a_delim; + delim[1] = 0; + + /* Count how many elements will be extracted. */ + while (*tmp) + { + if (a_delim == *tmp) + { + count++; + last_comma = tmp; + } + tmp++; + } + + /* Add space for trailing token. */ + count += last_comma < (a_str + strlen(a_str) - 1); + + /* Add space for terminating null string so caller + knows where the list of returned strings ends. */ + count++; + + result = (char**) malloc(sizeof(char*) * count); + + if (result) + { + size_t idx = 0; + char* token = strtok(a_str, delim); + + while (token) + { + assert(idx < count); + *(result + idx++) = strdup(token); + token = strtok(0, delim); + } + assert(idx == count - 1); + *(result + idx) = 0; + } + + return result; +} + #ifdef __cplusplus extern "C" { @@ -15,7 +73,11 @@ extern "C" { void C_InitI2P (int argc, char argv[], const char * appName) { - return i2p::api::InitI2P(argc, &argv, appName); + const char* delim = " "; + char* vargs = strdup(argv); + char** args = str_split(vargs, *delim); + std::cout << argv; + return i2p::api::InitI2P(argc, args, appName); } void C_TerminateI2P () @@ -40,49 +102,6 @@ void C_RunPeerTest () return i2p::api::RunPeerTest(); } -i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, - const std::map * params) -{ - return i2p::api::CreateLocalDestination(keys, isPublic, params).get(); -} - -i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, - const std::map * params) -{ - return i2p::api::CreateLocalDestination(isPublic, sigType, params).get(); -} - -void C_DestroyLocalDestination (i2p::client::ClientDestination *dest) -{ - std::shared_ptr cppDest(dest); - return i2p::api::DestroyLocalDestination(cppDest); -} - -void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) -{ - std::shared_ptr cppDest(dest); - return i2p::api::RequestLeaseSet(cppDest, remote); -} - -i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) -{ - std::shared_ptr cppDest(dest); - return i2p::api::CreateStream(cppDest, remote).get(); -} - -void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) -{ - std::shared_ptr cppDest(dest); - return i2p::api::AcceptStream(cppDest, acceptor); -} - -void C_DestroyStream (i2p::stream::Stream *stream) -{ - std::shared_ptr cppStream(stream); - return i2p::api::DestroyStream(cppStream); -} - - #ifdef __cplusplus } #endif diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 8395cfca..3e33a0ee 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,10 +9,6 @@ #ifndef CAPI_H__ #define CAPI_H__ -#include "Identity.h" -#include "Destination.h" -#include "Streaming.h" - #ifdef __cplusplus extern "C" { #endif @@ -26,19 +22,6 @@ void C_StartI2P (); //std::ostream *logStream = nullptr); void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP -// destinations -i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, - const std::map * params = nullptr); -i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, - const std::map * params = nullptr); // transient destinations usually not published -void C_DestroyLocalDestination (i2p::client::ClientDestination *dest); - -// streams -void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); -i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); -void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); -void C_DestroyStream (i2p::stream::Stream *stream); - #ifdef __cplusplus } #endif From f9d9aa0306eae1c19849e7ea40d0cfb2a15eb76d Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 24 Jun 2021 09:35:42 -0400 Subject: [PATCH 036/186] move wrapper code to own directory --- Makefile | 14 ++++++++++++++ filelist.mk | 2 ++ {libi2pd => libi2pd_wrapper}/api.go | 0 {libi2pd => libi2pd_wrapper}/api.swigcxx | 0 {libi2pd => libi2pd_wrapper}/capi.cpp | 0 {libi2pd => libi2pd_wrapper}/capi.h | 0 6 files changed, 16 insertions(+) rename {libi2pd => libi2pd_wrapper}/api.go (100%) rename {libi2pd => libi2pd_wrapper}/api.swigcxx (100%) rename {libi2pd => libi2pd_wrapper}/capi.cpp (100%) rename {libi2pd => libi2pd_wrapper}/capi.h (100%) diff --git a/Makefile b/Makefile index 72e68118..59faa94b 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,13 @@ SHLIB_LANG := libi2pdlang.so ARLIB_LANG := libi2pdlang.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a +SHLIB_WRAP := libi2pdwrapper.so +ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd LIB_SRC_DIR := libi2pd LIB_CLIENT_SRC_DIR := libi2pd_client +WRAP_SRC_DIR := libi2pd_wrapper LANG_SRC_DIR := i18n DAEMON_SRC_DIR := daemon @@ -56,6 +59,7 @@ NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SR LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) @@ -68,11 +72,13 @@ mk_obj_dir: @mkdir -p obj/$(LIB_SRC_DIR) @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) @mkdir -p obj/$(LANG_SRC_DIR) + @mkdir -p obj/$(WRAP_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) api: mk_obj_dir $(SHLIB) $(ARLIB) client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -101,6 +107,11 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif +$(SHLIB_WRAP): $(WRAP_LIB_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + $(SHLIB_LANG): $(LANG_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) @@ -112,6 +123,9 @@ $(ARLIB): $(LIB_OBJS) $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_WRAP): $(LIB_OBJS) + $(AR) -r $@ $^ + $(ARLIB_LANG): $(LANG_OBJS) $(AR) -r $@ $^ diff --git a/filelist.mk b/filelist.mk index e2a5d40e..d8f503e6 100644 --- a/filelist.mk +++ b/filelist.mk @@ -21,4 +21,6 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp) +WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp) + DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp) diff --git a/libi2pd/api.go b/libi2pd_wrapper/api.go similarity index 100% rename from libi2pd/api.go rename to libi2pd_wrapper/api.go diff --git a/libi2pd/api.swigcxx b/libi2pd_wrapper/api.swigcxx similarity index 100% rename from libi2pd/api.swigcxx rename to libi2pd_wrapper/api.swigcxx diff --git a/libi2pd/capi.cpp b/libi2pd_wrapper/capi.cpp similarity index 100% rename from libi2pd/capi.cpp rename to libi2pd_wrapper/capi.cpp diff --git a/libi2pd/capi.h b/libi2pd_wrapper/capi.h similarity index 100% rename from libi2pd/capi.h rename to libi2pd_wrapper/capi.h From d0c5732e16d28f0be86c4026ef23e0b70518f8ea Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 07:18:42 -0400 Subject: [PATCH 037/186] eliminate extra lookups for sequential fragments --- libi2pd/TunnelEndpoint.cpp | 143 +++++++++++++++++++++++++++---------- libi2pd/TunnelEndpoint.h | 12 ++-- 2 files changed, 113 insertions(+), 42 deletions(-) diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index eb70bdca..a07230cb 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -52,11 +52,13 @@ namespace tunnel bool isFollowOnFragment = flag & 0x80, isLastFragment = true; uint32_t msgID = 0; int fragmentNum = 0; - TunnelMessageBlockEx m; + TunnelMessageBlockEx& m = m_CurrentMessage; if (!isFollowOnFragment) { // first fragment - + if (m_CurrentMsgID) + AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete + m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); switch (m.deliveryType) { @@ -81,6 +83,7 @@ namespace tunnel // Message ID msgID = bufbe32toh (fragment); fragment += 4; + m_CurrentMsgID = msgID; isLastFragment = false; } } @@ -96,11 +99,20 @@ namespace tunnel uint16_t size = bufbe16toh (fragment); fragment += 2; + if (isFollowOnFragment && m_CurrentMsgID && m_CurrentMsgID == msgID && + m_CurrentMessage.nextFragmentNum == fragmentNum) + { + HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); + fragment += size; + continue; + } + msg->offset = fragment - msg->buf; msg->len = msg->offset + size; if (msg->len > msg->maxLen) { LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; return; } if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) @@ -114,31 +126,31 @@ namespace tunnel else m.data = msg; - if (!isFollowOnFragment && isLastFragment) - HandleNextMessage (m); + if (!isFollowOnFragment) + { + if (isLastFragment) + { + HandleNextMessage (m); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + else if (msgID) + { + m_CurrentMessage.nextFragmentNum = 1; + m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); + HandleOutOfSequenceFragments (msgID, m_CurrentMessage); + } + else + { + LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented"); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + } else { - if (msgID) // msgID is presented, assume message is fragmented - { - if (!isFollowOnFragment) // create new incomlete message - { - m.nextFragmentNum = 1; - m.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); - auto ret = m_IncompleteMessages.insert (std::pair(msgID, m)); - if (ret.second) - HandleOutOfSequenceFragments (msgID, ret.first->second); - else - LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists"); - } - else - { - m.nextFragmentNum = fragmentNum; - HandleFollowOnFragment (msgID, isLastFragment, m); - } - } - else - LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented"); - } + m.nextFragmentNum = fragmentNum; + HandleFollowOnFragment (msgID, isLastFragment, m); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } fragment += size; } @@ -157,17 +169,8 @@ namespace tunnel auto& msg = it->second; if (m.nextFragmentNum == msg.nextFragmentNum) { - if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long + if (ConcatFollowOnFragment (msg, fragment, size)) { - if (msg.data->len + size > msg.data->maxLen) - { - // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); - *newMsg = *(msg.data); - msg.data = newMsg; - } - if (msg.data->Concat (fragment, size) < size) // concatenate fragment - LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen); if (isLastFragment) { // message complete @@ -199,9 +202,67 @@ namespace tunnel } } + bool TunnelEndpoint::ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const + { + if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long + { + if (msg.data->len + size > msg.data->maxLen) + { + // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); + auto newMsg = NewI2NPMessage (); + *newMsg = *(msg.data); + msg.data = newMsg; + } + if (msg.data->Concat (fragment, size) < size) // concatenate fragment + { + LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen); + return false; + } + } + else + return false; + return true; + } + + void TunnelEndpoint::HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment) + { + if (ConcatFollowOnFragment (m_CurrentMessage, fragment, size)) + { + if (isLastFragment) + { + // message complete + HandleNextMessage (m_CurrentMessage); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + else + { + m_CurrentMessage.nextFragmentNum++; + HandleOutOfSequenceFragments (m_CurrentMsgID, m_CurrentMessage); + } + } + else + { + LogPrint (eLogError, "TunnelMessage: Fragment ", m_CurrentMessage.nextFragmentNum, " of message ", m_CurrentMsgID, " exceeds max I2NP message size, message dropped"); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + } + + void TunnelEndpoint::AddIncompleteCurrentMessage () + { + if (m_CurrentMsgID) + { + auto ret = m_IncompleteMessages.emplace (m_CurrentMsgID, m_CurrentMessage); + if (!ret.second) + LogPrint (eLogError, "TunnelMessage: Incomplete message ", m_CurrentMsgID, " already exists"); + m_CurrentMessage.data = nullptr; + m_CurrentMsgID = 0; + } + } + void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data) { - if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) + if (!m_OutOfSequenceFragments.insert ({(uint64_t)msgID << 32 | fragmentNum, + {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID); } @@ -212,7 +273,13 @@ namespace tunnel if (!msg.nextFragmentNum) // message complete { HandleNextMessage (msg); - m_IncompleteMessages.erase (msgID); + if (&msg == &m_CurrentMessage) + { + m_CurrentMsgID = 0; + m_CurrentMessage.data = nullptr; + } + else + m_IncompleteMessages.erase (msgID); break; } } @@ -220,7 +287,7 @@ namespace tunnel bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg) { - auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum}); + auto it = m_OutOfSequenceFragments.find ((uint64_t)msgID << 32 | msg.nextFragmentNum); if (it != m_OutOfSequenceFragments.end ()) { LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found"); diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 6466df3a..70514e35 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -10,7 +10,6 @@ #define TUNNEL_ENDPOINT_H__ #include -#include #include #include #include "I2NPProtocol.h" @@ -37,7 +36,7 @@ namespace tunnel public: - TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0) {}; + TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0), m_CurrentMsgID (0) {}; ~TunnelEndpoint (); size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; void Cleanup (); @@ -47,18 +46,23 @@ namespace tunnel private: void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m); + bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success + void HandleCurrenMessageFollowOnFragment (const uint8_t * frgament, size_t size, bool isLastFragment); void HandleNextMessage (const TunnelMessageBlock& msg); void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data); bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg); - + void AddIncompleteCurrentMessage (); + private: std::unordered_map m_IncompleteMessages; - std::map, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment + std::unordered_map m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; + TunnelMessageBlockEx m_CurrentMessage; + uint32_t m_CurrentMsgID; }; } } From da20cae25ca13f66603d9095fff208fc066829a8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 18:59:48 +0300 Subject: [PATCH 038/186] [webconsole] urldecode domain for registration string generator Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7eb296c4..0b9e8f0f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1281,7 +1281,7 @@ namespace http { else if (cmd == HTTP_COMMAND_GET_REG_STRING) { std::string b32 = params["b32"]; - std::string name = params["name"]; + std::string name = i2p::http::UrlDecode(params["name"]); i2p::data::IdentHash ident; ident.FromBase32 (b32); From 377a50fa1301063e2c3398a87ec0e84790e8659e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 23:45:55 +0300 Subject: [PATCH 039/186] [make] build translations as library Signed-off-by: R4SAS --- Makefile | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 40e72918..4117234e 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ SHLIB := libi2pd.so ARLIB := libi2pd.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a +SHLIB_LANG := libi2pdlang.so +ARLIB_LANG := libi2pdlang.a I2PD := i2pd LIB_SRC_DIR := libi2pd @@ -71,6 +73,7 @@ mk_obj_dir: api: mk_obj_dir $(SHLIB) $(ARLIB) client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -85,7 +88,7 @@ obj/%.o: %.cpp # '-' is 'ignore if missing' on first run -include $(DEPS) -$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) +$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) @@ -98,18 +101,26 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif +$(SHLIB_LANG): $(LANG_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + $(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_LANG): $(LANG_OBJS) + $(AR) -r $@ $^ + clean: $(RM) -r obj $(RM) -r docs/generated - $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) + $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) -strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB) +strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) strip $^ LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl) @@ -133,6 +144,7 @@ doxygen: .PHONY: api .PHONY: api_client .PHONY: client +.PHONY: lang .PHONY: mk_obj_dir .PHONY: install .PHONY: strip From 9fb8e8a582e8f23e39da0c635ee8c0efe4fcf0c5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 23:59:34 +0300 Subject: [PATCH 040/186] [cmake] build translations as library Signed-off-by: R4SAS --- .gitignore | 2 ++ build/CMakeLists.txt | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2506fd93..1fc6cefe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,10 @@ netDb /i2pd /libi2pd.a /libi2pdclient.a +/libi2pdlang.a /libi2pd.so /libi2pdclient.so +/libi2pdlang.so *.exe diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d1b51f23..d1502deb 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -69,6 +69,16 @@ if(WITH_LIBRARY) endif() FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp) +add_library(libi2pdlang ${LANG_SRC}) +set_target_properties(libi2pdlang PROPERTIES PREFIX "") + +if(WITH_LIBRARY) + install(TARGETS libi2pdlang + EXPORT libi2pdlang + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + COMPONENT Libraries) +endif() set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" @@ -198,10 +208,11 @@ if(WITH_PCH) ) target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) + target_compile_options(libi2pdlang PRIVATE -include libi2pd/stdafx.h) target_link_libraries(libi2pd stdafx) endif() -target_link_libraries(libi2pdclient libi2pd) +target_link_libraries(libi2pdclient libi2pd libi2pdlang) find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED) if(NOT DEFINED Boost_INCLUDE_DIRS) @@ -265,7 +276,7 @@ message(STATUS "---------------------------------------") include(GNUInstallDirs) if(WITH_BINARY) - add_executable("${PROJECT_NAME}" ${LANG_SRC} ${DAEMON_SRC}) + add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) if(WITH_STATIC) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") @@ -295,7 +306,7 @@ if(WITH_BINARY) endif() target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY}) - target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") From b9476791f4b6b2a46f5f2fc59d491c5d34b85db1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 17:40:25 -0400 Subject: [PATCH 041/186] eliminated extra I2NP messages for fragments --- libi2pd/TunnelEndpoint.cpp | 115 +++++++++++++++++++------------------ libi2pd/TunnelEndpoint.h | 10 ++-- 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index a07230cb..70004ede 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -52,26 +52,25 @@ namespace tunnel bool isFollowOnFragment = flag & 0x80, isLastFragment = true; uint32_t msgID = 0; int fragmentNum = 0; - TunnelMessageBlockEx& m = m_CurrentMessage; if (!isFollowOnFragment) { // first fragment if (m_CurrentMsgID) AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete - m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); - switch (m.deliveryType) + m_CurrentMessage.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); + switch (m_CurrentMessage.deliveryType) { case eDeliveryTypeLocal: // 0 break; case eDeliveryTypeTunnel: // 1 - m.tunnelID = bufbe32toh (fragment); + m_CurrentMessage.tunnelID = bufbe32toh (fragment); fragment += 4; // tunnelID - m.hash = i2p::data::IdentHash (fragment); + m_CurrentMessage.hash = i2p::data::IdentHash (fragment); fragment += 32; // hash break; case eDeliveryTypeRouter: // 2 - m.hash = i2p::data::IdentHash (fragment); + m_CurrentMessage.hash = i2p::data::IdentHash (fragment); fragment += 32; // to hash break; default: ; @@ -99,42 +98,51 @@ namespace tunnel uint16_t size = bufbe16toh (fragment); fragment += 2; - if (isFollowOnFragment && m_CurrentMsgID && m_CurrentMsgID == msgID && - m_CurrentMessage.nextFragmentNum == fragmentNum) - { - HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); - fragment += size; - continue; + // handle fragment + if (isFollowOnFragment) + { + // existing message + if (m_CurrentMsgID && m_CurrentMsgID == msgID && m_CurrentMessage.nextFragmentNum == fragmentNum) + HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); // previous + else + { + HandleFollowOnFragment (msgID, isLastFragment, fragmentNum, fragment, size); // another + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } } - - msg->offset = fragment - msg->buf; - msg->len = msg->offset + size; - if (msg->len > msg->maxLen) - { - LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); - m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; - return; - } - if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) - { - // this is not last message. we have to copy it - m.data = NewI2NPTunnelMessage (); - m.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - m.data->len += TUNNEL_GATEWAY_HEADER_SIZE; - *(m.data) = *msg; - } else - m.data = msg; - - if (!isFollowOnFragment) - { + { + // new message + msg->offset = fragment - msg->buf; + msg->len = msg->offset + size; + // check message size + if (msg->len > msg->maxLen) + { + LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + return; + } + // create new or assign I2NP message + if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) + { + // this is not last message. we have to copy it + m_CurrentMessage.data = NewI2NPTunnelMessage (); + m_CurrentMessage.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + m_CurrentMessage.data->len += TUNNEL_GATEWAY_HEADER_SIZE; + *(m_CurrentMessage.data) = *msg; + } + else + m_CurrentMessage.data = msg; + if (isLastFragment) { - HandleNextMessage (m); + // single message + HandleNextMessage (m_CurrentMessage); m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; } else if (msgID) { + // first fragment of a new message m_CurrentMessage.nextFragmentNum = 1; m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); HandleOutOfSequenceFragments (msgID, m_CurrentMessage); @@ -145,13 +153,7 @@ namespace tunnel m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; } } - else - { - m.nextFragmentNum = fragmentNum; - HandleFollowOnFragment (msgID, isLastFragment, m); - m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; - } - + fragment += size; } } @@ -159,15 +161,14 @@ namespace tunnel LogPrint (eLogError, "TunnelMessage: zero not found"); } - void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m) + void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, + uint8_t fragmentNum, const uint8_t * fragment, size_t size) { - auto fragment = m.data->GetBuffer (); - auto size = m.data->GetLength (); auto it = m_IncompleteMessages.find (msgID); if (it != m_IncompleteMessages.end()) { auto& msg = it->second; - if (m.nextFragmentNum == msg.nextFragmentNum) + if (fragmentNum == msg.nextFragmentNum) { if (ConcatFollowOnFragment (msg, fragment, size)) { @@ -185,20 +186,20 @@ namespace tunnel } else { - LogPrint (eLogError, "TunnelMessage: Fragment ", m.nextFragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped"); + LogPrint (eLogError, "TunnelMessage: Fragment ", fragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped"); m_IncompleteMessages.erase (it); } } else { - LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)m.nextFragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved"); - AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data); + LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)fragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved"); + AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } else { LogPrint (eLogWarning, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); - AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data); + AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } @@ -259,10 +260,12 @@ namespace tunnel } } - void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data) + void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, + bool isLastFragment, const uint8_t * fragment, size_t size) { - if (!m_OutOfSequenceFragments.insert ({(uint64_t)msgID << 32 | fragmentNum, - {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) + std::unique_ptr f(new Fragment (isLastFragment, i2p::util::GetMillisecondsSinceEpoch (), size)); + memcpy (f->data.data (), fragment, size); + if (!m_OutOfSequenceFragments.emplace ((uint64_t)msgID << 32 | fragmentNum, std::move (f)).second) LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID); } @@ -291,7 +294,7 @@ namespace tunnel if (it != m_OutOfSequenceFragments.end ()) { LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found"); - size_t size = it->second.data->GetLength (); + size_t size = it->second->data.size (); if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); @@ -299,9 +302,9 @@ namespace tunnel *newMsg = *(msg.data); msg.data = newMsg; } - if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment + if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); - if (it->second.isLastFragment) + if (it->second->isLastFragment) // message complete msg.nextFragmentNum = 0; else @@ -354,7 +357,7 @@ namespace tunnel // out-of-sequence fragments for (auto it = m_OutOfSequenceFragments.begin (); it != m_OutOfSequenceFragments.end ();) { - if (ts > it->second.receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT) + if (ts > it->second->receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT) it = m_OutOfSequenceFragments.erase (it); else ++it; diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 70514e35..f9878165 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -11,6 +11,7 @@ #include #include +#include #include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -29,9 +30,10 @@ namespace tunnel struct Fragment { + Fragment (bool last, uint64_t t, size_t size): isLastFragment (last), receiveTime (t), data (size) {}; bool isLastFragment; - std::shared_ptr data; uint64_t receiveTime; // milliseconds since epoch + std::vector data; }; public: @@ -45,12 +47,12 @@ namespace tunnel private: - void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m); + void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, uint8_t fragmentNum, const uint8_t * fragment, size_t size); bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success void HandleCurrenMessageFollowOnFragment (const uint8_t * frgament, size_t size, bool isLastFragment); void HandleNextMessage (const TunnelMessageBlock& msg); - void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data); + void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, const uint8_t * fragment, size_t size); bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg); void AddIncompleteCurrentMessage (); @@ -58,7 +60,7 @@ namespace tunnel private: std::unordered_map m_IncompleteMessages; - std::unordered_map m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From 66422d6d837ce25f4cf7eb2b90fa6f9e5f9a9d22 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 21:44:51 -0400 Subject: [PATCH 042/186] double size tunnel message --- libi2pd/I2NPProtocol.cpp | 3 ++- libi2pd/TunnelEndpoint.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 7c4d84c3..f570a2a1 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,7 +38,8 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage () { - auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + // should fit two tunnel message, enough for one garlic encrypted streaming packet + auto msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); return std::shared_ptr(msg); } diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 70004ede..109f3120 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -198,7 +198,7 @@ namespace tunnel } else { - LogPrint (eLogWarning, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); + LogPrint (eLogDebug, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } @@ -283,6 +283,7 @@ namespace tunnel } else m_IncompleteMessages.erase (msgID); + LogPrint (eLogDebug, "TunnelMessage: All fragments of message ", msgID, " found"); break; } } From 6d2c9e367bb35e0d3b4d19db734a243744a92fc9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 27 Jun 2021 12:24:41 +0300 Subject: [PATCH 043/186] remove unused CI and docker files Signed-off-by: R4SAS --- .travis.yml | 54 ---------------------- appveyor.yml | 57 ------------------------ build/docker/README.md | 34 -------------- build/docker/old-ubuntu-based/Dockerfile | 11 ----- build/fig.yml | 2 - contrib/docker/Dockerfile | 2 +- 6 files changed, 1 insertion(+), 159 deletions(-) delete mode 100644 .travis.yml delete mode 100644 appveyor.yml delete mode 100644 build/docker/README.md delete mode 100644 build/docker/old-ubuntu-based/Dockerfile delete mode 100644 build/fig.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index af47f458..00000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -language: cpp -cache: - apt: true -os: -- linux -#- osx -dist: xenial -sudo: required -compiler: -- g++ -- clang++ -env: - global: - - MAKEFLAGS="-j 2" - matrix: - - BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes - - BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no - - BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes - - BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no -matrix: - exclude: - - os: osx - env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes - - os: osx - env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no - - os: linux - compiler: clang++ - env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes - - os: linux - compiler: clang++ - env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no -addons: - apt: - packages: - - build-essential - - cmake - - g++ - - clang - - libboost-chrono-dev - - libboost-date-time-dev - - libboost-filesystem-dev - - libboost-program-options-dev - - libboost-system-dev - - libboost-thread-dev - - libminiupnpc-dev - - libssl-dev -before_install: -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi -script: -- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi -- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 89d85494..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,57 +0,0 @@ -version: 2.38.0.{build} -pull_requests: - do_not_increment_build_number: true -branches: - only: - - openssl -skip_tags: true -os: Visual Studio 2015 -shallow_clone: true -clone_depth: 1 - -# avoid building 32-bit if 64-bit failed already -matrix: - fast_finish: true - -environment: - APPVEYOR_SAVE_CACHE_ON_ERROR: true - MSYS2_PATH_TYPE: inherit - CHERE_INVOKING: enabled_from_arguments - matrix: - - MSYSTEM: MINGW64 - - MSYSTEM: MINGW32 - -cache: - - c:\msys64\var\cache\pacman\pkg\ - -install: -# install new signing keyring -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# remove packages which can break build -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" -# update runtime -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" -# Kill bash before next try -- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 -# update packages and install required -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc" - -build_script: -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3" -# prepare archive for uploading -- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d" -- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt -- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST% - -after_build: -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc" - -test: off - -deploy: off - -artifacts: -- path: i2pd-*.zip diff --git a/build/docker/README.md b/build/docker/README.md deleted file mode 100644 index 877a9ce5..00000000 --- a/build/docker/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Howto build & run -================== - -**Build** - -Assuming you're in the root directory of the anoncoin source code. - -$ `cd build/docker` -$ `docker -t meeh/i2pd:latest .` - -**Run** - -To run either the local build, or if not found - fetched prebuild from hub.docker.io, run the following command. - -$ `docker run --name anonnode -v /path/to/i2pd/datadir/on/host:/var/lib/i2pd -p 7070:7070 -p 4444:4444 -p 4447:4447 -p 7656:7656 -p 2827:2827 -p 7654:7654 -p 7650:7650 -d meeh/i2pd` - -All the ports ( -p HOSTPORT:DOCKERPORT ) is optional. However the command above enable all features (Webconsole, HTTP Proxy, BOB, SAM, i2cp, etc) - -The volume ( -v HOSTDIR:DOCKERDIR ) is also optional, but if you don't use it, your config, routerid and private keys will die along with the container. - -**Options** - -Options are set via docker environment variables. This can be set at run with -e parameters. - -* **ENABLE_IPV6** - Enable IPv6 support. Any value can be used - it triggers as long as it's not empty. -* **LOGLEVEL** - Set the loglevel. -* **ENABLE_AUTH** - Enable auth for the webconsole. Username and password needs to be set manually in i2pd.conf cause security reasons. - -**Logging** - -Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :) - - - diff --git a/build/docker/old-ubuntu-based/Dockerfile b/build/docker/old-ubuntu-based/Dockerfile deleted file mode 100644 index 3faddf2e..00000000 --- a/build/docker/old-ubuntu-based/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM ubuntu - -RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \ - libboost-program-options-dev libboost-date-time-dev \ - libssl-dev git build-essential - -RUN git clone https://github.com/PurpleI2P/i2pd.git -WORKDIR /i2pd -RUN make - -CMD ./i2pd diff --git a/build/fig.yml b/build/fig.yml deleted file mode 100644 index 372ef350..00000000 --- a/build/fig.yml +++ /dev/null @@ -1,2 +0,0 @@ -i2pd: - build: . diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 6470e148..71af141e 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:latest LABEL authors "Mikal Villa , Darknet Villain " # Expose git branch, tag and URL variables as arguments From 12d6f03dc9d1adef53abeba13b0499d52242220d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 27 Jun 2021 17:14:45 +0300 Subject: [PATCH 044/186] [i18n] add language changing at runtime in webconsole Signed-off-by: R4SAS --- contrib/i18n/English.po | 296 +++++++++++++++++++------------------- daemon/HTTPServer.cpp | 75 ++++++---- i18n/Afrikaans.cpp | 7 +- i18n/English.cpp | 7 +- i18n/I18N.h | 13 +- i18n/I18N_langs.h | 28 +++- i18n/Russian.cpp | 310 ++++++++++++++++++---------------------- i18n/Turkmen.cpp | 7 +- i18n/Ukrainian.cpp | 7 +- 9 files changed, 396 insertions(+), 354 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 1de2ddaa..011d0fee 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -26,548 +26,554 @@ msgstr "" msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:141 +#: daemon/HTTPServer.cpp:147 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:145 + +#: daemon/HTTPServer.cpp:151 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:149 + +#: daemon/HTTPServer.cpp:155 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:152 +#: daemon/HTTPServer.cpp:158 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188 +#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 msgid "KiB" msgstr "" -#: daemon/HTTPServer.cpp:162 +#: daemon/HTTPServer.cpp:168 msgid "MiB" msgstr "" -#: daemon/HTTPServer.cpp:164 +#: daemon/HTTPServer.cpp:170 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:181 +#: daemon/HTTPServer.cpp:187 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:182 +#: daemon/HTTPServer.cpp:188 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:183 +#: daemon/HTTPServer.cpp:189 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:184 +#: daemon/HTTPServer.cpp:190 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:185 +#: daemon/HTTPServer.cpp:191 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:187 +#: daemon/HTTPServer.cpp:193 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:223 +#: daemon/HTTPServer.cpp:229 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:226 +#: daemon/HTTPServer.cpp:232 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683 +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:689 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:228 +#: daemon/HTTPServer.cpp:234 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 +#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 +#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 +#: daemon/HTTPServer.cpp:605 daemon/HTTPServer.cpp:648 +#: daemon/HTTPServer.cpp:652 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:658 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727 -#: daemon/HTTPServer.cpp:743 +#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:746 +#: daemon/HTTPServer.cpp:762 msgid "Transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792 +#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:811 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:235 +#: daemon/HTTPServer.cpp:241 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854 -#: daemon/HTTPServer.cpp:864 +#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:873 +#: daemon/HTTPServer.cpp:883 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 +#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1273 +#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1279 +#: daemon/HTTPServer.cpp:1293 daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1341 daemon/HTTPServer.cpp:1344 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:260 +#: daemon/HTTPServer.cpp:266 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:261 +#: daemon/HTTPServer.cpp:267 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:262 +#: daemon/HTTPServer.cpp:268 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284 -#: daemon/HTTPServer.cpp:370 +#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290 +#: daemon/HTTPServer.cpp:376 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394 -#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922 -#: daemon/HTTPServer.cpp:931 +#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 +#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:941 +#: daemon/HTTPServer.cpp:950 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:265 +#: daemon/HTTPServer.cpp:271 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:268 +#: daemon/HTTPServer.cpp:274 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:272 +#: daemon/HTTPServer.cpp:278 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:275 +#: daemon/HTTPServer.cpp:281 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:278 +#: daemon/HTTPServer.cpp:284 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:290 +#: daemon/HTTPServer.cpp:296 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:293 +#: daemon/HTTPServer.cpp:299 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:298 +#: daemon/HTTPServer.cpp:304 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311 +#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:318 +#: daemon/HTTPServer.cpp:324 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:319 +#: daemon/HTTPServer.cpp:325 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:320 +#: daemon/HTTPServer.cpp:326 msgid "Received" msgstr "" -#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325 -#: daemon/HTTPServer.cpp:328 +#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 +#: daemon/HTTPServer.cpp:334 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:323 +#: daemon/HTTPServer.cpp:329 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:326 +#: daemon/HTTPServer.cpp:332 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:329 +#: daemon/HTTPServer.cpp:335 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:338 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:335 +#: daemon/HTTPServer.cpp:341 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:337 +#: daemon/HTTPServer.cpp:343 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:338 +#: daemon/HTTPServer.cpp:344 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:339 +#: daemon/HTTPServer.cpp:345 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:340 +#: daemon/HTTPServer.cpp:346 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:348 +#: daemon/HTTPServer.cpp:354 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:380 +#: daemon/HTTPServer.cpp:386 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:381 +#: daemon/HTTPServer.cpp:387 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908 +#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:927 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:389 +#: daemon/HTTPServer.cpp:395 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:393 +#: daemon/HTTPServer.cpp:399 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419 +#: daemon/HTTPServer.cpp:413 daemon/HTTPServer.cpp:425 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:442 +#: daemon/HTTPServer.cpp:448 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:451 +#: daemon/HTTPServer.cpp:457 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:456 +#: daemon/HTTPServer.cpp:462 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:457 +#: daemon/HTTPServer.cpp:463 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:458 +#: daemon/HTTPServer.cpp:464 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657 +#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:663 msgid "Inbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489 -#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672 -#: Means milliseconds +#. Milliseconds +#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 +#: daemon/HTTPServer.cpp:668 daemon/HTTPServer.cpp:678 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667 +#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:673 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:502 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:502 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506 +#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520 +#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:504 +#: daemon/HTTPServer.cpp:510 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:511 +#: daemon/HTTPServer.cpp:517 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522 +#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:520 +#: daemon/HTTPServer.cpp:526 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584 +#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:590 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887 +#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:906 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:560 +#: daemon/HTTPServer.cpp:566 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:589 +#: daemon/HTTPServer.cpp:595 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:592 +#: daemon/HTTPServer.cpp:598 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:618 +#: daemon/HTTPServer.cpp:624 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:621 +#: daemon/HTTPServer.cpp:627 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:622 +#: daemon/HTTPServer.cpp:628 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:627 +#: daemon/HTTPServer.cpp:633 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:630 +#: daemon/HTTPServer.cpp:636 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:631 +#: daemon/HTTPServer.cpp:637 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:632 +#: daemon/HTTPServer.cpp:638 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:642 +#: daemon/HTTPServer.cpp:648 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:653 +#: daemon/HTTPServer.cpp:659 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:684 +#: daemon/HTTPServer.cpp:690 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:687 +#: daemon/HTTPServer.cpp:693 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:689 +#: daemon/HTTPServer.cpp:695 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697 +#: daemon/HTTPServer.cpp:698 daemon/HTTPServer.cpp:703 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699 +#: daemon/HTTPServer.cpp:700 daemon/HTTPServer.cpp:705 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:701 +#: daemon/HTTPServer.cpp:707 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:704 +#: daemon/HTTPServer.cpp:710 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:706 +#: daemon/HTTPServer.cpp:712 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:714 +#: daemon/HTTPServer.cpp:720 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:737 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:743 +#: daemon/HTTPServer.cpp:729 +msgid "Change language" +msgstr "" + +#: daemon/HTTPServer.cpp:762 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871 +#: daemon/HTTPServer.cpp:867 daemon/HTTPServer.cpp:890 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:864 +#: daemon/HTTPServer.cpp:883 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:877 +#: daemon/HTTPServer.cpp:896 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:882 +#: daemon/HTTPServer.cpp:901 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:939 +#: daemon/HTTPServer.cpp:958 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:955 +#: daemon/HTTPServer.cpp:974 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:969 +#: daemon/HTTPServer.cpp:988 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1175 +#: daemon/HTTPServer.cpp:1194 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1194 +#: daemon/HTTPServer.cpp:1213 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309 -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1271 daemon/HTTPServer.cpp:1328 +#: daemon/HTTPServer.cpp:1364 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1252 +#: daemon/HTTPServer.cpp:1271 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1254 +#: daemon/HTTPServer.cpp:1273 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1257 +#: daemon/HTTPServer.cpp:1276 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1260 +#: daemon/HTTPServer.cpp:1279 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327 +#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1346 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276 +#: daemon/HTTPServer.cpp:1282 daemon/HTTPServer.cpp:1295 msgid "You will be redirected back in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1274 +#: daemon/HTTPServer.cpp:1293 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1294 daemon/HTTPServer.cpp:1365 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1311 +#: daemon/HTTPServer.cpp:1330 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1331 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1331 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1313 +#: daemon/HTTPServer.cpp:1332 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1319 +#: daemon/HTTPServer.cpp:1338 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1322 +#: daemon/HTTPServer.cpp:1341 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1325 +#: daemon/HTTPServer.cpp:1344 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1333 +#: daemon/HTTPServer.cpp:1360 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1364 msgid "Command accepted" msgstr "" -#: daemon/HTTPServer.cpp:1339 +#: daemon/HTTPServer.cpp:1366 msgid "You will be redirected in 5 seconds" msgstr "" diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 0b9e8f0f..8ed4511f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -68,11 +68,11 @@ namespace http { << " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" << " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n" << " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" - << " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" - << " .menu { float: left; } .menu a, .commands a { display: block; }\r\n" + << " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" + << " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n" << " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" << " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" - << " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n" + << " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 48em; overflow: auto; }\r\n" << " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n" << " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n" << " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" @@ -84,19 +84,24 @@ namespace http { << " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" << " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n" << " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n" - << " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + << " @media screen and (max-width: 1150px) {\r\n" /* adaptive style */ + << " .wrapper { max-width: 58em; } .menu { max-width: 10em; }\r\n" + << " .content { margin-left: 2em; max-width: 42em; }\r\n" + << " }\r\n" + << " @media screen and (max-width: 980px) {\r\n" << " body { padding: 1.5em 0 0 0; }\r\n" - << " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" + << " .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px;\r\n" << " text-align: center; }\r\n" - << " .menu a, .commands a { padding: 2px; }\r\n" + << " .menu a, .commands a { display: inline-block; padding: 4px; }\r\n" << " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n" << " text-align: center; }\r\n" << " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" << " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n" << " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" << " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" - << " input { width: 35%; text-align: center; padding: 5px;\r\n" + << " input, select { width: 35%; text-align: center; padding: 5px;\r\n" << " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n" + << " table.extaddr { margin: auto; text-align: unset; }\r\n" << " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n" << " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n" << " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n" @@ -127,6 +132,7 @@ namespace http { const char HTTP_COMMAND_KILLSTREAM[] = "closestream"; const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit"; const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; + const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; @@ -223,18 +229,18 @@ namespace http { "
" << tr("i2pd webconsole") << "
\r\n" "
\r\n" "\r\n" "
"; @@ -476,7 +482,7 @@ namespace http { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr(/* Milliseconds */ "ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -681,22 +687,22 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); /* commands */ s << "" << tr("Router commands") << "
\r\n
\r\n
\r\n"; - s << " " << tr("Run peer test") << "\r\n"; + s << " " << tr("Run peer test") << "
\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " " << tr("Decline transit tunnels") << "\r\n"; + s << " " << tr("Decline transit tunnels") << "
\r\n"; else - s << " " << tr("Accept transit tunnels") << "\r\n"; + s << " " << tr("Accept transit tunnels") << "
\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) - s << " " << tr("Cancel graceful shutdown") << "\r\n"; + s << " " << tr("Cancel graceful shutdown") << "
\r\n"; else - s << " " << tr("Start graceful shutdown") << "\r\n"; + s << " " << tr("Start graceful shutdown") << "
\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) - s << " " << tr("Cancel graceful shutdown") << "\r\n"; + s << " " << tr("Cancel graceful shutdown") << "
\r\n"; else - s << " " << tr("Start graceful shutdown") << "\r\n"; + s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif s << " " << tr("Force shutdown") << "\r\n"; s << "
"; @@ -718,6 +724,19 @@ namespace http { s << " \r\n"; s << " \r\n"; s << "\r\n
\r\n"; + + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + s << "" << tr("Change language") << "
\r\n"; + s << "
\r\n"; + s << " \r\n"; + s << " \r\n"; + s << " \r\n"; + s << " \r\n"; + s << "
\r\n
\r\n"; + } void ShowTransitTunnels (std::stringstream& s) @@ -1327,6 +1346,14 @@ namespace http { s << "" << tr("Return to destination page") << "\r\n"; return; } + else if (cmd == HTTP_COMMAND_SETLANGUAGE) + { + std::string lang = params["lang"]; + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); + + if (currLang.compare(lang) != 0) + i2p::i18n::SetLanguage(lang); + } else { res.code = 400; diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index d2b652b4..96ee52ee 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace afrikaans // language +namespace afrikaans // language namespace { + // language name in lowercase + static std::string language = "afrikaans"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -65,7 +68,7 @@ namespace afrikaans // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/English.cpp b/i18n/English.cpp index 6015f8e1..2670e984 100644 --- a/i18n/English.cpp +++ b/i18n/English.cpp @@ -19,8 +19,11 @@ namespace i2p { namespace i18n { -namespace english // language +namespace english // language namespace { + // language name in lowercase + static std::string language = "english"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -39,7 +42,7 @@ namespace english // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/I18N.h b/i18n/I18N.h index 272f65e8..03add48d 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -17,16 +17,11 @@ namespace i18n { inline void SetLanguage(const std::string &lang) { - 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()); - else if (!lang.compare("ukrainian")) - i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale()); - else // fallback + const auto it = i2p::i18n::languages.find(lang); + if (it == i2p::i18n::languages.end()) // fallback i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); + else + i2p::context.SetLanguage (it->second.LocaleFunc()); } inline std::string translate (const std::string& arg) diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 181a4793..949e5844 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -17,10 +17,17 @@ namespace i18n { public: Locale ( + const std::string& language, const std::map& strings, const std::map>& plurals, std::function formula - ): m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { }; + ): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { }; + + // Get activated language name for webconsole + std::string GetLanguage() const + { + return m_Language; + } std::string GetString (const std::string& arg) const { @@ -50,11 +57,18 @@ namespace i18n } private: + const std::string m_Language; const std::map m_Strings; const std::map> m_Plurals; std::function m_Formula; }; + struct langData + { + std::string LocaleName; //localized name + std::function (void)> LocaleFunc; + }; + // Add localization here with language name as namespace namespace afrikaans { std::shared_ptr GetLocale (); } namespace english { std::shared_ptr GetLocale (); } @@ -62,6 +76,18 @@ namespace i18n namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } + /** + * That map contains international language name lower-case and name in it's language + */ + static std::map languages + { + { "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} }, + { "english", {"English", i2p::i18n::english::GetLocale} }, + { "russian", {"русский язык", i2p::i18n::russian::GetLocale} }, + { "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} }, + { "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} }, + }; + } // i18n } // i2p diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 7df82d54..5e7f9c6b 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace russian // language +namespace russian // language namespace { + // language name in lowercase + static std::string language = "russian"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -28,23 +31,152 @@ namespace russian // language static std::map strings { - // HTTP Proxy + {"Disabled", "Выключено"}, + {"Enabled", "Включено"}, + {"KiB", "КиБ"}, + {"MiB", "МиБ"}, + {"GiB", "ГиБ"}, + {"building", "строится"}, + {"failed", "неудачный"}, + {"expiring", "истекает"}, + {"established", "работает"}, + {"unknown", "неизвестно"}, + {"exploratory", "исследовательский"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + {"Main page", "Главная"}, + {"Router commands", "Команды роутера"}, + {"Local destinations", "Локальные назначения"}, + {"LeaseSets", "Лизсеты"}, + {"Tunnels", "Туннели"}, + {"Transit tunnels", "Транзитные туннели"}, + {"Transports", "Транспорты"}, + {"I2P tunnels", "I2P туннели"}, + {"SAM sessions", "SAM сессии"}, + {"ERROR", "ОШИБКА"}, + {"OK", "OK"}, + {"Testing", "Тестирование"}, + {"Firewalled", "Заблокировано извне"}, + {"Unknown", "Неизвестно"}, + {"Proxy", "Прокси"}, + {"Mesh", "MESH-сеть"}, + {"Error", "Ошибка"}, + {"Clock skew", "Не точное время"}, + {"Offline", "Оффлайн"}, + {"Symmetric NAT", "Симметричный NAT"}, + {"Uptime", "В сети"}, + {"Network status", "Сетевой статус"}, + {"Network status v6", "Сетевой статус v6"}, + {"Stopping in", "Остановка через"}, + {"Family", "Семейство"}, + {"Tunnel creation success rate", "Успешно построенных туннелей"}, + {"Received", "Получено"}, + {"KiB/s", "КиБ/с"}, + {"Sent", "Отправлено"}, + {"Transit", "Транзит"}, + {"Data path", "Путь к данным"}, + {"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."}, + {"Router Ident", "Идентификатор роутера"}, + {"Router Family", "Семейство роутера"}, + {"Router Caps", "Флаги роутера"}, + {"Version", "Версия"}, + {"Our external address", "Наш внешний адрес"}, + {"supported", "поддерживается"}, + {"Routers", "Роутеры"}, + {"Floodfills", "Флудфилы"}, + {"Client Tunnels", "Клиентские туннели"}, + {"Transit Tunnels", "Транзитные туннели"}, + {"Services", "Сервисы"}, + {"Local Destinations", "Локальные назначения"}, + {"Encrypted B33 address", "Шифрованные B33 адреса"}, + {"Address registration line", "Строка регистрации адреса"}, + {"Domain", "Домен"}, + {"Generate", "Сгенерировать"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Примечание: полученная строка может быть использована только для регистрации доменов второго уровня (example.i2p). Для регистрации поддоменов используйте i2pd-tools."}, + {"Address", "Адрес"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Входящие туннели"}, + {"ms", "мс"}, + {"Outbound tunnels", "Исходящие туннели"}, + {"Tags", "Теги"}, + {"Incoming", "Входящие"}, + {"Outgoing", "Исходящие"}, + {"Destination", "Назначение"}, + {"Amount", "Количество"}, + {"Incoming Tags", "Входящие Теги"}, + {"Tags sessions", "Сессии Тегов"}, + {"Status", "Статус"}, + {"Local Destination", "Локальное назначение"}, + {"Streams", "Стримы"}, + {"Close stream", "Закрыть стрим"}, + {"I2CP session not found", "I2CP сессия не найдена"}, + {"I2CP is not enabled", "I2CP не включен"}, + {"Invalid", "Некорректный"}, + {"Store type", "Тип хранилища"}, + {"Expires", "Истекает"}, + {"Non Expired Leases", "Не истекшие Lease-ы"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID туннеля"}, + {"EndDate", "Заканчивается"}, + {"not floodfill", "не флудфил"}, + {"Queue size", "Размер очереди"}, + {"Run peer test", "Запустить тестирование"}, + {"Decline transit tunnels", "Отклонять транзитные туннели"}, + {"Accept transit tunnels", "Принимать транзитные туннели"}, + {"Cancel graceful shutdown", "Отменить плавную остановку"}, + {"Start graceful shutdown", "Запустить плавную остановку"}, + {"Force shutdown", "Принудительная остановка"}, + {"Note: any action done here are not persistent and not changes your config files.", "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, + {"Logging level", "Уровень логирования"}, + {"Transit tunnels limit", "Лимит транзитных туннелей"}, + {"Change", "Изменить"}, + {"Change language", "Изменение языка"}, + {"no transit tunnels currently built", "нет построенных транзитных туннелей"}, + {"SAM disabled", "SAM выключен"}, + {"no sessions currently running", "нет запущенных сессий"}, + {"SAM session not found", "SAM сессия не найдена"}, + {"SAM Session", "SAM сессия"}, + {"Server Tunnels", "Серверные туннели"}, + {"Client Forwards", "Клиентские перенаправления"}, + {"Server Forwards", "Серверные перенаправления"}, + {"Unknown page", "Неизвестная страница"}, + {"Invalid token", "Неверный токен"}, + {"SUCCESS", "УСПЕШНО"}, + {"Stream closed", "Стрим закрыт"}, + {"Stream not found or already was closed", "Стрим не найден или уже закрыт"}, + {"Destination not found", "Точка назначения не найдена"}, + {"StreamID can't be null", "StreamID не может быть пустым"}, + {"Return to destination page", "Вернуться на страницу точки назначения"}, + {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, + {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, + {"Back to commands list", "Вернуться к списку команд"}, + {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, + {"Description", "Описание"}, + {"A bit information about service on domain", "Немного информации о сервисе на домене"}, + {"Submit", "Отправить"}, + {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, + {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, + {"Such destination is not found", "Такая точка назначения не найдена"}, + {"Unknown command", "Неизвестная команда"}, + {"Command accepted", "Команда принята"}, + {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Proxy error", "Ошибка прокси"}, {"Proxy info", "Информация прокси"}, - {"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"}, - {"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"}, - {"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"}, + {"Proxy error: Host not found", "Ошибка прокси: Узел не найден"}, + {"Remote host not found in router's addressbook", "Запрошенный узел не найден в адресной книге роутера"}, + {"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"}, {"Invalid request", "Некорректный запрос"}, {"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"}, {"addresshelper is not supported", "addresshelper не поддерживается"}, - {"Host", "Адрес"}, + {"Host", "Узел"}, {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"already in router's addressbook", "уже в адресной книге роутера"}, {"Click", "Нажмите"}, {"here", "здесь"}, {"to proceed", "чтобы продолжить"}, - {"to update record", "чтобы обновить запись"}, {"Addresshelper found", "Найден addresshelper"}, + {"already in router's addressbook", "уже в адресной книге роутера"}, + {"to update record", "чтобы обновить запись"}, + {"Invalid Request", "неверный запрос"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, @@ -63,169 +195,13 @@ namespace russian // language {"cannot connect", "не удалось подключиться"}, {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, - {"Host is down", "Адрес недоступен"}, - {"Can't create connection to requested host, it may be down. Please try again later.", - "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, - - // Webconsole // - // cssStyles - {"Disabled", "Выключено"}, - {"Enabled", "Включено"}, - // ShowTraffic - {"KiB", "КиБ"}, - {"MiB", "МиБ"}, - {"GiB", "ГиБ"}, - // ShowTunnelDetails - {"building", "строится"}, - {"failed", "неудачный"}, - {"expiring", "истекает"}, - {"established", "работает"}, - {"exploratory", "исследовательский"}, - {"unknown", "неизвестно"}, - {"i2pd webconsole", "Веб-консоль i2pd"}, - // ShowPageHead - {"Main page", "Главная"}, - {"Router commands", "Команды роутера"}, - {"Local destinations", "Локальные назнач."}, - {"LeaseSets", "Лизсеты"}, - {"Tunnels", "Туннели"}, - {"Transit tunnels", "Транзит. туннели"}, - {"Transports", "Транспорты"}, - {"I2P tunnels", "I2P туннели"}, - {"SAM sessions", "SAM сессии"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Тестирование"}, - {"Firewalled", "Заблокировано извне"}, - {"Unknown", "Неизвестно"}, - {"Proxy", "Прокси"}, - {"Mesh", "MESH-сеть"}, - {"Error", "Ошибка"}, - {"Clock skew", "Не точное время"}, - {"Offline", "Оффлайн"}, - {"Symmetric NAT", "Симметричный NAT"}, - // Status - {"Uptime", "В сети"}, - {"Network status", "Сетевой статус"}, - {"Network status v6", "Сетевой статус v6"}, - {"Stopping in", "Остановка через"}, - {"Family", "Семейство"}, - {"Tunnel creation success rate", "Успешно построенных туннелей"}, - {"Received", "Получено"}, - {"Sent", "Отправлено"}, - {"Transit", "Транзит"}, - {"KiB/s", "КиБ/с"}, - {"Data path", "Путь к данным"}, - {"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."}, - {"Router Ident", "Идентификатор роутера"}, - {"Router Family", "Семейство роутера"}, - {"Router Caps", "Флаги роутера"}, - {"Version", "Версия"}, - {"Our external address", "Наш внешний адрес"}, - {"supported", "поддерживается"}, - {"Routers", "Роутеры"}, - {"Floodfills", "Флудфилы"}, - {"LeaseSets", "Лизсеты"}, - {"Client Tunnels", "Клиентские туннели"}, - {"Transit Tunnels", "Транзитные туннели"}, - {"Services", "Сервисы"}, - // ShowLocalDestinations - {"Local Destinations", "Локальные назначения"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Шифрованные B33 адреса"}, - {"Address registration line", "Строка регистрации адреса"}, - {"Domain", "Домен"}, - {"Generate", "Сгенерировать"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Примечание: полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."}, - {"Address", "Адрес"}, - {"Type", "Тип"}, - {"EncType", "ТипШифр"}, - {"Inbound tunnels", "Входящие туннели"}, - {"Outbound tunnels", "Исходящие туннели"}, - {"ms", "мс"}, // milliseconds - {"Tags", "Теги"}, - {"Incoming", "Входящие"}, - {"Outgoing", "Исходящие"}, - {"Destination", "Назначение"}, - {"Amount", "Количество"}, - {"Incoming Tags", "Входящие Теги"}, - {"Tags sessions", "Сессии Тегов"}, - {"Status", "Статус"}, - // ShowLocalDestination - {"Local Destination", "Локальное назначение"}, - {"Streams", "Стримы"}, - {"Close stream", "Закрыть стрим"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP сессия не найдена"}, - {"I2CP is not enabled", "I2CP не включен"}, - // ShowLeasesSets - {"Invalid", "Некорректный"}, - {"Store type", "Тип хранилища"}, - {"Expires", "Истекает"}, - {"Non Expired Leases", "Не истекшие Lease-ы"}, - {"Gateway", "Шлюз"}, - {"TunnelID", "ID туннеля"}, - {"EndDate", "Заканчивается"}, - {"not floodfill", "не флудфил"}, - // ShowTunnels - {"Queue size", "Размер очереди"}, - // ShowCommands - {"Run peer test", "Запустить тестирование"}, - {"Decline transit tunnels", "Отклонять транзитные туннели"}, - {"Accept transit tunnels", "Принимать транзитные туннели"}, - {"Cancel graceful shutdown", "Отменить плавную остановку"}, - {"Start graceful shutdown", "Запустить плавную остановку"}, - {"Force shutdown", "Принудительная остановка"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, - {"Logging level", "Уровень логирования"}, - {"Transit tunnels limit", "Лимит транзитных туннелей"}, - {"Change", "Изменить"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "нет построенных транзитных туннелей"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM выключен"}, - {"SAM session not found", "SAM сессия не найдена"}, - {"no sessions currently running", "нет запущенных сессий"}, - {"SAM Session", "SAM сессия"}, - // ShowI2PTunnels - {"Server Tunnels", "Серверные туннели"}, - {"Client Forwards", "Клиентские перенаправления"}, - {"Server Forwards", "Серверные перенаправления"}, - // HandlePage - {"Unknown page", "Неизвестная страница"}, - // HandleCommand, ShowError - {"Invalid token", "Неверный токен"}, - {"SUCCESS", "УСПЕШНО"}, - {"ERROR", "ОШИБКА"}, - {"Unknown command", "Неизвестная команда"}, - {"Command accepted", "Команда принята"}, - {"Back to commands list", "Вернуться к списку команд"}, - {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Стрим закрыт"}, - {"Stream not found or already was closed", "Стрим не найден или уже закрыт"}, - {"Destination not found", "Точка назначения не найдена"}, - {"StreamID can't be null", "StreamID не может быть пустым"}, - {"Return to destination page", "Вернуться на страницу точки назначения"}, - {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, - {"Description", "Описание"}, - {"A bit information about service on domain", "Немного информации о сервисе на домене"}, - {"Submit", "Отправить"}, - {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, - {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, - {"Such destination is not found", "Такая точка назначения не найдена"}, + {"Host is down", "Узел недоступен"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."}, {"", ""}, }; static std::map> plurals { - // ShowUptime {"days", {"день", "дня", "дней"}}, {"hours", {"час", "часа", "часов"}}, {"minutes", {"минуту", "минуты", "минут"}}, @@ -235,7 +211,7 @@ namespace russian // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 0edc9a6e..8af89f6f 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace turkmen // language +namespace turkmen // language namespace { + // language name in lowercase + static std::string language = "turkmen"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -234,7 +237,7 @@ namespace turkmen // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 5e856c52..8da132d7 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace ukrainian // language +namespace ukrainian // language namespace { + // language name in lowercase + static std::string language = "ukrainian"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -207,7 +210,7 @@ namespace ukrainian // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language From 25f63ac22a8604f05cabee447c28337190be404d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Jun 2021 15:49:57 -0400 Subject: [PATCH 045/186] create different I2NP tunnel messages for endpoint and non-endpoint --- libi2pd/I2NPProtocol.cpp | 26 ++++++++++++++++++-------- libi2pd/I2NPProtocol.h | 4 ++-- libi2pd/TransitTunnel.cpp | 4 ++-- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelEndpoint.cpp | 4 +--- libi2pd/TunnelGateway.cpp | 2 +- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index f570a2a1..a040e25b 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,11 +36,21 @@ namespace i2p return std::make_shared >(); } - std::shared_ptr NewI2NPTunnelMessage () + std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - // should fit two tunnel message, enough for one garlic encrypted streaming packet - auto msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12 - msg->Align (12); + I2NPMessage * msg = nullptr; + if (endpoint) + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + } + else + { + msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + msg->Align (12); + } return std::shared_ptr(msg); } @@ -692,7 +702,7 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (false); msg->Concat (buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE); msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; @@ -700,7 +710,7 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (false); htobe32buf (msg->GetPayload (), tunnelID); msg->len += 4; // tunnelID msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4); @@ -708,9 +718,9 @@ namespace i2p return msg; } - std::shared_ptr CreateEmptyTunnelDataMsg () + std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (endpoint); msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; return msg; } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index cc7c94af..69d6bb04 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -278,7 +278,7 @@ namespace tunnel std::shared_ptr NewI2NPMessage (); std::shared_ptr NewI2NPShortMessage (); - std::shared_ptr NewI2NPTunnelMessage (); + std::shared_ptr NewI2NPTunnelMessage (bool endpoint); std::shared_ptr NewI2NPMessage (size_t len); std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0); @@ -307,7 +307,7 @@ namespace tunnel std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf); std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); - std::shared_ptr CreateEmptyTunnelDataMsg (); + std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint); std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len); std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 73ca977c..dc7655d1 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -39,7 +39,7 @@ namespace tunnel void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (false); EncryptTunnelMsg (tunnelMsg, newMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); @@ -87,7 +87,7 @@ namespace tunnel void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (tunnelMsg, newMsg); LogPrint (eLogDebug, "TransitTunnel: handle msg for endpoint ", GetTunnelID ()); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index e016e9e4..ba01ae20 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -234,7 +234,7 @@ namespace tunnel void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (msg, newMsg); newMsg->from = shared_from_this (); m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 109f3120..4885c090 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -126,9 +126,7 @@ namespace tunnel if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) { // this is not last message. we have to copy it - m_CurrentMessage.data = NewI2NPTunnelMessage (); - m_CurrentMessage.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - m_CurrentMessage.data->len += TUNNEL_GATEWAY_HEADER_SIZE; + m_CurrentMessage.data = NewI2NPTunnelMessage (true); *(m_CurrentMessage.data) = *msg; } else diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 317926ae..08df569c 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -215,7 +215,7 @@ namespace tunnel const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs (); for (auto& tunnelMsg : tunnelDataMsgs) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (false); m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg); htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ()); newMsg->FillI2NPMessageHeader (eI2NPTunnelData); From f036b8df2dc74977b700bd543fec9d9754dbb4ce Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Jun 2021 12:45:28 +0300 Subject: [PATCH 046/186] [i18n] update translatable strings (remove douplicates) Signed-off-by: R4SAS --- contrib/i18n/English.po | 180 +++++++++++++++++------------------ daemon/HTTPServer.cpp | 39 ++++---- libi2pd_client/HTTPProxy.cpp | 2 +- 3 files changed, 108 insertions(+), 113 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 011d0fee..76d58390 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -50,14 +50,17 @@ msgid_plural "seconds" msgstr[0] "" msgstr[1] "" +#. tr: Kibibit #: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 msgid "KiB" msgstr "" +#. tr: Mebibit #: daemon/HTTPServer.cpp:168 msgid "MiB" msgstr "" +#. tr: Gibibit #: daemon/HTTPServer.cpp:170 msgid "GiB" msgstr "" @@ -94,31 +97,32 @@ msgstr "" msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:689 +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:690 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:234 -msgid "Local destinations" +#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:413 +#: daemon/HTTPServer.cpp:425 +msgid "Local Destinations" msgstr "" #: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 #: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 -#: daemon/HTTPServer.cpp:605 daemon/HTTPServer.cpp:648 -#: daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:606 daemon/HTTPServer.cpp:649 +#: daemon/HTTPServer.cpp:653 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:658 +#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:659 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:746 -#: daemon/HTTPServer.cpp:762 -msgid "Transit tunnels" +#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:395 +#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:769 +msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:811 +#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:818 msgid "Transports" msgstr "" @@ -126,15 +130,15 @@ msgstr "" msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:873 -#: daemon/HTTPServer.cpp:883 +#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:880 +#: daemon/HTTPServer.cpp:890 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1273 -#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1279 -#: daemon/HTTPServer.cpp:1293 daemon/HTTPServer.cpp:1338 -#: daemon/HTTPServer.cpp:1341 daemon/HTTPServer.cpp:1344 +#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1280 +#: daemon/HTTPServer.cpp:1283 daemon/HTTPServer.cpp:1286 +#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1345 +#: daemon/HTTPServer.cpp:1348 daemon/HTTPServer.cpp:1351 msgid "ERROR" msgstr "" @@ -156,8 +160,8 @@ msgid "Unknown" msgstr "" #: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 -#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:941 -#: daemon/HTTPServer.cpp:950 +#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:948 +#: daemon/HTTPServer.cpp:957 msgid "Proxy" msgstr "" @@ -209,6 +213,7 @@ msgstr "" msgid "Received" msgstr "" +#. tr: Kibibit/s #: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 #: daemon/HTTPServer.cpp:334 msgid "KiB/s" @@ -262,22 +267,14 @@ msgstr "" msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:927 +#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:934 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:395 -msgid "Transit Tunnels" -msgstr "" - #: daemon/HTTPServer.cpp:399 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:413 daemon/HTTPServer.cpp:425 -msgid "Local Destinations" -msgstr "" - #: daemon/HTTPServer.cpp:448 msgid "Encrypted B33 address" msgstr "" @@ -312,17 +309,17 @@ msgstr "" msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:663 +#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:664 msgid "Inbound tunnels" msgstr "" -#. Milliseconds +#. tr: Milliseconds #: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 -#: daemon/HTTPServer.cpp:668 daemon/HTTPServer.cpp:678 +#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:679 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:673 +#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:674 msgid "Outbound tunnels" msgstr "" @@ -358,225 +355,222 @@ msgstr "" msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:590 +#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:591 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:906 +#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:913 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:566 +#: daemon/HTTPServer.cpp:567 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:595 +#: daemon/HTTPServer.cpp:596 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:598 +#: daemon/HTTPServer.cpp:599 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:624 +#: daemon/HTTPServer.cpp:625 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:627 +#: daemon/HTTPServer.cpp:628 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:629 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:633 +#: daemon/HTTPServer.cpp:634 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:636 +#: daemon/HTTPServer.cpp:637 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:637 +#: daemon/HTTPServer.cpp:638 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:638 +#: daemon/HTTPServer.cpp:639 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:648 +#: daemon/HTTPServer.cpp:649 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:659 +#: daemon/HTTPServer.cpp:660 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:690 +#: daemon/HTTPServer.cpp:691 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:693 +#: daemon/HTTPServer.cpp:698 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:695 +#: daemon/HTTPServer.cpp:700 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:698 daemon/HTTPServer.cpp:703 +#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:709 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:700 daemon/HTTPServer.cpp:705 +#: daemon/HTTPServer.cpp:706 daemon/HTTPServer.cpp:711 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:707 +#: daemon/HTTPServer.cpp:714 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:710 +#: daemon/HTTPServer.cpp:717 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:712 +#: daemon/HTTPServer.cpp:719 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:720 +#: daemon/HTTPServer.cpp:727 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:737 +#: daemon/HTTPServer.cpp:732 daemon/HTTPServer.cpp:744 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:729 +#: daemon/HTTPServer.cpp:736 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:762 +#: daemon/HTTPServer.cpp:769 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:867 daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:874 daemon/HTTPServer.cpp:897 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:883 +#: daemon/HTTPServer.cpp:890 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:896 +#: daemon/HTTPServer.cpp:903 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:901 +#: daemon/HTTPServer.cpp:908 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:958 +#: daemon/HTTPServer.cpp:965 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:974 +#: daemon/HTTPServer.cpp:981 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:988 +#: daemon/HTTPServer.cpp:995 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1194 +#: daemon/HTTPServer.cpp:1201 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1213 +#: daemon/HTTPServer.cpp:1220 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1271 daemon/HTTPServer.cpp:1328 -#: daemon/HTTPServer.cpp:1364 +#: daemon/HTTPServer.cpp:1278 daemon/HTTPServer.cpp:1335 +#: daemon/HTTPServer.cpp:1371 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1271 +#: daemon/HTTPServer.cpp:1278 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1273 +#: daemon/HTTPServer.cpp:1280 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1276 +#: daemon/HTTPServer.cpp:1283 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1279 +#: daemon/HTTPServer.cpp:1286 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1346 +#: daemon/HTTPServer.cpp:1288 daemon/HTTPServer.cpp:1353 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1282 daemon/HTTPServer.cpp:1295 -msgid "You will be redirected back in 5 seconds" +#: daemon/HTTPServer.cpp:1289 daemon/HTTPServer.cpp:1302 +#: daemon/HTTPServer.cpp:1373 +msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1293 +#: daemon/HTTPServer.cpp:1300 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1294 daemon/HTTPServer.cpp:1365 +#: daemon/HTTPServer.cpp:1301 daemon/HTTPServer.cpp:1372 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1330 +#: daemon/HTTPServer.cpp:1337 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1331 +#: daemon/HTTPServer.cpp:1338 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1331 +#: daemon/HTTPServer.cpp:1338 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1332 +#: daemon/HTTPServer.cpp:1339 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1345 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1341 +#: daemon/HTTPServer.cpp:1348 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1344 +#: daemon/HTTPServer.cpp:1351 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1360 +#: daemon/HTTPServer.cpp:1367 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1364 +#: daemon/HTTPServer.cpp:1371 msgid "Command accepted" msgstr "" -#: daemon/HTTPServer.cpp:1366 -msgid "You will be redirected in 5 seconds" -msgstr "" - #: libi2pd_client/HTTPProxy.cpp:157 msgid "Proxy error" msgstr "" @@ -598,7 +592,7 @@ 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 +#: libi2pd_client/HTTPProxy.cpp:322 libi2pd_client/HTTPProxy.cpp:365 msgid "Invalid request" msgstr "" @@ -643,10 +637,6 @@ msgstr "" msgid "to update record" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:322 -msgid "Invalid Request" -msgstr "" - #: libi2pd_client/HTTPProxy.cpp:322 msgid "invalid request uri" msgstr "" diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8ed4511f..fd26d8f1 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -163,11 +163,11 @@ namespace http { s << std::fixed << std::setprecision(2); auto numKBytes = (double) bytes / 1024; if (numKBytes < 1024) - s << numKBytes << " " << tr("KiB"); + s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB"); else if (numKBytes < 1024 * 1024) - s << numKBytes / 1024 << " " << tr("MiB"); + s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB"); else - s << numKBytes / 1024 / 1024 << " " << tr("GiB"); + s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB"); } static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) @@ -191,7 +191,7 @@ namespace http { else stateText = tr("unknown"); s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; - s << " " << (int) (bytes / 1024) << " " << tr("KiB") << "\r\n"; + s << " " << (int) (bytes / 1024) << " " << tr(/* tr: Kibibit */ "KiB") << "\r\n"; } static void SetLogLevel (const std::string& level) @@ -231,12 +231,12 @@ namespace http { "
\r\n" " " << tr("Main page") << "

\r\n" " " << tr("Router commands") << "
\r\n" - " " << tr("Local destinations") << "
\r\n"; + " " << tr("Local Destinations") << "
\r\n"; if (i2p::context.IsFloodfill ()) s << " " << tr("LeaseSets") << "
\r\n"; s << " " << tr("Tunnels") << "
\r\n" - " " << tr("Transit tunnels") << "
\r\n" + " " << tr("Transit Tunnels") << "
\r\n" " " << tr ("Transports") << "
\r\n" " " << tr("I2P tunnels") << "
\r\n"; if (i2p::client::context.GetSAMBridge ()) @@ -325,13 +325,13 @@ namespace http { s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { @@ -482,7 +482,7 @@ namespace http { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr(/* Milliseconds */ "ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -540,7 +540,8 @@ namespace http { if (dest) { ShowLeaseSetDestination (s, dest, token); - // show streams + + // Print table with streams information s << "\r\n\r\n\r\n"; s << ""; s << "
" << tr("Streams") << "
StreamID"; // Stream closing button column @@ -685,14 +686,17 @@ namespace http { static void ShowCommands (std::stringstream& s, uint32_t token) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - /* commands */ + s << "" << tr("Router commands") << "
\r\n
\r\n
\r\n"; s << " " << tr("Run peer test") << "
\r\n"; - //s << " Reload config
\r\n"; + + // s << " Reload config
\r\n"; + if (i2p::context.AcceptsTunnels ()) s << " " << tr("Decline transit tunnels") << "
\r\n"; else s << " " << tr("Accept transit tunnels") << "
\r\n"; + #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) s << " " << tr("Cancel graceful shutdown") << "
\r\n"; @@ -704,6 +708,7 @@ namespace http { else s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif + s << " " << tr("Force shutdown") << "\r\n"; s << "
"; @@ -743,7 +748,7 @@ namespace http { { if(i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "" << tr("Transit tunnels") << ":
\r\n
\r\n"; + s << "" << tr("Transit Tunnels") << ":
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { s << "
\r\n"; @@ -759,7 +764,7 @@ namespace http { } else { - s << "" << tr("Transit tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; + s << "" << tr("Transit Tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; } } @@ -1279,7 +1284,7 @@ namespace http { s << "" << tr("ERROR") << ": " << tr("StreamID can't be null") << "
\r\n
\r\n"; s << "" << tr("Return to destination page") << "
\r\n"; - s << "

" << tr("You will be redirected back in 5 seconds") << ""; + s << "

" << tr("You will be redirected in 5 seconds") << ""; redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32; res.add_header("Refresh", redirect.c_str()); return; @@ -1292,7 +1297,7 @@ namespace http { else { s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed 65535") << "\r\n
\r\n
\r\n"; s << "" << tr("Back to commands list") << "\r\n
\r\n"; - s << "

" << tr("You will be redirected back in 5 seconds") << ""; + s << "

" << tr("You will be redirected in 5 seconds") << ""; res.add_header("Refresh", redirect.c_str()); return; } diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index d8b84e82..70cf78a8 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -319,7 +319,7 @@ namespace proxy { auto pos = uri.find(":"); if(pos == std::string::npos || pos == uri.size() - 1) { - GenericProxyError(tr("Invalid Request"), tr("invalid request uri")); + GenericProxyError(tr("Invalid request"), tr("invalid request uri")); return true; } else From 5781335814b1c3766ccaadb66418c715daa88e55 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 29 Jun 2021 19:08:11 -0400 Subject: [PATCH 047/186] save and check last stream --- libi2pd/Streaming.cpp | 21 +++++++++++++++------ libi2pd/Streaming.h | 11 ++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 612b1058..3269e040 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1050,6 +1050,7 @@ namespace stream it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); + m_LastStream = nullptr; } } @@ -1058,9 +1059,16 @@ namespace stream uint32_t sendStreamID = packet->GetSendStreamID (); if (sendStreamID) { - auto it = m_Streams.find (sendStreamID); - if (it != m_Streams.end ()) - it->second->HandleNextPacket (packet); + if (!m_LastStream || sendStreamID != m_LastStream->GetRecvStreamID ()) + { + auto it = m_Streams.find (sendStreamID); + if (it != m_Streams.end ()) + m_LastStream = it->second; + else + m_LastStream = nullptr; + } + if (m_LastStream) + m_LastStream->HandleNextPacket (packet); else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ()) { // ping @@ -1166,7 +1174,7 @@ namespace stream { auto s = std::make_shared (m_Owner->GetService (), *this, remote, port); std::unique_lock l(m_StreamsMutex); - m_Streams[s->GetRecvStreamID ()] = s; + m_Streams.emplace (s->GetRecvStreamID (), s); return s; } @@ -1174,8 +1182,8 @@ namespace stream { auto s = std::make_shared (m_Owner->GetService (), *this); std::unique_lock l(m_StreamsMutex); - m_Streams[s->GetRecvStreamID ()] = s; - m_IncomingStreams[receiveStreamID] = s; + m_Streams.emplace (s->GetRecvStreamID (), s); + m_IncomingStreams.emplace (receiveStreamID, s); return s; } @@ -1186,6 +1194,7 @@ namespace stream std::unique_lock l(m_StreamsMutex); m_Streams.erase (stream->GetRecvStreamID ()); m_IncomingStreams.erase (stream->GetSendStreamID ()); + if (m_LastStream == stream) m_LastStream = nullptr; } } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index fe035136..c40c49f5 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -297,12 +297,13 @@ namespace stream uint16_t m_LocalPort; bool m_Gzip; // gzip compression of data messages std::mutex m_StreamsMutex; - std::map > m_Streams; // sendStreamID->stream - std::map > m_IncomingStreams; // receiveStreamID->stream + std::unordered_map > m_Streams; // sendStreamID->stream + std::unordered_map > m_IncomingStreams; // receiveStreamID->stream + std::shared_ptr m_LastStream; Acceptor m_Acceptor; std::list > m_PendingIncomingStreams; boost::asio::deadline_timer m_PendingIncomingTimer; - std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN + std::unordered_map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; i2p::util::MemoryPool > m_I2NPMsgsPool; From abee29719d57c6569ad0bc462cd13cdcd4b466b3 Mon Sep 17 00:00:00 2001 From: idk Date: Fri, 2 Jul 2021 10:47:55 -0400 Subject: [PATCH 048/186] fix go linking --- Makefile | 2 +- libi2pd_wrapper/api.go | 14 ++++++++++++-- libi2pd_wrapper/capi.cpp | 3 +-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 59faa94b..b1db36a8 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ $(ARLIB): $(LIB_OBJS) $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ -$(ARLIB_WRAP): $(LIB_OBJS) +$(ARLIB_WRAP): $(WRAP_LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_LANG): $(LANG_OBJS) diff --git a/libi2pd_wrapper/api.go b/libi2pd_wrapper/api.go index 48a41a4f..4674f16f 100644 --- a/libi2pd_wrapper/api.go +++ b/libi2pd_wrapper/api.go @@ -1,7 +1,17 @@ package api /* -#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes -#cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +* Copyright (c) 2013-2020, 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 +*/ + +/* +#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -I${SRCDIR}/../libi2pd -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" + +// -D, -U, -I, and \ No newline at end of file diff --git a/libi2pd_wrapper/capi.cpp b/libi2pd_wrapper/capi.cpp index 55b1b051..fc4df917 100644 --- a/libi2pd_wrapper/capi.cpp +++ b/libi2pd_wrapper/capi.cpp @@ -85,10 +85,9 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P ()//std::ostream *logStream) +void C_StartI2P () { std::shared_ptr logStream; - //cppLogStream(&out); return i2p::api::StartI2P(logStream); } From ff0e23d2c40fd52ba1fd1f7fba67c09444c57b9f Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 2 Jul 2021 16:43:41 +0000 Subject: [PATCH 049/186] [cmake] use GNUInstallDirs for libraries destination path (#1672) Signed-off-by: r4sas --- build/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d1502deb..2cd598f4 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -27,6 +27,9 @@ option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") set(CMAKE_SOURCE_DIR "..") +#Handle paths nicely +include(GNUInstallDirs) + # architecture include(TargetArch) target_architecture(ARCHITECTURE) @@ -48,8 +51,8 @@ set_target_properties(libi2pd PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pd EXPORT libi2pd - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) # TODO Make libi2pd available to 3rd party projects via CMake as imported target # FIXME This pulls stdafx @@ -63,8 +66,8 @@ set_target_properties(libi2pdclient PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pdclient EXPORT libi2pdclient - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) endif() @@ -75,8 +78,8 @@ set_target_properties(libi2pdlang PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pdlang EXPORT libi2pdlang - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) endif() @@ -272,9 +275,6 @@ message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS "---------------------------------------") -#Handle paths nicely -include(GNUInstallDirs) - if(WITH_BINARY) add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) From 8b35ce33202591c092fc57be6f8e27eb91ead2b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 13:20:24 -0400 Subject: [PATCH 050/186] separate decryption between own record and other records --- libi2pd/Tunnel.cpp | 36 ++++++++++++++++++------------------ libi2pd/TunnelConfig.cpp | 23 +++++++++++++++++++++++ libi2pd/TunnelConfig.h | 1 + 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index ba01ae20..7e154cbf 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -111,31 +111,31 @@ namespace tunnel TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { + // decrypt current hop + auto idx = hop->recordIndex; + if (idx >= 0 && idx < msg[0]) + { + uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; + if (!hop->DecryptBuildResponseRecord (record, record)) + return false; + } + else + { + LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); + return false; + } + + // decrypt records before current hop decryption.SetKey (hop->replyKey); - // decrypt records before and current hop - TunnelHopConfig * hop1 = hop; + TunnelHopConfig * hop1 = hop->prev; while (hop1) { auto idx = hop1->recordIndex; if (idx >= 0 && idx < msg[0]) { uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - if (hop1 == hop && hop1->IsECIES ()) - { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, - hop->m_H, 32, hop->m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt - { - LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); - return false; - } - } - else - { - decryption.SetIV (hop->replyIV); - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); - } + decryption.SetIV (hop->replyIV); + decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 8f515c5d..9079e134 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -147,5 +147,28 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } + + bool TunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + if (IsECIES ()) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, + m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; + } + } + else + { + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + } + return true; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 45693970..548ef031 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -43,6 +43,7 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); void EncryptECIES (std::shared_ptr& encryptor, const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); }; class TunnelConfig From 5d01ee95810aa72ccb6d0aca5c39a9b8eca37ef5 Mon Sep 17 00:00:00 2001 From: idk Date: Fri, 2 Jul 2021 13:20:28 -0400 Subject: [PATCH 051/186] Also add the languages to the linker flags in the api.go file --- libi2pd_wrapper/api.go | 4 +--- libi2pd_wrapper/capi.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd_wrapper/api.go b/libi2pd_wrapper/api.go index 4674f16f..64403aae 100644 --- a/libi2pd_wrapper/api.go +++ b/libi2pd_wrapper/api.go @@ -10,8 +10,6 @@ package api /* #cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -I${SRCDIR}/../libi2pd -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes -#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -l:libi2pdlang.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" - -// -D, -U, -I, and \ No newline at end of file diff --git a/libi2pd_wrapper/capi.h b/libi2pd_wrapper/capi.h index 3e33a0ee..bfc4f88b 100644 --- a/libi2pd_wrapper/capi.h +++ b/libi2pd_wrapper/capi.h @@ -17,7 +17,7 @@ extern "C" { void C_InitI2P (int argc, char argv[], const char * appName); //void C_InitI2P (int argc, char** argv, const char * appName); void C_TerminateI2P (); -void C_StartI2P (); //std::ostream *logStream = nullptr); +void C_StartI2P (); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP From 0ae170531e942f9488889d2f4367f90109f35928 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 15:41:33 -0400 Subject: [PATCH 052/186] different ElGamal and ECIES hops configs --- libi2pd/TunnelConfig.cpp | 122 ++++++++++++++++++++------------------- libi2pd/TunnelConfig.h | 42 +++++++++++--- 2 files changed, 99 insertions(+), 65 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 9079e134..6a314ec3 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -78,53 +78,42 @@ namespace tunnel } } - void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { + // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); + htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); + htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); + // encrypt auto encryptor = ident->CreateEncryptor (nullptr); - if (IsECIES ()) - { - uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - memset (clearText + ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 3); // set to 0 for compatibility - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET, 600); // +10 minutes - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); - if (encryptor) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); - } - else - { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); - htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); - htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); - } + if (encryptor) + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); - } + } - void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + return true; + } + + void ECIESTunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { uint8_t hepk[32]; @@ -147,26 +136,43 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } - - bool TunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + + void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { - if (IsECIES ()) + // fill clear text + uint8_t flag = 0; + if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; + if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + memset (clearText + ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 3); // set to 0 for compatibility + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET, 600); // +10 minutes + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); + // encrypt + auto encryptor = ident->CreateEncryptor (nullptr); + if (encryptor) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); + } + + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, + m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt - { - LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); - return false; - } - } - else - { - i2p::crypto::CBCDecryption decryption; - decryption.SetKey (replyKey); - decryption.SetIV (replyIV); - decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; } return true; } diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 548ef031..f64db0b0 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -18,7 +18,7 @@ namespace i2p { namespace tunnel { - struct TunnelHopConfig: public i2p::crypto::NoiseSymmetricState + struct TunnelHopConfig { std::shared_ptr ident; i2p::data::IdentHash nextIdent; @@ -33,18 +33,42 @@ namespace tunnel int recordIndex; // record # in tunnel build message TunnelHopConfig (std::shared_ptr r); + virtual ~TunnelHopConfig () {}; void SetNextIdent (const i2p::data::IdentHash& ident); void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent); void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - bool IsECIES () const { return ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + virtual bool IsECIES () const { return false; }; + virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; + virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) = 0; }; + + struct ElGamalTunnelHopConfig: public TunnelHopConfig + { + ElGamalTunnelHopConfig (std::shared_ptr r): + TunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; + + struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState + { + ECIESTunnelHopConfig (std::shared_ptr r): + TunnelHopConfig (r) {}; + bool IsECIES () const { return true; }; + void EncryptECIES (std::shared_ptr& encryptor, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + }; + + struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig + { + LongECIESTunnelHopConfig (std::shared_ptr r): + ECIESTunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; class TunnelConfig { @@ -154,7 +178,11 @@ namespace tunnel TunnelHopConfig * prev = nullptr; for (const auto& it: peers) { - auto hop = new TunnelHopConfig (it); + TunnelHopConfig * hop; + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + hop = new ElGamalTunnelHopConfig (it); if (prev) prev->SetNext (hop); else From aace644815dbf170b3e9e8e720b2116922de0f8a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 22:06:24 -0400 Subject: [PATCH 053/186] added ShortECIESTunnelHopConfig --- libi2pd/I2NPProtocol.h | 1 + libi2pd/TunnelConfig.cpp | 59 ++++++++++++++++++++++++++++++++-------- libi2pd/TunnelConfig.h | 12 ++++++-- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 69d6bb04..8cb68856 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -113,6 +113,7 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1; const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; + const size_t SHORT_REQUEST_RECORD_PADDING_OFFSET = SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; enum I2NPMessageType diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 6a314ec3..505f66cc 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -113,9 +113,10 @@ namespace tunnel return true; } - void ECIESTunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) + void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { + auto encryptor = ident->CreateEncryptor (nullptr); + if (!encryptor) return; uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); i2p::crypto::InitNoiseNState (*this, hepk); @@ -128,13 +129,19 @@ namespace tunnel MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, m_H, 32, - m_CK + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, len, m_H, 32, m_CK + 32, nonce, encrypted, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed"); return; } - MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) + MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) + } + + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, m_CK, nonce, clearText, len - 16, false); // decrypt } void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) @@ -158,18 +165,46 @@ namespace tunnel htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + EncryptECIES (clearText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + if (!DecryptECIES (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + { + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; + } + return true; + } + + void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + { + // fill clear text + uint8_t flag = 0; + if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; + if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE ]; + htobe32buf (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + htobe32buf (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] = flag; + memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2); + clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES + htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); + htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes + htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); + // TODO: derive layer and reply keys + // encrypt + EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); + } + + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + if (!DecryptECIES (encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f64db0b0..7d6456fd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -58,8 +58,8 @@ namespace tunnel ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; - void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); + bool DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText); }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -69,6 +69,14 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); }; + + struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig + { + ShortECIESTunnelHopConfig (std::shared_ptr r): + ECIESTunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; class TunnelConfig { From a71754273319bd12f6f92007d943f62714a49e67 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Jul 2021 07:33:28 -0400 Subject: [PATCH 054/186] update yggdrasil reseed to 0.4 --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e5640ad0..de294357 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -213,7 +213,7 @@ namespace config { "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( - "http://[324:9de3:fea4:f6ac::ace]:7070/" + "http://[324:71e:281a:9ed3::ace]:7070/" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From 9000b3df4edcbe7f2c8afd0e1e30609746311ace Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 5 Jul 2021 14:31:07 -0400 Subject: [PATCH 055/186] KDF for short tunnel build messages --- libi2pd/I2NPProtocol.cpp | 28 +++++++++++++++++++--------- libi2pd/TunnelConfig.cpp | 22 +++++++++++++++++----- libi2pd/TunnelConfig.h | 2 +- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a040e25b..6034e5f4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -622,17 +622,28 @@ namespace i2p return; } auto& noiseState = i2p::context.GetCurrentNoiseState (); - uint8_t layerKeys[64]; // (layer key, iv key) - i2p::crypto::HKDF (noiseState.m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain + uint8_t replyKey[32], layerKey[32], ivKey[32]; + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); + memcpy (replyKey, noiseState.m_CK + 32, 32); + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelLayerKey", noiseState.m_CK); + memcpy (layerKey, noiseState.m_CK + 32, 32); + bool isEndpoint = clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + if (isEndpoint) + { + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "TunnelLayerIVKey", noiseState.m_CK); + memcpy (ivKey, noiseState.m_CK + 32, 32); + } + else + memcpy (ivKey, noiseState.m_CK , 32); auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - layerKeys, layerKeys + 32, + layerKey, ivKey, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - if (clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) + if (isEndpoint) { // we are endpoint, create OutboundTunnelBuildReply auto otbrm = NewI2NPShortMessage (); @@ -658,14 +669,13 @@ 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, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; - memcpy (&tag, replyKeys + 32, 8); + memcpy (&tag, noiseState.m_CK, 8); // send garlic to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, replyKeys, tag))); + i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, noiseState.m_CK + 32, tag))); } else { @@ -680,7 +690,7 @@ 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, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); return; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 505f66cc..cc612c00 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -137,11 +137,11 @@ namespace tunnel MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) } - bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText) + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText) { uint8_t nonce[12]; memset (nonce, 0, 12); - return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, m_CK, nonce, clearText, len - 16, false); // decrypt + return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) @@ -171,7 +171,7 @@ namespace tunnel bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - if (!DecryptECIES (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (m_CK, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -196,15 +196,27 @@ namespace tunnel htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); - // TODO: derive layer and reply keys // encrypt EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); + // derive reply and layer key + i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); + memcpy (replyKey, m_CK + 32, 32); + i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelLayerKey", m_CK); + memcpy (layerKey, m_CK + 32, 32); + if (isEndpoint) + { + i2p::crypto::HKDF (m_CK, nullptr, 0, "TunnelLayerIVKey", m_CK); + memcpy (ivKey, m_CK + 32, 32); + i2p::crypto::HKDF (m_CK, nullptr, 0, "RGarlicKeyAndTag", m_CK); // OTBRM garlic key m_CK + 32, tag first 8 bytes of m_CK + } + else + memcpy (ivKey, m_CK, 32); // last HKDF memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - if (!DecryptECIES (encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (replyKey, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 7d6456fd..d4c85558 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -59,7 +59,7 @@ namespace tunnel TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); - bool DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText); + bool DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText); }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig From 4255c4901de8199ffae805ff040cb0bf54d2ad82 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 17:44:39 -0400 Subject: [PATCH 056/186] orignal's reseed ceritifcate --- contrib/certificates/{router => reseed}/orignal_at_mail.i2p.crt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/certificates/{router => reseed}/orignal_at_mail.i2p.crt (100%) diff --git a/contrib/certificates/router/orignal_at_mail.i2p.crt b/contrib/certificates/reseed/orignal_at_mail.i2p.crt similarity index 100% rename from contrib/certificates/router/orignal_at_mail.i2p.crt rename to contrib/certificates/reseed/orignal_at_mail.i2p.crt From 431265a86af2979b37ef1a1cb679b7a462a5bf15 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 18:22:08 -0400 Subject: [PATCH 057/186] update orignal's certificate --- .../reseed/orignal_at_mail.i2p.crt | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/contrib/certificates/reseed/orignal_at_mail.i2p.crt b/contrib/certificates/reseed/orignal_at_mail.i2p.crt index c1229f3b..799b601b 100644 --- a/contrib/certificates/reseed/orignal_at_mail.i2p.crt +++ b/contrib/certificates/reseed/orignal_at_mail.i2p.crt @@ -1,31 +1,32 @@ -----BEGIN CERTIFICATE----- -MIIFVDCCAzwCCQC2r1XWYtqtAzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJY -WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRMwEQYDVQQKDApQdXJwbGUgSTJQ -MQ0wCwYDVQQLDARJMlBEMR8wHQYJKoZIhvcNAQkBFhBvcmlnbmFsQG1haWwuaTJw -MB4XDTE1MDIyMjEzNTgxOFoXDTI1MDIxOTEzNTgxOFowbDELMAkGA1UEBhMCWFgx -CzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEGA1UECgwKUHVycGxlIEkyUDEN -MAsGA1UECwwESTJQRDEfMB0GCSqGSIb3DQEJARYQb3JpZ25hbEBtYWlsLmkycDCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALp3D/gdvFjrMm+IE8tHZCWE -hQ6Pp0CCgCGDBC3WQFLqR98bqVPl4UwRG/MKY/LY7Woai06JNmGcpfw0LMoNnHxT -bvKtDRe/8kQdhdLHhgIkWKSbMvTAl7uUdV6FzsPgDR0x7scoFVWEhkF0wfmzGF2V -yr/WCBQejFPu69z03m5tRQ8Xjp2txWV45RawUmFu50bgbZvLCSLfTkIvxmfJzgPN -pJ3sPa/g7TBZl2uEiAu4uaEKvTuuzStOWCGgFaHYFVlTfFXTvmhFMqHfaidtzrlu -H35WGrmIWTDl6uGPC5QkSppvkj73rDj5aEyPzWMz5DN3YeECoVSchN+OJJCM6m7+ -rLFYXghVEp2h+T9O1GBRfcHlQ2E3CrWWvxhmK8dfteJmd501dyNX2paeuIg/aPFO -54/8m2r11uyF29hgY8VWLdXtqvwhKuK36PCzofEwDp9QQX8GRsEV4pZTrn4bDhGo -kb9BF7TZTqtL3uyiRmIyBXrNNiYlA1Xm4fyKRtxl0mrPaUXdgdnCt3KxOAJ8WM2B -7L/kk9U8C/nexHbMxIZfTap49XcUg5dxSO9kOBosIOcCUms8sAzBPDV2tWAByhYF -jI/Tutbd3F0+fvcmTcIFOlGbOxKgO2SfwXjv/44g/3LMK6IAMFB9UOc8KhnnJP0f -uAHvMXn1ahRs4pM1VizLAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAIOxdaXT+wfu -nv/+1hy5T4TlRMNNsuj79ROcy6Mp+JwMG50HjTc0qTlXh8C7nHybDJn4v7DA+Nyn -RxT0J5I+Gqn+Na9TaC9mLeX/lwe8/KomyhBWxjrsyWj1V6v/cLO924S2rtcfzMDm -l3SFh9YHM1KF/R9N1XYBwtMzr3bupWDnE1yycYp1F4sMLr5SMzMQ0svQpQEM2/y5 -kly8+eUzryhm+ag9x1686uEG5gxhQ1eHQoZEaClHUOsV+28+d5If7cqcYx9Hf5Tt -CiVjJQzdxBF+6GeiJtKxnLtevqlkbyIJt6Cm9/7YIy/ovRGF2AKSYN6oCwmZQ6i1 -8nRnFq5zE7O94m+GXconWZxy0wVqA6472HThMi7S+Tk/eLYen2ilGY+KCb9a0FH5 -5MOuWSoJZ8/HfW2VeQmL8EjhWm5F2ybg28wgXK4BOGR3jQi03Fsc+AFidnWxSKo0 -aiJoPgOsfyu8/fnCcAi07kSmjzUKIWskApgcpGQLNXHFK9mtg7+VA8esRnfLlKtP -tJf+nNAPY1sqHfGBzh7WWGWal5RGHF5nEm3ta3oiFF5sMKCJ6C87zVwFkEcRytGC -xOGmiG1O1RPrO5NG7rZUaQ4y1OKl2Y1H+nGONzZ3mvoAOvxEq6JtUnU2kZscpPlk -fpeOSDoGBYJGbIpzDreBDhxaZrwGq36k +MIIFfzCCA2egAwIBAgIEbNbRPjANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY +WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt +b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEZMBcGA1UEAwwQb3JpZ25hbEBtYWls +LmkycDAeFw0yMTA3MDYyMjExMDFaFw0zMTA3MDQyMjExMDFaMHAxCzAJBgNVBAYT +AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u +eW1vdXMgTmV0d29yazEMMAoGA1UECwwDSTJQMRkwFwYDVQQDDBBvcmlnbmFsQG1h +aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvNJz2KGuAkHP +tGFobfLvpybtxB50fkcEsTc9opmiy7wBKK9rSI01VS616IhABkWKZVfK2A9NqpGv +v/CyhTKoaeSNeXY7+zORUWgWK/zA9fA4GRZFqlW8j4tbompDwcLYNqRBCsn1C0OY +YA5JhXPBixMcnXl8N8x4sXhQ4l9R3+QrydhUHRvgDc8dOxRyIX7zuQAyf8tmA2Xo +xZLdvDcCJdLBIbFwxhIceIhgcOwaOx7oRkZDZdYcLJd3zjyPbu8JtOM2ZkwH7r+0 +ro5PktuDp2LAS6SII5yYNcwcrvPZGPqhLdifIw1BrdTIb/rIkQZ5iXOOdyPmT7e8 +IwAJcPFlfvrS4Vbi9oDqyx3aDUBoubgmFnO1TirL56ck83R/ubcKtdnyzAn5dp+f +ZNYW6/foSBpDDOCViylbFAR5H0HJEbBns7PZx6mGEEI4tUAJdNYl7Ly7Df60a9Rz +cD/gz08U9UwFXYKoT6roEjToADGAzb5MI4cVlAb2AmQaMNXNe04HcDL1bU50mkNU +amqPv8nxf72fBQCEmZz2G57T6QiYTtcCwiWS1QdWsuaOtCo9zO0MKcjzSdUxuxEc +dXhjQdNegsgg/Xk7bJ8lKOsACqMpFftdPmuyeZU2t+3RPuBpV/0j2qUfg/y6kb0z +CxAOYmlcL4kqw4VT+5V/EeZLIG0h9I0CAwEAAaMhMB8wHQYDVR0OBBYEFD/wJObg +CCDuhMJCVWTSTj+B3rsUMA0GCSqGSIb3DQEBDQUAA4ICAQC0PjsTSPWlGbLNeeI8 +F0B5xAwXYJzZ7/LRxh8u42HDUqVIDjqkuls1l3v9D7htty2Gr3Ws2dcvcOr2KcOy +mEWg+jdP/N3vt9IkZeVS4YQoPgq6orn7lVkk00bcKb24f7ZnoQnnVV0/m42Y5P4j +LLh+8MBxsez9azXyZbDVEkgsMUAkdVO6KNz6scqz7wb8egV2GAMAp7cwChC6lanK +gv9ZyJhG/HdTv6VyuMZhJy6rX4geM97tm1iHu1VLsQcIzBKAdEvWJv8ofMeiyINe +hqAP9NYaeowKi975NOrmf+XZwxd0niApIohV684RCVUfL8H7HSPbdXhBJ/WslyDP +cTGhA2BLqEXZBn/nLQknlnl0SZTQxG2n4fEgD1E5YS/aoBrig/uXtWm2Zdf8U3mM ++bNXhbi9s7LneN2ye8LlNJBSRklNn/bNo8OmzLII1RQwf1+vaHT96lASbTVepMZ/ +Y9VcC8fAmho/zfQEKueLEB03K+gr2dGD+1crmMtUBjWJ9vPjtooZArtkDbh+kVYA +cx4N4NXULRwxVWZe5wTQOqcZ3qSS1ClMwaziwychGaj8xRAirHMZnlPOZO1UK4+5 +8F4RMJktyZjNgSLP76XPS4rJK5fobuPqFeA4OpDFn/5+/XeQFF6i6wntx1tzztzH +zc+BrVZOdcYPqu9iLXyRQ9JwwA== -----END CERTIFICATE----- From a6294df9e8bbfae39a71bd39fd3248699f8b41e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 20:15:55 -0400 Subject: [PATCH 058/186] decrypt one-time message encrypted with tag on router --- libi2pd/Garlic.cpp | 37 +++++++++++++++++++++---------------- libi2pd/Garlic.h | 1 + libi2pd/RouterContext.cpp | 12 ++++++++---- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 2bf89556..38eda05a 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -494,22 +494,9 @@ namespace garlic buf += 4; // length bool found = false; - uint64_t tag; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - { // try ECIESx25519 tag - memcpy (&tag, buf, 8); - auto it1 = m_ECIESx25519Tags.find (tag); - if (it1 != m_ECIESx25519Tags.end ()) - { - found = true; - if (it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) - m_LastTagset = it1->second.tagset; - else - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); - m_ECIESx25519Tags.erase (it1); - } - } + found = HandleECIESx25519TagMessage (buf, length); if (!found) { auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16 @@ -555,6 +542,7 @@ namespace garlic // try to gererate more tags for last tagset if (m_LastTagset && (m_LastTagset->GetNextIndex () - m_LastTagset->GetTrimBehind () < 3*ECIESX25519_MAX_NUM_GENERATED_TAGS)) { + uint64_t missingTag; memcpy (&missingTag, buf, 8); auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); LogPrint (eLogWarning, "Garlic: trying to generate more ECIES-X25519-AEAD-Ratchet tags"); for (int i = 0; i < maxTags; i++) @@ -565,10 +553,10 @@ namespace garlic LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for last tagset"); break; } - if (nextTag == tag) + if (nextTag == missingTag) { LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); - if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) + if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[nextTag].index)) found = true; break; } @@ -585,6 +573,23 @@ namespace garlic } } + bool GarlicDestination::HandleECIESx25519TagMessage (uint8_t * buf, size_t len) + { + uint64_t tag; + memcpy (&tag, buf, 8); + auto it = m_ECIESx25519Tags.find (tag); + if (it != m_ECIESx25519Tags.end ()) + { + if (it->second.tagset->HandleNextMessage (buf, len, it->second.index)) + m_LastTagset = it->second.tagset; + else + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + m_ECIESx25519Tags.erase (it); + return true; + } + return false; + } + void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, std::shared_ptr from) { diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 4288e74b..a898e6a1 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -260,6 +260,7 @@ namespace garlic protected: + bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b2a19890..c25f5064 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -843,10 +843,14 @@ namespace i2p return; } buf += 4; - if (m_ECIESSession) - m_ECIESSession->HandleNextMessage (buf, len); - else - LogPrint (eLogError, "Router: Session is not set for ECIES router"); + if (!HandleECIESx25519TagMessage (buf, len)) // try tag first + { + // then Noise_N one-time decryption + if (m_ECIESSession) + m_ECIESSession->HandleNextMessage (buf, len); + else + LogPrint (eLogError, "Router: Session is not set for ECIES router"); + } } else i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); From 847225c6bfa0d8e83ff27606104805b2870b93ad Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Jul 2021 08:24:01 -0400 Subject: [PATCH 059/186] more yggdrasil reseeds added --- libi2pd/Config.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index de294357..a8516e00 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -213,7 +213,9 @@ namespace config { "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( - "http://[324:71e:281a:9ed3::ace]:7070/" + "http://[324:71e:281a:9ed3::ace]:7070/," + "http://[301:65b9:c7cd:9a36::1]:18801/," + "http://[320:8936:ec1a:31f1::216]/" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From ed0c2e68a5e45f06caf5d394ff240129967c68ae Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Jul 2021 21:16:30 -0400 Subject: [PATCH 060/186] DecryptRecord per tunnel hop --- libi2pd/Tunnel.cpp | 12 ++---------- libi2pd/TunnelConfig.cpp | 37 +++++++++++++++++++++++++++++-------- libi2pd/TunnelConfig.h | 19 ++++++++++--------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 7e154cbf..84df9b56 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -78,18 +78,14 @@ namespace tunnel } // decrypt real records - i2p::crypto::CBCDecryption decryption; hop = m_Config->GetLastHop ()->prev; while (hop) { - decryption.SetKey (hop->replyKey); // decrypt records after current hop TunnelHopConfig * hop1 = hop->next; while (hop1) { - decryption.SetIV (hop->replyIV); - uint8_t * record = records + hop1->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); + hop->DecryptRecord (records, hop1->recordIndex); hop1 = hop1->next; } hop = hop->prev; @@ -132,11 +128,7 @@ namespace tunnel { auto idx = hop1->recordIndex; if (idx >= 0 && idx < msg[0]) - { - uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - decryption.SetIV (hop->replyIV); - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); - } + hop->DecryptRecord (msg + 1, idx); else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); hop1 = hop1->prev; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index cc612c00..1680a0b1 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -77,6 +77,15 @@ namespace tunnel isGateway = false; } } + + void TunnelHopConfig::DecryptRecord (uint8_t * records, int index) const + { + uint8_t * record = records + index*TUNNEL_BUILD_RECORD_SIZE; + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); + } void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { @@ -104,7 +113,7 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { i2p::crypto::CBCDecryption decryption; decryption.SetKey (replyKey); @@ -137,10 +146,8 @@ namespace tunnel MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) } - bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText) + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const { - uint8_t nonce[12]; - memset (nonce, 0, 12); return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } @@ -169,9 +176,11 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { - if (!DecryptECIES (m_CK, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -214,14 +223,26 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { - if (!DecryptECIES (replyKey, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + uint8_t nonce[12]; + memset (nonce, 0, 12); + nonce[4] = recordIndex; // nonce is record index + if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; } return true; } + + void ShortECIESTunnelHopConfig::DecryptRecord (uint8_t * records, int index) const + { + uint8_t * record = records + index*SHORT_TUNNEL_BUILD_RECORD_SIZE; + uint8_t nonce[12]; + memset (nonce, 0, 12); + nonce[4] = index; // nonce is index + i2p::crypto::ChaCha20 (record, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, record); + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index d4c85558..e356a9f0 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -42,7 +42,8 @@ namespace tunnel virtual bool IsECIES () const { return false; }; virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; - virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) = 0; + virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0; + virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; struct ElGamalTunnelHopConfig: public TunnelHopConfig @@ -50,7 +51,7 @@ namespace tunnel ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState @@ -59,7 +60,7 @@ namespace tunnel TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); - bool DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText); + bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -67,7 +68,7 @@ namespace tunnel LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -75,20 +76,21 @@ namespace tunnel ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; class TunnelConfig { public: - TunnelConfig (std::vector > peers) // inbound + TunnelConfig (const std::vector >& peers) // inbound { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } - TunnelConfig (std::vector > peers, + TunnelConfig (const std::vector >& peers, uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) // outbound { CreatePeers (peers); @@ -180,8 +182,7 @@ namespace tunnel private: - template - void CreatePeers (const Peers& peers) + void CreatePeers (const std::vector >& peers) { TunnelHopConfig * prev = nullptr; for (const auto& it: peers) From d73b42b7266233ae399cd54a949c382f755803e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 16:39:38 -0400 Subject: [PATCH 061/186] extract ret code per hop --- libi2pd/Tunnel.cpp | 13 ++++--------- libi2pd/TunnelConfig.cpp | 15 +++++++++------ libi2pd/TunnelConfig.h | 17 +++++++++++------ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 84df9b56..fe219214 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -103,26 +103,22 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); - i2p::crypto::CBCDecryption decryption; TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { // decrypt current hop - auto idx = hop->recordIndex; - if (idx >= 0 && idx < msg[0]) + if (hop->recordIndex >= 0 && hop->recordIndex < msg[0]) { - uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - if (!hop->DecryptBuildResponseRecord (record, record)) + if (!hop->DecryptBuildResponseRecord (msg + 1)) return false; } else { - LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); + LogPrint (eLogWarning, "Tunnel: hop index ", hop->recordIndex, " is out of range"); return false; } // decrypt records before current hop - decryption.SetKey (hop->replyKey); TunnelHopConfig * hop1 = hop->prev; while (hop1) { @@ -140,8 +136,7 @@ namespace tunnel hop = m_Config->GetFirstHop (); while (hop) { - const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET]; + uint8_t ret = hop->GetRetCode (msg + 1); LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret); auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ()); if (profile) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 1680a0b1..b461a3d5 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -113,12 +113,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; i2p::crypto::CBCDecryption decryption; decryption.SetKey (replyKey); decryption.SetIV (replyIV); - decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record); return true; } @@ -176,11 +177,12 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -223,12 +225,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); nonce[4] = recordIndex; // nonce is record index - if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (replyKey, nonce, record, SHORT_TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index e356a9f0..b2bf26b7 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -40,9 +40,9 @@ namespace tunnel void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - virtual bool IsECIES () const { return false; }; + virtual uint8_t GetRetCode (const uint8_t * records) const = 0; virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; - virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0; + virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; @@ -50,15 +50,16 @@ namespace tunnel { ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; @@ -67,16 +68,20 @@ namespace tunnel { LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig { ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; From 84f6024cc92182793ea974fccf791cae1dcde799 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 19:00:25 -0400 Subject: [PATCH 062/186] locate record to build inside CreateBuildRequestRecord --- libi2pd/Tunnel.cpp | 8 ++------ libi2pd/TunnelConfig.cpp | 13 ++++++++++--- libi2pd/TunnelConfig.h | 8 ++++---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index fe219214..1eb30db2 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -55,7 +55,6 @@ namespace tunnel uint8_t * records = msg->GetPayload () + 1; TunnelHopConfig * hop = m_Config->GetFirstHop (); int i = 0; - BN_CTX * ctx = BN_CTX_new (); while (hop) { uint32_t msgID; @@ -63,13 +62,10 @@ namespace tunnel RAND_bytes ((uint8_t *)&msgID, 4); else msgID = replyMsgID; - int idx = recordIndicies[i]; - hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx); - hop->recordIndex = idx; - i++; + hop->recordIndex = recordIndicies[i]; i++; + hop->CreateBuildRequestRecord (records, msgID); hop = hop->next; } - BN_CTX_free (ctx); // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index b461a3d5..948ffc01 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -87,7 +87,7 @@ namespace tunnel decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } - void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -107,9 +107,14 @@ namespace tunnel htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) + { + BN_CTX * ctx = BN_CTX_new (); encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + BN_CTX_free (ctx); + } memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } @@ -152,7 +157,7 @@ namespace tunnel return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } - void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -173,6 +178,7 @@ namespace tunnel htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } @@ -190,7 +196,7 @@ namespace tunnel return true; } - void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -208,6 +214,7 @@ namespace tunnel htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); // derive reply and layer key i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index b2bf26b7..591fed52 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -41,7 +41,7 @@ namespace tunnel void SetPrev (TunnelHopConfig * p); virtual uint8_t GetRetCode (const uint8_t * records) const = 0; - virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; + virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; @@ -52,7 +52,7 @@ namespace tunnel TunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; }; @@ -70,7 +70,7 @@ namespace tunnel ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; }; @@ -80,7 +80,7 @@ namespace tunnel ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; From c02a0c4da9f417c9958812ebd682f1abdf443f59 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 22:22:00 -0400 Subject: [PATCH 063/186] process DELAY_REQUESTED option --- libi2pd/Streaming.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3269e040..bbb649df 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -276,7 +276,20 @@ namespace stream const uint8_t * optionData = packet->GetOptionData (); size_t optionSize = packet->GetOptionSize (); if (flags & PACKET_FLAG_DELAY_REQUESTED) + { + if (!m_IsAckSendScheduled) + { + uint16_t delayRequested = bufbe16toh (optionData); + if (delayRequested > 0 && delayRequested < m_RTT) + { + m_IsAckSendScheduled = true; + m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(delayRequested)); + m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer, + shared_from_this (), std::placeholders::_1)); + } + } optionData += 2; + } if (flags & PACKET_FLAG_FROM_INCLUDED) { @@ -793,7 +806,7 @@ namespace stream if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { std::vector msgs; - for (auto it: packets) + for (const auto& it: packets) { auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage ( it->GetBuffer (), it->GetLength (), m_Port, !m_RoutingSession->IsRatchets ())); From 59dd60f5cbc458830d4f7eec30f3e4251f95347b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Jul 2021 19:24:28 -0400 Subject: [PATCH 064/186] genarate keys in CreateBuildRequestRecord --- libi2pd/TunnelConfig.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 948ffc01..930c565b 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -23,10 +23,6 @@ namespace tunnel { TunnelHopConfig::TunnelHopConfig (std::shared_ptr r) { - RAND_bytes (layerKey, 32); - RAND_bytes (ivKey, 32); - RAND_bytes (replyKey, 32); - RAND_bytes (replyIV, 16); RAND_bytes ((uint8_t *)&tunnelID, 4); if (!tunnelID) tunnelID = 1; // tunnelID can't be zero isGateway = true; @@ -89,6 +85,11 @@ namespace tunnel void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { + // generate keys + RAND_bytes (layerKey, 32); + RAND_bytes (ivKey, 32); + RAND_bytes (replyKey, 32); + RAND_bytes (replyIV, 16); // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; @@ -159,6 +160,11 @@ namespace tunnel void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { + // generate keys + RAND_bytes (layerKey, 32); + RAND_bytes (ivKey, 32); + RAND_bytes (replyKey, 32); + RAND_bytes (replyIV, 16); // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; @@ -216,7 +222,7 @@ namespace tunnel // encrypt uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); - // derive reply and layer key + // derive keys i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); memcpy (replyKey, m_CK + 32, 32); i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelLayerKey", m_CK); From d47bf1bada8621e0ac084bef8639a609f99a83b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Jul 2021 19:26:14 -0400 Subject: [PATCH 065/186] different tunnel build record size --- libi2pd/Tunnel.cpp | 7 ++++--- libi2pd/TunnelConfig.h | 14 +++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 1eb30db2..34105962 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -42,10 +42,11 @@ namespace tunnel void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { auto numHops = m_Config->GetNumHops (); - int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : MAX_NUM_RECORDS; + const int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : MAX_NUM_RECORDS; auto msg = numRecords <= STANDARD_NUM_RECORDS ? NewI2NPShortMessage () : NewI2NPMessage (); *msg->GetPayload () = numRecords; - msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; + const size_t recordSize = m_Config->IsShort () ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; + msg->len += numRecords*recordSize + 1; // shuffle records std::vector recordIndicies; for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i); @@ -70,7 +71,7 @@ namespace tunnel for (int i = numHops; i < numRecords; i++) { int idx = recordIndicies[i]; - RAND_bytes (records + idx*TUNNEL_BUILD_RECORD_SIZE, TUNNEL_BUILD_RECORD_SIZE); + RAND_bytes (records + idx*recordSize, recordSize); } // decrypt real records diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 591fed52..b33f7668 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -115,6 +115,8 @@ namespace tunnel } } + bool IsShort () const { return m_IsShort; } + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -193,10 +195,15 @@ namespace tunnel for (const auto& it: peers) { TunnelHopConfig * hop; - if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - hop = new LongECIESTunnelHopConfig (it); + if (m_IsShort) + hop = new ShortECIESTunnelHopConfig (it); else - hop = new ElGamalTunnelHopConfig (it); + { + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + hop = new ElGamalTunnelHopConfig (it); + } if (prev) prev->SetNext (hop); else @@ -209,6 +216,7 @@ namespace tunnel private: TunnelHopConfig * m_FirstHop, * m_LastHop; + bool m_IsShort = false; }; class ZeroHopsTunnelConfig: public TunnelConfig From 1e9eb30aa32b73e7a15929ecaf72e873926830ce Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 14:33:23 -0400 Subject: [PATCH 066/186] garlic encryption of inbound tunnel build message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 ++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- libi2pd/I2NPProtocol.cpp | 2 +- libi2pd/NetDb.cpp | 2 +- libi2pd/Tunnel.cpp | 6 ++++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 55e962d8..9a76ea3c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1133,7 +1133,7 @@ namespace garlic return true; } - std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -1167,5 +1167,12 @@ namespace garlic return m; } + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) + { + // TODO: implement without session + auto session = std::make_shared(nullptr, false); + session->SetRemoteStaticKey (routerPublicKey); + return session->WrapOneTimeMessage (msg, true); + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cd7b9b40..71e0a803 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -256,7 +256,8 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; }; - std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); } } diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 6034e5f4..b9b15c8d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -675,7 +675,7 @@ namespace i2p // send garlic to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, noiseState.m_CK + 32, tag))); + i2p::garlic::WrapECIESX25519Message (otbrm, noiseState.m_CK + 32, tag))); } else { diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5e93fabb..e3a55832 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -988,7 +988,7 @@ namespace data { uint64_t tag; memcpy (&tag, excluded + 33, 8); - replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); + replyMsg = i2p::garlic::WrapECIESX25519Message (replyMsg, sessionKey, tag); } else { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 34105962..63f90077 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -23,6 +23,7 @@ #include "Tunnel.h" #include "TunnelPool.h" #include "util.h" +#include "ECIESX25519AEADRatchetSession.h" namespace i2p { @@ -91,7 +92,12 @@ namespace tunnel // send message if (outboundTunnel) + { + auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; + if (ident && ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + msg = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); + } else i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); } From ba1b8c7c2b57f84ccc7fe9011688b64a5437406b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 16:15:15 -0400 Subject: [PATCH 067/186] WrapECIESX25519MessageForRouter wihout session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 108 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 8 +- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9a76ea3c..09bbfe53 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -518,36 +518,7 @@ namespace garlic } return true; } - - bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Alice, router's bpk is m_RemoteStaticKey - i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); - size_t offset = 0; - m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); - MixHash (out + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return false; - } - MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return false; - } - - m_State = eSessionStateNewSessionSent; - return true; - } - + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -858,11 +829,6 @@ namespace garlic return nullptr; len += 96; break; - case eSessionStateForRouter: - if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 48; - break; default: return nullptr; } @@ -873,9 +839,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) { - m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; + m_State = eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1132,19 +1098,10 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + + static size_t CreateGarlicCloveBlock (std::shared_ptr msg, uint8_t * payload) { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1153,14 +1110,26 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt + return cloveSize + 3; + } + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; + size_t len = CreateGarlicCloveBlock (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; - htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1169,10 +1138,39 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // TODO: implement without session - auto session = std::make_shared(nullptr, false); - session->SetRemoteStaticKey (routerPublicKey); - return session->WrapOneTimeMessage (msg, true); + // Noise_N, we are Alice, routerPublicKey is Bob's + i2p::crypto::NoiseSymmetricState noiseState; + i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); + noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return nullptr; + } + noiseState.MixKey (sharedSecret); + auto payload = buf + offset; + size_t len = CreateGarlicCloveBlock (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return nullptr; + } + offset += len + 16; + htobe32buf (m->GetPayload (), offset); + m->len += offset + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 71e0a803..762e00ef 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -147,8 +147,7 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime, - eSessionStateForRouter + eSessionStateOneTime }; struct DHRatchet @@ -166,7 +165,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -207,8 +206,7 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); From 6a467a09bd6be0800478fa68ca6fcb3c001c505e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 16:47:28 -0400 Subject: [PATCH 068/186] fixed build error --- libi2pd/Garlic.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 38eda05a..d91c75f5 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -754,11 +754,7 @@ namespace garlic std::shared_ptr msg) { if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - { - auto session = std::make_shared(this, false); - session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ()); - return session->WrapOneTimeMessage (msg, true); - } + return WrapECIESX25519MessageForRouter (msg, router->GetIdentity ()->GetEncryptionPublicKey ()); else { auto session = GetRoutingSession (router, false); From 15c3d46492cc9b04e51a210bce554b9fe40b12d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 17:28:18 -0400 Subject: [PATCH 069/186] encrypt inbound tunnel build message for short tunnel build only --- libi2pd/Tunnel.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 63f90077..6c9d59e9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -93,9 +93,15 @@ namespace tunnel // send message if (outboundTunnel) { - auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; - if (ident && ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - msg = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); + if (m_Config->IsShort ()) + { + auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; + if (ident) + { + auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); + if (msg1) msg = msg; + } + } outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); } else From 3e281d47907234110569083c4b23b24e53e1fa47 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Jul 2021 23:10:53 +0300 Subject: [PATCH 070/186] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 37c4553a..6f2d23ec 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE) [![Packaging status](https://repology.org/badge/tiny-repos/i2pd.svg)](https://repology.org/project/i2pd/versions) [![Docker Pulls](https://img.shields.io/docker/pulls/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd) +[![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd) *note: i2pd for Android can be found in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository and with Qt GUI in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository* @@ -85,6 +86,16 @@ Using i2pd See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and [example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf). +Localization +------------ + +You can help us with translation i2pd to your language using Crowdin platform! +Translation project can be found [here](https://crowdin.com/project/i2pd). + +New languages can be requested on project's [discussion page](https://crowdin.com/project/i2pd/discussions). + +Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd) + Donations --------- From dbe427d5eb43c4a5abb5d7c43be10048c39788ca Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Jul 2021 19:29:16 -0400 Subject: [PATCH 071/186] set reply code for short tunnel build messages --- libi2pd/I2NPProtocol.cpp | 22 ++++++++++++++++++++-- libi2pd/I2NPProtocol.h | 4 ++++ libi2pd/TunnelConfig.h | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b9b15c8d..6ffa1551 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -608,7 +608,24 @@ namespace i2p LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len); return; } - // TODO: check replyMsgID + auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); + if (tunnel) + { + // endpoint of inbound tunnel + LogPrint (eLogDebug, "I2NP: ShortTunnelBuild reply for tunnel ", tunnel->GetTunnelID ()); + if (tunnel->HandleTunnelBuildResponse (buf, len)) + { + LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been created"); + tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); + i2p::tunnel::tunnels.AddInboundTunnel (tunnel); + } + else + { + LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been declined"); + tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed); + } + return; + } const uint8_t * record = buf + 1; for (int i = 0; i < num; i++) { @@ -688,7 +705,8 @@ namespace i2p nonce[4] = j; // nonce is record # if (j == i) { - // TODO: fill reply + memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 8cb68856..e20a0c0d 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -115,6 +115,10 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_PADDING_OFFSET = SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; + + // ShortResponseRecord + const size_t SHORT_RESPONSE_RECORD_OPTIONS_OFFSET = 0; + const size_t SHORT_RESPONSE_RECORD_RET_OFFSET = 201; enum I2NPMessageType { diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index b33f7668..306d8a72 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -79,7 +79,7 @@ namespace tunnel ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 From 2c129b6d39607f84a8372f3d731d232f342f1b22 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Jul 2021 19:40:40 -0400 Subject: [PATCH 072/186] create and handle short tunnel build reply --- libi2pd/Garlic.cpp | 7 +++- libi2pd/Garlic.h | 3 +- libi2pd/I2NPProtocol.cpp | 87 ++++++++++++++++------------------------ libi2pd/I2NPProtocol.h | 2 +- libi2pd/Tunnel.cpp | 13 +++++- libi2pd/TunnelConfig.cpp | 8 ++++ libi2pd/TunnelConfig.h | 2 + 7 files changed, 65 insertions(+), 57 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index d91c75f5..94dadab2 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -471,8 +471,13 @@ namespace garlic { uint64_t t; memcpy (&t, tag, 8); + AddECIESx25519Key (key, t); + } + + void GarlicDestination::AddECIESx25519Key (const uint8_t * key, uint64_t tag) + { auto tagset = std::make_shared(this, key); - m_ECIESx25519Tags.emplace (t, ECIESX25519AEADRatchetIndexTagset{0, tagset}); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{0, tagset}); } bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index a898e6a1..d3d11641 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -243,7 +243,7 @@ namespace garlic std::shared_ptr msg); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag - void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag + void AddECIESx25519Key (const uint8_t * key, uint64_t tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset); @@ -260,6 +260,7 @@ namespace garlic protected: + void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 6ffa1551..07ce2518 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -660,68 +660,47 @@ namespace i2p clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + + // encrypt reply + uint8_t nonce[12]; + memset (nonce, 0, 12); + uint8_t * reply = buf + 1; + for (int j = 0; j < num; j++) + { + nonce[4] = j; // nonce is record # + if (j == i) + { + memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState.m_H, 32, replyKey, 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); + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + // send reply if (isEndpoint) { - // we are endpoint, create OutboundTunnelBuildReply - auto otbrm = NewI2NPShortMessage (); - auto payload = otbrm->GetPayload (); - payload[0] = num; // num - payload[1] = i; // slot - payload +=2; - // reply - htobe16buf (payload, 3); payload += 2; // length, TODO - memset (payload, 0, 3); payload += 3; // ClearText: no options, and zero ret code. TODO - // ShortBuildReplyRecords. Exclude ours - uint8_t * records = buf + 1; - if (i > 0) - { - memcpy (payload, records, i*SHORT_TUNNEL_BUILD_RECORD_SIZE); - payload += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; - records += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - if (i < num-1) - { - memcpy (payload, records, (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE); - payload += (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - otbrm->len += (payload - otbrm->GetPayload ()); - otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); + auto replyMsg = NewI2NPShortMessage (); + replyMsg->Concat (buf, len); + replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; memcpy (&tag, noiseState.m_CK, 8); - // send garlic to reply tunnel + // we send it to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519Message (otbrm, noiseState.m_CK + 32, tag))); - } - else - { - // we are participant, encrypt reply - uint8_t nonce[12]; - memset (nonce, 0, 12); - uint8_t * reply = buf + 1; - for (int j = 0; j < num; j++) - { - nonce[4] = j; // nonce is record # - if (j == i) - { - memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code - if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState.m_H, 32, replyKey, 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); - reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; - } + CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + } + else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } return; } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; @@ -843,6 +822,7 @@ namespace i2p HandleVariableTunnelBuildMsg (msgID, buf, size); break; case eI2NPVariableTunnelBuildReply: + case eI2NPShortTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; case eI2NPShortTunnelBuild: @@ -905,6 +885,7 @@ namespace i2p case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); break; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index e20a0c0d..a0b5802c 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -136,7 +136,7 @@ namespace i2p eI2NPVariableTunnelBuild = 23, eI2NPVariableTunnelBuildReply = 24, eI2NPShortTunnelBuild = 25, - eI2NPOutboundTunnelBuildReply = 26 + eI2NPShortTunnelBuildReply = 26 }; const uint8_t TUNNEL_BUILD_RECORD_GATEWAY_FLAG = 0x80; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 6c9d59e9..f9f5ac38 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -105,7 +105,16 @@ namespace tunnel outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); } else + { + if (m_Config->IsShort () && m_Config->GetLastHop ()) + { + // add garlic key/tag for reply + uint8_t key[32]; + uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key); + i2p::context.AddECIESx25519Key (key, tag); + } i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); + } } bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len) @@ -513,8 +522,10 @@ namespace tunnel } case eI2NPVariableTunnelBuild: case eI2NPVariableTunnelBuildReply: + case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: case eI2NPTunnelBuild: - case eI2NPTunnelBuildReply: + case eI2NPTunnelBuildReply: HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); break; default: diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 930c565b..45e8a12a 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -260,5 +260,13 @@ namespace tunnel nonce[4] = index; // nonce is index i2p::crypto::ChaCha20 (record, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, record); } + + uint64_t ShortECIESTunnelHopConfig::GetGarlicKey (uint8_t * key) const + { + uint64_t tag; + memcpy (&tag, m_CK, 8); + memcpy (key, m_CK + 32, 32); + return tag; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 306d8a72..d6441b03 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -44,6 +44,7 @@ namespace tunnel virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES + virtual uint64_t GetGarlicKey (uint8_t * key) const { return 0; }; // return tag }; struct ElGamalTunnelHopConfig: public TunnelHopConfig @@ -83,6 +84,7 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 + uint64_t GetGarlicKey (uint8_t * key) const override; }; class TunnelConfig From 41bfc7899dbf00332a74083cb86ffb251eecd11e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Jul 2021 14:46:56 -0400 Subject: [PATCH 073/186] keep own RouterInfo in netdb --- libi2pd/I2NPProtocol.cpp | 6 ++++++ libi2pd/NetDb.cpp | 24 +++++++++++++++++++++++- libi2pd/RouterContext.h | 8 ++++---- libi2pd/TunnelPool.cpp | 2 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 07ce2518..15b51e7d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -262,6 +262,12 @@ namespace i2p if (!router) // we send own RouterInfo router = context.GetSharedRouterInfo (); + if (!router->GetBuffer ()) + { + LogPrint (eLogError, "I2NP: Invalid RouterInfo buffer for DatabaseStore"); + return nullptr; + } + auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index e3a55832..b81289f3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -59,6 +59,18 @@ namespace data Reseed (); else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false)) Reseed (); // we don't have a router we can connect to. Trying to reseed + + auto it = m_RouterInfos.find (i2p::context.GetIdentHash ()); + if (it != m_RouterInfos.end ()) + { + // remove own router + m_RouterInfos.erase (it); + m_Floodfills.remove (it->second); + } + // insert own router + m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); + if (i2p::context.IsFloodfill ()) + m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ()); i2p::config::GetOption("persist.profiles", m_PersistProfiles); @@ -162,10 +174,18 @@ namespace data bool publish = false; if (m_PublishReplyToken) { + // next publishing attempt if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true; } else if (i2p::context.GetLastUpdateTime () > lastPublish || - ts - lastPublish >= NETDB_PUBLISH_INTERVAL) publish = true; + ts - lastPublish >= NETDB_PUBLISH_INTERVAL) + { + // new publish + m_PublishExcluded.clear (); + if (i2p::context.IsFloodfill ()) + m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // do publish to ourselves + publish = true; + } if (publish) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); @@ -567,8 +587,10 @@ namespace data expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL : NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; + auto own = i2p::context.GetSharedRouterInfo (); for (auto& it: m_RouterInfos) { + if (it.second == own) continue; // skip own std::string ident = it.second->GetIdentHashBase64(); std::string path = m_Storage.Path(ident); if (it.second->IsUpdated ()) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index acb33795..978490ae 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -68,11 +68,11 @@ namespace garlic void Init (); const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; - i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; }; - std::shared_ptr GetSharedRouterInfo () const + i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; }; + std::shared_ptr GetSharedRouterInfo () { - return std::shared_ptr (&m_RouterInfo, - [](const i2p::data::RouterInfo *) {}); + return std::shared_ptr (&m_RouterInfo, + [](i2p::data::RouterInfo *) {}); } std::shared_ptr GetSharedDestination () { diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index e45c6090..faa28e69 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -423,7 +423,7 @@ namespace tunnel bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) { int start = 0; - auto prevHop = i2p::context.GetSharedRouterInfo (); + std::shared_ptr prevHop = i2p::context.GetSharedRouterInfo (); if(i2p::transport::transports.RoutesRestricted()) { /** if routes are restricted prepend trusted first hop */ From 197f13f9c0e241c75f30ce75c50d0883c2089ecb Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 14:02:20 -0400 Subject: [PATCH 074/186] rollback --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 113 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 10 +- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 09bbfe53..7b3947f1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -518,7 +518,36 @@ namespace garlic } return true; } - + + bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Alice, router's bpk is m_RemoteStaticKey + i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); + size_t offset = 0; + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); + MixHash (out + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return false; + } + MixKey (sharedSecret); + uint8_t nonce[12]; + CreateNonce (0, nonce); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return false; + } + + m_State = eSessionStateNewSessionSent; + return true; + } + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -829,6 +858,11 @@ namespace garlic return nullptr; len += 96; break; + case eSessionStateForRouter: + if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 48; + break; default: return nullptr; } @@ -839,9 +873,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) { - m_State = eSessionStateOneTime; + m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1098,10 +1132,19 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - static size_t CreateGarlicCloveBlock (std::shared_ptr msg, uint8_t * payload) + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1110,26 +1153,14 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - return cloveSize + 3; - } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) - { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; - size_t len = CreateGarlicCloveBlock (msg, payload); - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt + + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; + htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1138,39 +1169,13 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // Noise_N, we are Alice, routerPublicKey is Bob's - i2p::crypto::NoiseSymmetricState noiseState; - i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - size_t offset = 0; - auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); - noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return nullptr; - } - noiseState.MixKey (sharedSecret); - auto payload = buf + offset; - size_t len = CreateGarlicCloveBlock (msg, payload); - uint8_t nonce[12]; - memset (nonce, 0, 12); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return nullptr; - } - offset += len + 16; - htobe32buf (m->GetPayload (), offset); - m->len += offset + 4; - m->FillI2NPMessageHeader (eI2NPGarlic); - return m; + // TODO: implement without session + auto session = std::make_shared(nullptr, false); + session->SetRemoteStaticKey (routerPublicKey); + return session->WrapOneTimeMessage (msg, true); } } } + + + \ No newline at end of file diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 762e00ef..68599c3e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -147,7 +147,8 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime + eSessionStateOneTime, + eSessionStateForRouter }; struct DHRatchet @@ -165,7 +166,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -206,7 +207,8 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); From a1d1a5df74536e2c5ae194beeca98c97c76b0721 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 18:18:55 -0400 Subject: [PATCH 075/186] datetime block for message for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 126 ++++++++++++---------- libi2pd/ECIESX25519AEADRatchetSession.h | 10 +- 2 files changed, 73 insertions(+), 63 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7b3947f1..a29f0ded 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -518,36 +518,7 @@ namespace garlic } return true; } - - bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Alice, router's bpk is m_RemoteStaticKey - i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); - size_t offset = 0; - m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); - MixHash (out + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return false; - } - MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return false; - } - - m_State = eSessionStateNewSessionSent; - return true; - } - + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -858,11 +829,6 @@ namespace garlic return nullptr; len += 96; break; - case eSessionStateForRouter: - if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 48; - break; default: return nullptr; } @@ -873,9 +839,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) { - m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; + m_State = eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1132,19 +1098,17 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload) { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; + size_t len = 7; + // DateTime + payload[0] = eECIESx25519BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + // I2NP + payload += len; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1153,14 +1117,34 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt + len += cloveSize + 3; + /* payload += cloveSize + 3; + // padding + uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 + payload[0] = eECIESx25519BlkPadding; + htobe16buf (payload + 1, paddingSize); + memset (payload + 3, 0, paddingSize); + len += paddingSize + 3;*/ + return len; + } + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; + size_t len = CreateGarlicPayload (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; - htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1169,13 +1153,39 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // TODO: implement without session - auto session = std::make_shared(nullptr, false); - session->SetRemoteStaticKey (routerPublicKey); - return session->WrapOneTimeMessage (msg, true); + // Noise_N, we are Alice, routerPublicKey is Bob's + i2p::crypto::NoiseSymmetricState noiseState; + i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); + noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return nullptr; + } + noiseState.MixKey (sharedSecret); + auto payload = buf + offset; + size_t len = CreateGarlicPayload (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return nullptr; + } + offset += len + 16; + htobe32buf (m->GetPayload (), offset); + m->len += offset + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; } } } - - - \ No newline at end of file diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 68599c3e..3e627fff 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2013-2021, The PurpleI2P Project * @@ -147,8 +148,7 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime, - eSessionStateForRouter + eSessionStateOneTime }; struct DHRatchet @@ -166,7 +166,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -207,8 +207,7 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); @@ -262,3 +261,4 @@ namespace garlic } #endif + From cd0751d3f172dace381483d403f208c5934afffc Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 18:30:32 -0400 Subject: [PATCH 076/186] padding block for message for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a29f0ded..8a525d19 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1108,23 +1108,23 @@ namespace garlic htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); // I2NP payload += len; - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + uint16_t cloveSize = msg->GetPayloadLength () + 10; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; - *payload = 0; payload++; // flag and delivery instructions - *payload = msg->GetTypeID (); // I2NP msg type - htobe32buf (payload + 1, msg->GetMsgID ()); // msgID - htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds - memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); + payload[0] = 0; // flag and delivery instructions + payload[1] = msg->GetTypeID (); // I2NP msg type + htobe32buf (payload + 2, msg->GetMsgID ()); // msgID + htobe32buf (payload + 6, msg->GetExpiration () / 1000); // expiration in seconds + memcpy (payload + 10, msg->GetPayload (), msg->GetPayloadLength ()); len += cloveSize + 3; - /* payload += cloveSize + 3; + payload += cloveSize; // padding uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 payload[0] = eECIESx25519BlkPadding; htobe16buf (payload + 1, paddingSize); memset (payload + 3, 0, paddingSize); - len += paddingSize + 3;*/ + len += paddingSize + 3; return len; } From 0cd9f1b0028bd0f5ae9b971b9b2d380d21848393 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 19:01:43 -0400 Subject: [PATCH 077/186] precalculate padding sizes --- libi2pd/NTCP2.cpp | 13 +++++++++++-- libi2pd/NTCP2.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index cb200b42..ed84b8e7 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -332,7 +332,8 @@ namespace transport m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), - m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false) + m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false), + m_NextPaddingSize (16) { if (in_RemoteRouter) // Alice { @@ -1058,7 +1059,15 @@ namespace transport size_t paddingSize = (msgLen*NTCP2_MAX_PADDING_RATIO)/100; if (msgLen + paddingSize + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) paddingSize = NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; if (paddingSize > len) paddingSize = len; - if (paddingSize) paddingSize = rand () % paddingSize; + if (paddingSize) + { + if (m_NextPaddingSize >= 16) + { + RAND_bytes ((uint8_t *)m_PaddingSizes, sizeof (m_PaddingSizes)); + m_NextPaddingSize = 0; + } + paddingSize = m_PaddingSizes[m_NextPaddingSize++] % paddingSize; + } buf[0] = eNTCP2BlkPadding; // blk htobe16buf (buf + 1, paddingSize); // size memset (buf + 3, 0, paddingSize); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 01ee3e34..bcee1b09 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -218,6 +218,9 @@ namespace transport bool m_IsSending; std::list > m_SendQueue; uint64_t m_NextRouterInfoResendTime; // seconds since epoch + + uint16_t m_PaddingSizes[16]; + int m_NextPaddingSize; }; class NTCP2Server: private i2p::util::RunnableServiceWithWork From 5d022c25ba8924ec09e89c8c261b0b00fdaf9e53 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 09:44:22 -0400 Subject: [PATCH 078/186] don't send datetime for one time key message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8a525d19..03c5b00e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1099,13 +1099,17 @@ namespace garlic return true; } - static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload) + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, bool datetime) { - size_t len = 7; - // DateTime - payload[0] = eECIESx25519BlkDateTime; - htobe16buf (payload + 1, 4); - htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + size_t len = 0; + if (datetime) + { + // DateTime + payload[0] = eECIESx25519BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + len = 7; + } // I2NP payload += len; uint16_t cloveSize = msg->GetPayloadLength () + 10; @@ -1120,10 +1124,10 @@ namespace garlic len += cloveSize + 3; payload += cloveSize; // padding - uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 + uint8_t paddingSize = rand () & 0x0F; // 0 - 15 payload[0] = eECIESx25519BlkPadding; htobe16buf (payload + 1, paddingSize); - memset (payload + 3, 0, paddingSize); + if (paddingSize) memset (payload + 3, 0, paddingSize); len += paddingSize + 3; return len; } @@ -1136,7 +1140,7 @@ namespace garlic size_t offset = 0; memcpy (buf + offset, &tag, 8); offset += 8; auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload); + size_t len = CreateGarlicPayload (msg, payload, false); uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt @@ -1172,7 +1176,7 @@ namespace garlic } noiseState.MixKey (sharedSecret); auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload); + size_t len = CreateGarlicPayload (msg, payload, true); uint8_t nonce[12]; memset (nonce, 0, 12); // encrypt payload From f4902e66422c829d519d163997f7a185bb7ba624 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 13:53:12 -0400 Subject: [PATCH 079/186] eligble floodfill must be reachable by ipv4 --- libi2pd/RouterInfo.cpp | 5 ++--- libi2pd/RouterInfo.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index a426d9b7..65470a88 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1163,9 +1163,8 @@ namespace data bool RouterInfo::IsEligibleFloodfill () const { - // floodfill must be reachable somehow, >= 0.9.28 and not DSA - return (IsReachable () || (m_SupportedTransports & eSSUV4)) && - m_Version >= NETDB_MIN_FLOODFILL_VERSION && + // floodfill must be reachable by ipv4, >= 0.9.28 and not DSA + return IsReachableBy (eNTCP2V4 | eSSUV4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f27a5d68..b2b6df61 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -206,7 +206,7 @@ namespace data void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; - bool IsReachableBy (SupportedTransports transport) const { return m_ReachableTransports & transport; }; + bool IsReachableBy (uint8_t transports) const { return m_ReachableTransports & transports; }; bool HasValidAddresses () const { return m_SupportedTransports; }; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; From a37cf058cd7834c207d5f8b5daca901afdc9239c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 20:12:41 -0400 Subject: [PATCH 080/186] router with expired introducer is still valid --- libi2pd/NetDb.cpp | 13 +++++++------ libi2pd/RouterInfo.cpp | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b81289f3..1f63c054 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -473,14 +473,15 @@ namespace data bool NetDb::LoadRouterInfo (const std::string & path) { auto r = std::make_shared(path); - if (r->GetRouterIdentity () && !r->IsUnreachable () && - (r->IsReachable () || !r->IsSSU (false) || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour - { + if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses ()) + { r->DeleteBuffer (); r->ClearProperties (); // properties are not used for regular routers - m_RouterInfos[r->GetIdentHash ()] = r; - if (r->IsFloodfill () && r->IsReachable ()) // floodfill must be reachable - m_Floodfills.push_back (r); + if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) + { + if (r->IsFloodfill () && r->IsEligibleFloodfill ()) + m_Floodfills.push_back (r); + } } else { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 65470a88..3feaa504 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -343,7 +343,8 @@ namespace data int numValid = 0; for (auto& it: address->ssu->introducers) { - if ((!it.iExp || ts <= it.iExp) && it.iPort > 0 && + if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT; + if (ts <= it.iExp && it.iPort > 0 && ((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ()))) numValid++; else From 6ecfe0789f4a07e9737cc53e7287802beb5e40c6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Jul 2021 18:45:08 -0400 Subject: [PATCH 081/186] don't allocate payload buffer for every single ECIESx25519 message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 81 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 11 ++- libi2pd/Garlic.h | 4 +- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 03c5b00e..9c76320b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -795,8 +795,9 @@ namespace garlic std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { - auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); - size_t len = payload.size (); + uint8_t * payload = GetOwner ()->GetPayloadBuffer (); + if (!payload) return nullptr; + size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload); if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -805,27 +806,27 @@ namespace garlic switch (m_State) { case eSessionStateEstablished: - if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewExistingSessionMessage (payload, len, buf, m->maxLen)) return nullptr; len += 24; break; case eSessionStateNew: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen)) return nullptr; len += 96; break; case eSessionStateNewSessionReceived: - if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; break; case eSessionStateNewSessionReplySent: - if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; break; case eSessionStateOneTime: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen, false)) + if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false)) return nullptr; len += 96; break; @@ -845,7 +846,7 @@ namespace garlic return WrapSingleMessage (msg); } - std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) + size_t ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first, uint8_t * payload) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 0; @@ -907,89 +908,93 @@ namespace garlic payloadLen += paddingSize + 3; } } - std::vector v(payloadLen); if (payloadLen) - { + { + if (payloadLen > I2NP_MAX_MESSAGE_SIZE) + { + LogPrint (eLogError, "Garlic: payload length ", payloadLen, " is too long"); + return 0; + } m_LastSentTimestamp = ts; size_t offset = 0; // DateTime if (first) { - v[offset] = eECIESx25519BlkDateTime; offset++; - htobe16buf (v.data () + offset, 4); offset += 2; - htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds + payload[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (payload + offset, 4); offset += 2; + htobe32buf (payload + offset, ts/1000); offset += 4; // in seconds } // LeaseSet if (leaseSet) { - offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); + offset += CreateLeaseSetClove (leaseSet, ts, payload + offset, payloadLen - offset); if (!first) { // ack request - v[offset] = eECIESx25519BlkAckRequest; offset++; - htobe16buf (v.data () + offset, 1); offset += 2; - v[offset] = 0; offset++; // flags + payload[offset] = eECIESx25519BlkAckRequest; offset++; + htobe16buf (payload + offset, 1); offset += 2; + payload[offset] = 0; offset++; // flags } } // msg if (msg) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); + offset += CreateGarlicClove (msg, payload + offset, payloadLen - offset); // ack if (m_AckRequests.size () > 0) { - v[offset] = eECIESx25519BlkAck; offset++; - htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2; + payload[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (payload + offset, m_AckRequests.size () * 4); offset += 2; for (auto& it: m_AckRequests) { - htobe16buf (v.data () + offset, it.first); offset += 2; - htobe16buf (v.data () + offset, it.second); offset += 2; + htobe16buf (payload + offset, it.first); offset += 2; + htobe16buf (payload + offset, it.second); offset += 2; } m_AckRequests.clear (); } // next keys if (m_SendReverseKey) { - v[offset] = eECIESx25519BlkNextKey; offset++; - htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; + payload[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (payload + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; + payload[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; int keyID = m_NextReceiveRatchet->keyID - 1; if (m_NextReceiveRatchet->newKey) { - v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; + payload[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; keyID++; } offset++; // flag - htobe16buf (v.data () + offset, keyID); offset += 2; // keyid + htobe16buf (payload + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) { - memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); + memcpy (payload + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); offset += 32; // public key } m_SendReverseKey = false; } if (m_SendForwardKey) { - v[offset] = eECIESx25519BlkNextKey; offset++; - htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; - if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only + payload[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (payload + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; + payload[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; + if (!m_NextSendRatchet->keyID) payload[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only offset++; // flag - htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid + htobe16buf (payload + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) { - memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32); + memcpy (payload + offset, m_NextSendRatchet->key->GetPublicKey (), 32); offset += 32; // public key } } // padding if (paddingSize) { - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + payload[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (payload + offset, paddingSize); offset += 2; + memset (payload + offset, 0, paddingSize); offset += paddingSize; } } - return v; + return payloadLen; } size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 3e627fff..aa72e4b0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -208,7 +208,7 @@ namespace garlic bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - std::vector CreatePayload (std::shared_ptr msg, bool first); + size_t CreatePayload (std::shared_ptr msg, bool first, uint8_t * payload); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 94dadab2..62e9e423 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -433,7 +433,7 @@ namespace garlic } GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default - m_NumRatchetInboundTags (0) // 0 means standard + m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard { m_Ctx = BN_CTX_new (); } @@ -441,6 +441,8 @@ namespace garlic GarlicDestination::~GarlicDestination () { BN_CTX_free (m_Ctx); + if (m_PayloadBuffer) + delete[] m_PayloadBuffer; } void GarlicDestination::CleanUp () @@ -1121,5 +1123,12 @@ namespace garlic m_ECIESx25519Sessions.erase (it); } } + + uint8_t * GarlicDestination::GetPayloadBuffer () + { + if (!m_PayloadBuffer) + m_PayloadBuffer = new uint8_t[I2NP_MAX_MESSAGE_SIZE]; + return m_PayloadBuffer; + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index d3d11641..561f4ff7 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -250,7 +250,8 @@ namespace garlic void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); - + uint8_t * GetPayloadBuffer (); + virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); virtual void SetLeaseSetUpdated (); @@ -284,6 +285,7 @@ namespace garlic std::mutex m_SessionsMutex; std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session + uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet // incoming int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; From db9223b0d57f5dc94f3fd94403348ab958eedd62 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 19 Jul 2021 17:50:55 -0400 Subject: [PATCH 082/186] set minimal version for floodfill to 0.9.38 --- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterInfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 364cae4b..ccab664b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -44,7 +44,7 @@ namespace data const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 - const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 28); // 0.9.28 + const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3feaa504..0d439dfc 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1164,7 +1164,7 @@ namespace data bool RouterInfo::IsEligibleFloodfill () const { - // floodfill must be reachable by ipv4, >= 0.9.28 and not DSA + // floodfill must be reachable by ipv4, >= 0.9.38 and not DSA return IsReachableBy (eNTCP2V4 | eSSUV4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } From bdc1107c9608da51fe69492b054c7291842af136 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 14:35:02 -0400 Subject: [PATCH 083/186] correct message type for ShortTunnelBuild --- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/TunnelConfig.h | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f9f5ac38..9f096282 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -88,7 +88,7 @@ namespace tunnel } hop = hop->prev; } - msg->FillI2NPMessageHeader (eI2NPVariableTunnelBuild); + msg->FillI2NPMessageHeader (m_Config->IsShort () ? eI2NPShortTunnelBuild : eI2NPVariableTunnelBuild); // send message if (outboundTunnel) @@ -99,7 +99,7 @@ namespace tunnel if (ident) { auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); - if (msg1) msg = msg; + if (msg1) msg = msg1; } } outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index d6441b03..76aa0b34 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -91,14 +91,17 @@ namespace tunnel { public: - TunnelConfig (const std::vector >& peers) // inbound + TunnelConfig (const std::vector >& peers, + bool isShort = false): // inbound + m_IsShort (isShort) { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } TunnelConfig (const std::vector >& peers, - uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) // outbound + uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort = false): // outbound + m_IsShort (isShort) { CreatePeers (peers); m_FirstHop->isGateway = false; @@ -185,7 +188,7 @@ namespace tunnel protected: // this constructor can't be called from outside - TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr) + TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false) { } @@ -218,7 +221,7 @@ namespace tunnel private: TunnelHopConfig * m_FirstHop, * m_LastHop; - bool m_IsShort = false; + bool m_IsShort; }; class ZeroHopsTunnelConfig: public TunnelConfig From 4807092df63499ceaa2e1f205ecc83a8ad812c6e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 15:17:58 -0400 Subject: [PATCH 084/186] fixed typo --- libi2pd/I2NPProtocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 15b51e7d..48b4a34c 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -704,7 +704,7 @@ namespace i2p i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); } else - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); return; From c2334db8f8f51494678be698c8557f1992865790 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 18:02:48 -0400 Subject: [PATCH 085/186] correct reply key for short tunnel build record --- libi2pd/I2NPProtocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 48b4a34c..9c71632a 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -686,7 +686,7 @@ namespace i2p } } else - i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply); + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply); reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } // send reply From 0b14c810fbd9453259acc68a567a822c1a517166 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 19:38:36 -0400 Subject: [PATCH 086/186] handle ShortTunnelBuildReply --- libi2pd/I2NPProtocol.cpp | 27 +++++++++++++++------------ libi2pd/I2NPProtocol.h | 6 ------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 9c71632a..1123407d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -381,7 +381,7 @@ namespace i2p return g_MaxNumTransitTunnels; } - bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) + static bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) { @@ -470,7 +470,7 @@ namespace i2p return false; } - void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { int num = buf[0]; LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); @@ -540,7 +540,7 @@ namespace i2p } } - void HandleTunnelBuildMsg (uint8_t * buf, size_t len) + static void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { if (i2p::context.IsECIES ()) { @@ -570,13 +570,14 @@ namespace i2p } } - void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len, bool isShort) { int num = buf[0]; - LogPrint (eLogDebug, "I2NP: VariableTunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); - if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1) + LogPrint (eLogDebug, "I2NP: TunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); + size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; + if (len < num*recordSize + 1) { - LogPrint (eLogError, "I2NP: VaribleTunnelBuildReply message of ", num, " records is too short ", len); + LogPrint (eLogError, "I2NP: TunnelBuildReply message of ", num, " records is too short ", len); return; } @@ -600,7 +601,7 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Pending tunnel for message ", replyMsgID, " not found"); } - void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { if (!i2p::context.IsECIES ()) { @@ -827,12 +828,14 @@ namespace i2p case eI2NPVariableTunnelBuild: HandleVariableTunnelBuildMsg (msgID, buf, size); break; - case eI2NPVariableTunnelBuildReply: - case eI2NPShortTunnelBuildReply: - HandleVariableTunnelBuildReplyMsg (msgID, buf, size); - break; case eI2NPShortTunnelBuild: HandleShortTunnelBuildMsg (msgID, buf, size); + break; + case eI2NPVariableTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, buf, size, false); + break; + case eI2NPShortTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, buf, size, true); break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index a0b5802c..32aebbb2 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -304,12 +304,6 @@ namespace tunnel std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken = 0, std::shared_ptr replyTunnel = nullptr); bool IsRouterInfoMsg (std::shared_ptr msg); - bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText); - void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleTunnelBuildMsg (uint8_t * buf, size_t len); - std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf); std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint); From 5cb1f5986dc3e5a29e2a8e4ccf3ba2f287ae848b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 22:00:06 -0400 Subject: [PATCH 087/186] use msgID from ECIESx25519 block --- libi2pd/Destination.cpp | 5 +++-- libi2pd/Destination.h | 2 +- libi2pd/Garlic.cpp | 10 ++++++---- libi2pd/Garlic.h | 2 +- libi2pd/RouterContext.cpp | 4 ++-- libi2pd/RouterContext.h | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 7bcfe111..62f8ed26 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -345,10 +345,11 @@ namespace client void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) { I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]); - LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); + uint32_t msgID = bufbe32toh (buf + I2NP_HEADER_MSGID_OFFSET); + LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID); } - bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) + bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { switch (typeID) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 6695796d..2effff27 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -144,7 +144,7 @@ namespace client // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID); void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 62e9e423..e5b74624 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1044,10 +1044,11 @@ namespace garlic { LogPrint (eLogDebug, "Garlic: type local"); I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid - buf += (4 + 4); // msgID + expiration + int32_t msgID = bufbe32toh (buf); buf += 4; // msgID + buf += 4; // expiration ptrdiff_t offset = buf - buf1; if (offset <= (int)len) - HandleCloveI2NPMessage (typeID, buf, len - offset); + HandleCloveI2NPMessage (typeID, buf, len - offset, msgID); else LogPrint (eLogError, "Garlic: clove is too long"); break; @@ -1066,13 +1067,14 @@ namespace garlic } uint32_t gwTunnel = bufbe32toh (buf); buf += 4; I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid - buf += (4 + 4); // msgID + expiration + uint32_t msgID = bufbe32toh (buf); buf += 4; // msgID + buf += 4; // expiration offset += 13; if (GetTunnelPool ()) { auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); if (tunnel) - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID)); else LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 561f4ff7..b150e78d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -264,7 +264,7 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only - virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; + virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c25f5064..edabcdfa 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -821,9 +821,9 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); } - bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) + bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { - auto msg = CreateI2NPMessage (typeID, payload, len); + auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); return true; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 978490ae..b52e20d9 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -154,7 +154,7 @@ namespace garlic // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID); private: From cfbf5862f9643b6b74e5d90b6487eaa402dc7073 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 13:08:12 -0400 Subject: [PATCH 088/186] set pool for tunnel before build --- libi2pd/Tunnel.cpp | 24 +++++++++++++++--------- libi2pd/Tunnel.h | 7 ++++--- libi2pd/TunnelPool.cpp | 17 ++++++----------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 9f096282..d0aaa482 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -111,7 +111,10 @@ namespace tunnel // add garlic key/tag for reply uint8_t key[32]; uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key); - i2p::context.AddECIESx25519Key (key, tag); + if (m_Pool && m_Pool->GetLocalDestination ()) + m_Pool->GetLocalDestination ()->AddECIESx25519Key (key, tag); + else + i2p::context.AddECIESx25519Key (key, tag); } i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); } @@ -710,7 +713,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); CreateTunnel ( std::make_shared (std::vector > { router->GetRouterIdentity () }, - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) + inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()), nullptr ); } } @@ -786,7 +789,7 @@ namespace tunnel } LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel"); CreateTunnel ( - std::make_shared (std::vector > { router->GetRouterIdentity () }) + std::make_shared (std::vector > { router->GetRouterIdentity () }), nullptr ); } } @@ -832,9 +835,11 @@ namespace tunnel } template - std::shared_ptr Tunnels::CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + std::shared_ptr Tunnels::CreateTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel) { auto newTunnel = std::make_shared (config); + newTunnel->SetTunnelPool (pool); uint32_t replyMsgID; RAND_bytes ((uint8_t *)&replyMsgID, 4); AddPendingTunnel (replyMsgID, newTunnel); @@ -842,18 +847,19 @@ namespace tunnel return newTunnel; } - std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel) { if (config) - return CreateTunnel(config, outboundTunnel); + return CreateTunnel(config, pool, outboundTunnel); else return CreateZeroHopsInboundTunnel (); } - std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config) + std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool) { if (config) - return CreateTunnel(config); + return CreateTunnel(config, pool); else return CreateZeroHopsOutboundTunnel (); } @@ -889,7 +895,7 @@ namespace tunnel { // build symmetric outbound tunnel CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), - newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), + newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), nullptr, GetNextOutboundTunnel ()); } else diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index f30eab14..c85b734b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -205,8 +205,8 @@ namespace tunnel void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); - std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel); - std::shared_ptr CreateOutboundTunnel (std::shared_ptr config); + std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr pool, std::shared_ptr outboundTunnel); + std::shared_ptr CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool); void PostTunnelData (std::shared_ptr msg); void PostTunnelData (const std::vector >& msgs); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); @@ -219,7 +219,8 @@ namespace tunnel private: template - std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); + std::shared_ptr CreateTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel = nullptr); template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index faa28e69..8abab3d6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -526,8 +526,7 @@ namespace tunnel std::reverse (peers.begin (), peers.end ()); config = std::make_shared (peers); } - auto tunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); - tunnel->SetTunnelPool (shared_from_this ()); + auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } @@ -551,10 +550,9 @@ namespace tunnel { config = std::make_shared(tunnel->GetPeers ()); } - if (m_NumInboundHops == 0 || config) + if (!m_NumInboundHops || config) { - auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); - newTunnel->SetTunnelPool (shared_from_this()); + auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); } @@ -574,8 +572,7 @@ namespace tunnel std::shared_ptr config; if (m_NumOutboundHops > 0) config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); - auto tunnel = tunnels.CreateOutboundTunnel (config); - tunnel->SetTunnelPool (shared_from_this ()); + auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } @@ -606,8 +603,7 @@ namespace tunnel } if (!m_NumOutboundHops || config) { - auto newTunnel = tunnels.CreateOutboundTunnel (config); - newTunnel->SetTunnelPool (shared_from_this ()); + auto newTunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); } @@ -621,8 +617,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); auto tunnel = tunnels.CreateInboundTunnel ( m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers ()) : nullptr, - outboundTunnel); - tunnel->SetTunnelPool (shared_from_this ()); + shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } From 911ab9813e76098b39435b6d2b3a9f6bf5767a0f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 14:55:38 -0400 Subject: [PATCH 089/186] handle encrypteed I2NPShortTunnelBuildReply in destination --- libi2pd/Destination.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 62f8ed26..bc6ca31e 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -366,6 +366,9 @@ namespace client case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (payload, len); break; + case eI2NPShortTunnelBuildReply: // might come as garlic encrypted + i2p::HandleI2NPMessage (CreateI2NPMessage (typeID, payload, len, msgID)); + break; default: LogPrint (eLogWarning, "Destination: Unexpected I2NP message type ", typeID); return false; From f28024cfe849a1eb54f716df8671982d551392e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 18:12:37 -0400 Subject: [PATCH 090/186] decline transit tunnels from short tunnel build message --- libi2pd/I2NPProtocol.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 1123407d..5c6e6e02 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -645,6 +645,11 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); return; } + if (clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE]) // not AES + { + LogPrint (eLogWarning, "I2NP: Unknown layer encryption type ", clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE], " in short request record"); + return; + } auto& noiseState = i2p::context.GetCurrentNoiseState (); uint8_t replyKey[32], layerKey[32], ivKey[32]; i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); @@ -659,15 +664,27 @@ namespace i2p } else memcpy (ivKey, noiseState.m_CK , 32); - auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( - bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), - clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - layerKey, ivKey, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); - i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - + + // check if we accept this tunnel + uint8_t retCode = 0; + if (!i2p::context.AcceptsTunnels () || + i2p::tunnel::tunnels.GetTransitTunnels ().size () > g_MaxNumTransitTunnels || + i2p::transport::transports.IsBandwidthExceeded () || + i2p::transport::transports.IsTransitBandwidthExceeded ()) + retCode = 30; + if (!retCode) + { + // create new transit tunnel + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( + bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), + clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + layerKey, ivKey, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); + i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + } + // encrypt reply uint8_t nonce[12]; memset (nonce, 0, 12); @@ -678,7 +695,7 @@ namespace i2p if (j == i) { memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = retCode; if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { From 7078ca53c32f3619d5b61bb3aeaf62778d478dbd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:23:05 +0000 Subject: [PATCH 091/186] [debian] update patch for upnp --- debian/patches/02-upnp.patch | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 7b9bb317..5098b098 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -6,12 +6,12 @@ Last-Update: 2021-01-16 --- i2pd.orig/Makefile +++ i2pd/Makefile -@@ -15,7 +15,7 @@ include filelist.mk - USE_AESNI := yes - USE_STATIC := no - USE_MESHNET := no --USE_UPNP := no -+USE_UPNP := yes - DEBUG := yes - +@@ -21,7 +21,7 @@ include filelist.mk + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) + ifeq ($(DEBUG),yes) From 445c5f47ae58abe33dbc4be11c9cb6f09c8610cc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:24:42 +0000 Subject: [PATCH 092/186] [debian] update patch for upnp --- debian/patches/02-upnp.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 5098b098..379b2f60 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -13,5 +13,5 @@ Last-Update: 2021-01-16 -USE_UPNP := $(or $(USE_UPNP),no) +USE_UPNP := $(or $(USE_UPNP),yes) DEBUG := $(or $(DEBUG),yes) - + ifeq ($(DEBUG),yes) From 28369faa0079eaf610557e5fd9ffc41a7e8dc60f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:35:58 +0000 Subject: [PATCH 093/186] [debian] fix tabulation in patch --- debian/patches/02-upnp.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 379b2f60..75ea2bfa 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -7,11 +7,11 @@ Last-Update: 2021-01-16 --- i2pd.orig/Makefile +++ i2pd/Makefile @@ -21,7 +21,7 @@ include filelist.mk - USE_AESNI := $(or $(USE_AESNI),yes) - USE_STATIC := $(or $(USE_STATIC),no) - USE_MESHNET := $(or $(USE_MESHNET),no) --USE_UPNP := $(or $(USE_UPNP),no) -+USE_UPNP := $(or $(USE_UPNP),yes) - DEBUG := $(or $(DEBUG),yes) + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) ifeq ($(DEBUG),yes) From c153471c4980e5d0b29808d9c2a63a5600c9d663 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Jul 2021 20:58:35 -0400 Subject: [PATCH 094/186] use short tunnel build if possible --- libi2pd/NetDb.hpp | 1 + libi2pd/TunnelPool.cpp | 63 +++++++++++++++++++-------- libi2pd/TunnelPool.h | 18 +++++--- libi2pd_client/MatchedDestination.cpp | 10 ++--- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index ccab664b..c52be02b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -45,6 +45,7 @@ namespace data const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 + const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 8abab3d6..614a04f0 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -24,6 +24,22 @@ namespace i2p { namespace tunnel { + void Path::Add (std::shared_ptr r) + { + if (r) + { + peers.push_back (r->GetRouterIdentity ()); + if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION || + r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + isShort = false; + } + } + + void Path::Reverse () + { + std::reverse (peers.begin (), peers.end ()); + } + TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), @@ -420,7 +436,7 @@ namespace tunnel return hop; } - bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) + bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop) { int start = 0; std::shared_ptr prevHop = i2p::context.GetSharedRouterInfo (); @@ -429,7 +445,7 @@ namespace tunnel /** if routes are restricted prepend trusted first hop */ auto hop = i2p::transport::transports.GetRestrictedPeer(); if(!hop) return false; - peers.push_back(hop->GetRouterIdentity()); + path.Add (hop); prevHop = hop; start++; } @@ -441,7 +457,7 @@ namespace tunnel (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { prevHop = r; - peers.push_back (r->GetRouterIdentity ()); + path.Add (r); start++; } } @@ -466,12 +482,12 @@ namespace tunnel if (hop1) hop = hop1; } prevHop = hop; - peers.push_back (hop->GetRouterIdentity ()); + path.Add (hop); } return true; } - bool TunnelPool::SelectPeers (std::vector >& peers, bool isInbound) + bool TunnelPool::SelectPeers (Path& path, bool isInbound) { int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; // peers is empty @@ -480,14 +496,14 @@ namespace tunnel { std::lock_guard lock(m_CustomPeerSelectorMutex); if (m_CustomPeerSelector) - return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); + return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } // explicit peers in use - if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); - return StandardSelectPeers(peers, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); + if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); + return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } - bool TunnelPool::SelectExplicitPeers (std::vector >& peers, bool isInbound) + bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { int size = m_ExplicitPeers->size (); std::vector peerIndicies; @@ -500,7 +516,7 @@ namespace tunnel auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; auto r = i2p::data::netdb.FindRouter (ident); if (r) - peers.push_back (r->GetRouterIdentity ()); + path.Add (r); else { LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ()); @@ -517,14 +533,14 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); - std::vector > peers; - if (SelectPeers (peers, true)) + Path path; + if (SelectPeers (path, true)) { std::shared_ptr config; if (m_NumInboundHops > 0) { - std::reverse (peers.begin (), peers.end ()); - config = std::make_shared (peers); + path.Reverse (); + config = std::make_shared (path.peers, path.isShort); } auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops @@ -566,14 +582,23 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); - std::vector > peers; - if (SelectPeers (peers, false)) + Path path; + if (SelectPeers (path, false)) { std::shared_ptr config; if (m_NumOutboundHops > 0) - config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); - auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); - if (tunnel->IsEstablished ()) // zero hops + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort); + + std::shared_ptr tunnel; + if (path.isShort) + { + // TODO: implement it better + tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); + tunnel->SetTunnelPool (shared_from_this ()); + } + else + tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); + if (tunnel && tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } else diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 164ca7a1..97ca0419 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -36,7 +36,14 @@ namespace tunnel class OutboundTunnel; typedef std::shared_ptr Peer; - typedef std::vector Path; + struct Path + { + std::vector peers; + bool isShort = true; + + void Add (std::shared_ptr r); + void Reverse (); + }; /** interface for custom tunnel peer selection algorithm */ struct ITunnelPeerSelector @@ -47,9 +54,8 @@ namespace tunnel typedef std::function(std::shared_ptr, bool)> SelectHopFunc; - // standard peer selection algorithm - bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop); - + bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); + class TunnelPool: public std::enable_shared_from_this // per local destination { public: @@ -114,8 +120,8 @@ namespace tunnel void CreatePairedInboundTunnel (std::shared_ptr outboundTunnel); template typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; - bool SelectPeers (std::vector >& hops, bool isInbound); - bool SelectExplicitPeers (std::vector >& hops, bool isInbound); + bool SelectPeers (Path& path, bool isInbound); + bool SelectExplicitPeers (Path& path, bool isInbound); private: diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index c0766096..8d17632b 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -79,23 +79,23 @@ namespace client if(!inbound && m_RemoteLeaseSet) { if(m_RemoteLeaseSet->IsExpired()) - { ResolveCurrentLeaseSet(); - } if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired()) { // remote lease set is good auto leases = m_RemoteLeaseSet->GetNonExpiredLeases(); // pick lease std::shared_ptr obep; - while(!obep && leases.size() > 0) { + while(!obep && leases.size() > 0) + { auto idx = rand() % leases.size(); auto lease = leases[idx]; obep = i2p::data::netdb.FindRouter(lease->tunnelGateway); leases.erase(leases.begin()+idx); } - if(obep) { - path.push_back(obep->GetRouterIdentity()); + if(obep) + { + path.Add (obep); LogPrint(eLogDebug, "Destination: found OBEP matching IBGW"); } else LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel"); From c7234f705a5a74dc5169ae5d0847c2376d368b5e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Jul 2021 18:34:51 -0400 Subject: [PATCH 095/186] let NTCP sync through ipv6 --- libi2pd/Timestamp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 3cd336ed..4664061f 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -60,14 +60,14 @@ namespace util { LogPrint (eLogInfo, "Timestamp: NTP request to ", address); boost::asio::io_service service; - boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp"); boost::system::error_code ec; - auto it = boost::asio::ip::udp::resolver (service).resolve (query, ec); + auto it = boost::asio::ip::udp::resolver (service).resolve ( + boost::asio::ip::udp::resolver::query (address, "ntp"), ec); if (!ec && it != boost::asio::ip::udp::resolver::iterator()) { auto ep = (*it).endpoint (); // take first one boost::asio::ip::udp::socket socket (service); - socket.open (boost::asio::ip::udp::v4 (), ec); + socket.open (ep.protocol (), ec); if (!ec) { uint8_t buf[48];// 48 bytes NTP request/response @@ -103,7 +103,7 @@ namespace util LogPrint (eLogError, "Timestamp: Couldn't open UDP socket"); } else - LogPrint (eLogError, "Timestamp: Couldn't resove address ", address); + LogPrint (eLogError, "Timestamp: Couldn't resolve address ", address); } NTPTimeSync::NTPTimeSync (): m_IsRunning (false), m_Timer (m_Service) From 26d5ced2efce37eb80662bcc7984eca36dd361dc Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Jul 2021 20:28:55 -0400 Subject: [PATCH 096/186] optimal padding for one-time messages --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9c76320b..8faf1cd9 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1104,7 +1104,8 @@ namespace garlic return true; } - static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, bool datetime) + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, + bool datetime, size_t optimalSize) { size_t len = 0; if (datetime) @@ -1129,11 +1130,20 @@ namespace garlic len += cloveSize + 3; payload += cloveSize; // padding - uint8_t paddingSize = rand () & 0x0F; // 0 - 15 - payload[0] = eECIESx25519BlkPadding; - htobe16buf (payload + 1, paddingSize); - if (paddingSize) memset (payload + 3, 0, paddingSize); - len += paddingSize + 3; + int delta = (int)optimalSize - (int)len; + if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size + { + uint8_t paddingSize = rand () & 0x0F; // 0 - 15 + if (delta > 3) + { + delta -= 3; + if (paddingSize > delta) paddingSize %= delta; + } + payload[0] = eECIESx25519BlkPadding; + htobe16buf (payload + 1, paddingSize); + if (paddingSize) memset (payload + 3, 0, paddingSize); + len += paddingSize + 3; + } return len; } @@ -1145,7 +1155,7 @@ namespace garlic size_t offset = 0; memcpy (buf + offset, &tag, 8); offset += 8; auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload, false); + size_t len = CreateGarlicPayload (msg, payload, false, 956); // 1003 - 8 tag - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 3 local tunnel delivery uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt @@ -1181,7 +1191,7 @@ namespace garlic } noiseState.MixKey (sharedSecret); auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload, true); + size_t len = CreateGarlicPayload (msg, payload, true, 900); // 1003 - 32 eph key - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 35 router tunnel delivery uint8_t nonce[12]; memset (nonce, 0, 12); // encrypt payload From cd8e8970deb28a87d2d3b554d62139c351dfe032 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Jul 2021 16:01:11 -0400 Subject: [PATCH 097/186] NTP request through compatible address --- libi2pd/Timestamp.cpp | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 4664061f..ec0c25f2 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -16,6 +16,7 @@ #include #include "Config.h" #include "Log.h" +#include "RouterContext.h" #include "I2PEndian.h" #include "Timestamp.h" #include "util.h" @@ -63,9 +64,38 @@ namespace util boost::system::error_code ec; auto it = boost::asio::ip::udp::resolver (service).resolve ( boost::asio::ip::udp::resolver::query (address, "ntp"), ec); - if (!ec && it != boost::asio::ip::udp::resolver::iterator()) + if (!ec) { - auto ep = (*it).endpoint (); // take first one + bool found = false; + boost::asio::ip::udp::resolver::iterator end; + boost::asio::ip::udp::endpoint ep; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + { + if (i2p::context.SupportsV4 ()) found = true; + } + else if (ep.address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (i2p::context.SupportsMesh ()) found = true; + } + else if (i2p::context.SupportsV6 ()) found = true; + } + } + if (found) break; + it++; + } + if (!found) + { + LogPrint (eLogError, "Timestamp: can't find compatible address for ", address); + return; + } + boost::asio::ip::udp::socket socket (service); socket.open (ep.protocol (), ec); if (!ec) From 99c7d5c23a08526357d3cdf97b1af8a656297139 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Jul 2021 22:30:54 -0400 Subject: [PATCH 098/186] don't create enryptor for ECIES record encryption --- libi2pd/TunnelConfig.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 45e8a12a..543ba0fa 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -131,17 +131,14 @@ namespace tunnel void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { - auto encryptor = ident->CreateEncryptor (nullptr); - if (!encryptor) return; - uint8_t hepk[32]; - encryptor->Encrypt (nullptr, hepk, nullptr, false); - i2p::crypto::InitNoiseNState (*this, hepk); + if (!ident) return; + i2p::crypto::InitNoiseNState (*this, ident->GetEncryptionPublicKey ()); auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); memcpy (encrypted, ephemeralKeys->GetPublicKey (), 32); MixHash (encrypted, 32); // h = SHA256(h || sepk) encrypted += 32; uint8_t sharedSecret[32]; - ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) + ephemeralKeys->Agree (ident->GetEncryptionPublicKey (), sharedSecret); // x25519(sesk, hepk) MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); From a6937c792fba9c3736fdd5c6b39c70498e74136f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Jul 2021 17:51:32 -0400 Subject: [PATCH 099/186] more precise router selection --- libi2pd/NetDb.cpp | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 1f63c054..c8d8dc38 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1223,24 +1223,34 @@ namespace data { if (m_RouterInfos.empty()) return 0; - uint32_t ind = rand () % m_RouterInfos.size (); - for (int j = 0; j < 2; j++) + std::unique_lock l(m_RouterInfosMutex); + auto ind = rand () % m_RouterInfos.size (); + auto it = m_RouterInfos.begin (); + std::advance (it, ind); + // try random router + if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) + return it->second; + // try closest routers + auto it1 = it; it1++; + // forward + while (it1 != m_RouterInfos.end ()) { - uint32_t i = 0; - std::unique_lock l(m_RouterInfosMutex); - for (const auto& it: m_RouterInfos) + if (!it1->second->IsUnreachable () && filter (it1->second)) + return it1->second; + it1++; + } + // still not found, try from the beginning + if (ind) + { + it1 = m_RouterInfos.begin (); + while (it1 != it || it1 != m_RouterInfos.end ()) { - if (i >= ind) - { - if (!it.second->IsUnreachable () && filter (it.second)) - return it.second; - } - else - i++; - } - // we couldn't find anything, try second pass - ind = 0; - } + if (!it1->second->IsUnreachable () && filter (it1->second)) + return it1->second; + it1++; + } + } + return nullptr; // seems we have too few routers } From 513493fa78973bb81540bd1d39145f1b48963335 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Jul 2021 18:46:29 -0400 Subject: [PATCH 100/186] fixed typo --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index c8d8dc38..429d06b2 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1243,10 +1243,10 @@ namespace data if (ind) { it1 = m_RouterInfos.begin (); - while (it1 != it || it1 != m_RouterInfos.end ()) + while (it1 != it && it1 != m_RouterInfos.end ()) { if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; + return it1->second; it1++; } } From e68cff8bba374a2d06478a6732886cf76b452afe Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Jul 2021 18:35:30 -0400 Subject: [PATCH 101/186] try routers before random router --- libi2pd/NetDb.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 429d06b2..edbd7800 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1230,25 +1230,38 @@ namespace data // try random router if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) return it->second; - // try closest routers + // try routers after auto it1 = it; it1++; - // forward while (it1 != m_RouterInfos.end ()) { if (!it1->second->IsUnreachable () && filter (it1->second)) return it1->second; it1++; } - // still not found, try from the beginning + // still not found, try some routers before if (ind) { + ind = rand () % ind; it1 = m_RouterInfos.begin (); - while (it1 != it && it1 != m_RouterInfos.end ()) + std::advance (it1, ind); + auto it2 = it1; + while (it2 != it && it2 != m_RouterInfos.end ()) { - if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; - it1++; - } + if (!it2->second->IsUnreachable () && filter (it2->second)) + return it2->second; + it2++; + } + if (ind) + { + // still not found, try from the begining + it2 = m_RouterInfos.begin (); + while (it2 != it1 && it2 != m_RouterInfos.end ()) + { + if (!it2->second->IsUnreachable () && filter (it2->second)) + return it2->second; + it2++; + } + } } return nullptr; // seems we have too few routers From 9a3c22f47d42b88a6ff42ee7d4cb70b856d6decf Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 15:06:24 -0400 Subject: [PATCH 102/186] don't encrypt ShortTunnelBuild and ShortTunnelBuildReply if on the same router --- libi2pd/I2NPProtocol.cpp | 30 ++++++++++++++++++++++-------- libi2pd/Tunnel.cpp | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5c6e6e02..54924451 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -709,17 +709,31 @@ namespace i2p } // send reply if (isEndpoint) - { + { auto replyMsg = NewI2NPShortMessage (); replyMsg->Concat (buf, len); replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); - i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); - uint64_t tag; - memcpy (&tag, noiseState.m_CK, 8); - // we send it to reply tunnel - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (), + clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local? + { + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); + uint64_t tag; + memcpy (&tag, noiseState.m_CK, 8); + // we send it to reply tunnel + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + } + else + { + // IBGW is local + uint32_t tunnelID = bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET); + auto tunnel = i2p::tunnel::tunnels.GetTunnel (tunnelID); + if (tunnel) + tunnel->SendTunnelDataMsg (replyMsg); + else + LogPrint (eLogWarning, "I2NP: Tunnel ", tunnelID, " not found for short tunnel build reply"); + } } else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index d0aaa482..54b24d37 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -96,7 +96,7 @@ namespace tunnel if (m_Config->IsShort ()) { auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; - if (ident) + if (ident && ident->GetIdentHash () != outboundTunnel->GetNextIdentHash ()) // don't encrypt if IBGW = OBEP { auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); if (msg1) msg = msg1; From f8623b612148c490a9148d91d916226e10646da6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 19:08:55 -0400 Subject: [PATCH 103/186] consistent path for explicit peers --- libi2pd/TunnelPool.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 614a04f0..1745ebb8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -505,15 +505,12 @@ namespace tunnel bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { - int size = m_ExplicitPeers->size (); - std::vector peerIndicies; - for (int i = 0; i < size; i++) peerIndicies.push_back(i); - std::shuffle (peerIndicies.begin(), peerIndicies.end(), std::mt19937(std::random_device()())); - int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; + if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); + if (!numHops) return false; for (int i = 0; i < numHops; i++) { - auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; + auto& ident = (*m_ExplicitPeers)[i]; auto r = i2p::data::netdb.FindRouter (ident); if (r) path.Add (r); From 7a55d1fc38451c40ec4c215106a85ee0b8954e95 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 21:14:03 -0400 Subject: [PATCH 104/186] don't insert garlic tag for short tunnel build reply if the same router --- libi2pd/Tunnel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 54b24d37..416519a4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -106,7 +106,8 @@ namespace tunnel } else { - if (m_Config->IsShort () && m_Config->GetLastHop ()) + if (m_Config->IsShort () && m_Config->GetLastHop () && + m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent) { // add garlic key/tag for reply uint8_t key[32]; From b16b753ed2e1d47702072fd6d8f5d935ab8a8fbb Mon Sep 17 00:00:00 2001 From: TomasGl Date: Fri, 30 Jul 2021 17:49:19 +0300 Subject: [PATCH 105/186] Change default irc server to IRC ILITA (#1677) --- contrib/tunnels.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/tunnels.conf b/contrib/tunnels.conf index 3358ffc4..55723c43 100644 --- a/contrib/tunnels.conf +++ b/contrib/tunnels.conf @@ -1,16 +1,16 @@ -[IRC-IRC2P] +[IRC-ILITA] type = client address = 127.0.0.1 port = 6668 -destination = irc.postman.i2p +destination = irc.ilita.i2p destinationport = 6667 keys = irc-keys.dat -#[IRC-ILITA] +#[IRC-IRC2P] #type = client #address = 127.0.0.1 #port = 6669 -#destination = irc.ilita.i2p +#destination = irc.postman.i2p #destinationport = 6667 #keys = irc-keys.dat From 1e01c30e63b45c3ccf9bb1b1189d485509426c12 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 30 Jul 2021 14:12:50 -0400 Subject: [PATCH 106/186] set pool for zero-hops tunnels --- libi2pd/Tunnel.cpp | 14 ++++++++------ libi2pd/Tunnel.h | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 416519a4..f1f0d087 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -763,8 +763,8 @@ namespace tunnel if (m_InboundTunnels.empty ()) { LogPrint (eLogDebug, "Tunnel: Creating zero hops inbound tunnel"); - CreateZeroHopsInboundTunnel (); - CreateZeroHopsOutboundTunnel (); + CreateZeroHopsInboundTunnel (nullptr); + CreateZeroHopsOutboundTunnel (nullptr); if (!m_ExploratoryPool) { int ibLen; i2p::config::GetOption("exploratory.inbound.length", ibLen); @@ -854,7 +854,7 @@ namespace tunnel if (config) return CreateTunnel(config, pool, outboundTunnel); else - return CreateZeroHopsInboundTunnel (); + return CreateZeroHopsInboundTunnel (pool); } std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool) @@ -862,7 +862,7 @@ namespace tunnel if (config) return CreateTunnel(config, pool); else - return CreateZeroHopsOutboundTunnel (); + return CreateZeroHopsOutboundTunnel (pool); } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) @@ -912,18 +912,20 @@ namespace tunnel } - std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel (std::shared_ptr pool) { auto inboundTunnel = std::make_shared (); + inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; } - std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel (std::shared_ptr pool) { auto outboundTunnel = std::make_shared (); + outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index c85b734b..acfa21e8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -237,8 +237,8 @@ namespace tunnel void ManagePendingTunnels (PendingTunnels& pendingTunnels); void ManageTunnelPools (uint64_t ts); - std::shared_ptr CreateZeroHopsInboundTunnel (); - std::shared_ptr CreateZeroHopsOutboundTunnel (); + std::shared_ptr CreateZeroHopsInboundTunnel (std::shared_ptr pool); + std::shared_ptr CreateZeroHopsOutboundTunnel (std::shared_ptr pool); private: From d88fe203e1296bea928726f9f6d257b9d661e3a2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 1 Aug 2021 09:25:02 +0300 Subject: [PATCH 107/186] [tunnels] count outbound traffic for zero-hop tunnels Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- libi2pd/Tunnel.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index fd26d8f1..283313fb 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -492,7 +492,7 @@ namespace http { s << "

"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); s << "
\r\n"; } diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f1f0d087..e7b38686 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -328,10 +328,11 @@ namespace tunnel for (auto& msg : msgs) { if (!msg.data) continue; + m_NumSentBytes += msg.data->GetLength (); switch (msg.deliveryType) { case eDeliveryTypeLocal: - i2p::HandleI2NPMessage (msg.data); + HandleI2NPMessage (msg.data); break; case eDeliveryTypeTunnel: i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data)); From da7e41c188ced4921c2963a71da0396dc26bbb71 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Aug 2021 18:42:13 -0400 Subject: [PATCH 108/186] use Tag<64> for ratechet tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 11 +---------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8faf1cd9..5ff2ae5c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -31,16 +31,16 @@ namespace garlic uint8_t keydata[64]; i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31] - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_SessionTagKeyData); // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) - memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32); + memcpy (m_SymmKeyCK, (const uint8_t *)m_SessionTagKeyData + 32, 32); m_NextSymmKeyIndex = 0; } void RatchetTagSet::NextSessionTagRatchet () { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) - memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32); + i2p::crypto::HKDF (m_SessionTagKeyData, nullptr, 0, "STInitialization", m_SessionTagKeyData); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + memcpy (m_SessTagConstant, (const uint8_t *)m_SessionTagKeyData + 32, 32); // SESSTAG_CONSTANT = keydata[32:63] m_NextIndex = 0; } @@ -52,8 +52,8 @@ namespace garlic LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); return 0; } - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - return m_KeyData.GetTag (); + i2p::crypto::HKDF (m_SessionTagKeyData, m_SessTagConstant, 32, "SessionTagKeyGen", m_SessionTagKeyData); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + return m_SessionTagKeyData.GetLL ()[4]; // tag = keydata[32:39] } void RatchetTagSet::GetSymmKey (int index, uint8_t * key) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index aa72e4b0..5fd2c929 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -60,16 +60,7 @@ namespace garlic private: - union - { - uint64_t ll[8]; - uint8_t buf[64]; - - const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31] - const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63] - uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39] - - } m_KeyData; + i2p::data::Tag<64> m_SessionTagKeyData; uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; int m_NextIndex, m_NextSymmKeyIndex; std::unordered_map > m_ItermediateSymmKeys; From 367df4d0dbb90b1b272a9575343304f0dc5acc8c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Aug 2021 15:43:58 -0400 Subject: [PATCH 109/186] RAND_bytes from random router selection --- libi2pd/NetDb.cpp | 75 ++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index edbd7800..825242b5 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1223,47 +1223,54 @@ namespace data { if (m_RouterInfos.empty()) return 0; + uint16_t inds[3]; + RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::unique_lock l(m_RouterInfosMutex); - auto ind = rand () % m_RouterInfos.size (); + inds[0] %= m_RouterInfos.size (); auto it = m_RouterInfos.begin (); - std::advance (it, ind); + std::advance (it, inds[0]); // try random router if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) return it->second; - // try routers after - auto it1 = it; it1++; - while (it1 != m_RouterInfos.end ()) + // try some routers around + auto it1 = m_RouterInfos.begin (); + if (inds[0]) { - if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; - it1++; + // before + inds[1] %= inds[0]; + std::advance (it1, inds[1]); } - // still not found, try some routers before - if (ind) - { - ind = rand () % ind; - it1 = m_RouterInfos.begin (); - std::advance (it1, ind); - auto it2 = it1; - while (it2 != it && it2 != m_RouterInfos.end ()) - { - if (!it2->second->IsUnreachable () && filter (it2->second)) - return it2->second; - it2++; - } - if (ind) - { - // still not found, try from the begining - it2 = m_RouterInfos.begin (); - while (it2 != it1 && it2 != m_RouterInfos.end ()) - { - if (!it2->second->IsUnreachable () && filter (it2->second)) - return it2->second; - it2++; - } - } - } - + auto it2 = it; + if (inds[0] < m_RouterInfos.size () - 1) + { + // after + inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); + std::advance (it2, inds[2]); + } + // it1 - from, it2 - to + it = it1; + while (it != it2 && it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } + // still not found, try from the begining + it = m_RouterInfos.begin (); + while (it != it1 && it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } + // still not found, try to the begining + it = it2; + while (it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } return nullptr; // seems we have too few routers } From 64ec7dd559e9fe11dd28c1ea0fbeb664b50f4127 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Aug 2021 19:26:09 -0400 Subject: [PATCH 110/186] narrow down random range --- libi2pd/NetDb.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 825242b5..4bc144e4 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1237,14 +1237,16 @@ namespace data if (inds[0]) { // before - inds[1] %= inds[0]; - std::advance (it1, inds[1]); + inds[1] %= inds[0]; + std::advance (it1, (inds[1] + inds[0])/2); } + else + it1 = it; auto it2 = it; if (inds[0] < m_RouterInfos.size () - 1) { // after - inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); + inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); inds[2] /= 2; std::advance (it2, inds[2]); } // it1 - from, it2 - to From 37f1a551479eab1627c842b1484869a9b2f98092 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Aug 2021 12:32:21 -0400 Subject: [PATCH 111/186] encryption type 0,4 by default for server tunnel --- libi2pd_client/ClientContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 94311297..f8bc5667 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -457,7 +457,7 @@ namespace client options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption(section, I2CP_PARAM_STREAMING_ANSWER_PINGS, isServer ? DEFAULT_ANSWER_PINGS : false); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); - std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, isServer ? "" : "0,4"); + std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, "0,4"); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; std::string privKey = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_PRIV_KEY, ""); if (privKey.length () > 0) options[I2CP_PARAM_LEASESET_PRIV_KEY] = privKey; From 28a055bd78d6d3c413a74ca9dc1fa6ac3019b354 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 17:42:08 +0000 Subject: [PATCH 112/186] [webconsole] add external CSS support (#1682) Signed-off-by: R4SAS --- contrib/i18n/English.po | 314 ++++++++++++++++++----------------- contrib/i18n/README.md | 29 ++++ contrib/i18n/regex.txt | 10 -- contrib/webconsole/style.css | 245 +++++++++++++++++++++++++++ daemon/HTTPServer.cpp | 172 +++++++++++-------- i18n/I18N_langs.h | 13 +- i18n/Russian.cpp | 19 +-- i18n/Turkmen.cpp | 288 +++++++++++++++----------------- i18n/Ukrainian.cpp | 16 +- 9 files changed, 689 insertions(+), 417 deletions(-) create mode 100644 contrib/i18n/README.md delete mode 100644 contrib/i18n/regex.txt create mode 100644 contrib/webconsole/style.css diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 76d58390..5a7cc09c 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -7,7 +7,7 @@ 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" +"POT-Creation-Date: 2021-08-06 17:12\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,556 +18,564 @@ msgstr "" "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:147 +#: daemon/HTTPServer.cpp:175 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:151 +#: daemon/HTTPServer.cpp:179 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:155 +#: daemon/HTTPServer.cpp:183 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:158 +#: daemon/HTTPServer.cpp:186 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" #. tr: Kibibit -#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 +#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:222 msgid "KiB" msgstr "" #. tr: Mebibit -#: daemon/HTTPServer.cpp:168 +#: daemon/HTTPServer.cpp:196 msgid "MiB" msgstr "" #. tr: Gibibit -#: daemon/HTTPServer.cpp:170 +#: daemon/HTTPServer.cpp:198 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:187 +#: daemon/HTTPServer.cpp:215 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:188 +#: daemon/HTTPServer.cpp:216 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:189 +#: daemon/HTTPServer.cpp:217 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:190 +#: daemon/HTTPServer.cpp:218 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:191 +#: daemon/HTTPServer.cpp:219 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:193 +#: daemon/HTTPServer.cpp:221 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:229 +#: daemon/HTTPServer.cpp:257 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:232 +#: daemon/HTTPServer.cpp:260 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:690 +#: daemon/HTTPServer.cpp:261 daemon/HTTPServer.cpp:723 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:413 -#: daemon/HTTPServer.cpp:425 +#: daemon/HTTPServer.cpp:262 daemon/HTTPServer.cpp:446 +#: daemon/HTTPServer.cpp:458 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 -#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 -#: daemon/HTTPServer.cpp:606 daemon/HTTPServer.cpp:649 -#: daemon/HTTPServer.cpp:653 +#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:416 +#: daemon/HTTPServer.cpp:502 daemon/HTTPServer.cpp:508 +#: daemon/HTTPServer.cpp:639 daemon/HTTPServer.cpp:682 +#: daemon/HTTPServer.cpp:686 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:659 +#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:692 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:395 -#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:769 +#: daemon/HTTPServer.cpp:267 daemon/HTTPServer.cpp:423 +#: daemon/HTTPServer.cpp:785 daemon/HTTPServer.cpp:801 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:818 +#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:850 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:241 +#: daemon/HTTPServer.cpp:269 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:880 -#: daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:271 daemon/HTTPServer.cpp:912 +#: daemon/HTTPServer.cpp:922 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1280 -#: daemon/HTTPServer.cpp:1283 daemon/HTTPServer.cpp:1286 -#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1345 -#: daemon/HTTPServer.cpp:1348 daemon/HTTPServer.cpp:1351 +#: daemon/HTTPServer.cpp:287 daemon/HTTPServer.cpp:1304 +#: daemon/HTTPServer.cpp:1307 daemon/HTTPServer.cpp:1310 +#: daemon/HTTPServer.cpp:1324 daemon/HTTPServer.cpp:1369 +#: daemon/HTTPServer.cpp:1372 daemon/HTTPServer.cpp:1375 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:266 +#: daemon/HTTPServer.cpp:294 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:267 +#: daemon/HTTPServer.cpp:295 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:268 +#: daemon/HTTPServer.cpp:296 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290 -#: daemon/HTTPServer.cpp:376 +#: daemon/HTTPServer.cpp:297 daemon/HTTPServer.cpp:318 +#: daemon/HTTPServer.cpp:404 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 -#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:948 -#: daemon/HTTPServer.cpp:957 +#: daemon/HTTPServer.cpp:298 daemon/HTTPServer.cpp:433 +#: daemon/HTTPServer.cpp:434 daemon/HTTPServer.cpp:980 +#: daemon/HTTPServer.cpp:989 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:271 +#: daemon/HTTPServer.cpp:299 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:274 +#: daemon/HTTPServer.cpp:302 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:278 +#: daemon/HTTPServer.cpp:306 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:281 +#: daemon/HTTPServer.cpp:309 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:284 +#: daemon/HTTPServer.cpp:312 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:296 +#: daemon/HTTPServer.cpp:324 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:299 +#: daemon/HTTPServer.cpp:327 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:304 +#: daemon/HTTPServer.cpp:332 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317 +#: daemon/HTTPServer.cpp:338 daemon/HTTPServer.cpp:345 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:324 +#: daemon/HTTPServer.cpp:352 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:325 +#: daemon/HTTPServer.cpp:353 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:326 +#: daemon/HTTPServer.cpp:354 msgid "Received" msgstr "" #. tr: Kibibit/s -#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 -#: daemon/HTTPServer.cpp:334 +#: daemon/HTTPServer.cpp:356 daemon/HTTPServer.cpp:359 +#: daemon/HTTPServer.cpp:362 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:329 +#: daemon/HTTPServer.cpp:357 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:360 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:335 +#: daemon/HTTPServer.cpp:363 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:338 +#: daemon/HTTPServer.cpp:366 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:341 +#: daemon/HTTPServer.cpp:369 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:343 +#: daemon/HTTPServer.cpp:371 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:344 +#: daemon/HTTPServer.cpp:372 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:345 +#: daemon/HTTPServer.cpp:373 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:346 +#: daemon/HTTPServer.cpp:374 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:354 +#: daemon/HTTPServer.cpp:382 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:386 +#: daemon/HTTPServer.cpp:414 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:387 +#: daemon/HTTPServer.cpp:415 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:934 +#: daemon/HTTPServer.cpp:422 daemon/HTTPServer.cpp:966 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:399 +#: daemon/HTTPServer.cpp:432 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:448 +#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 +#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 +#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +msgid "Enabled" +msgstr "" + +#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 +#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 +#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +msgid "Disabled" +msgstr "" + +#: daemon/HTTPServer.cpp:481 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:457 +#: daemon/HTTPServer.cpp:490 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:462 +#: daemon/HTTPServer.cpp:495 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:463 +#: daemon/HTTPServer.cpp:496 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:497 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:664 +#: daemon/HTTPServer.cpp:513 daemon/HTTPServer.cpp:697 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 -#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:679 +#: daemon/HTTPServer.cpp:518 daemon/HTTPServer.cpp:528 +#: daemon/HTTPServer.cpp:702 daemon/HTTPServer.cpp:712 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:674 +#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:707 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:502 +#: daemon/HTTPServer.cpp:535 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:502 +#: daemon/HTTPServer.cpp:535 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512 +#: daemon/HTTPServer.cpp:542 daemon/HTTPServer.cpp:545 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:543 daemon/HTTPServer.cpp:559 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:510 +#: daemon/HTTPServer.cpp:543 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:517 +#: daemon/HTTPServer.cpp:550 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528 +#: daemon/HTTPServer.cpp:558 daemon/HTTPServer.cpp:561 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:559 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:591 +#: daemon/HTTPServer.cpp:568 daemon/HTTPServer.cpp:624 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:913 +#: daemon/HTTPServer.cpp:578 daemon/HTTPServer.cpp:945 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:567 +#: daemon/HTTPServer.cpp:600 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:596 +#: daemon/HTTPServer.cpp:629 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:599 +#: daemon/HTTPServer.cpp:632 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:625 +#: daemon/HTTPServer.cpp:658 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:661 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:629 +#: daemon/HTTPServer.cpp:662 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:634 +#: daemon/HTTPServer.cpp:667 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:637 +#: daemon/HTTPServer.cpp:670 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:638 +#: daemon/HTTPServer.cpp:671 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:639 +#: daemon/HTTPServer.cpp:672 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:649 +#: daemon/HTTPServer.cpp:682 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:660 +#: daemon/HTTPServer.cpp:693 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:691 +#: daemon/HTTPServer.cpp:724 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:698 +#: daemon/HTTPServer.cpp:729 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:700 +#: daemon/HTTPServer.cpp:731 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:709 +#: daemon/HTTPServer.cpp:735 daemon/HTTPServer.cpp:740 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:706 daemon/HTTPServer.cpp:711 +#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:714 +#: daemon/HTTPServer.cpp:745 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:717 +#: daemon/HTTPServer.cpp:746 +msgid "Reload external CSS styles" +msgstr "" + +#: daemon/HTTPServer.cpp:749 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:751 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:727 +#: daemon/HTTPServer.cpp:759 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:732 daemon/HTTPServer.cpp:744 +#: daemon/HTTPServer.cpp:764 daemon/HTTPServer.cpp:776 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:736 +#: daemon/HTTPServer.cpp:768 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:769 +#: daemon/HTTPServer.cpp:801 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:874 daemon/HTTPServer.cpp:897 +#: daemon/HTTPServer.cpp:906 daemon/HTTPServer.cpp:929 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:922 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:903 +#: daemon/HTTPServer.cpp:935 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:908 +#: daemon/HTTPServer.cpp:940 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:965 +#: daemon/HTTPServer.cpp:997 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:981 +#: daemon/HTTPServer.cpp:1013 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:995 +#: daemon/HTTPServer.cpp:1027 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1201 +#: daemon/HTTPServer.cpp:1225 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1220 +#: daemon/HTTPServer.cpp:1244 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1278 daemon/HTTPServer.cpp:1335 -#: daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1302 daemon/HTTPServer.cpp:1359 +#: daemon/HTTPServer.cpp:1399 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1278 +#: daemon/HTTPServer.cpp:1302 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1280 +#: daemon/HTTPServer.cpp:1304 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1283 +#: daemon/HTTPServer.cpp:1307 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1286 +#: daemon/HTTPServer.cpp:1310 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1288 daemon/HTTPServer.cpp:1353 +#: daemon/HTTPServer.cpp:1312 daemon/HTTPServer.cpp:1377 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1289 daemon/HTTPServer.cpp:1302 -#: daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:1313 daemon/HTTPServer.cpp:1326 +#: daemon/HTTPServer.cpp:1401 msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1300 +#: daemon/HTTPServer.cpp:1324 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1301 daemon/HTTPServer.cpp:1372 +#: daemon/HTTPServer.cpp:1325 daemon/HTTPServer.cpp:1400 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1361 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1362 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1362 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1339 +#: daemon/HTTPServer.cpp:1363 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1345 +#: daemon/HTTPServer.cpp:1369 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1348 +#: daemon/HTTPServer.cpp:1372 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1351 +#: daemon/HTTPServer.cpp:1375 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1367 +#: daemon/HTTPServer.cpp:1395 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1399 msgid "Command accepted" msgstr "" diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md new file mode 100644 index 00000000..be44e87f --- /dev/null +++ b/contrib/i18n/README.md @@ -0,0 +1,29 @@ +`xgettext` command for extracting translation +=== + +``` +xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp +``` + +Regex for transforming gettext translations to our format: +=== + +``` +in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? +out: #{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n +``` + +``` +in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n +out: {"$1", "$2"},\n +``` + +``` +in: ^#[:.](.*)$\n +out: +``` + +``` +in: \n\n +out: \n +``` diff --git a/contrib/i18n/regex.txt b/contrib/i18n/regex.txt deleted file mode 100644 index e74f9d2d..00000000 --- a/contrib/i18n/regex.txt +++ /dev/null @@ -1,10 +0,0 @@ -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 - -^#:(.*)$\n - diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css new file mode 100644 index 00000000..b6e56477 --- /dev/null +++ b/contrib/webconsole/style.css @@ -0,0 +1,245 @@ +body { + font: 100%/1.5em sans-serif; + margin: 0; + padding: 1.5em; + background: #FAFAFA; + color: #103456; +} + +a, .slide label { + text-decoration: none; + color: #894C84; +} + +a:hover, .slide label:hover { + color: #FAFAFA; + background: #894C84; +} + +a.button { + -webkit-appearance: button; + -moz-appearance: button; + appearance: button; + text-decoration: none; + color: initial; + padding: 0 5px; + border: 1px solid #894C84; +} + +.header { + font-size: 2.5em; + text-align: center; + margin: 1em 0; + color: #894C84; +} + +.wrapper { + margin: 0 auto; + padding: 1em; + max-width: 64em; +} + +.menu { + display: block; + float: left; + overflow: hidden; + max-width: 12em; + white-space: nowrap; + text-overflow: ellipsis; +} + +.listitem { + display: block; + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.tableitem { + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.content { + float: left; + font-size: 1em; + margin-left: 4em; + max-width: 48em; + overflow: auto; +} + +.tunnel.established { + color: #56B734; +} + +.tunnel.expiring { + color: #D3AE3F; +} + +.tunnel.failed { + color: #D33F3F; +} + +.tunnel.building { + color: #434343; +} + +caption { + font-size: 1.5em; + text-align: center; + color: #894C84; +} + +table { + display: table; + border-collapse: collapse; + text-align: center; +} + +table.extaddr { + text-align: left; +} + +table.services { + width: 100%; +} + +textarea { + word-break: break-all; +} + +.streamdest { + width: 120px; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; +} + +.slide div.slidecontent, .slide [type="checkbox"] { + display: none; +} + +.slide [type="checkbox"]:checked ~ div.slidecontent { + display: block; + margin-top: 0; + padding: 0; +} + +.disabled { + color: #D33F3F; +} + +.enabled { + color: #56B734; +} + +@media screen and (max-width: 1150px) { /* adaptive style */ + .wrapper { + max-width: 58em; + } + + .menu { + max-width: 10em; + } + + .content { + margin-left: 2em; + max-width: 42em; + } +} + +@media screen and (max-width: 980px) { + body { + padding: 1.5em 0 0 0; + } + + .menu { + width: 100%; + max-width: unset; + display: block; + float: none; + position: unset; + font-size: 16px; + text-align: center; + } + + .menu a, .commands a { + display: inline-block; + padding: 4px; + } + + .content { + float: none; + margin-left: unset; + margin-top: 16px; + max-width: 100%; + width: 100%; + text-align: center; + } + + a, .slide label { + /* margin-right: 10px; */ + display: block; + /* font-size: 18px; */ + } + + .header { + margin: unset; + font-size: 1.5em; + } + + small { + display: block + } + + a.button { + -webkit-appearance: button; + -moz-appearance: button; + appearance: button; + text-decoration: none; + color: initial; + margin-top: 10px; + padding: 6px; + border: 1px solid #894c84; + width: -webkit-fill-available; + } + + input, select { + width: 35%; + text-align: center; + padding: 5px; + border: 2px solid #ccc; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 18px; + } + + table.extaddr { + margin: auto; + text-align: unset; + } + + textarea { + width: -webkit-fill-available; + height: auto; + padding:5px; + border:2px solid #ccc; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 12px; + } + + button[type=submit] { + padding: 5px 15px; + background: #ccc; + border: 0 none; + cursor: pointer; + -webkit-border-radius: 5px; + border-radius: 5px; + position: relative; + height: 36px; + display: -webkit-inline-box; + margin-top: 10px; + } +} \ No newline at end of file diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 283313fb..5c6a3cd8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -59,55 +59,75 @@ namespace http { "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" "RU5ErkJggg=="; + // Bundled style + const std::string internalCSS = + "\r\n"; + + // for external style sheet + std::string externalCSS; + + static void LoadExtCSS () + { + std::stringstream s; + std::string styleFile = i2p::fs::DataDirPath ("webconsole/style.css"); + if (i2p::fs::Exists(styleFile)) { + std::ifstream f(styleFile, std::ifstream::binary); + s << f.rdbuf(); + externalCSS = s.str(); + } + } + static void GetStyles (std::stringstream& s) { - s << "\r\n"; + if (externalCSS.length() != 0) + s << "\r\n"; + else + s << internalCSS; } const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -133,11 +153,19 @@ namespace http { const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit"; const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; + const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; - static std::string ConvertTime (uint64_t time); - std::map HTTPConnection::m_Tokens; + static std::string ConvertTime (uint64_t time) + { + lldiv_t divTime = lldiv(time, 1000); + time_t t = divTime.quot; + struct tm *tm = localtime(&t); + char date[128]; + snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); + return date; + } static void ShowUptime (std::stringstream& s, int seconds) { @@ -210,9 +238,9 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); // Page language - std::string lang, langCode; i2p::config::GetOption("http.lang", lang); - if (lang == "russian") langCode = "ru"; - else langCode = "en"; + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + auto it = i2p::i18n::languages.find(currLang); + std::string langCode = it->second.ShortCode; s << "\r\n" @@ -395,14 +423,19 @@ namespace http { s << "" << tr("Transit Tunnels") << ": " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forWebConsole) { - bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); + bool httpproxy = i2p::client::context.GetHttpProxy () ? true : false; + bool socksproxy = i2p::client::context.GetSocksProxy () ? true : false; + bool bob = i2p::client::context.GetBOBCommandChannel () ? true : false; + bool sam = i2p::client::context.GetSAMBridge () ? true : false; + bool i2cp = i2p::client::context.GetI2CPServer () ? true : false; + bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; s << "
" << tr("Services") << "
" << "HTTP " << tr("Proxy") << "
" << "SOCKS " << tr("Proxy") << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
" << "HTTP " << tr("Proxy") << "" << (httpproxy ? tr("Enabled") : tr("Disabled")) << "
" << "SOCKS " << tr("Proxy") << "" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "
" << "BOB" << "" << (bob ? tr("Enabled") : tr("Disabled")) << "
" << "SAM" << "" << (sam ? tr("Enabled") : tr("Disabled")) << "
" << "I2CP" << "" << (i2cp ? tr("Enabled") : tr("Disabled")) << "
" << "I2PControl" << "" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "
\r\n"; } } @@ -709,7 +742,8 @@ namespace http { s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif - s << " " << tr("Force shutdown") << "\r\n"; + s << " " << tr("Force shutdown") << "

\r\n"; + s << " " << tr("Reload external CSS styles") << "\r\n"; s << "
"; s << "
\r\n" << tr("Note: any action done here are not persistent and not changes your config files.") << "\r\n
\r\n"; @@ -1003,16 +1037,6 @@ namespace http { } } - std::string ConvertTime (uint64_t time) - { - lldiv_t divTime = lldiv(time, 1000); - time_t t = divTime.quot; - struct tm *tm = localtime(&t); - char date[128]; - snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); - return date; - } - HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr socket): m_Socket (socket), m_BufferLen (0), expected_host(hostname) { @@ -1139,6 +1163,8 @@ namespace http { SendReply (res, content); } + std::map HTTPConnection::m_Tokens; + uint32_t HTTPConnection::CreateToken () { uint32_t token; @@ -1359,6 +1385,10 @@ namespace http { if (currLang.compare(lang) != 0) i2p::i18n::SetLanguage(lang); } + else if (cmd == HTTP_COMMAND_RELOAD_CSS) + { + LoadExtCSS(); + } else { res.code = 400; @@ -1421,6 +1451,8 @@ namespace http { m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); + + LoadExtCSS(); } void HTTPServer::Stop () diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 949e5844..a5029782 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -65,7 +65,8 @@ namespace i18n struct langData { - std::string LocaleName; //localized name + std::string LocaleName; // localized name + std::string ShortCode; // short language code, like "en" std::function (void)> LocaleFunc; }; @@ -81,11 +82,11 @@ namespace i18n */ static std::map languages { - { "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} }, - { "english", {"English", i2p::i18n::english::GetLocale} }, - { "russian", {"русский язык", i2p::i18n::russian::GetLocale} }, - { "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} }, - { "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} }, + { "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} }, + { "english", {"English", "en", i2p::i18n::english::GetLocale} }, + { "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} }, + { "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, + { "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, }; } // i18n diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 5e7f9c6b..a826cdda 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -31,8 +31,6 @@ namespace russian // language namespace static std::map strings { - {"Disabled", "Выключено"}, - {"Enabled", "Включено"}, {"KiB", "КиБ"}, {"MiB", "МиБ"}, {"GiB", "ГиБ"}, @@ -45,10 +43,10 @@ namespace russian // language namespace {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Главная"}, {"Router commands", "Команды роутера"}, - {"Local destinations", "Локальные назначения"}, + {"Local Destinations", "Локальные назначения"}, {"LeaseSets", "Лизсеты"}, {"Tunnels", "Туннели"}, - {"Transit tunnels", "Транзитные туннели"}, + {"Transit Tunnels", "Транзитные туннели"}, {"Transports", "Транспорты"}, {"I2P tunnels", "I2P туннели"}, {"SAM sessions", "SAM сессии"}, @@ -84,9 +82,9 @@ namespace russian // language namespace {"Routers", "Роутеры"}, {"Floodfills", "Флудфилы"}, {"Client Tunnels", "Клиентские туннели"}, - {"Transit Tunnels", "Транзитные туннели"}, {"Services", "Сервисы"}, - {"Local Destinations", "Локальные назначения"}, + {"Enabled", "Включено"}, + {"Disabled", "Выключено"}, {"Encrypted B33 address", "Шифрованные B33 адреса"}, {"Address registration line", "Строка регистрации адреса"}, {"Domain", "Домен"}, @@ -103,8 +101,8 @@ namespace russian // language namespace {"Outgoing", "Исходящие"}, {"Destination", "Назначение"}, {"Amount", "Количество"}, - {"Incoming Tags", "Входящие Теги"}, - {"Tags sessions", "Сессии Тегов"}, + {"Incoming Tags", "Входящие теги"}, + {"Tags sessions", "Сессии тегов"}, {"Status", "Статус"}, {"Local Destination", "Локальное назначение"}, {"Streams", "Стримы"}, @@ -126,6 +124,7 @@ namespace russian // language namespace {"Cancel graceful shutdown", "Отменить плавную остановку"}, {"Start graceful shutdown", "Запустить плавную остановку"}, {"Force shutdown", "Принудительная остановка"}, + {"Reload external CSS styles", "Перезагрузить внешние CSS стили"}, {"Note: any action done here are not persistent and not changes your config files.", "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, {"Logging level", "Уровень логирования"}, {"Transit tunnels limit", "Лимит транзитных туннелей"}, @@ -147,7 +146,7 @@ namespace russian // language namespace {"Destination not found", "Точка назначения не найдена"}, {"StreamID can't be null", "StreamID не может быть пустым"}, {"Return to destination page", "Вернуться на страницу точки назначения"}, - {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, + {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, {"Back to commands list", "Вернуться к списку команд"}, {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, @@ -159,7 +158,6 @@ namespace russian // language namespace {"Such destination is not found", "Такая точка назначения не найдена"}, {"Unknown command", "Неизвестная команда"}, {"Command accepted", "Команда принята"}, - {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Proxy error", "Ошибка прокси"}, {"Proxy info", "Информация прокси"}, {"Proxy error: Host not found", "Ошибка прокси: Узел не найден"}, @@ -176,7 +174,6 @@ namespace russian // language namespace {"Addresshelper found", "Найден addresshelper"}, {"already in router's addressbook", "уже в адресной книге роутера"}, {"to update record", "чтобы обновить запись"}, - {"Invalid Request", "неверный запрос"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 8af89f6f..2bcd77cd 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -31,7 +31,133 @@ namespace turkmen // language namespace static std::map strings { - // HTTP Proxy + {"KiB", "KiB"}, + {"MiB", "MiB"}, + {"GiB", "GiB"}, + {"building", "bina"}, + {"failed", "şowsuz"}, + {"expiring", "möhleti gutarýar"}, + {"established", "işleýär"}, + {"unknown", "näbelli"}, + {"exploratory", "gözleg"}, + {"i2pd webconsole", "Web konsoly i2pd"}, + {"Main page", "Esasy sahypa"}, + {"Router commands", "Marşrutizator buýruklary"}, + {"Local Destinations", "Ýerli ýerler"}, + {"LeaseSets", "Lizset"}, + {"Tunnels", "Tuneller"}, + {"Transit Tunnels", "Tranzit Tunelleri"}, + {"Transports", "Daşamak"}, + {"I2P tunnels", "I2P tuneller"}, + {"SAM sessions", "SAM Sessiýasy"}, + {"ERROR", "Ýalňyşlyk"}, + {"OK", "OK"}, + {"Testing", "Synag etmek"}, + {"Firewalled", "Daşynda petiklendi"}, + {"Unknown", "Näbelli"}, + {"Proxy", "Proksi"}, + {"Mesh", "MESH-tor"}, + {"Error", "Ýalňyşlyk"}, + {"Clock skew", "Takyk wagt däl"}, + {"Offline", "Awtonom"}, + {"Symmetric NAT", "Simmetriklik NAT"}, + {"Uptime", "Onlaýn onlaýn sözlügi"}, + {"Network status", "Tor ýagdaýy"}, + {"Network status v6", "Tor ýagdaýy v6"}, + {"Stopping in", "Soň duruň"}, + {"Family", "Maşgala"}, + {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, + {"Received", "Alnan"}, + {"KiB/s", "KiB/s"}, + {"Sent", "Ýerleşdirildi"}, + {"Transit", "Tranzit"}, + {"Data path", "Maglumat ýoly"}, + {"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."}, + {"Router Ident", "Marşrutly kesgitleýji"}, + {"Router Family", "Marşrutler maşgalasy"}, + {"Router Caps", "Baýdaklar marşruteri"}, + {"Version", "Wersiýasy"}, + {"Our external address", "Daşarky salgymyz"}, + {"supported", "goldanýar"}, + {"Routers", "Marşrutizatorlar"}, + {"Floodfills", "Fludfillar"}, + {"Client Tunnels", "Müşderi tunelleri"}, + {"Services", "Hyzmatlar"}, + {"Enabled", "Goşuldy"}, + {"Disabled", "Öçürildi"}, + {"Encrypted B33 address", "Şifrlenen B33 salgylar"}, + {"Address registration line", "Hasaba alyş salgysy"}, + {"Domain", "Domen"}, + {"Generate", "Öndürmek"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Bellik: Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner (example.i2p). Subýutmalary hasaba almak üçin i2pd ulanyň-tools."}, + {"Address", "Salgysy"}, + {"Type", "Görnüş"}, + {"EncType", "Şifrlemek görnüşi"}, + {"Inbound tunnels", "Gelýän tuneller"}, + {"ms", "ms"}, + {"Outbound tunnels", "Çykýan tuneller"}, + {"Tags", "Bellikler"}, + {"Incoming", "Gelýän"}, + {"Outgoing", "Çykýan"}, + {"Destination", "Maksat"}, + {"Amount", "Sany"}, + {"Incoming Tags", "Gelýän bellikler"}, + {"Tags sessions", "Sapaklar bellikler"}, + {"Status", "Ýagdaýy"}, + {"Local Destination", "Ýerli maksat"}, + {"Streams", "Strimlary"}, + {"Close stream", "Yap strim"}, + {"I2CP session not found", "I2CP Sessiýa tapylmady"}, + {"I2CP is not enabled", "I2CP goşulmaýar"}, + {"Invalid", "Nädogry"}, + {"Store type", "Ammar görnüşi"}, + {"Expires", "Möhleti gutarýar"}, + {"Non Expired Leases", "Möhleti gutarmady Lizsetlary"}, + {"Gateway", "Derweze"}, + {"TunnelID", "Tuneliň ID"}, + {"EndDate", "Gutarýar"}, + {"not floodfill", "fludfil däl"}, + {"Queue size", "Nobatyň ululygy"}, + {"Run peer test", "Synag başlaň"}, + {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, + {"Accept transit tunnels", "Tranzit tunellerini alyň"}, + {"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"}, + {"Start graceful shutdown", "Tekiz durmak"}, + {"Force shutdown", "Mejbury duralga"}, + {"Reload external CSS styles", "Daşarky CSS stillerini täzeden ýükläň"}, + {"Note: any action done here are not persistent and not changes your config files.", "Bellik: 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"}, + {"Change language", "Dil üýtgetmek"}, + {"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"}, + {"SAM disabled", "SAM öçürilen"}, + {"no sessions currently running", "başlamagyň sessiýalary ýok"}, + {"SAM session not found", "SAM Sessiýa tapylmady"}, + {"SAM Session", "SAM Sessiýa"}, + {"Server Tunnels", "Serwer tunelleri"}, + {"Client Forwards", "Müşderi gönükdirýär"}, + {"Server Forwards", "Serweriň täzeden düzlüleri"}, + {"Unknown page", "Näbelli sahypa"}, + {"Invalid token", "Nädogry token"}, + {"SUCCESS", "Üstünlikli"}, + {"Stream closed", "Strim ýapyk"}, + {"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"}, + {"Destination not found", "Niýetlenen ýeri tapylmady"}, + {"StreamID can't be null", "StreamID boş bolup bilmez"}, + {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, + {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, + {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, + {"Back to commands list", "Topar sanawyna dolan"}, + {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, + {"Description", "Beýany"}, + {"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 must end with .i2p", "Domeni .i2p bilen gutarmaly"}, + {"Such destination is not found", "Bu barmaly ýer tapylmady"}, + {"Unknown command", "Näbelli topar"}, + {"Command accepted", "Topar kabul edilýär"}, {"Proxy error", "Proksi ýalňyşlygy"}, {"Proxy info", "Proksi maglumat"}, {"Proxy error: Host not found", "Proksi ýalňyşlygy: Host tapylmady"}, @@ -42,12 +168,12 @@ namespace turkmen // language namespace {"addresshelper is not supported", "Salgylandyryjy goldanok"}, {"Host", "Adres"}, {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, - {"already in router's addressbook", "marşruteriň adres kitaby"}, {"Click", "Basyň"}, {"here", "bu ýerde"}, {"to proceed", "dowam etmek"}, - {"to update record", "recordazgyny täzelemek üçin"}, {"Addresshelper found", "Forgelper tapyldy"}, + {"already in router's addressbook", "marşruteriň adres kitaby"}, + {"to update record", "recordazgyny täzelemek üçin"}, {"invalid request uri", "nädogry haýyş URI"}, {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, @@ -67,161 +193,7 @@ namespace turkmen // language namespace {"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.", - "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, - - // Webconsole // - // cssStyles - {"Disabled", "Öçürildi"}, - {"Enabled", "Goşuldy"}, - // ShowTraffic - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, - // ShowTunnelDetails - {"building", "bina"}, - {"failed", "şowsuz"}, - {"expiring", "möhleti gutarýar"}, - {"established", "işleýär"}, - {"exploratory", "gözleg"}, - {"unknown", "näbelli"}, - {"i2pd webconsole", "Web konsoly i2pd"}, - // ShowPageHead - {"Main page", "Esasy sahypa"}, - {"Router commands", "Marşrutizator buýruklary"}, - {"Local destinations", "Ýerli ýerler"}, - {"LeaseSets", "Lizset"}, - {"Tunnels", "Tuneller"}, - {"Transit tunnels", "Tranzit tunels"}, - {"Transports", "Daşamak"}, - {"I2P tunnels", "I2P tuneller"}, - {"SAM sessions", "SAM Sessiýasy"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Synag etmek"}, - {"Firewalled", "Daşynda petiklendi"}, - {"Unknown", "Näbelli"}, - {"Proxy", "Proksi"}, - {"Mesh", "MESH-tor"}, - {"Error", "Ýalňyşlyk"}, - {"Clock skew", "Takyk wagt däl"}, - {"Offline", "Awtonom"}, - {"Symmetric NAT", "Simmetriklik NAT"}, - // Status - {"Uptime", "Onlaýn onlaýn sözlügi"}, - {"Network status", "Tor ýagdaýy"}, - {"Network status v6", "Tor ýagdaýy v6"}, - {"Stopping in", "Soň duruň"}, - {"Family", "Maşgala"}, - {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, - {"Received", "Alnan"}, - {"Sent", "Ýerleşdirildi"}, - {"Transit", "Tranzit"}, - {"KiB/s", "KiB/s"}, - {"Data path", "Maglumat ýoly"}, - {"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."}, - {"Router Ident", "Marşrutly kesgitleýji"}, - {"Router Family", "Marşrutler maşgalasy"}, - {"Router Caps", "Baýdaklar marşruteri"}, - {"Version", "Wersiýasy"}, - {"Our external address", "Daşarky salgymyz"}, - {"supported", "goldanýar"}, - {"Routers", "Marşrutizatorlar"}, - {"Floodfills", "Fludfillar"}, - {"Client Tunnels", "Müşderi tunelleri"}, - {"Transit Tunnels", "Tranzit Tunelleri"}, - {"Services", "Hyzmatlar"}, - // ShowLocalDestinations - {"Local Destinations", "Ýerli ýerler"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Şifrlenen B33 salgylar"}, - {"Address registration line", "Hasaba alyş salgysy"}, - {"Domain", "Domen"}, - {"Generate", "Öndürmek"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Bellik: Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner. Subýutmalary hasaba almak üçin i2pd ulanyň-tools."}, - {"Address", "Salgysy"}, - {"Type", "Görnüş"}, - {"EncType", "Şifrlemek görnüşi"}, - {"Inbound tunnels", "Gelýän tuneller"}, - {"Outbound tunnels", "Çykýan tuneller"}, - {"ms", "ms"}, // milliseconds - {"Tags", "Bellikler"}, - {"Incoming", "Gelýän"}, - {"Outgoing", "Çykýan"}, - {"Destination", "Maksat"}, - {"Amount", "Sany"}, - {"Incoming Tags", "Gelýän bellikler"}, - {"Tags sessions", "Sapaklar bellikler"}, - {"Status", "Ýagdaýy"}, - // ShowLocalDestination - {"Local Destination", "Ýerli maksat"}, - {"Streams", "Strimlary"}, - {"Close stream", "Yap strim"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP Sessiýa tapylmady"}, - {"I2CP is not enabled", "I2CP goşulmaýar"}, - // ShowLeasesSets - {"Invalid", "Nädogry"}, - {"Store type", "Ammar görnüşi"}, - {"Expires", "Möhleti gutarýar"}, - {"Non Expired Leases", "Möhleti gutarmady Lizsetlary"}, - {"Gateway", "Derweze"}, - {"TunnelID", "Tuneliň ID"}, - {"EndDate", "Gutarýar"}, - {"not floodfill", "fludfil däl"}, - // ShowTunnels - {"Queue size", "Nobatyň ululygy"}, - // ShowCommands - {"Run peer test", "Synag başlaň"}, - {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, - {"Accept transit tunnels", "Tranzit tunellerini alyň"}, - {"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"}, - {"Start graceful shutdown", "Tekiz durmak"}, - {"Force shutdown", "Mejbury duralga"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Bellik: 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"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM öçürilen"}, - {"SAM session not found", "SAM Sessiýa tapylmady"}, - {"no sessions currently running", "başlamagyň sessiýalary ýok"}, - {"SAM Session", "SAM Sessiýa"}, - // ShowI2PTunnels - {"Server Tunnels", "Serwer tunelleri"}, - {"Client Forwards", "Müşderi gönükdirýär"}, - {"Server Forwards", "Serweriň täzeden düzlüleri"}, - // HandlePage - {"Unknown page", "Näbelli sahypa"}, - // HandleCommand, ShowError - {"Invalid token", "Nädogry token"}, - {"SUCCESS", "Üstünlikli"}, - {"ERROR", "Ýalňyşlyk"}, - {"Unknown command", "Näbelli topar"}, - {"Command accepted", "Topar kabul edilýär"}, - {"Back to commands list", "Topar sanawyna dolan"}, - {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Strim ýapyk"}, - {"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"}, - {"Destination not found", "Niýetlenen ýeri tapylmady"}, - {"StreamID can't be null", "StreamID boş bolup bilmez"}, - {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, - {"You will be redirected back in 5 seconds", "5 sekuntda yzyna iberiler"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, - {"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 must end with .i2p", "Domeni .i2p bilen gutarmaly"}, - {"Such destination is not found", "Bu barmaly ýer tapylmady"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, {"", ""}, }; diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 8da132d7..413375ba 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -31,8 +31,6 @@ namespace ukrainian // language namespace static std::map strings { - {"Disabled", "Вимкнуто"}, - {"Enabled", "Увімкнуто"}, {"KiB", "КіБ"}, {"MiB", "МіБ"}, {"GiB", "ГіБ"}, @@ -45,10 +43,10 @@ namespace ukrainian // language namespace {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Головна"}, {"Router commands", "Команди маршрутизатора"}, - {"Local destinations", "Локальні призначення"}, + {"Local Destinations", "Локальні Призначення"}, {"LeaseSets", "Лізсети"}, {"Tunnels", "Тунелі"}, - {"Transit tunnels", "Транзитні тунелі"}, + {"Transit Tunnels", "Транзитні Тунелі"}, {"Transports", "Транспорти"}, {"I2P tunnels", "I2P тунелі"}, {"SAM sessions", "SAM сесії"}, @@ -84,9 +82,9 @@ namespace ukrainian // language namespace {"Routers", "Маршрутизатори"}, {"Floodfills", "Флудфіли"}, {"Client Tunnels", "Клієнтські Тунелі"}, - {"Transit Tunnels", "Транзитні Тунелі"}, {"Services", "Сервіси"}, - {"Local Destinations", "Локальні Призначення"}, + {"Enabled", "Увімкнуто"}, + {"Disabled", "Вимкнуто"}, {"Encrypted B33 address", "Шифровані B33 адреси"}, {"Address registration line", "Рядок реєстрації адреси"}, {"Domain", "Домен"}, @@ -126,10 +124,12 @@ namespace ukrainian // language namespace {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, {"Start graceful shutdown", "Запустити плавну зупинку"}, {"Force shutdown", "Примусова зупинка"}, + {"Reload external CSS styles", "Перезавантажити зовнішні стилі CSS"}, {"Note: any action done here are not persistent and not changes your config files.", "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, {"Logging level", "Рівень логування"}, {"Transit tunnels limit", "Обмеження транзитних тунелів"}, {"Change", "Змінити"}, + {"Change language", "Змінити мову"}, {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, {"SAM disabled", "SAM вимкнуто"}, {"no sessions currently running", "немає запущених сесій"}, @@ -146,7 +146,7 @@ namespace ukrainian // language namespace {"Destination not found", "Точка призначення не знайдена"}, {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, {"Return to destination page", "Повернутися на сторінку точки призначення"}, - {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, + {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, {"Back to commands list", "Повернутися до списку команд"}, {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, @@ -158,7 +158,6 @@ namespace ukrainian // language namespace {"Such destination is not found", "Така точка призначення не знайдена"}, {"Unknown command", "Невідома команда"}, {"Command accepted", "Команда прийнята"}, - {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Proxy error", "Помилка проксі"}, {"Proxy info", "Інформація проксі"}, {"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"}, @@ -175,7 +174,6 @@ namespace ukrainian // language namespace {"Addresshelper found", "Знайдено addresshelper"}, {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, {"to update record", "щоб оновити запис"}, - {"Invalid Request", "Некоректний Запит"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, From 939682737950f53cd5b6dc68d029b3218c2efe6a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 4 Aug 2021 07:03:54 +0300 Subject: [PATCH 113/186] [makefile] build libraries on default target Signed-off-by: R4SAS --- .gitignore | 3 +++ Makefile | 49 +++++++++++++++++++++++++++---------------------- Makefile.mingw | 4 ++-- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 1fc6cefe..bafe2e18 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ netDb /libi2pd.so /libi2pdclient.so /libi2pdlang.so +/libi2pd.dll +/libi2pdclient.dll +/libi2pdlang.dll *.exe diff --git a/Makefile b/Makefile index abea5fd7..1db11c21 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,20 @@ SYS := $(shell $(CXX) -dumpmachine) -SHLIB := libi2pd.so + +ifneq (, $(findstring darwin, $(SYS))) + SHARED_PREFIX = dylib +else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) + SHARED_PREFIX = dll +else + SHARED_PREFIX = so +endif + +SHLIB := libi2pd.$(SHARED_PREFIX) ARLIB := libi2pd.a -SHLIB_LANG := libi2pdlang.so +SHLIB_LANG := libi2pdlang.$(SHARED_PREFIX) ARLIB_LANG := libi2pdlang.a -SHLIB_CLIENT := libi2pdclient.so +SHLIB_CLIENT := libi2pdclient.$(SHARED_PREFIX) ARLIB_CLIENT := libi2pdclient.a -SHLIB_WRAP := libi2pdwrapper.so +SHLIB_WRAP := libi2pdwrapper.$(SHARED_PREFIX) ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd @@ -64,22 +73,18 @@ LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) -all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) +## Build all code (libi2pd, libi2pdclient, libi2pdlang), link code to .a and .so (.dll on windows) and build binary +## Windows binary is not depending on output dlls +all: | api_client $(I2PD) mk_obj_dir: - @mkdir -p obj - @mkdir -p obj/Win32 - @mkdir -p obj/$(LIB_SRC_DIR) - @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) - @mkdir -p obj/$(LANG_SRC_DIR) - @mkdir -p obj/$(WRAP_SRC_DIR) - @mkdir -p obj/$(DAEMON_SRC_DIR) + @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) -wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) -lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api: | mk_obj_dir $(SHLIB) $(ARLIB) +client: | mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: | mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api_client: | api client lang +wrapper: | mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -98,14 +103,14 @@ obj/%.o: %.cpp $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG) endif $(SHLIB_WRAP): $(WRAP_LIB_OBJS) @@ -118,7 +123,7 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) diff --git a/Makefile.mingw b/Makefile.mingw index ce1966a1..b57860b4 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -3,9 +3,9 @@ USE_WIN32_APP := yes WINDRES = windres -CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse +CXXFLAGS := $(CXX_DEBUG) -DWIN32_LEAN_AND_MEAN -fPIC -msse INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32 -LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc +LDFLAGS := ${LD_DEBUG} -static # detect proper flag for c++11 support by compilers CXXVER := $(shell $(CXX) -dumpversion) From dc9e5dc2f1479c519db5bab16a9258d025e8f99c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 20:51:25 +0300 Subject: [PATCH 114/186] [makefile] suffix, not prefix Signed-off-by: R4SAS --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1db11c21..328214cd 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,20 @@ SYS := $(shell $(CXX) -dumpmachine) ifneq (, $(findstring darwin, $(SYS))) - SHARED_PREFIX = dylib + SHARED_SUFFIX = dylib else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) - SHARED_PREFIX = dll + SHARED_SUFFIX = dll else - SHARED_PREFIX = so + SHARED_SUFFIX = so endif -SHLIB := libi2pd.$(SHARED_PREFIX) +SHLIB := libi2pd.$(SHARED_SUFFIX) ARLIB := libi2pd.a -SHLIB_LANG := libi2pdlang.$(SHARED_PREFIX) +SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX) ARLIB_LANG := libi2pdlang.a -SHLIB_CLIENT := libi2pdclient.$(SHARED_PREFIX) +SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX) ARLIB_CLIENT := libi2pdclient.a -SHLIB_WRAP := libi2pdwrapper.$(SHARED_PREFIX) +SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX) ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd From 2f945a4fce3fafa3dc34abccf9e08c059026331d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 21:27:37 +0300 Subject: [PATCH 115/186] [makefile] dont build .so and .dll on default target Signed-off-by: R4SAS --- Makefile | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 328214cd..a4b3c3fa 100644 --- a/Makefile +++ b/Makefile @@ -73,19 +73,17 @@ LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) -## Build all code (libi2pd, libi2pdclient, libi2pdlang), link code to .a and .so (.dll on windows) and build binary -## Windows binary is not depending on output dlls -all: | api_client $(I2PD) +## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary +all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) mk_obj_dir: @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} -api: | mk_obj_dir $(SHLIB) $(ARLIB) -client: | mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -lang: | mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) -api_client: | api client lang -wrapper: | mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) - +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api_client: api client lang +wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -138,7 +136,7 @@ $(ARLIB_LANG): $(LANG_OBJS) clean: $(RM) -r obj $(RM) -r docs/generated - $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) + $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP) strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) strip $^ From a3b172bbcbdd279514e37c78ad6d8a67e315eda2 Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 6 Aug 2021 22:18:02 +0200 Subject: [PATCH 116/186] [makefile] change back directories creation, create them before compiling object files --- Makefile | 25 +++++++++++++++---------- build/.gitignore | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index a4b3c3fa..d7765af7 100644 --- a/Makefile +++ b/Makefile @@ -68,22 +68,27 @@ NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SR LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) -WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) -DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) +WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) +DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d) ## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary -all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) +all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) mk_obj_dir: - @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} + @mkdir -p obj/$(LIB_SRC_DIR) + @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) + @mkdir -p obj/$(LANG_SRC_DIR) + @mkdir -p obj/$(DAEMON_SRC_DIR) + @mkdir -p obj/$(WRAP_SRC_DIR) + @mkdir -p obj/Win32 -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api: $(SHLIB) $(ARLIB) +client: $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: $(SHLIB_LANG) $(ARLIB_LANG) api_client: api client lang -wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) +wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -92,7 +97,7 @@ wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## -std=c++11. If you want to remove this variable please do so in a way that allows setting ## custom FLAGS to work at build-time. -obj/%.o: %.cpp +obj/%.o: %.cpp | mk_obj_dir $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< # '-' is 'ignore if missing' on first run @@ -121,7 +126,7 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) diff --git a/build/.gitignore b/build/.gitignore index b595141b..872332c5 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -3,6 +3,7 @@ /i2pd /libi2pd.a /libi2pdclient.a +/libi2pdlang.a /cmake_install.cmake /CMakeCache.txt /CPackConfig.cmake @@ -11,4 +12,4 @@ /arch.c # windows build script i2pd*.zip -build*.log \ No newline at end of file +build*.log From fcbc16f2fd8e34734cfda6c8fd3ba635863fcce9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 01:37:45 +0300 Subject: [PATCH 117/186] [webconsole] fix style issues, clean external style in file was not found on reload Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 5c6a3cd8..ac83f87c 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -66,7 +66,7 @@ namespace http { " a, .slide label { text-decoration: none; color: #894C84; }\r\n" " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n" " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" - " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n" + " padding: 0 5px; border: 1px solid #894C84; }\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n" @@ -97,7 +97,7 @@ namespace http { " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n" " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" - " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" + " margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" " input, select { width: 35%; text-align: center; padding: 5px;\r\n" " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n" " table.extaddr { margin: auto; text-align: unset; }\r\n" @@ -119,6 +119,8 @@ namespace http { std::ifstream f(styleFile, std::ifstream::binary); s << f.rdbuf(); externalCSS = s.str(); + } else if (externalCSS.length() != 0) { // clean up external style if file was removed + externalCSS = ""; } } From bef8587d8fa6684575939d8a2ed5f042aff1a935 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 01:38:35 +0300 Subject: [PATCH 118/186] [makefile] create object dirs on windres (race condition) Signed-off-by: R4SAS --- Makefile.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.mingw b/Makefile.mingw index b57860b4..e31d895e 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -61,5 +61,5 @@ ifeq ($(USE_ASLR),yes) LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols endif -obj/%.o : %.rc +obj/%.o : %.rc | mk_obj_dir $(WINDRES) -i $< -o $@ From ba369d9b3064eaf01a4b9bf523fa680928e7cafa Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 17:31:26 +0300 Subject: [PATCH 119/186] [webconsole] fix style in css Signed-off-by: R4SAS --- contrib/webconsole/style.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index b6e56477..047839a6 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -21,7 +21,6 @@ a.button { -moz-appearance: button; appearance: button; text-decoration: none; - color: initial; padding: 0 5px; border: 1px solid #894C84; } @@ -198,7 +197,6 @@ textarea { -moz-appearance: button; appearance: button; text-decoration: none; - color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; From d124d4caceb17a0fb212b79ab258d90184b893c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Aug 2021 11:36:12 -0400 Subject: [PATCH 120/186] allow ipv6 adresses for UDP server tunnels --- libi2pd_client/ClientContext.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index f8bc5667..6e9ac391 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -720,9 +720,15 @@ namespace client { // udp server tunnel // TODO: hostnames - if (address.empty ()) address = "127.0.0.1"; - auto localAddress = boost::asio::ip::address::from_string(address); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); + if (address.empty ()) + { + if (!endpoint.address ().is_unspecified () && endpoint.address ().is_v6 ()) + address = "::1"; + else + address = "127.0.0.1"; + } + auto localAddress = boost::asio::ip::address::from_string(address); auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { From 49b3ac7f77431723f88bb79cf2390778ddfadac8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Aug 2021 12:23:43 -0400 Subject: [PATCH 121/186] don't reschedule resend timer for terminated streams --- libi2pd/Streaming.cpp | 16 ++++++++++------ libi2pd/Streaming.h | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index bbb649df..95f6a150 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -104,6 +104,7 @@ namespace stream void Stream::Terminate (bool deleteFromDestination) // shoudl be called from StreamingDestination::Stop only { + m_Status = eStreamStatusTerminated; m_AckSendTimer.cancel (); m_ReceiveTimer.cancel (); m_ResendTimer.cancel (); @@ -857,12 +858,15 @@ namespace stream void Stream::ScheduleResend () { - m_ResendTimer.cancel (); - // check for invalid value - if (m_RTO <= 0) m_RTO = INITIAL_RTO; - m_ResendTimer.expires_from_now (boost::posix_time::milliseconds(m_RTO)); - m_ResendTimer.async_wait (std::bind (&Stream::HandleResendTimer, - shared_from_this (), std::placeholders::_1)); + if (m_Status != eStreamStatusTerminated) + { + m_ResendTimer.cancel (); + // check for invalid value + if (m_RTO <= 0) m_RTO = INITIAL_RTO; + m_ResendTimer.expires_from_now (boost::posix_time::milliseconds(m_RTO)); + m_ResendTimer.async_wait (std::bind (&Stream::HandleResendTimer, + shared_from_this (), std::placeholders::_1)); + } } void Stream::HandleResendTimer (const boost::system::error_code& ecode) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index c40c49f5..9d206098 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -152,7 +152,8 @@ namespace stream eStreamStatusOpen, eStreamStatusReset, eStreamStatusClosing, - eStreamStatusClosed + eStreamStatusClosed, + eStreamStatusTerminated }; class StreamingDestination; From 38a2d45a3c24a3be48aee1b16ffec63500e374f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Aug 2021 12:31:46 -0400 Subject: [PATCH 122/186] close all existing streams when command SAM socket got closed --- libi2pd_client/SAM.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index af9ba6a8..c2983f43 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1207,7 +1207,11 @@ namespace client void SAMSingleSession::StopLocalDestination () { localDestination->Release (); + // stop accepting new streams localDestination->StopAcceptingStreams (); + // terminate existing streams + auto s = localDestination->GetStreamingDestination (); // TODO: take care about datagrams + if (s) s->Stop (); } void SAMMasterSession::Close () From b3e7b1b5ac79e2283835a07e15efab3f9083756e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 13 Aug 2021 09:11:56 +0300 Subject: [PATCH 123/186] Squashed commit of the following: commit 40ec4e8b59e91efe2ef7654c8c0938facfddef1b Author: Simon Vetter Date: Fri Jul 30 21:23:27 2021 +0200 libi2pd: mark additional ipv6 addresses/nets as reserved This adds :: (undefined address), ::1 (loopback address) as well as ff00::/8 (multicast prefix) to reservedIPv6Ranges. A bunch of nodes seem to be publishing bogus addresses (mostly ::1) in the netDB, resulting in unnecessary tunnel build failures. Signed-off-by: R4SAS --- libi2pd/util.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 69fc366a..2d5617b6 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -555,7 +555,10 @@ namespace net static const std::vector< std::pair > reservedIPv6Ranges { address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), - address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff") + address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("ff00::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("::", "::"), + address_pair_v6("::1", "::1") }; boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); From 1e17ef2f21b83a9b49fb803354b377aff6998ca1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 13 Aug 2021 09:17:27 +0300 Subject: [PATCH 124/186] [webconsole] show v4 status only ipv4 is enabled Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ac83f87c..d13aeb32 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -326,9 +326,12 @@ namespace http { s << "" << tr("Uptime") << ": "; ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; - s << "" << tr("Network status") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatus ()); - s << "
\r\n"; + if (i2p::context.SupportsV4 ()) + { + s << "" << tr("Network status") << ": "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); + s << "
\r\n"; + } if (i2p::context.SupportsV6 ()) { s << "" << tr("Network status v6") << ": "; From fc29911ffda418cfa94d39f16ebdc425e920032b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 11:36:04 -0400 Subject: [PATCH 125/186] rollback --- daemon/HTTPServer.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d13aeb32..ac83f87c 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -326,12 +326,9 @@ namespace http { s << "" << tr("Uptime") << ": "; ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; - if (i2p::context.SupportsV4 ()) - { - s << "" << tr("Network status") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatus ()); - s << "
\r\n"; - } + s << "" << tr("Network status") << ": "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); + s << "
\r\n"; if (i2p::context.SupportsV6 ()) { s << "" << tr("Network status v6") << ": "; From 797f5eb714a9c4accf7dce10fc865c9e3a816f2c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 13:31:04 -0400 Subject: [PATCH 126/186] select compatible resolved address for server tunnel --- libi2pd_client/I2PTunnel.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5476bfe2..378dc705 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -605,7 +605,40 @@ namespace client { if (!ecode) { - auto addr = (*it).endpoint ().address (); + bool found = false; + boost::asio::ip::tcp::resolver::iterator end; + boost::asio::ip::tcp::endpoint ep; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + { + if (!m_LocalAddress || m_LocalAddress->is_v4 ()) // look for ipv4 if not specified + found = true; + } + else if (ep.address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (m_LocalAddress && i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + found = true; + } + else if (m_LocalAddress && m_LocalAddress->is_v6 ()) + found = true; + } + } + if (found) break; + it++; + } + if (!found) + { + LogPrint (eLogError, "I2PTunnel: Unable to reslove to compatible address"); + return; + } + + auto addr = ep.address (); LogPrint (eLogInfo, "I2PTunnel: server tunnel ", (*it).host_name (), " has been resolved to ", addr); m_Endpoint.address (addr); Accept (); From b0874410f1a48a158461c4971a74604b6e7a9542 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 13:54:23 -0400 Subject: [PATCH 127/186] take first avalable resolved address if local address is not specified --- libi2pd_client/I2PTunnel.cpp | 51 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 378dc705..e8a66228 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -606,35 +606,42 @@ namespace client if (!ecode) { bool found = false; - boost::asio::ip::tcp::resolver::iterator end; boost::asio::ip::tcp::endpoint ep; - while (it != end) + if (m_LocalAddress) { - ep = *it; - if (!ep.address ().is_unspecified ()) - { - if (ep.address ().is_v4 ()) - { - if (!m_LocalAddress || m_LocalAddress->is_v4 ()) // look for ipv4 if not specified - found = true; - } - else if (ep.address ().is_v6 ()) + boost::asio::ip::tcp::resolver::iterator end; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) { - if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + if (ep.address ().is_v4 ()) + { + if (m_LocalAddress->is_v4 ()) found = true; + } + else if (ep.address ().is_v6 ()) { - if (m_LocalAddress && i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + found = true; + } + else if (m_LocalAddress->is_v6 ()) found = true; - } - else if (m_LocalAddress && m_LocalAddress->is_v6 ()) - found = true; - } - } - if (found) break; - it++; - } + } + } + if (found) break; + it++; + } + } + else + { + found = true; + ep = *it; // first available + } if (!found) { - LogPrint (eLogError, "I2PTunnel: Unable to reslove to compatible address"); + LogPrint (eLogError, "I2PTunnel: Unable to resolve to compatible address"); return; } From 8c3823fc920578eb09efd330f3b33c1408ab30b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 15 Aug 2021 16:53:10 +0300 Subject: [PATCH 128/186] [gha] build docker containers for arm/arm64 Signed-off-by: R4SAS --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index aced7f39..1c01d373 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -38,7 +38,7 @@ jobs: with: context: ./contrib/docker file: ./contrib/docker/Dockerfile - platforms: linux/amd64,linux/386 + platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7 push: true tags: | purplei2p/i2pd:latest @@ -54,7 +54,7 @@ jobs: with: context: ./contrib/docker file: ./contrib/docker/Dockerfile - platforms: linux/amd64,linux/386 + platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7 push: true tags: | purplei2p/i2pd:latest From 86e118f2b78d6f8ce6c1e50fe79220a546c1f27f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 22:23:39 +0300 Subject: [PATCH 129/186] [i18n] change string in HTTPProxy Signed-off-by: R4SAS --- contrib/i18n/English.po | 308 +++++++++++++++++------------------ contrib/i18n/README.md | 4 +- libi2pd_client/HTTPProxy.cpp | 6 +- 3 files changed, 157 insertions(+), 161 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 5a7cc09c..25378f82 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -18,564 +18,564 @@ msgstr "" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" -#: daemon/HTTPServer.cpp:175 +#: daemon/HTTPServer.cpp:177 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:179 +#: daemon/HTTPServer.cpp:181 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:183 +#: daemon/HTTPServer.cpp:185 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:186 +#: daemon/HTTPServer.cpp:188 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" #. tr: Kibibit -#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:222 +#: daemon/HTTPServer.cpp:196 daemon/HTTPServer.cpp:224 msgid "KiB" msgstr "" #. tr: Mebibit -#: daemon/HTTPServer.cpp:196 +#: daemon/HTTPServer.cpp:198 msgid "MiB" msgstr "" #. tr: Gibibit -#: daemon/HTTPServer.cpp:198 +#: daemon/HTTPServer.cpp:200 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:215 +#: daemon/HTTPServer.cpp:217 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:216 +#: daemon/HTTPServer.cpp:218 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:217 +#: daemon/HTTPServer.cpp:219 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:218 +#: daemon/HTTPServer.cpp:220 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:219 +#: daemon/HTTPServer.cpp:221 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:221 +#: daemon/HTTPServer.cpp:223 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:257 +#: daemon/HTTPServer.cpp:259 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:260 +#: daemon/HTTPServer.cpp:262 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:261 daemon/HTTPServer.cpp:723 +#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:725 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:262 daemon/HTTPServer.cpp:446 -#: daemon/HTTPServer.cpp:458 +#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:448 +#: daemon/HTTPServer.cpp:460 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:416 -#: daemon/HTTPServer.cpp:502 daemon/HTTPServer.cpp:508 -#: daemon/HTTPServer.cpp:639 daemon/HTTPServer.cpp:682 -#: daemon/HTTPServer.cpp:686 +#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:418 +#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:510 +#: daemon/HTTPServer.cpp:641 daemon/HTTPServer.cpp:684 +#: daemon/HTTPServer.cpp:688 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:692 +#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:694 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:267 daemon/HTTPServer.cpp:423 -#: daemon/HTTPServer.cpp:785 daemon/HTTPServer.cpp:801 +#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:425 +#: daemon/HTTPServer.cpp:787 daemon/HTTPServer.cpp:803 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:850 +#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:852 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:269 +#: daemon/HTTPServer.cpp:271 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:271 daemon/HTTPServer.cpp:912 -#: daemon/HTTPServer.cpp:922 +#: daemon/HTTPServer.cpp:273 daemon/HTTPServer.cpp:914 +#: daemon/HTTPServer.cpp:924 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:287 daemon/HTTPServer.cpp:1304 -#: daemon/HTTPServer.cpp:1307 daemon/HTTPServer.cpp:1310 -#: daemon/HTTPServer.cpp:1324 daemon/HTTPServer.cpp:1369 -#: daemon/HTTPServer.cpp:1372 daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:289 daemon/HTTPServer.cpp:1306 +#: daemon/HTTPServer.cpp:1309 daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1326 daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1374 daemon/HTTPServer.cpp:1377 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:294 +#: daemon/HTTPServer.cpp:296 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:295 +#: daemon/HTTPServer.cpp:297 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:296 +#: daemon/HTTPServer.cpp:298 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:297 daemon/HTTPServer.cpp:318 -#: daemon/HTTPServer.cpp:404 +#: daemon/HTTPServer.cpp:299 daemon/HTTPServer.cpp:320 +#: daemon/HTTPServer.cpp:406 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:298 daemon/HTTPServer.cpp:433 -#: daemon/HTTPServer.cpp:434 daemon/HTTPServer.cpp:980 -#: daemon/HTTPServer.cpp:989 +#: daemon/HTTPServer.cpp:300 daemon/HTTPServer.cpp:435 +#: daemon/HTTPServer.cpp:436 daemon/HTTPServer.cpp:982 +#: daemon/HTTPServer.cpp:991 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:299 +#: daemon/HTTPServer.cpp:301 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:302 +#: daemon/HTTPServer.cpp:304 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:306 +#: daemon/HTTPServer.cpp:308 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:309 +#: daemon/HTTPServer.cpp:311 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:312 +#: daemon/HTTPServer.cpp:314 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:324 +#: daemon/HTTPServer.cpp:326 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:327 +#: daemon/HTTPServer.cpp:329 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:334 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:338 daemon/HTTPServer.cpp:345 +#: daemon/HTTPServer.cpp:340 daemon/HTTPServer.cpp:347 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:352 +#: daemon/HTTPServer.cpp:354 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:353 +#: daemon/HTTPServer.cpp:355 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:354 +#: daemon/HTTPServer.cpp:356 msgid "Received" msgstr "" #. tr: Kibibit/s -#: daemon/HTTPServer.cpp:356 daemon/HTTPServer.cpp:359 -#: daemon/HTTPServer.cpp:362 +#: daemon/HTTPServer.cpp:358 daemon/HTTPServer.cpp:361 +#: daemon/HTTPServer.cpp:364 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:357 +#: daemon/HTTPServer.cpp:359 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:360 +#: daemon/HTTPServer.cpp:362 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:363 +#: daemon/HTTPServer.cpp:365 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:366 +#: daemon/HTTPServer.cpp:368 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:369 +#: daemon/HTTPServer.cpp:371 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:371 +#: daemon/HTTPServer.cpp:373 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:372 +#: daemon/HTTPServer.cpp:374 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:373 +#: daemon/HTTPServer.cpp:375 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:374 +#: daemon/HTTPServer.cpp:376 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:382 +#: daemon/HTTPServer.cpp:384 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:414 +#: daemon/HTTPServer.cpp:416 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:415 +#: daemon/HTTPServer.cpp:417 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:422 daemon/HTTPServer.cpp:966 +#: daemon/HTTPServer.cpp:424 daemon/HTTPServer.cpp:968 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:432 +#: daemon/HTTPServer.cpp:434 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 #: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 #: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440 msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 #: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 #: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440 msgid "Disabled" msgstr "" -#: daemon/HTTPServer.cpp:481 +#: daemon/HTTPServer.cpp:483 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:490 +#: daemon/HTTPServer.cpp:492 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:495 +#: daemon/HTTPServer.cpp:497 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:498 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:497 +#: daemon/HTTPServer.cpp:499 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:513 daemon/HTTPServer.cpp:697 +#: daemon/HTTPServer.cpp:515 daemon/HTTPServer.cpp:699 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:518 daemon/HTTPServer.cpp:528 -#: daemon/HTTPServer.cpp:702 daemon/HTTPServer.cpp:712 +#: daemon/HTTPServer.cpp:520 daemon/HTTPServer.cpp:530 +#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:714 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:707 +#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:709 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:535 +#: daemon/HTTPServer.cpp:537 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:535 +#: daemon/HTTPServer.cpp:537 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:542 daemon/HTTPServer.cpp:545 +#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:547 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:543 daemon/HTTPServer.cpp:559 +#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:561 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:543 +#: daemon/HTTPServer.cpp:545 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:550 +#: daemon/HTTPServer.cpp:552 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:558 daemon/HTTPServer.cpp:561 +#: daemon/HTTPServer.cpp:560 daemon/HTTPServer.cpp:563 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:559 +#: daemon/HTTPServer.cpp:561 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:568 daemon/HTTPServer.cpp:624 +#: daemon/HTTPServer.cpp:570 daemon/HTTPServer.cpp:626 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:578 daemon/HTTPServer.cpp:945 +#: daemon/HTTPServer.cpp:580 daemon/HTTPServer.cpp:947 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:600 +#: daemon/HTTPServer.cpp:602 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:629 +#: daemon/HTTPServer.cpp:631 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:632 +#: daemon/HTTPServer.cpp:634 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:658 +#: daemon/HTTPServer.cpp:660 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:661 +#: daemon/HTTPServer.cpp:663 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:662 +#: daemon/HTTPServer.cpp:664 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:667 +#: daemon/HTTPServer.cpp:669 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:670 +#: daemon/HTTPServer.cpp:672 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:671 +#: daemon/HTTPServer.cpp:673 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:672 +#: daemon/HTTPServer.cpp:674 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:682 +#: daemon/HTTPServer.cpp:684 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:693 +#: daemon/HTTPServer.cpp:695 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:724 +#: daemon/HTTPServer.cpp:726 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:729 +#: daemon/HTTPServer.cpp:731 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:731 +#: daemon/HTTPServer.cpp:733 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:735 daemon/HTTPServer.cpp:740 +#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 +#: daemon/HTTPServer.cpp:739 daemon/HTTPServer.cpp:744 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:745 +#: daemon/HTTPServer.cpp:747 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:746 +#: daemon/HTTPServer.cpp:748 msgid "Reload external CSS styles" msgstr "" -#: daemon/HTTPServer.cpp:749 +#: daemon/HTTPServer.cpp:751 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:751 +#: daemon/HTTPServer.cpp:753 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:759 +#: daemon/HTTPServer.cpp:761 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:764 daemon/HTTPServer.cpp:776 +#: daemon/HTTPServer.cpp:766 daemon/HTTPServer.cpp:778 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:768 +#: daemon/HTTPServer.cpp:770 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:801 +#: daemon/HTTPServer.cpp:803 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:906 daemon/HTTPServer.cpp:929 +#: daemon/HTTPServer.cpp:908 daemon/HTTPServer.cpp:931 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:922 +#: daemon/HTTPServer.cpp:924 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:935 +#: daemon/HTTPServer.cpp:937 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:940 +#: daemon/HTTPServer.cpp:942 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:997 +#: daemon/HTTPServer.cpp:999 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:1013 +#: daemon/HTTPServer.cpp:1015 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1027 +#: daemon/HTTPServer.cpp:1029 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1225 +#: daemon/HTTPServer.cpp:1227 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1244 +#: daemon/HTTPServer.cpp:1246 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1302 daemon/HTTPServer.cpp:1359 -#: daemon/HTTPServer.cpp:1399 +#: daemon/HTTPServer.cpp:1304 daemon/HTTPServer.cpp:1361 +#: daemon/HTTPServer.cpp:1401 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1302 +#: daemon/HTTPServer.cpp:1304 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1304 +#: daemon/HTTPServer.cpp:1306 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1307 +#: daemon/HTTPServer.cpp:1309 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1310 +#: daemon/HTTPServer.cpp:1312 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1312 daemon/HTTPServer.cpp:1377 +#: daemon/HTTPServer.cpp:1314 daemon/HTTPServer.cpp:1379 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1313 daemon/HTTPServer.cpp:1326 -#: daemon/HTTPServer.cpp:1401 +#: daemon/HTTPServer.cpp:1315 daemon/HTTPServer.cpp:1328 +#: daemon/HTTPServer.cpp:1403 msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1324 +#: daemon/HTTPServer.cpp:1326 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1325 daemon/HTTPServer.cpp:1400 +#: daemon/HTTPServer.cpp:1327 daemon/HTTPServer.cpp:1402 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1361 +#: daemon/HTTPServer.cpp:1363 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1362 +#: daemon/HTTPServer.cpp:1364 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1362 +#: daemon/HTTPServer.cpp:1364 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1363 +#: daemon/HTTPServer.cpp:1365 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1369 +#: daemon/HTTPServer.cpp:1371 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1372 +#: daemon/HTTPServer.cpp:1374 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:1377 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1395 +#: daemon/HTTPServer.cpp:1397 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1399 +#: daemon/HTTPServer.cpp:1401 msgid "Command accepted" msgstr "" @@ -621,16 +621,12 @@ msgstr "" msgid "added to router's addressbook from helper" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:307 -msgid "Click" +#: libi2pd_client/HTTPProxy.cpp:298 +msgid "Click here to proceed:" msgstr "" #: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:308 -msgid "here" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:298 -msgid "to proceed" +msgid "Continue" msgstr "" #: libi2pd_client/HTTPProxy.cpp:299 libi2pd_client/HTTPProxy.cpp:309 @@ -641,8 +637,8 @@ msgstr "" msgid "already in router's addressbook" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:308 -msgid "to update record" +#: libi2pd_client/HTTPProxy.cpp:307 +msgid "Click here to update record:" msgstr "" #: libi2pd_client/HTTPProxy.cpp:322 diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md index be44e87f..04779473 100644 --- a/contrib/i18n/README.md +++ b/contrib/i18n/README.md @@ -1,12 +1,12 @@ `xgettext` command for extracting translation -=== +--- ``` xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp ``` Regex for transforming gettext translations to our format: -=== +--- ``` in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 70cf78a8..7acdc333 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -295,7 +295,7 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; - ss << tr("Click") << " " << tr("here") << " " << tr("to proceed") << "."; + ss << tr("Click here to proceed:") << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } @@ -304,8 +304,8 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; - ss << tr("Click") << " " << tr("here") << " " << tr("to update record") << "."; + ss << tr("Click here to update record:") << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } From 8943d212ee16f297f2bb09789f6fd22e9f299d67 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 22:55:14 +0300 Subject: [PATCH 130/186] [i18n] add Uzbek translation (partial) Signed-off-by: R4SAS --- i18n/Afrikaans.cpp | 11 ++- i18n/I18N_langs.h | 1 + i18n/Russian.cpp | 7 +- i18n/Turkmen.cpp | 7 +- i18n/Ukrainian.cpp | 7 +- i18n/Uzbek.cpp | 206 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 15 deletions(-) create mode 100644 i18n/Uzbek.cpp diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 96ee52ee..5860facf 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -31,12 +31,9 @@ namespace afrikaans // language namespace static std::map 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"}, @@ -54,6 +51,14 @@ namespace afrikaans // language namespace {"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."}, {"Router Ident", "Router Ident"}, {"Router Family", "Router Familie"}, + {"Enabled", "Geaktiveer"}, + {"Disabled", "Gedeaktiveer"}, + {"Change", "Verander"}, + {"Change language", "Verander taal"}, + {"Description", "Beskrywing"}, + {"Submit", "Stuur"}, + {"Proxy error", "Proxy-fout"}, + {"Host", "Gasheer"}, {"", ""}, }; diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index a5029782..957d550d 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -87,6 +87,7 @@ namespace i18n { "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} }, { "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, { "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, + { "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} }, }; } // i18n diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index a826cdda..f6a19c7c 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -168,12 +168,11 @@ namespace russian // language namespace {"addresshelper is not supported", "addresshelper не поддерживается"}, {"Host", "Узел"}, {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"Click", "Нажмите"}, - {"here", "здесь"}, - {"to proceed", "чтобы продолжить"}, + {"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"}, + {"Continue", "Продолжить"}, {"Addresshelper found", "Найден addresshelper"}, {"already in router's addressbook", "уже в адресной книге роутера"}, - {"to update record", "чтобы обновить запись"}, + {"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 2bcd77cd..1d4f5ee1 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -168,12 +168,11 @@ namespace turkmen // language namespace {"addresshelper is not supported", "Salgylandyryjy goldanok"}, {"Host", "Adres"}, {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, - {"Click", "Basyň"}, - {"here", "bu ýerde"}, - {"to proceed", "dowam etmek"}, + {"Click here to proceed:", "Dowam etmek bu ýerde basyň:"}, + {"Continue", "Dowam et"}, {"Addresshelper found", "Forgelper tapyldy"}, {"already in router's addressbook", "marşruteriň adres kitaby"}, - {"to update record", "recordazgyny täzelemek üçin"}, + {"Click here to update record:", "Recordazgyny täzelemek üçin bu ýerde basyň:"}, {"invalid request uri", "nädogry haýyş URI"}, {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 413375ba..abbe8f81 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -168,12 +168,11 @@ namespace ukrainian // language namespace {"addresshelper is not supported", "addresshelper не підтримується"}, {"Host", "Адреса"}, {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"}, - {"Click", "Натисніть"}, - {"here", "тут"}, - {"to proceed", "щоб продовжити"}, + {"Click here to proceed:", "Натисніть тут щоб продовжити:"}, + {"Continue", "Продовжити"}, {"Addresshelper found", "Знайдено addresshelper"}, {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, - {"to update record", "щоб оновити запис"}, + {"Click here to update record:", "Натисніть тут щоб оновити запис:"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, diff --git a/i18n/Uzbek.cpp b/i18n/Uzbek.cpp new file mode 100644 index 00000000..72734b58 --- /dev/null +++ b/i18n/Uzbek.cpp @@ -0,0 +1,206 @@ +/* +* 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 +#include +#include +#include +#include "I18N.h" + +// Ukrainian localization file + +namespace i2p +{ +namespace i18n +{ +namespace uzbek // language namespace +{ + // language name in lowercase + static std::string language = "uzbek"; + + // 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 strings + { + {"KiB", "KiB"}, + {"MiB", "MiB"}, + {"GiB", "GiB"}, + {"building", "qurilish"}, + {"failed", "muvaffaqiyatsiz"}, + {"expiring", "muddati tugaydi"}, + {"established", "aloqa o'rnatildi"}, + {"unknown", "noma'lum"}, + {"exploratory", "tadqiqiy"}, + {"i2pd webconsole", "i2pd veb -konsoli"}, + {"Main page", "Asosiy sahifa"}, + {"Router commands", "Router buyruqlari"}, + {"LeaseSets", "LeaseSets"}, + {"Tunnels", "Tunnellar"}, + {"Transit Tunnels", "Tranzit Tunellar"}, + {"Transports", "Transportlar"}, + {"I2P tunnels", "I2P tunnellar"}, + {"SAM sessions", "SAM sessiyalari"}, + {"ERROR", "XATO"}, + {"OK", "OK"}, + {"Testing", "Testlash"}, + {"Firewalled", "Xavfsizlik devori bilan himoyalangan"}, + {"Unknown", "Notanish"}, + {"Proxy", "Proksi"}, + {"Mesh", "Mesh To'r"}, + {"Error", "Xato"}, + {"Clock skew", "Aniq vaqt emas"}, + {"Offline", "Oflayn"}, + {"Symmetric NAT", "Simmetrik NAT"}, + {"Uptime", "Ish vaqti"}, + {"Network status", "Tarmoq holati"}, + {"Network status v6", "Tarmoq holati v6"}, + {"Stopping in", "Ichida to'xtatish"}, + {"Family", "Oila"}, + {"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"}, + {"Received", "Qabul qilindi"}, + {"KiB/s", "KiB/s"}, + {"Sent", "Yuborilgan"}, + {"Transit", "Tranzit"}, + {"Data path", "Ma'lumotlar yo'li"}, + {"Hidden content. Press on text to see.", "Yashirin tarkib. Ko'rish uchun matn ustida bosing."}, + {"Router Ident", "Router identifikatori"}, + {"Router Family", "Router Oila"}, + {"Router Caps", "Router bayroqlari"}, + {"Version", "Versiya"}, + {"Our external address", "Bizning tashqi manzilimiz"}, + {"supported", "qo'llab -quvvatlanadi"}, + {"Routers", "Routerlar"}, + {"Floodfills", "Floodfills"}, + {"Client Tunnels", "Mijoz tunellari"}, + {"Services", "Xizmatlar"}, + {"Enabled", "Yoqilgan"}, + {"Disabled", "O'chirilgan"}, + {"Encrypted B33 address", "Shifrlangan B33 manzil"}, + {"Address registration line", "Manzilni ro'yxatga olish liniyasi"}, + {"Domain", "Domen"}, + {"Generate", "Varatish"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Eslatma: natija satridan faqat 2LD domenlarini ro'yxatdan o'tkazish uchun foydalanish mumkin (example.i2p). Subdomenlarni ro'yxatdan o'tkazish uchun i2pd-tools dan foydalaning."}, + {"Address", "Manzil"}, + {"Type", "Turi"}, + {"EncType", "ShifrlashTuri"}, + {"Inbound tunnels", "Kirish tunnellari"}, + {"ms", "ms"}, + {"Outbound tunnels", "Chiquvchi tunnellar"}, + {"Tags", "Teglar"}, + {"Incoming", "Kiruvchi"}, + {"Outgoing", "Chiquvchi"}, + {"Destination", "Manzilgoh"}, + {"Amount", "Yig'indi"}, + {"Incoming Tags", "Kiruvchi teglar"}, + {"Tags sessions", "Teglar sessiyalari"}, + {"Status", "Holat"}, + {"Streams", "Strim"}, + {"Close stream", "Strimni o'chirish"}, + {"I2CP session not found", "I2CP sessiyasi topilmadi"}, + {"I2CP is not enabled", "I2CP yoqilmagan"}, + {"Invalid", "Noto'g'ri"}, + {"Store type", "Saqlash turi"}, + {"Expires", "Muddati tugaydi"}, + {"Non Expired Leases", "Muddati O'tmagan Leases"}, + {"Gateway", "Kirish yo'li"}, + {"TunnelID", "TunnelID"}, + {"EndDate", "Tugash Sanasi"}, + {"not floodfill", "floodfill emas"}, + {"Queue size", "Navbat hajmi"}, + {"Run peer test", "Sinovni boshlang"}, + {"Decline transit tunnels", "Tranzit tunnellarni rad etish"}, + {"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"}, + {"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qiling"}, + {"Start graceful shutdown", "Yumshoq to'xtashni boshlang"}, + {"Force shutdown", "Bizning tashqi manzilimiz"}, + {"Reload external CSS styles", "Tashqi CSS uslublarini qayta yuklang"}, + {"Note: any action done here are not persistent and not changes your config files.", "Eslatma: bu erda qilingan har qanday harakat doimiy emas va konfiguratsiya fayllarini o'zgartirmaydi."}, + {"Transit tunnels limit", "Tranzit tunellar chegarasi"}, + {"Change", "O'zgartirish"}, + {"Change language", "Tilni o'zgartirish"}, + {"no transit tunnels currently built", "qurilgan tranzit tunnellari yo'q"}, + {"SAM disabled", "SAM o'chirilgan"}, + {"no sessions currently running", "hech qanday ishlaydigan sessiyalar yo'q"}, + {"SAM session not found", "SAM sessiyasi topilmadi"}, + {"SAM Session", "SAM sessiyasi"}, + {"Server Tunnels", "Server Tunellari"}, + {"Client Forwards", "Mijozlarni Yo'naltirish"}, + {"Server Forwards", "Serverni Yo'naltirish"}, + {"Unknown page", "Noma'lum sahifa"}, + {"Invalid token", "Noto‘g‘ri belgi"}, + {"SUCCESS", "Muvaffaqiyat"}, + {"Stream closed", "Strim yopiq"}, + {"Stream not found or already was closed", "Strim topilmadi yoki allaqachon yopilgan"}, + {"Destination not found", "Yo'nalish topilmadi"}, + {"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"}, + {"Return to destination page", "Belgilangan sahifaga qaytish"}, + {"You will be redirected in 5 seconds", "Siz 5 soniyada qayta yo'naltirilasiz"}, + {"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"}, + {"Back to commands list", "Buyruqlar ro'yxatiga qaytish"}, + {"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"}, + {"Description", "Tavsif"}, + {"A bit information about service on domain", "Domen xizmatlari haqida bir oz ma'lumot"}, + {"Submit", "Yuborish"}, + {"Domain can't end with .b32.i2p", "Domen .b32.i2p bilan tugashi mumkin emas"}, + {"Domain must end with .i2p", "Domen .i2p bilan tugashi kerak"}, + {"Such destination is not found", "Bunday yo'nalish topilmadi"}, + {"Unknown command", "Noma'lum buyruq"}, + {"Command accepted", "Buyruq qabul qilindi"}, + {"Proxy error", "Proksi xatosi"}, + {"Proxy info", "Proksi ma'lumotlari"}, + {"Proxy error: Host not found", "Proksi xatosi: Xost topilmadi"}, + {"Remote host not found in router's addressbook", "Masofaviy xost yo'riqnoma manzillar kitobida topilmadi"}, + {"Invalid request", "Noto‘g‘ri so‘rov"}, + {"Proxy unable to parse your request", "Proksi sizning so'rovingizni tahlil qila olmaydi"}, + {"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"}, + {"Host", "Xost"}, + {"Addresshelper found", "Addresshelper topildi"}, + {"invalid request uri", "noto'g'ri URI so'rovi"}, + {"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"}, + {"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"}, + {"bad outproxy settings", "noto'g'ri tashqi proksi -server sozlamalari"}, + {"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"}, + {"unknown outproxy url", "noma'lum outproxy url"}, + {"cannot resolve upstream proxy", "yuqoridagi proksi -serverni aniqlab olib bolmaydi"}, + {"hostname too long", "xost nomi juda uzun"}, + {"cannot connect to upstream socks proxy", "yuqori soks proksi -serveriga ulanib bo'lmaydi"}, + {"Cannot negotiate with socks proxy", "Soks proksi bilan muzokara olib bo'lmaydi"}, + {"CONNECT error", "CONNECT xatosi"}, + {"Failed to Connect", "Ulanmadi"}, + {"socks proxy error", "soks proksi xatosi"}, + {"failed to send request to upstream", "yuqori http proksi-serveriga ulanib bo'lmadi"}, + {"No Reply From socks proxy", "Soks-proksidan javob yo'q"}, + {"cannot connect", "ulab bo'lmaydi"}, + {"http out proxy not implemented", "tashqi HTTP proksi -serverni qo'llab -quvvatlash amalga oshirilmagan"}, + {"cannot connect to upstream http proxy", "yuqori http proksi-serveriga ulanib bo'lmadi"}, + {"Host is down", "Xost ishlamayapti"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Talab qilingan xost bilan aloqa o'rnatilmadi, u ishlamay qolishi mumkin. Iltimos keyinroq qayta urinib ko'ring."}, + {"", ""}, + }; + + static std::map> plurals + { + {"days", {"kun", "kunlar"}}, + {"hours", {"soat", "soat"}}, + {"minutes", {"daqiqa", "daqiqalar"}}, + {"seconds", {"soniya", "soniyalar"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p From 97765ef895c7fe4187bfea60cf0103ba8a2efcbb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 23:04:52 +0300 Subject: [PATCH 131/186] [i18n] add namespace Signed-off-by: R4SAS --- i18n/I18N_langs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 957d550d..559b17be 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -76,6 +76,7 @@ namespace i18n namespace russian { std::shared_ptr GetLocale (); } namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } + namespace uzbek { std::shared_ptr GetLocale (); } /** * That map contains international language name lower-case and name in it's language From b830babcf41e6bb8b3be3f60f3ed9cdf830012af Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 22:32:03 +0300 Subject: [PATCH 132/186] [rpm] try fix build on fedora rawhide Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 1061fc8f..46ed8a51 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -56,33 +56,38 @@ cd build %endif %endif -%if 0%{?fedora} >= 33 -pushd %{_target_platform} + +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} > 7 -pushd build + pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 -popd + popd %endif %if 0%{?mageia} > 7 -popd + popd %endif %install pushd build %if 0%{?fedora} >= 33 -pushd %{_target_platform} + pushd %{_target_platform} %endif %if 0%{?mageia} -pushd build + pushd build %endif chrpath -d i2pd From 33355c0abe752095742190019ba8b4c6255bfe19 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 22:44:04 +0300 Subject: [PATCH 133/186] [rpm] try fix build on fedora rawhide Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 12 ++++++++---- contrib/rpm/i2pd.spec | 28 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 46ed8a51..c99c2c8b 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -82,8 +82,12 @@ make %{?_smp_mflags} %install pushd build -%if 0%{?fedora} >= 33 - pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index a2994f28..1339fe90 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -54,33 +54,41 @@ cd build %endif %endif -%if 0%{?fedora} >= 33 -pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} > 7 -pushd build + pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 -popd + popd %endif %if 0%{?mageia} > 7 -popd + popd %endif %install pushd build -%if 0%{?fedora} >= 33 -pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} -pushd build + pushd build %endif chrpath -d i2pd From 8abd08bd1b3bc845d4c7b33a564bee79060ae360 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Aug 2021 15:58:46 -0400 Subject: [PATCH 134/186] change log for 2.39.0 --- ChangeLog | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9a79440e..d12bdd22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,45 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog -## [2.38.0] - 2021-03-17 +## [2.39.0] - 2021-08-23 +### Added +- Short tunnel build messages +- Localization. To: Russian, Ukrainian, Turkmen, Uzbek and Afrikaans +- Custom CSS styles for webconsole +- Avoid slow tunnels with more than 250 ms per hop +- Process DELAY_REQUESTED streaming option +- "certsdir" options for certificates location +- Keep own RouterInfo in NetBb +- Pick ECIES routers only for tunneln on non-x64 +- NTP sync through ipv6 +- Allow ipv6 adresses for UDP server tunnels +### Changed +- Rekey of all routers to ECIES +- Better distribution for random tunnel's peer selection +- Yggdrasil reseed for v0.4, added two more +- Encyption type 0,4 by default for server tunnels +- Handle i2cp.dontPublishLeaseSet param for all destinations +- reg.i2p for subscriptions +- LeaseSet type 3 by default +- Don't allocate payload buffer for every single ECIESx25519 message +- Prefer public ipv6 instead rfc4941 +- Optimal padding for one-time ECIESx25519 message +- Don't send datetime block for one-time ECIESx25519 message with one-time key +- Router with expired introducer is still valid +- Don't disable floodfill if still reachable by ipv6 +- Set minimal version for floodfill to 0.9.38 +- Eliminate extra lookups for sequential fragments on tunnel endpoint +- Consistent path for explicit peers +### Fixed +- Zero-hop tunnels +- Crash upon SAM session termination +- Build with boost < 1.55.0 +- Address type for NTCP2 acceptors +- Check of ipv4/ipv6 address +- Requst router to send to if not in NetDb +- Count outbound traffic for zero-hop tunnels + +## [2.38.0] - 2021-05-17 ### Added - Publish ipv6 introducers - Bind ipv6 or yggdrasil NTCP2 acceptor to specified address From c93ab8f829a1f2afb6d6b7d2855a0927df0201fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:36:08 +0300 Subject: [PATCH 135/186] update changelog, i2pd.conf Signed-off-by: R4SAS --- ChangeLog | 16 ++++++++++------ contrib/i2pd.conf | 3 +-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d12bdd22..2128f5d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,14 +10,14 @@ - Process DELAY_REQUESTED streaming option - "certsdir" options for certificates location - Keep own RouterInfo in NetBb -- Pick ECIES routers only for tunneln on non-x64 +- Pick ECIES routers only for tunnels on non-x64 - NTP sync through ipv6 -- Allow ipv6 adresses for UDP server tunnels +- Allow ipv6 addresses for UDP server tunnels ### Changed - Rekey of all routers to ECIES - Better distribution for random tunnel's peer selection - Yggdrasil reseed for v0.4, added two more -- Encyption type 0,4 by default for server tunnels +- Encryption type 0,4 by default for server tunnels - Handle i2cp.dontPublishLeaseSet param for all destinations - reg.i2p for subscriptions - LeaseSet type 3 by default @@ -30,14 +30,18 @@ - Set minimal version for floodfill to 0.9.38 - Eliminate extra lookups for sequential fragments on tunnel endpoint - Consistent path for explicit peers +- Always create new tunnel from exploratory pool +- Don't try to connect to a router not reachable from us +- Mark additional ipv6 addresses/nets as reserved (#1679) ### Fixed - Zero-hop tunnels - Crash upon SAM session termination -- Build with boost < 1.55.0 +- Build with boost < 1.55.0 - Address type for NTCP2 acceptors - Check of ipv4/ipv6 address -- Requst router to send to if not in NetDb -- Count outbound traffic for zero-hop tunnels +- Request router to send to if not in NetDb +- Count outbound traffic for zero-hop tunnels +- URLdecode domain for registration string generator in webconsole ## [2.38.0] - 2021-05-17 ### Added diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 599a2081..25402629 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,8 +108,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), afrikaans, russian, turkmen and ukrainian languages - +## Currently supported english (default), afrikaans, russian, turkmen ukrainian and uzbek languages # lang = english [httpproxy] From 2bdfcedd0e7acf9616b7204896fa8497043b8b07 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:37:56 +0300 Subject: [PATCH 136/186] [docs] add comma to description Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 25402629..dbf74002 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,7 +108,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), afrikaans, russian, turkmen ukrainian and uzbek languages +## Currently supported english (default), afrikaans, russian, turkmen, ukrainian and uzbek languages # lang = english [httpproxy] From 6ba992dabd22520dd2a9b99674dbd9c0fe796a9f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:41:36 +0300 Subject: [PATCH 137/186] [rpm] try fix build on fedora rawhide [try 3] Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 28 ++++++++++++++-------------- contrib/rpm/i2pd.spec | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index c99c2c8b..c9a848ee 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath @@ -58,40 +58,40 @@ cd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} > 7 - pushd build +pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 - popd +popd %endif %if 0%{?mageia} > 7 - popd +popd %endif %install pushd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} - pushd build +pushd build %endif chrpath -d i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 1339fe90..218a6bf7 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath @@ -55,40 +55,40 @@ cd build %endif %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} > 7 - pushd build +pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 - popd +popd %endif %if 0%{?mageia} > 7 - popd +popd %endif %install pushd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} - pushd build +pushd build %endif chrpath -d i2pd From 96850da31e2ddde169b53b81c98c70d2849ceffd Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Aug 2021 06:58:36 -0400 Subject: [PATCH 138/186] 2.39.0 --- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 6 +++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index c9a848ee..880d937e 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.38.0 +Version: 2.39.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 23 2021 orignal - 2.39.0 +- update to 2.39.0 + * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 218a6bf7..5bdc5231 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.38.0 +Version: 2.39.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -143,6 +143,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 23 2021 orignal - 2.39.0 +- update to 2.39.0 + * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/debian/changelog b/debian/changelog index 777b6216..c675f263 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.39.0-1) unstable; urgency=medium + + * updated to version 2.39.0/0.9.51 + + -- orignal Mon, 23 Aug 2021 16:00:00 +0000 + i2pd (2.38.0-1) unstable; urgency=medium * updated to version 2.38.0/0.9.50 diff --git a/libi2pd/version.h b/libi2pd/version.h index 028d1692..97351c40 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -16,7 +16,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 38 +#define I2PD_VERSION_MINOR 39 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 50 +#define I2P_VERSION_MICRO 51 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 455c71ff2557dde7104744cb0e8822ba8177440e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 17:00:46 +0300 Subject: [PATCH 139/186] fix warning about ifr_name size Signed-off-by: R4SAS --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 2d5617b6..f7b376f6 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -344,7 +344,7 @@ namespace net if(fd > 0) { ifreq ifr; - strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); // set interface for query + strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ-1); // set interface for query if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0) mtu = ifr.ifr_mtu; // MTU else From 24eeadea765931d46697b3e44746f24eb65d1c53 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 17:03:26 +0300 Subject: [PATCH 140/186] [rpm] add changelog note Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 1 + contrib/rpm/i2pd.spec | 1 + 2 files changed, 2 insertions(+) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 880d937e..0643ea8b 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -148,6 +148,7 @@ getent passwd i2pd >/dev/null || \ %changelog * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 +- fixed build on fedora 36 * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5bdc5231..844901c9 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -145,6 +145,7 @@ getent passwd i2pd >/dev/null || \ %changelog * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 +- fixed build on fedora 36 * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 From f0c49b58fbffd2afcb56a39e2294105298866275 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 19:29:55 +0300 Subject: [PATCH 141/186] suppress inconsistent-missing-override warning message Signed-off-by: R4SAS --- libi2pd/TunnelConfig.h | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 76aa0b34..875c20bb 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -31,14 +31,14 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - + TunnelHopConfig (std::shared_ptr r); virtual ~TunnelHopConfig () {}; - + void SetNextIdent (const i2p::data::IdentHash& ident); void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent); void SetNext (TunnelHopConfig * n); - void SetPrev (TunnelHopConfig * p); + void SetPrev (TunnelHopConfig * p); virtual uint8_t GetRetCode (const uint8_t * records) const = 0; virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; @@ -51,47 +51,47 @@ namespace tunnel { ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); + bool DecryptBuildResponseRecord (uint8_t * records) const; + }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); + void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; - + struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig { LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; + uint8_t GetRetCode (const uint8_t * records) const override + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) override; + bool DecryptBuildResponseRecord (uint8_t * records) const override; + }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig { ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; + uint8_t GetRetCode (const uint8_t * records) const override + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) override; + bool DecryptBuildResponseRecord (uint8_t * records) const override; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 - uint64_t GetGarlicKey (uint8_t * key) const override; - }; - + uint64_t GetGarlicKey (uint8_t * key) const override; + }; + class TunnelConfig { public: - TunnelConfig (const std::vector >& peers, + TunnelConfig (const std::vector >& peers, bool isShort = false): // inbound m_IsShort (isShort) { @@ -121,7 +121,7 @@ namespace tunnel } bool IsShort () const { return m_IsShort; } - + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -203,12 +203,12 @@ namespace tunnel if (m_IsShort) hop = new ShortECIESTunnelHopConfig (it); else - { + { if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) hop = new LongECIESTunnelHopConfig (it); else hop = new ElGamalTunnelHopConfig (it); - } + } if (prev) prev->SetNext (hop); else From 7d220fb2ebc1213030defa79cf265d56c7a9621a Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Mon, 23 Aug 2021 17:22:28 -0300 Subject: [PATCH 142/186] [tests] fix compilation of test-blinding test-blinding currently fails to build with the following error: In file included from ../libi2pd/Timestamp.cpp:19: ../libi2pd/RouterContext.h:21:10: fatal error: I18N_langs.h: No such file or directory 21 | #include "I18N_langs.h" | ^~~~~~~~~~~~~~ compilation terminated. --- tests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile b/tests/Makefile index 4c80c37c..2cb5348f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,5 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files +INCFLAGS += -I ../i18n TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator From af2c6c5575d28fa320f3b048b9d791d98fe77761 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 24 Aug 2021 03:16:28 +0300 Subject: [PATCH 143/186] [rpm] change if statement to cover fedora 35 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 7 +++++-- contrib/rpm/i2pd.spec | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 0643ea8b..b1354173 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -57,7 +57,7 @@ cd build %endif -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -82,7 +82,7 @@ popd %install pushd build -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2021 r4sas - 2.39.0-2 +- changed if statements to cover fedora 35 + * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 - fixed build on fedora 36 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 844901c9..ef8e32f2 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.39.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -54,7 +54,7 @@ cd build %endif %endif -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -79,7 +79,7 @@ popd %install pushd build -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -143,6 +143,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2021 r4sas - 2.39.0-2 +- changed if statements to cover fedora 35 + * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 - fixed build on fedora 36 From ec98ff297c2d8050e3a525abe1b4203a3c97a0db Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 24 Aug 2021 13:23:10 +0300 Subject: [PATCH 144/186] Make blinding test runnable --- tests/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 2cb5348f..89fceeec 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,7 @@ -CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files -INCFLAGS += -I ../i18n +CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files +INCFLAGS += -I../libi2pd -I../i18n + +LOCALESRC = ../i18n/Afrikaans.cpp ../i18n/English.cpp ../i18n/Russian.cpp ../i18n/Turkmen.cpp ../i18n/Ukrainian.cpp ../i18n/Uzbek.cpp TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator @@ -23,7 +25,7 @@ test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system -test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp +test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp $(LOCALESRC) test-blinding.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp From 541464b7057095a220db0d094fdaef16d8191fd5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Aug 2021 15:13:58 -0400 Subject: [PATCH 145/186] don't delete floodfill if number of remaining floodfills is less than minimal --- libi2pd/NetDb.cpp | 9 ++++++--- libi2pd/NetDb.hpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4bc144e4..904782cf 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -577,8 +577,9 @@ namespace data void NetDb::SaveUpdated () { - int updatedCount = 0, deletedCount = 0; + int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0; auto total = m_RouterInfos.size (); + auto totalFloodfills = m_Floodfills.size (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); auto uptime = i2p::context.GetUptime (); @@ -603,8 +604,9 @@ namespace data updatedCount++; continue; } - // make router reachable back if too few routers - if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) + // make router reachable back if too few routers or floodfills + if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS || + (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) it.second->SetUnreachable (false); // find & mark expired routers if (!it.second->IsReachable () && it.second->IsSSU (false)) @@ -618,6 +620,7 @@ namespace data if (it.second->IsUnreachable ()) { + if (it.second->IsFloodfill ()) deletedFloodfillsCount++; // delete RI file m_Storage.Remove(ident); deletedCount++; diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index c52be02b..097f92e7 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -36,6 +36,7 @@ namespace i2p namespace data { const int NETDB_MIN_ROUTERS = 90; + const int NETDB_MIN_FLOODFILLS = 5; const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60; const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours From c45e202fabbb7a0763428d81a06a6d681a22b020 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 Aug 2021 14:22:01 -0400 Subject: [PATCH 146/186] removed ElGamal encryption support for own router --- libi2pd/Crypto.cpp | 29 +++++++++-------------------- libi2pd/Crypto.h | 8 ++++---- libi2pd/CryptoKey.cpp | 16 ++++++++-------- libi2pd/CryptoKey.h | 30 +++++++++++++++--------------- libi2pd/Destination.cpp | 4 ++-- libi2pd/RouterContext.cpp | 13 +++++-------- libi2pd_client/I2CP.cpp | 6 +++--- 7 files changed, 46 insertions(+), 60 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 14ef83ae..136a2072 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -451,15 +451,15 @@ namespace crypto BN_CTX_end (ctx); } - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, - uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, + uint8_t * data, BN_CTX * ctx) { BN_CTX_start (ctx); BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); BN_bin2bn (key, 256, x); BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1 - BN_bin2bn (zeroPadding ? encrypted + 1 : encrypted, 256, a); - BN_bin2bn (zeroPadding ? encrypted + 258 : encrypted + 256, 256, b); + BN_bin2bn (encrypted + 1, 256, a); + BN_bin2bn (encrypted + 258, 256, b); // m = b*(a^x mod p) mod p BN_mod_exp (x, a, x, elgp, ctx); BN_mod_mul (b, b, x, elgp, ctx); @@ -552,7 +552,7 @@ namespace crypto BN_CTX_end (ctx); } - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { bool ret = true; BN_CTX_start (ctx); @@ -561,16 +561,8 @@ namespace crypto int len = BN_num_bytes (q); // point for shared secret BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); - if (zeroPadding) - { - BN_bin2bn (encrypted + 1, len, x); - BN_bin2bn (encrypted + 1 + len, len, y); - } - else - { - BN_bin2bn (encrypted, len, x); - BN_bin2bn (encrypted + len, len, y); - } + BN_bin2bn (encrypted + 1, len, x); + BN_bin2bn (encrypted + 1 + len, len, y); auto p = EC_POINT_new (curve); if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr)) { @@ -587,10 +579,7 @@ namespace crypto CBCDecryption decryption; decryption.SetKey (shared); decryption.SetIV (iv); - if (zeroPadding) - decryption.Decrypt (encrypted + 258, 256, m); - else - decryption.Decrypt (encrypted + 256, 256, m); + decryption.Decrypt (encrypted + 258, 256, m); // verify and copy uint8_t hash[32]; SHA256 (m + 33, 222, hash); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index a6c64c70..56791ceb 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -108,13 +108,13 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index ad93d386..3b2105a4 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -31,10 +31,10 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (!ctx) return false; - return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -72,10 +72,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); return false; } @@ -130,10 +130,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx); return false; } @@ -171,7 +171,7 @@ namespace crypto m_StaticKeys.SetPrivateKey (priv, calculatePublic); } - bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) { return m_StaticKeys.Agree (epub, sharedSecret); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index fb69558f..a5b96c47 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; // 222 bytes data, 512/514 bytes encrypted + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; }; class CryptoKeyDecryptor @@ -29,7 +29,7 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2 }; @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted private: @@ -51,8 +51,8 @@ namespace crypto public: ElGamalDecryptor (const uint8_t * priv); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 256; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; // 514 bytes encrypted, 222 bytes data + size_t GetPublicKeyLen () const override { return 256; }; private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; private: @@ -82,8 +82,8 @@ namespace crypto ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 64; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + size_t GetPublicKeyLen () const override { return 64; }; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; private: @@ -115,8 +115,8 @@ namespace crypto ECIESGOSTR3410Decryptor (const uint8_t * priv); ~ECIESGOSTR3410Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 64; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + size_t GetPublicKeyLen () const override { return 64; }; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); + void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) override; // copies m_PublicKey to pub private: @@ -147,9 +147,9 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) override; // agree with static and return in sharedSecret (32 bytes) - size_t GetPublicKeyLen () const { return 32; }; + size_t GetPublicKeyLen () const override { return 32; }; const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; private: diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index bc6ca31e..f269c092 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1249,9 +1249,9 @@ namespace client { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor) - return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true); + return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx); if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) - return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true); + return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx); else LogPrint (eLogError, "Destinations: decryptor is not set"); return false; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index edabcdfa..92dc5aea 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -880,7 +880,7 @@ namespace i2p bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false; + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false; } bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) @@ -889,11 +889,8 @@ namespace i2p return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); else { - if (!m_TunnelDecryptor) return false; - BN_CTX * ctx = BN_CTX_new (); - bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); - BN_CTX_free (ctx); - return success; + LogPrint (eLogError, "Router: Non-ECIES router is not longer supported"); + return false; } } @@ -903,7 +900,7 @@ namespace i2p 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)) + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; @@ -928,7 +925,7 @@ namespace i2p return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); else { - LogPrint (eLogWarning, "Router: Can't decrypt short request record on non-ECIES router"); + LogPrint (eLogError, "Router: Can't decrypt short request record on non-ECIES router"); return false; } } diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 25a5504a..b6618ff9 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -55,9 +55,9 @@ namespace client bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) - return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true); + return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx); if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx, true); + return m_Decryptor->Decrypt (encrypted, data, ctx); else LogPrint (eLogError, "I2CP: decryptor is not set"); return false; From bb518d3d51bda9d965952d786558825fd877b27a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Aug 2021 18:51:40 -0400 Subject: [PATCH 147/186] don't pass BN_CTX to encrypt/decrypt functions --- libi2pd/Crypto.cpp | 17 +++++++++---- libi2pd/Crypto.h | 8 +++--- libi2pd/CryptoKey.cpp | 30 +++++++++++------------ libi2pd/CryptoKey.h | 20 +++++++-------- libi2pd/Destination.cpp | 8 +++--- libi2pd/Destination.h | 4 +-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 ++++---- libi2pd/Garlic.cpp | 12 +++------ libi2pd/Garlic.h | 3 +-- libi2pd/Identity.h | 6 ++--- libi2pd/LeaseSet.cpp | 10 ++++---- libi2pd/LeaseSet.h | 6 ++--- libi2pd/RouterContext.cpp | 8 +++--- libi2pd/RouterContext.h | 4 +-- libi2pd/RouterInfo.cpp | 4 +-- libi2pd/RouterInfo.h | 2 +- libi2pd/TunnelConfig.cpp | 6 +---- libi2pd_client/I2CP.cpp | 6 ++--- libi2pd_client/I2CP.h | 2 +- 19 files changed, 81 insertions(+), 85 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 136a2072..9c9d5252 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -398,8 +398,9 @@ namespace crypto } // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); // everything, but a, because a might come from table BIGNUM * k = BN_CTX_get (ctx); @@ -449,11 +450,12 @@ namespace crypto } BN_free (a); BN_CTX_end (ctx); + BN_CTX_free (ctx); } - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, - uint8_t * data, BN_CTX * ctx) + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); BN_bin2bn (key, 256, x); @@ -466,6 +468,7 @@ namespace crypto uint8_t m[255]; bn2buf (b, m, 255); BN_CTX_end (ctx); + BN_CTX_free (ctx); uint8_t hash[32]; SHA256 (m + 33, 222, hash); if (memcmp (m + 1, hash, 32)) @@ -499,8 +502,9 @@ namespace crypto } // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order(curve, q, ctx); @@ -550,11 +554,13 @@ namespace crypto encryption.Encrypt (m, 256, encrypted + 256); EC_POINT_free (p); BN_CTX_end (ctx); + BN_CTX_free (ctx); } - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data) { bool ret = true; + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order(curve, q, ctx); @@ -599,6 +605,7 @@ namespace crypto EC_POINT_free (p); BN_CTX_end (ctx); + BN_CTX_free (ctx); return ret; } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 56791ceb..f165d59d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -108,13 +108,13 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 3b2105a4..8e49792a 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -20,10 +20,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { - if (!ctx) return; - ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding); + ElGamalEncrypt (m_PublicKey, data, encrypted, zeroPadding); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -31,10 +30,9 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { - if (!ctx) return false; - return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx); + return ElGamalDecrypt (m_PrivateKey, encrypted, data); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -54,10 +52,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, zeroPadding); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -72,10 +70,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data); return false; } @@ -114,10 +112,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, zeroPadding); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -130,10 +128,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data); return false; } @@ -161,7 +159,7 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, bool) { memcpy (pub, m_PublicKey, 32); } @@ -171,7 +169,7 @@ namespace crypto m_StaticKeys.SetPrivateKey (priv, calculatePublic); } - bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret) { return m_StaticKeys.Agree (epub, sharedSecret); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index a5b96c47..705de49e 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) = 0; }; class CryptoKeyDecryptor @@ -29,7 +29,7 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data) = 0; virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2 }; @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted private: @@ -51,7 +51,7 @@ namespace crypto public: ElGamalDecryptor (const uint8_t * priv); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; // 514 bytes encrypted, 222 bytes data + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; // 514 bytes encrypted, 222 bytes data size_t GetPublicKeyLen () const override { return 256; }; private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; private: @@ -82,7 +82,7 @@ namespace crypto ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; size_t GetPublicKeyLen () const override { return 64; }; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; private: @@ -115,7 +115,7 @@ namespace crypto ECIESGOSTR3410Decryptor (const uint8_t * priv); ~ECIESGOSTR3410Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; size_t GetPublicKeyLen () const override { return 64; }; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) override; + void Encrypt (const uint8_t *, uint8_t * pub, bool) override; // copies m_PublicKey to pub private: @@ -147,7 +147,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret) override; // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const override { return 32; }; const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f269c092..438b3f19 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1245,13 +1245,13 @@ namespace client if (m_DatagramDestination) m_DatagramDestination->CleanUp (); } - bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor) - return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx); + return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data); if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) - return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx); + return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data); else LogPrint (eLogError, "Destinations: decryptor is not set"); return false; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 2effff27..9e63d9bb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -254,7 +254,7 @@ namespace client i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5ff2ae5c..c9671a7e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -239,7 +239,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); return false; @@ -263,7 +263,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - if (!GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) + if (!GetOwner ()->Decrypt (fs, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); return false; @@ -492,7 +492,7 @@ namespace garlic // KDF2 if (isStatic) { - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) MixKey (sharedSecret); } else @@ -639,7 +639,7 @@ namespace garlic return false; } MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) MixKey (sharedSecret); uint8_t nonce[12]; @@ -1084,7 +1084,7 @@ namespace garlic // we are Bob 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) + if (!GetOwner ()->Decrypt (buf, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) { LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key"); return false; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index e5b74624..ea30a249 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -164,9 +164,7 @@ namespace garlic RAND_bytes (elGamal.preIV, 32); // Pre-IV uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); - BN_CTX * ctx = BN_CTX_new (); - m_Destination->Encrypt ((uint8_t *)&elGamal, buf, ctx); - BN_CTX_free (ctx); + m_Destination->Encrypt ((uint8_t *)&elGamal, buf); m_Encryption.SetIV (iv); buf += 514; len += 514; @@ -435,12 +433,10 @@ namespace garlic GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard { - m_Ctx = BN_CTX_new (); } GarlicDestination::~GarlicDestination () { - BN_CTX_free (m_Ctx); if (m_PayloadBuffer) delete[] m_PayloadBuffer; } @@ -531,7 +527,7 @@ namespace garlic // try ElGamal/AES first if leading block is 514 ElGamalBlock elGamal; if (mod == 2 && length >= 514 && SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) && - Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) + Decrypt (buf, (uint8_t *)&elGamal, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) { auto decryption = std::make_shared(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes @@ -777,7 +773,7 @@ namespace garlic { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; - destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + destination->Encrypt (nullptr, staticKey); // we are supposed to get static key auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) { diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b150e78d..0d7b8461 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -279,7 +279,6 @@ namespace garlic private: - BN_CTX * m_Ctx; // incoming // outgoing sessions int m_NumTags; std::mutex m_SessionsMutex; diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index e9cf63ed..b52f36cf 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -222,7 +222,7 @@ namespace data virtual ~RoutingDestination () {}; virtual std::shared_ptr GetIdentity () const = 0; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const = 0; // encrypt data for + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for virtual bool IsDestination () const = 0; // for garlic const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; @@ -234,7 +234,7 @@ namespace data public: virtual ~LocalDestination() {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index a0b14385..4d5e58d4 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -254,12 +254,12 @@ namespace data return ts > m_ExpirationTime; } - void LeaseSet::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void LeaseSet::Encrypt (const uint8_t * data, uint8_t * encrypted) const { if (!m_EncryptionKey) return; auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } void LeaseSet::SetBuffer (const uint8_t * buf, size_t len) @@ -658,11 +658,11 @@ namespace data return offset - 1; } - void LeaseSet2::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void LeaseSet2::Encrypt (const uint8_t * data, uint8_t * encrypted) const { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index cd6535df..8d501cb1 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -93,7 +93,7 @@ namespace data // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_Identity; }; - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; bool IsDestination () const { return true; }; protected: @@ -156,7 +156,7 @@ namespace data bool IsNewer (const uint8_t * buf, size_t len) const; // implements RoutingDestination - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; CryptoKeyType GetEncryptionType () const { return m_EncryptionType; }; private: diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 92dc5aea..1a2dd335 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -878,9 +878,9 @@ namespace i2p return std::chrono::duration_cast (std::chrono::steady_clock::now() - m_StartupTime).count (); } - bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false; + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data) : false; } bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) @@ -900,7 +900,7 @@ namespace i2p m_CurrentNoiseState = m_InitialNoiseState; m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; - if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr)) + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index b52e20d9..98ee6a72 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -134,7 +134,7 @@ namespace garlic // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; void SetLeaseSetUpdated () {}; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0d439dfc..78abbb51 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1155,11 +1155,11 @@ namespace data return m_Profile; } - void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted) const { auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } bool RouterInfo::IsEligibleFloodfill () const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b2b6df61..6ba52c7f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -243,7 +243,7 @@ namespace data // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; bool IsDestination () const { return false; }; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 543ba0fa..3eee2067 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -111,11 +111,7 @@ namespace tunnel uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) - { - BN_CTX * ctx = BN_CTX_new (); - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); - BN_CTX_free (ctx); - } + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, false); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index b6618ff9..7c76d359 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -52,12 +52,12 @@ namespace client } } - bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) - return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx); + return m_ECIESx25519Decryptor->Decrypt (encrypted, data); if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx); + return m_Decryptor->Decrypt (encrypted, data); else LogPrint (eLogError, "I2CP: decryptor is not set"); return false; diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 9a8bda4e..08a96af6 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -83,7 +83,7 @@ namespace client void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only std::shared_ptr GetIdentity () const { return m_Identity; }; From 349022ae42791e2ce39da84ae81fbd40742cf85e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Sep 2021 13:30:01 -0400 Subject: [PATCH 148/186] don't select ElGamal routers for tunnels --- libi2pd/Crypto.cpp | 47 ++++++++------------------- libi2pd/Crypto.h | 4 +-- libi2pd/CryptoKey.cpp | 14 ++++---- libi2pd/CryptoKey.h | 10 +++--- libi2pd/LeaseSet.cpp | 4 +-- libi2pd/NetDb.cpp | 12 +++---- libi2pd/RouterInfo.cpp | 2 +- libi2pd/RouterInfo.h | 1 + libi2pd/TunnelConfig.cpp | 69 ++++++++++++++++------------------------ libi2pd/TunnelConfig.h | 34 +------------------- libi2pd/TunnelPool.cpp | 13 ++++++-- 11 files changed, 75 insertions(+), 135 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 9c9d5252..427bbbd6 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -398,7 +398,7 @@ namespace crypto } // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -436,18 +436,11 @@ namespace crypto BN_bin2bn (m, 255, b); BN_mod_mul (b, b1, b, elgp, ctx); // copy a and b - if (zeroPadding) - { - encrypted[0] = 0; - bn2buf (a, encrypted + 1, 256); - encrypted[257] = 0; - bn2buf (b, encrypted + 258, 256); - } - else - { - bn2buf (a, encrypted, 256); - bn2buf (b, encrypted + 256, 256); - } + encrypted[0] = 0; + bn2buf (a, encrypted + 1, 256); + encrypted[257] = 0; + bn2buf (b, encrypted + 258, 256); + BN_free (a); BN_CTX_end (ctx); BN_CTX_free (ctx); @@ -502,7 +495,7 @@ namespace crypto } // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -516,19 +509,10 @@ namespace crypto EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); - if (zeroPadding) - { - encrypted[0] = 0; - bn2buf (x, encrypted + 1, len); - bn2buf (y, encrypted + 1 + len, len); - RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); - } - else - { - bn2buf (x, encrypted, len); - bn2buf (y, encrypted + len, len); - RAND_bytes (encrypted + 2*len, 256 - 2*len); - } + encrypted[0] = 0; + bn2buf (x, encrypted + 1, len); + bn2buf (y, encrypted + 1 + len, len); + RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); // encryption key and iv EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); @@ -545,13 +529,8 @@ namespace crypto CBCEncryption encryption; encryption.SetKey (shared); encryption.SetIV (iv); - if (zeroPadding) - { - encrypted[257] = 0; - encryption.Encrypt (m, 256, encrypted + 258); - } - else - encryption.Encrypt (m, 256, encrypted + 256); + encrypted[257] = 0; + encryption.Encrypt (m, 256, encrypted + 258); EC_POINT_free (p); BN_CTX_end (ctx); BN_CTX_free (ctx); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index f165d59d..5f42b527 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -108,12 +108,12 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 8e49792a..ad986129 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -20,9 +20,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { - ElGamalEncrypt (m_PublicKey, data, encrypted, zeroPadding); + ElGamalEncrypt (m_PublicKey, data, encrypted); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -52,10 +52,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, zeroPadding); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -112,10 +112,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, zeroPadding); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -159,7 +159,7 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, bool) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub) { memcpy (pub, m_PublicKey, 32); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 705de49e..0ac0bdd5 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) = 0; + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) = 0; }; class CryptoKeyDecryptor @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; // 222 bytes data, 514 bytes encrypted private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, bool) override; + void Encrypt (const uint8_t *, uint8_t * pub) override; // copies m_PublicKey to pub private: diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 4d5e58d4..75187cfe 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -259,7 +259,7 @@ namespace data if (!m_EncryptionKey) return; auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } void LeaseSet::SetBuffer (const uint8_t * buf, size_t len) @@ -662,7 +662,7 @@ namespace data { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 904782cf..7c473a09 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1171,7 +1171,8 @@ namespace data { return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : - router->IsReachableFrom (*compatibleWith)); + router->IsReachableFrom (*compatibleWith)) && + router->IsECIES (); }); } @@ -1212,12 +1213,9 @@ namespace data return !router->IsHidden () && router != compatibleWith && (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 + (router->GetCaps () & RouterInfo::eHighBandwidth) && + router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && + router->IsECIES (); }); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 78abbb51..5d66e0e4 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1159,7 +1159,7 @@ namespace data { auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } bool RouterInfo::IsEligibleFloodfill () const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 6ba52c7f..8ffd81cd 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -191,6 +191,7 @@ namespace data void UpdateSupportedTransports (); bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; + bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 3eee2067..4592c663 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -82,48 +82,6 @@ namespace tunnel decryption.SetIV (replyIV); decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } - - void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) - { - // generate keys - RAND_bytes (layerKey, 32); - RAND_bytes (ivKey, 32); - RAND_bytes (replyKey, 32); - RAND_bytes (replyIV, 16); - // fill clear text - uint8_t flag = 0; - if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; - if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); - htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); - htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - // encrypt - uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, false); - memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); - } - - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const - { - uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; - i2p::crypto::CBCDecryption decryption; - decryption.SetKey (replyKey); - decryption.SetIV (replyIV); - decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record); - return true; - } void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { @@ -261,5 +219,32 @@ namespace tunnel memcpy (key, m_CK + 32, 32); return tag; } + + void TunnelConfig::CreatePeers (const std::vector >& peers) + { + TunnelHopConfig * prev = nullptr; + for (const auto& it: peers) + { + TunnelHopConfig * hop = nullptr; + if (m_IsShort) + hop = new ShortECIESTunnelHopConfig (it); + else + { + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + LogPrint (eLogError, "Tunnel: ElGamal router is not supported"); + } + if (hop) + { + if (prev) + prev->SetNext (hop); + else + m_FirstHop = hop; + prev = hop; + } + } + m_LastHop = prev; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 875c20bb..8cb46d09 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -47,16 +47,6 @@ namespace tunnel virtual uint64_t GetGarlicKey (uint8_t * key) const { return 0; }; // return tag }; - struct ElGamalTunnelHopConfig: public TunnelHopConfig - { - ElGamalTunnelHopConfig (std::shared_ptr r): - TunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; - struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): @@ -194,29 +184,7 @@ namespace tunnel private: - void CreatePeers (const std::vector >& peers) - { - TunnelHopConfig * prev = nullptr; - for (const auto& it: peers) - { - TunnelHopConfig * hop; - if (m_IsShort) - hop = new ShortECIESTunnelHopConfig (it); - else - { - if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - hop = new LongECIESTunnelHopConfig (it); - else - hop = new ElGamalTunnelHopConfig (it); - } - if (prev) - prev->SetNext (hop); - else - m_FirstHop = hop; - prev = hop; - } - m_LastHop = prev; - } + void CreatePeers (const std::vector >& peers); private: diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 1745ebb8..b885f69f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -453,7 +453,7 @@ namespace tunnel (inbound && i2p::transport::transports.GetNumPeers () > 25)) { auto r = i2p::transport::transports.GetRandomPeer (); - if (r && !r->GetProfile ()->IsBad () && + if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { prevHop = r; @@ -469,6 +469,7 @@ namespace tunnel { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); hop = i2p::transport::transports.GetRandomPeer (); + if (!hop->IsECIES ()) hop = nullptr; } if (!hop) { @@ -513,7 +514,15 @@ namespace tunnel auto& ident = (*m_ExplicitPeers)[i]; auto r = i2p::data::netdb.FindRouter (ident); if (r) - path.Add (r); + { + if (r->IsECIES ()) + path.Add (r); + else + { + LogPrint (eLogError, "Tunnels: ElGamal router ", ident.ToBase64 (), " is not supported"); + return false; + } + } else { LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ()); From 6b1ef6e1b97081617816a95e8bea3be86dd1ea79 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 3 Sep 2021 23:25:47 +0300 Subject: [PATCH 149/186] tunnels reload changes: fix tcp tunnels reload Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 132 ++++++++++++++++++++----------- libi2pd_client/ClientContext.h | 3 +- libi2pd_client/I2PTunnel.cpp | 10 ++- libi2pd_client/I2PTunnel.h | 10 ++- 4 files changed, 100 insertions(+), 55 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 6e9ac391..41efa611 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -185,7 +185,7 @@ namespace client LogPrint(eLogInfo, "Clients: stopping AddressBook"); m_AddressBook.Stop (); - { + { std::lock_guard lock(m_ForwardsMutex); m_ServerForwards.clear(); m_ClientForwards.clear(); @@ -200,6 +200,8 @@ namespace client for (auto& it: m_Destinations) it.second->Stop (); m_Destinations.clear (); + + m_SharedLocalDestination->Release (); m_SharedLocalDestination = nullptr; } @@ -209,14 +211,6 @@ namespace client /*std::string config; i2p::config::GetOption("conf", config); i2p::config::ParseConfig(config);*/ - // handle tunnels - // reset isUpdated for each tunnel - VisitTunnels ([](I2PService * s)->bool { s->isUpdated = false; return true; }); - // reload tunnels - ReadTunnels(); - // delete not updated tunnels (not in config anymore) - VisitTunnels ([](I2PService * s)->bool { return s->isUpdated; }); - // change shared local destination m_SharedLocalDestination->Release (); CreateNewSharedLocalDestination (); @@ -225,6 +219,7 @@ namespace client if (m_HttpProxy) { m_HttpProxy->Stop (); + delete m_HttpProxy; m_HttpProxy = nullptr; } ReadHttpProxy (); @@ -233,10 +228,19 @@ namespace client if (m_SocksProxy) { m_SocksProxy->Stop (); + delete m_SocksProxy; m_SocksProxy = nullptr; } ReadSocksProxy (); + // handle tunnels + // reset isUpdated for each tunnel + VisitTunnels (false); + // reload tunnels + ReadTunnels(); + // delete not updated tunnels (not in config anymore) + VisitTunnels (true); + // delete unused destinations std::unique_lock l(m_DestinationsMutex); for (auto it = m_Destinations.begin (); it != m_Destinations.end ();) @@ -504,20 +508,15 @@ namespace client int numClientTunnels = 0, numServerTunnels = 0; std::string tunConf; i2p::config::GetOption("tunconf", tunConf); if (tunConf.empty ()) - { - // TODO: cleanup this in 2.8.0 - tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); - if (i2p::fs::Exists(tunConf)) - LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); - else - tunConf = i2p::fs::DataDirPath ("tunnels.conf"); - } + tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf); ReadTunnels (tunConf, numClientTunnels, numServerTunnels); std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir); if (tunDir.empty ()) tunDir = i2p::fs::DataDirPath ("tunnels.d"); + if (i2p::fs::Exists (tunDir)) { std::vector files; @@ -582,7 +581,7 @@ namespace client if (it != destinations.end ()) localDestination = it->second; else - { + { i2p::data::PrivateKeys k; if(LoadPrivateKeys (k, keys, sigType, cryptoType)) { @@ -597,7 +596,7 @@ namespace client destinations[keys] = localDestination; } } - } + } } if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { @@ -609,10 +608,18 @@ namespace client bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true); auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort, gzip); - if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second) + + auto ins = m_ClientForwards.insert(std::make_pair(end, clientTunnel)); + if (ins.second) + { clientTunnel->Start(); + numClientTunnels++; + } else + { + ins.first->second->isUpdated = true; LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); + } } else { boost::asio::ip::tcp::endpoint clientEndpoint; @@ -666,13 +673,16 @@ namespace client if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ()) { LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated"); + ins.first->second->Stop (); ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ()); + ins.first->second->Start (); } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists"); } } } + else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP || type == I2P_TUNNELS_SECTION_TYPE_IRC @@ -705,17 +715,17 @@ namespace client if (it != destinations.end ()) localDestination = it->second; else - { + { i2p::data::PrivateKeys k; if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) continue; localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); if (!localDestination) - { + { localDestination = CreateNewLocalDestination (k, true, &options); destinations[keys] = localDestination; - } - } + } + } if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { // udp server tunnel @@ -727,8 +737,8 @@ namespace client address = "::1"; else address = "127.0.0.1"; - } - auto localAddress = boost::asio::ip::address::from_string(address); + } + auto localAddress = boost::asio::ip::address::from_string(address); auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { @@ -736,16 +746,16 @@ namespace client serverTunnel->SetUniqueLocal(isUniqueLocal); } std::lock_guard lock(m_ForwardsMutex); - if(m_ServerForwards.insert( - std::make_pair( - std::make_pair( - localDestination->GetIdentHash(), port), - serverTunnel)).second) + auto ins = m_ServerForwards.insert(std::make_pair( + std::make_pair(localDestination->GetIdentHash(), port), + serverTunnel)); + if (ins.second) { serverTunnel->Start(); LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32()); } else + ins.first->second->isUpdated = true; LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, "already exists"); continue; @@ -795,7 +805,9 @@ namespace client if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ()) { LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated"); + ins.first->second->Stop (); ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ()); + ins.first->second->Start (); } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); @@ -872,7 +884,7 @@ namespace client { localDestination = m_HttpProxy->GetLocalDestination (); localDestination->Acquire (); - } + } else if (socksProxyKeys.length () > 0) { i2p::data::PrivateKeys keys; @@ -920,27 +932,51 @@ namespace client } } - template - void VisitTunnelsContainer (Container& c, Visitor v) + void ClientContext::VisitTunnels (bool clean) { - for (auto it = c.begin (); it != c.end ();) + for (auto it = m_ClientTunnels.begin (); it != m_ClientTunnels.end ();) { - if (!v (it->second.get ())) - { + if(clean && !it->second->isUpdated) { it->second->Stop (); - it = c.erase (it); - } - else + it = m_ClientTunnels.erase(it); + } else { + it->second->isUpdated = false; it++; + } + } + + for (auto it = m_ServerTunnels.begin (); it != m_ServerTunnels.end ();) + { + if(clean && !it->second->isUpdated) { + it->second->Stop (); + it = m_ServerTunnels.erase(it); + } else { + it->second->isUpdated = false; + it++; + } + } + + for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();) + { + if(clean && !it->second->isUpdated) { + it->second = nullptr; + it = m_ClientForwards.erase(it); + } else { + it->second->isUpdated = false; + it++; + } + } + + for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();) + { + if(clean && !it->second->isUpdated) { + it->second = nullptr; + it = m_ServerForwards.erase(it); + } else { + it->second->isUpdated = false; + it++; + } } } - - template - void ClientContext::VisitTunnels (Visitor v) - { - VisitTunnelsContainer (m_ClientTunnels, v); - VisitTunnelsContainer (m_ServerTunnels, v); - // TODO: implement UDP forwards - } } } diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 076aaa5f..90a21a60 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -121,8 +121,7 @@ namespace client void CleanupUDP(const boost::system::error_code & ecode); void ScheduleCleanupUDP(); - template - void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain + void VisitTunnels (bool clean); void CreateNewSharedLocalDestination (); void AddLocalDestination (std::shared_ptr localDestination); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index e8a66228..c01f0fe3 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -303,7 +303,7 @@ namespace client m_ProxyConnectionSent = true; } else - m_OutHeader << line << "\n"; + m_OutHeader << line << "\n"; } } else @@ -888,7 +888,8 @@ namespace client LogPrint(eLogInfo, "UDPServer: done"); } - void I2PUDPServerTunnel::Start() { + void I2PUDPServerTunnel::Start() + { m_LocalDest->Start(); } @@ -1064,8 +1065,9 @@ namespace client else LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); } - - I2PUDPClientTunnel::~I2PUDPClientTunnel() { + + I2PUDPClientTunnel::~I2PUDPClientTunnel() + { auto dgram = m_LocalDest->GetDatagramDestination(); if (dgram) dgram->ResetReceiver(); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 3b52ea1a..1db34b6c 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -254,6 +254,10 @@ namespace client std::vector m_Sessions; std::shared_ptr m_LocalDest; UDPSessionPtr m_LastSession; + + public: + + bool isUpdated; // transient, used during reload only }; class I2PUDPClientTunnel @@ -283,7 +287,7 @@ namespace client void TryResolving(); private: - + const std::string m_Name; std::mutex m_SessionsMutex; std::unordered_map > m_Sessions; // maps i2p port -> local udp convo @@ -298,6 +302,10 @@ namespace client uint16_t RemotePort, m_LastPort; bool m_cancel_resolve; std::shared_ptr m_LastSession; + + public: + + bool isUpdated; // transient, used during reload only }; class I2PServerTunnel: public I2PService From 3f46ca41cad15f5bf5c66b53581d7ff48fa6811d Mon Sep 17 00:00:00 2001 From: yangfl Date: Sat, 4 Sep 2021 15:07:09 +0800 Subject: [PATCH 150/186] disable pthread_setname_np on GNU/Hurd which does not exist on GNU/Hurd --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f7b376f6..2b5c79f2 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -129,7 +129,7 @@ namespace util pthread_set_name_np(pthread_self(), name); #elif defined(__NetBSD__) pthread_setname_np(pthread_self(), "%s", (void *)name); -#else +#elif !defined(__gnu_hurd__) pthread_setname_np(pthread_self(), name); #endif } From bce8469e59ca714c06ea35b6898517f89c35b114 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 08:53:39 -0400 Subject: [PATCH 151/186] eliminate extra error message --- libi2pd_client/ClientContext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 41efa611..a0ebb315 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -755,8 +755,10 @@ namespace client LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32()); } else + { ins.first->second->isUpdated = true; - LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, "already exists"); + LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); + } continue; } From e8f4c42bfb297ec8d5ee64d9889b47685acfbdd6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 14:01:57 -0400 Subject: [PATCH 152/186] moved current language from RouterContext to ClientContext --- daemon/HTTPServer.cpp | 6 +++--- i18n/I18N.h | 10 +++++----- libi2pd/RouterContext.h | 8 -------- libi2pd_client/ClientContext.h | 8 ++++++++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ac83f87c..c2aee205 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -240,7 +240,7 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); // Page language - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); // get current used language auto it = i2p::i18n::languages.find(currLang); std::string langCode = it->second.ShortCode; @@ -766,7 +766,7 @@ namespace http { s << " \r\n"; s << "\r\n
\r\n"; - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); // get current used language s << "" << tr("Change language") << "
\r\n"; s << "
\r\n"; s << " \r\n"; @@ -1382,7 +1382,7 @@ namespace http { else if (cmd == HTTP_COMMAND_SETLANGUAGE) { std::string lang = params["lang"]; - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); if (currLang.compare(lang) != 0) i2p::i18n::SetLanguage(lang); diff --git a/i18n/I18N.h b/i18n/I18N.h index 03add48d..5024fb56 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -9,7 +9,7 @@ #ifndef __I18N_H__ #define __I18N_H__ -#include "RouterContext.h" +#include "ClientContext.h" namespace i2p { @@ -19,19 +19,19 @@ namespace i18n { const auto it = i2p::i18n::languages.find(lang); if (it == i2p::i18n::languages.end()) // fallback - i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); + i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale()); else - i2p::context.SetLanguage (it->second.LocaleFunc()); + i2p::client::context.SetLanguage (it->second.LocaleFunc()); } inline std::string translate (const std::string& arg) { - return i2p::context.GetLanguage ()->GetString (arg); + return i2p::client::context.GetLanguage ()->GetString (arg); } inline std::string translate (const std::string& arg, const std::string& arg2, const int& n) { - return i2p::context.GetLanguage ()->GetPlural (arg, arg2, n); + return i2p::client::context.GetLanguage ()->GetPlural (arg, arg2, n); } } // i18n } // i2p diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 98ee6a72..3535f1ac 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -18,7 +18,6 @@ #include "Identity.h" #include "RouterInfo.h" #include "Garlic.h" -#include "I18N_langs.h" namespace i2p { @@ -146,10 +145,6 @@ namespace garlic void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatusMessage (std::shared_ptr msg); - // i18n - std::shared_ptr GetLanguage () { return m_Language; }; - void SetLanguage (const std::shared_ptr language) { m_Language = language; }; - protected: // implements GarlicDestination @@ -186,9 +181,6 @@ namespace garlic std::unique_ptr m_StaticKeys; // for ECIESx25519 i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; - - // i18n - std::shared_ptr m_Language; }; extern RouterContext context; diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 90a21a60..801dc0cd 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -22,6 +22,7 @@ #include "BOB.h" #include "I2CP.h" #include "AddressBook.h" +#include "I18N_langs.h" namespace i2p { @@ -102,6 +103,10 @@ namespace client std::vector > GetForwardInfosFor(const i2p::data::IdentHash & destination); + // i18n + std::shared_ptr GetLanguage () { return m_Language; }; + void SetLanguage (const std::shared_ptr language) { m_Language = language; }; + private: void ReadTunnels (); @@ -149,6 +154,9 @@ namespace client std::unique_ptr m_CleanupUDPTimer; + // i18n + std::shared_ptr m_Language; + public: // for HTTP From 41d6c117ee2063c4328d9e35d77eaaf2016de4e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 18:45:32 -0400 Subject: [PATCH 153/186] make sure server tunnel is published --- libi2pd/Destination.h | 1 + libi2pd_client/ClientContext.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 9e63d9bb..0dc5450b 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -139,6 +139,7 @@ namespace client void SetLeaseSetUpdated (); bool IsPublic () const { return m_IsPublic; }; + void SetPublic (bool pub) { m_IsPublic = pub; }; protected: diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index a0ebb315..081fa67d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -713,7 +713,10 @@ namespace client std::shared_ptr localDestination = nullptr; auto it = destinations.find (keys); if (it != destinations.end ()) + { localDestination = it->second; + localDestination->SetPublic (true); + } else { i2p::data::PrivateKeys k; @@ -725,6 +728,8 @@ namespace client localDestination = CreateNewLocalDestination (k, true, &options); destinations[keys] = localDestination; } + else + localDestination->SetPublic (true); } if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { From 3a77e7ba2dc892d75c4a823901aab31324bab86c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 18:55:51 -0400 Subject: [PATCH 154/186] remove dependancy from localization --- tests/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 89fceeec..8eb52fde 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,7 +1,5 @@ CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files -INCFLAGS += -I../libi2pd -I../i18n - -LOCALESRC = ../i18n/Afrikaans.cpp ../i18n/English.cpp ../i18n/Russian.cpp ../i18n/Turkmen.cpp ../i18n/Ukrainian.cpp ../i18n/Uzbek.cpp +INCFLAGS += -I../libi2pd TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator @@ -25,7 +23,7 @@ test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system -test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp $(LOCALESRC) test-blinding.cpp +test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp From c76347291429164f977e6e30de5c21804e2e7697 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 08:41:32 -0400 Subject: [PATCH 155/186] select ECIES routers only for peer tests and introducers --- libi2pd/NetDb.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 7c473a09..2ac5408c 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1181,8 +1181,8 @@ namespace data return GetRandomRouter ( [v4, &excluded](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (v4) && - !excluded.count (router->GetIdentHash ()); + return !router->IsHidden () && router->IsECIES () && + router->IsPeerTesting (v4) && !excluded.count (router->GetIdentHash ()); }); } @@ -1191,7 +1191,7 @@ namespace data return GetRandomRouter ( [](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsSSUV6 (); + return !router->IsHidden () && router->IsECIES () && router->IsSSUV6 (); }); } @@ -1200,8 +1200,8 @@ namespace data return GetRandomRouter ( [v4, &excluded](std::shared_ptr router)->bool { - return router->IsIntroducer (v4) && !excluded.count (router->GetIdentHash ()) && - !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag + return !router->IsHidden () && router->IsECIES () && !router->IsFloodfill () && // floodfills don't send relay tag + router->IsIntroducer (v4) && !excluded.count (router->GetIdentHash ()); }); } From a54b5c18c63d97a2e1f93b5e66b63cdf13cfe84b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 09:08:29 -0400 Subject: [PATCH 156/186] fixed crash --- libi2pd/TunnelPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b885f69f..05eed7e5 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -469,7 +469,7 @@ namespace tunnel { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); hop = i2p::transport::transports.GetRandomPeer (); - if (!hop->IsECIES ()) hop = nullptr; + if (hop && !hop->IsECIES ()) hop = nullptr; } if (!hop) { From 76dca1b46b2b19b2937dc65c2358682891dc483c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 09:10:13 -0400 Subject: [PATCH 157/186] don't handle ElGamal build record --- libi2pd/I2NPProtocol.cpp | 133 +++++++++------------------------------ libi2pd/I2NPProtocol.h | 21 ------- 2 files changed, 29 insertions(+), 125 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 54924451..07ecb19e 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -391,76 +391,48 @@ namespace i2p LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; - bool isECIES = i2p::context.IsECIES (); // replace record to reply if (i2p::context.AcceptsTunnels () && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && !i2p::transport::transports.IsBandwidthExceeded () && !i2p::transport::transports.IsTransitBandwidthExceeded ()) { - auto transitTunnel = isECIES ? - i2p::tunnel::CreateTransitTunnel ( + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) : - i2p::tunnel::CreateTransitTunnel ( - bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), - clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, - clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); } else retCode = 30; // always reject with bandwidth reason (30) - if (isECIES) - { - memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; - } - else - { - record[BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; - SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret - record + BUILD_RESPONSE_RECORD_HASH_OFFSET); - } + memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; // encrypt reply i2p::crypto::CBCEncryption encryption; for (int j = 0; j < num; j++) { uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE; - if (isECIES) - { - if (j == i) + if (j == i) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + auto& noiseState = i2p::context.GetCurrentNoiseState (); + 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 { - uint8_t nonce[12]; - memset (nonce, 0, 12); - auto& noiseState = i2p::context.GetCurrentNoiseState (); - 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; - } - } - else - { - encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); - encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); + LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); + return false; } } else - { - encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); + { + encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); + encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); } } @@ -499,75 +471,28 @@ namespace i2p } else { - if (i2p::context.IsECIES ()) + uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + if (HandleBuildRequestRecords (num, buf + 1, clearText)) { - uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (num, buf + 1, clearText)) + if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel { - if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + // so we send it to reply tunnel + transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateTunnelGatewayMsg (bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + eI2NPVariableTunnelBuildReply, buf, len, + bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } + else + transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, + bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } - else - { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (num, buf + 1, clearText)) - { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - } } } static void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { - if (i2p::context.IsECIES ()) - { - LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router"); - return; - } - if (len < NUM_TUNNEL_BUILD_RECORDS*TUNNEL_BUILD_RECORD_SIZE) - { - LogPrint (eLogError, "I2NP: TunnelBuild message is too short ", len); - return; - } - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText)) - { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outbound tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } + LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router"); } static void HandleTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len, bool isShort) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 32aebbb2..f0777ac2 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -57,31 +57,10 @@ namespace i2p const size_t TUNNEL_BUILD_RECORD_SIZE = 528; const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218; - //BuildRequestRecordClearText - const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; - const size_t BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET = BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_IV_KEY_OFFSET = BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_FLAG_OFFSET = BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16; - const size_t BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = BUILD_REQUEST_RECORD_FLAG_OFFSET + 1; - const size_t BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_PADDING_OFFSET = BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 222; - // BuildRequestRecordEncrypted const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0; const size_t BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET = BUILD_REQUEST_RECORD_TO_PEER_OFFSET + 16; - // BuildResponseRecord - const size_t BUILD_RESPONSE_RECORD_HASH_OFFSET = 0; - const size_t BUILD_RESPONSE_RECORD_PADDING_OFFSET = 32; - const size_t BUILD_RESPONSE_RECORD_PADDING_SIZE = 495; - const size_t BUILD_RESPONSE_RECORD_RET_OFFSET = BUILD_RESPONSE_RECORD_PADDING_OFFSET + BUILD_RESPONSE_RECORD_PADDING_SIZE; - // ECIES BuildRequestRecordClearText const size_t ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; From 292fe94352d4b55fed148edb6a37be87717b5b7b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 11:16:41 -0400 Subject: [PATCH 158/186] RouterContext is always ECIES --- libi2pd/I2NPProtocol.cpp | 5 ---- libi2pd/RouterContext.cpp | 56 +++++++++++++-------------------------- libi2pd/RouterContext.h | 1 - 3 files changed, 18 insertions(+), 44 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 07ecb19e..5a2fa9c1 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -528,11 +528,6 @@ namespace i2p static void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { - if (!i2p::context.IsECIES ()) - { - LogPrint (eLogWarning, "I2NP: ShortTunnelBuild can be handled by ECIES router only"); - return; - } int num = buf[0]; LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records"); if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 1a2dd335..3710092b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -43,11 +43,8 @@ namespace i2p m_Decryptor = m_Keys.CreateDecryptor (nullptr); m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr); UpdateRouterInfo (); - if (IsECIES ()) - { - i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); - m_ECIESSession = std::make_shared(m_InitialNoiseState); - } + i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); + m_ECIESSession = std::make_shared(m_InitialNoiseState); } void RouterContext::CreateNewRouter () @@ -833,27 +830,22 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); - if (IsECIES ()) + uint8_t * buf = msg->GetPayload (); + uint32_t len = bufbe32toh (buf); + if (len > msg->GetLength ()) { - uint8_t * buf = msg->GetPayload (); - uint32_t len = bufbe32toh (buf); - if (len > msg->GetLength ()) - { - LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ()); - return; - } - buf += 4; - if (!HandleECIESx25519TagMessage (buf, len)) // try tag first - { - // then Noise_N one-time decryption - if (m_ECIESSession) - m_ECIESSession->HandleNextMessage (buf, len); - else - LogPrint (eLogError, "Router: Session is not set for ECIES router"); - } + LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ()); + return; } - else - i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); + buf += 4; + if (!HandleECIESx25519TagMessage (buf, len)) // try tag first + { + // then Noise_N one-time decryption + if (m_ECIESSession) + m_ECIESSession->HandleNextMessage (buf, len); + else + LogPrint (eLogError, "Router: Session is not set for ECIES router"); + } } void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) @@ -885,13 +877,7 @@ namespace i2p bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) { - if (IsECIES ()) - return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); - else - { - LogPrint (eLogError, "Router: Non-ECIES router is not longer supported"); - return false; - } + return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); } bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) @@ -921,13 +907,7 @@ namespace i2p bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data) { - if (IsECIES ()) - return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); - else - { - LogPrint (eLogError, "Router: Can't decrypt short request record on non-ECIES router"); - return false; - } + return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); } i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 3535f1ac..647c1a7f 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -123,7 +123,6 @@ namespace garlic void SetSupportsV6 (bool supportsV6); 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; }; i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove From 20652f799569039470416e8997d6a25892cb4734 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Sep 2021 15:12:53 -0400 Subject: [PATCH 159/186] resseed if too few floodfills --- libi2pd/NetDb.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 2ac5408c..9c079d57 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -55,8 +55,10 @@ namespace data Load (); uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); - if (m_RouterInfos.size () < threshold) // reseed if # of router less than threshold + if (m_RouterInfos.size () < threshold || m_Floodfills.size () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils + { Reseed (); + } else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false)) Reseed (); // we don't have a router we can connect to. Trying to reseed From ad036de69d3009bf55efce21aa083c3c72529a10 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Sep 2021 21:19:52 -0400 Subject: [PATCH 160/186] eliminate allocation of m_ExtendedBuffer --- libi2pd/Identity.cpp | 33 ++++++++++++--------------------- libi2pd/Identity.h | 5 +++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 9dfaa1fc..aa03bfb7 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -42,7 +42,7 @@ namespace data } IdentityEx::IdentityEx (): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { } @@ -119,11 +119,15 @@ namespace data m_StandardIdentity.certificate[0] = CERTIFICATE_TYPE_KEY; htobe16buf (m_StandardIdentity.certificate + 1, m_ExtendedLen); // fill extended buffer - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; htobe16buf (m_ExtendedBuffer, type); htobe16buf (m_ExtendedBuffer + 2, cryptoType); if (excessLen && excessBuf) { + if (excessLen > MAX_EXTENDED_BUFFER_SIZE - 4) + { + LogPrint (eLogError, "Identity: Unexpected excessive signing key len ", excessLen); + excessLen = MAX_EXTENDED_BUFFER_SIZE - 4; + } memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen); delete[] excessBuf; } @@ -136,7 +140,6 @@ namespace data memset (m_StandardIdentity.certificate, 0, sizeof (m_StandardIdentity.certificate)); m_IdentHash = m_StandardIdentity.Hash (); m_ExtendedLen = 0; - m_ExtendedBuffer = nullptr; } CreateVerifier (); } @@ -154,26 +157,25 @@ namespace data } IdentityEx::IdentityEx (const uint8_t * buf, size_t len): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { FromBuffer (buf, len); } IdentityEx::IdentityEx (const IdentityEx& other): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { *this = other; } IdentityEx::IdentityEx (const Identity& standard): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { *this = standard; } IdentityEx::~IdentityEx () { - delete[] m_ExtendedBuffer; delete m_Verifier; } @@ -182,15 +184,12 @@ namespace data memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE); m_IdentHash = other.m_IdentHash; - delete[] m_ExtendedBuffer; m_ExtendedLen = other.m_ExtendedLen; if (m_ExtendedLen > 0) { - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); } - else - m_ExtendedBuffer = nullptr; delete m_Verifier; m_Verifier = nullptr; @@ -203,8 +202,6 @@ namespace data m_StandardIdentity = standard; m_IdentHash = m_StandardIdentity.Hash (); - delete[] m_ExtendedBuffer; - m_ExtendedBuffer = nullptr; m_ExtendedLen = 0; delete m_Verifier; @@ -222,15 +219,12 @@ namespace data } memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE); - if(m_ExtendedBuffer) delete[] m_ExtendedBuffer; - m_ExtendedBuffer = nullptr; - m_ExtendedLen = bufbe16toh (m_StandardIdentity.certificate + 1); if (m_ExtendedLen) { if (m_ExtendedLen + DEFAULT_IDENTITY_SIZE <= len) { - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); } else @@ -241,10 +235,7 @@ namespace data } } else - { m_ExtendedLen = 0; - m_ExtendedBuffer = nullptr; - } SHA256(buf, GetFullLen (), m_IdentHash); delete m_Verifier; @@ -258,7 +249,7 @@ namespace data const size_t fullLen = GetFullLen(); if (fullLen > len) return 0; // buffer is too small and may overflow somewhere else memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE); - if (m_ExtendedLen > 0 && m_ExtendedBuffer) + if (m_ExtendedLen > 0) memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen); return fullLen; } diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index b52f36cf..f96d5f41 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -84,8 +84,9 @@ namespace data typedef uint16_t SigningKeyType; typedef uint16_t CryptoKeyType; + const size_t MAX_EXTENDED_BUFFER_SIZE = 8; // cryptoKeyType + signingKeyType + 4 extra bytes of P521 class IdentityEx - { + { public: IdentityEx (); @@ -137,7 +138,7 @@ namespace data mutable i2p::crypto::Verifier * m_Verifier = nullptr; mutable std::mutex m_VerifierMutex; size_t m_ExtendedLen; - uint8_t * m_ExtendedBuffer; + uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; }; class PrivateKeys // for eepsites From 5e2e1a1e3d08e563b9d4db656c17325507df1de9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Sep 2021 19:57:38 -0400 Subject: [PATCH 161/186] don't include old tunnel to LeaseSet if recreated --- libi2pd/Tunnel.cpp | 6 +++--- libi2pd/Tunnel.h | 6 +++--- libi2pd/TunnelPool.cpp | 13 +++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index e7b38686..76504e1f 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -692,7 +692,7 @@ namespace tunnel // let it die if the tunnel pool has been reconfigured and this is old if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) { - tunnel->SetIsRecreated (); + tunnel->SetRecreated (true); pool->RecreateOutboundTunnel (tunnel); } } @@ -746,7 +746,7 @@ namespace tunnel // let it die if the tunnel pool was reconfigured and has different number of hops if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) { - tunnel->SetIsRecreated (); + tunnel->SetRecreated (true); pool->RecreateInboundTunnel (tunnel); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index acfa21e8..a1fd247a 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -76,7 +76,7 @@ namespace tunnel bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; bool IsFailed () const { return m_State == eTunnelStateFailed; }; bool IsRecreated () const { return m_IsRecreated; }; - void SetIsRecreated () { m_IsRecreated = true; }; + void SetRecreated (bool recreated) { m_IsRecreated = recreated; }; int GetNumHops () const { return m_Hops.size (); }; virtual bool IsInbound() const = 0; @@ -111,7 +111,7 @@ namespace tunnel std::vector > m_Hops; std::shared_ptr m_Pool; // pool, tunnel belongs to, or null TunnelState m_State; - bool m_IsRecreated; + bool m_IsRecreated; // if tunnel is replaced by new, or new tunnel requested to replace uint64_t m_Latency; // in milliseconds }; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 05eed7e5..7a5721fb 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -113,6 +113,17 @@ namespace tunnel if (!m_IsActive) return; { std::unique_lock l(m_InboundTunnelsMutex); + if (createdTunnel->IsRecreated ()) + { + // find and mark old tunnel as expired + createdTunnel->SetRecreated (false); + for (auto& it: m_InboundTunnels) + if (it->IsRecreated () && it->GetNextIdentHash () == createdTunnel->GetNextIdentHash ()) + { + it->SetState (eTunnelStateExpiring); + break; + } + } m_InboundTunnels.insert (createdTunnel); } if (m_LocalDestination) @@ -577,6 +588,8 @@ namespace tunnel auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); + else + newTunnel->SetRecreated (true); } } From e054c6e82caa489285f8abb9a3165930272d7478 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Sep 2021 18:58:27 -0400 Subject: [PATCH 162/186] memory pool for SSU messages and fragments --- libi2pd/SSU.cpp | 5 +++++ libi2pd/SSU.h | 11 ++++++++++- libi2pd/SSUData.cpp | 20 ++++++++++---------- libi2pd/SSUData.h | 12 ++++++------ libi2pd/SSUSession.h | 3 ++- libi2pd/util.h | 11 ++++++++--- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f3da611c..a4fec82e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -919,6 +919,11 @@ namespace transport } if (numDeleted > 0) LogPrint (eLogDebug, "SSU: ", numDeleted, " peer tests have been expired"); + // some cleaups. TODO: use separate timer + m_FragmentsPool.CleanUp (); + m_IncompleteMessagesPool.CleanUp (); + m_SentMessagesPool.CleanUp (); + SchedulePeerTestsCleanupTimer (); } } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index aad3a384..586d7089 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -18,6 +18,7 @@ #include #include #include "Crypto.h" +#include "util.h" #include "I2PEndian.h" #include "Identity.h" #include "RouterInfo.h" @@ -63,6 +64,10 @@ namespace transport void DeleteAllSessions (); boost::asio::io_service& GetService () { return m_Service; }; + i2p::util::MemoryPool& GetFragmentsPool () { return m_FragmentsPool; }; + i2p::util::MemoryPool& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; }; + i2p::util::MemoryPool& GetSentMessagesPool () { return m_SentMessagesPool; }; + uint16_t GetPort () const { return m_Endpoint.port (); }; void SetLocalAddress (const boost::asio::ip::address& localAddress); @@ -136,6 +141,10 @@ namespace transport std::map > m_Relays; // we are introducer std::map m_PeerTests; // nonce -> creation time in milliseconds + i2p::util::MemoryPool m_FragmentsPool; + i2p::util::MemoryPool m_IncompleteMessagesPool; + i2p::util::MemoryPool m_SentMessagesPool; + public: // for HTTP only const decltype(m_Sessions)& GetSessions () const { return m_Sessions; }; diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 5458cc97..2c6f72e1 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -140,7 +140,7 @@ namespace transport if (bitfield & mask) { if (fragment < numSentFragments) - it->second->fragments[fragment].reset (nullptr); + it->second->fragments[fragment] = nullptr; } fragment++; mask <<= 1; @@ -182,9 +182,9 @@ namespace transport auto msg = NewI2NPShortMessage (); msg->len -= I2NP_SHORT_HEADER_SIZE; it = m_IncompleteMessages.insert (std::make_pair (msgID, - std::unique_ptr(new IncompleteMessage (msg)))).first; + m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (msg))).first; } - std::unique_ptr& incompleteMessage = it->second; + auto& incompleteMessage = it->second; // mark fragment as received if (fragmentNum < 64) incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum); @@ -224,8 +224,8 @@ namespace transport { // missing fragment LogPrint (eLogWarning, "SSU: Missing fragments from ", (int)incompleteMessage->nextFragmentNum, " to ", fragmentNum - 1, " of message ", msgID); - auto savedFragment = new Fragment (fragmentNum, buf, fragmentSize, isLast); - if (incompleteMessage->savedFragments.insert (std::unique_ptr(savedFragment)).second) + auto savedFragment = m_Session.GetServer ().GetFragmentsPool ().AcquireShared (fragmentNum, buf, fragmentSize, isLast); + if (incompleteMessage->savedFragments.insert (savedFragment).second) incompleteMessage->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); else LogPrint (eLogWarning, "SSU: Fragment ", (int)fragmentNum, " of message ", msgID, " already saved"); @@ -313,8 +313,8 @@ namespace transport if (m_SentMessages.empty ()) // schedule resend at first message only ScheduleResend (); - auto ret = m_SentMessages.insert (std::make_pair (msgID, std::unique_ptr(new SentMessage))); - std::unique_ptr& sentMessage = ret.first->second; + auto ret = m_SentMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ())); + auto& sentMessage = ret.first->second; if (ret.second) { sentMessage->nextResendTime = i2p::util::GetSecondsSinceEpoch () + RESEND_INTERVAL; @@ -328,7 +328,7 @@ namespace transport uint32_t fragmentNum = 0; while (len > 0 && fragmentNum <= 127) { - Fragment * fragment = new Fragment; + auto fragment = m_Session.GetServer ().GetFragmentsPool ().AcquireShared (); fragment->fragmentNum = fragmentNum; uint8_t * payload = fragment->buf + sizeof (SSUHeader); *payload = DATA_FLAG_WANT_REPLY; // for compatibility @@ -358,7 +358,7 @@ namespace transport size += padding; } fragment->len = size; - fragments.push_back (std::unique_ptr (fragment)); + fragments.push_back (fragment); // encrypt message with session key uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 902c009a..1eb98b1d 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -64,7 +64,7 @@ namespace transport struct FragmentCmp { - bool operator() (const std::unique_ptr& f1, const std::unique_ptr& f2) const + bool operator() (const std::shared_ptr& f1, const std::shared_ptr& f2) const { return f1->fragmentNum < f2->fragmentNum; }; @@ -76,7 +76,7 @@ namespace transport int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds uint64_t receivedFragmentsBits; - std::set, FragmentCmp> savedFragments; + std::set, FragmentCmp> savedFragments; IncompleteMessage (std::shared_ptr m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0), receivedFragmentsBits (0) {}; @@ -85,7 +85,7 @@ namespace transport struct SentMessage { - std::vector > fragments; + std::vector > fragments; uint32_t nextResendTime; // in seconds int numResends; }; @@ -126,8 +126,8 @@ namespace transport private: SSUSession& m_Session; - std::unordered_map > m_IncompleteMessages; - std::unordered_map > m_SentMessages; + std::unordered_map > m_IncompleteMessages; + std::unordered_map > m_SentMessages; std::unordered_set m_ReceivedMessages; boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 43d0d595..462afc35 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -89,7 +89,8 @@ namespace transport void Done (); void Failed (); const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; - + SSUServer& GetServer () { return m_Server; }; + bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice diff --git a/libi2pd/util.h b/libi2pd/util.h index 000cb74e..282ce7aa 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -50,6 +50,11 @@ namespace util MemoryPool (): m_Head (nullptr) {} ~MemoryPool () + { + CleanUp (); + } + + void CleanUp () { while (m_Head) { @@ -57,8 +62,8 @@ namespace util m_Head = static_cast(*(void * *)m_Head); // next ::operator delete ((void *)tmp); } - } - + } + template T * Acquire (TArgs&&... args) { From f7f36568efb3f9b9feffc3d6a6caee9816dd237e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Sep 2021 14:29:43 -0400 Subject: [PATCH 163/186] set gzip compression to false by default --- libi2pd/Streaming.h | 2 +- libi2pd_client/ClientContext.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 9d206098..51fb03ab 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -261,7 +261,7 @@ namespace stream typedef std::function)> Acceptor; - StreamingDestination (std::shared_ptr owner, uint16_t localPort = 0, bool gzip = true); + StreamingDestination (std::shared_ptr owner, uint16_t localPort = 0, bool gzip = false); ~StreamingDestination (); void Start (); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 081fa67d..09516bb9 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -699,7 +699,7 @@ namespace client accessList=section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, ""); std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); - bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); + bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, false); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); From 247b6a0ed236202eb0d5778ef02d71044c8d3a92 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Sep 2021 13:13:27 -0400 Subject: [PATCH 164/186] memory pool for SSU packets --- libi2pd/SSU.cpp | 18 +++++++++--------- libi2pd/SSU.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index a4fec82e..86e76b8e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -255,14 +255,14 @@ namespace transport void SSUServer::Receive () { - SSUPacket * packet = new SSUPacket (); + SSUPacket * packet = m_PacketsPool.AcquireMt (); m_Socket.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, std::bind (&SSUServer::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet)); } void SSUServer::ReceiveV6 () { - SSUPacket * packet = new SSUPacket (); + SSUPacket * packet = m_PacketsPool.AcquireMt (); m_SocketV6.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from, std::bind (&SSUServer::HandleReceivedFromV6, this, std::placeholders::_1, std::placeholders::_2, packet)); } @@ -293,7 +293,7 @@ namespace transport { while (moreBytes && packets.size () < 25) { - packet = new SSUPacket (); + packet = m_PacketsPool.AcquireMt (); packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, 0, ec); if (!ec) { @@ -304,7 +304,7 @@ namespace transport else { LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ()); - delete packet; + m_PacketsPool.ReleaseMt (packet); break; } } @@ -315,7 +315,7 @@ namespace transport } else { - delete packet; + m_PacketsPool.ReleaseMt (packet); if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ()); @@ -352,7 +352,7 @@ namespace transport { while (moreBytes && packets.size () < 25) { - packet = new SSUPacket (); + packet = m_PacketsPool.AcquireMt (); packet->len = m_SocketV6.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from, 0, ec); if (!ec) { @@ -363,7 +363,7 @@ namespace transport else { LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ()); - delete packet; + m_PacketsPool.ReleaseMt (packet);; break; } } @@ -374,7 +374,7 @@ namespace transport } else { - delete packet; + m_PacketsPool.ReleaseMt (packet); if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ()); @@ -421,8 +421,8 @@ namespace transport if (session) session->FlushData (); session = nullptr; } - delete packet; } + m_PacketsPool.ReleaseMt (packets); if (session) session->FlushData (); } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 586d7089..b97cacb4 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -144,6 +144,7 @@ namespace transport i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; i2p::util::MemoryPool m_SentMessagesPool; + i2p::util::MemoryPoolMt m_PacketsPool; public: // for HTTP only From ec86c4611d527cf9c9b3e4d9b9db53f7bde8e393 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Sep 2021 05:19:55 +0300 Subject: [PATCH 165/186] disable reload checks for UDP tunnels (TODO) Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 09516bb9..4eab189f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -963,6 +963,7 @@ namespace client } } + /* // TODO: Write correct UDP tunnels stop for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();) { if(clean && !it->second->isUpdated) { @@ -983,7 +984,7 @@ namespace client it->second->isUpdated = false; it++; } - } + } */ } } } From e5c773a3eb22e95c33a293a8ccdd6bdf4899a607 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 13 Sep 2021 13:27:29 +0300 Subject: [PATCH 166/186] [webconsole] move resources to separate header file Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 73 +---------------------------- daemon/HTTPServerResources.h | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 71 deletions(-) create mode 100644 daemon/HTTPServerResources.h diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c2aee205..1e002b1b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -36,81 +36,12 @@ #include "Win32App.h" #endif -// For image and info +// For image, style and info #include "version.h" +#include "HTTPServerResources.h" namespace i2p { namespace http { - const std::string itoopieFavicon = - "data:image/png;base64," - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx" - "jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0" - "d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB" - "vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn" - "cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP" - "6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps" - "/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X" - "+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/" - "z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/" - "P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am" - "+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM" - "EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1" - "oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ" - "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" - "RU5ErkJggg=="; - - // Bundled style - const std::string internalCSS = - "\r\n"; - - // for external style sheet - std::string externalCSS; - static void LoadExtCSS () { std::stringstream s; diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h new file mode 100644 index 00000000..876948e8 --- /dev/null +++ b/daemon/HTTPServerResources.h @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2013-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 +*/ + +#ifndef HTTP_SERVER_RESOURCES_H__ +#define HTTP_SERVER_RESOURCES_H__ + +namespace i2p +{ +namespace http +{ + const std::string itoopieFavicon = + "data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx" + "jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0" + "d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB" + "vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn" + "cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP" + "6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps" + "/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X" + "+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/" + "z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/" + "P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am" + "+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM" + "EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1" + "oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ" + "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" + "RU5ErkJggg=="; + + // bundled style sheet + const std::string internalCSS = + "\r\n"; + + // for external style sheet + std::string externalCSS; + +} // http +} // i2p + +#endif /* HTTP_SERVER_RESOURCES_H__ */ From d2faec70be9cfac055c0296e58a8299d47d6d01b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 14 Sep 2021 14:48:21 +0300 Subject: [PATCH 167/186] [gzip] do not initialize deflator if gzip is not enabled for tunnel Signed-off-by: R4SAS --- libi2pd/Datagram.cpp | 14 ++++++-- libi2pd/Datagram.h | 4 +-- libi2pd/I2NPProtocol.cpp | 72 ++++++++++++++++++++-------------------- libi2pd/Streaming.cpp | 14 +++++--- libi2pd/Streaming.h | 2 +- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index d000a9e0..627c0481 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -21,6 +21,9 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { + if (m_Gzip) + m_Deflator.reset (new i2p::data::GzipDeflator); + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); m_From.resize (identityLen); m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); @@ -152,11 +155,16 @@ namespace datagram const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { + size_t size; auto msg = m_I2NPMsgsPool.AcquireShared (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : - i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); + + if (m_Gzip && m_Deflator) + size = m_Deflator->Deflate (payloads, buf, msg->maxLen - msg->len); + else + size = i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); + if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 5dd6c8b6..564eb10b 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -164,7 +164,7 @@ namespace datagram std::map m_ReceiversByPorts; i2p::data::GzipInflator m_Inflator; - i2p::data::GzipDeflator m_Deflator; + std::unique_ptr m_Deflator; std::vector m_From, m_Signature; i2p::util::MemoryPool > m_I2NPMsgsPool; }; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5a2fa9c1..29d68b3c 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -40,7 +40,7 @@ namespace i2p { I2NPMessage * msg = nullptr; if (endpoint) - { + { // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 msg->Align (6); @@ -50,7 +50,7 @@ namespace i2p { msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); - } + } return std::shared_ptr(msg); } @@ -222,12 +222,12 @@ namespace i2p { memcpy (buf + 33, replyTag, 8); // 8 bytes tag buf += 41; - } - else - { + } + else + { memcpy (buf + 33, replyTag, 32); // 32 bytes tag buf += 65; - } + } m->len += (buf - m->GetPayload ()); m->FillI2NPMessageHeader (eI2NPDatabaseLookup); @@ -267,7 +267,7 @@ namespace i2p LogPrint (eLogError, "I2NP: Invalid RouterInfo buffer for DatabaseStore"); return nullptr; } - + auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); @@ -285,12 +285,12 @@ namespace i2p buf += 32; // reply tunnel gateway } else - { + { memset (buf, 0, 4); // zero tunnelID means direct reply buf += 4; memcpy (buf, context.GetIdentHash (), 32); buf += 32; - } + } } uint8_t * sizePtr = buf; @@ -303,7 +303,7 @@ namespace i2p { i2p::data::GzipDeflator deflator; size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); - } + } if (size) { htobe16buf (sizePtr, size); // size @@ -427,14 +427,14 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); return false; - } + } } else - { + { encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); + encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); - } + } } return true; } @@ -561,7 +561,7 @@ namespace i2p LogPrint (eLogDebug, "I2NP: Short request record ", i, " is ours"); uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (!i2p::context.DecryptTunnelShortRequestRecord (record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) - { + { LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); return; } @@ -569,7 +569,7 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Unknown layer encryption type ", clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE], " in short request record"); return; - } + } auto& noiseState = i2p::context.GetCurrentNoiseState (); uint8_t replyKey[32], layerKey[32], ivKey[32]; i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); @@ -581,7 +581,7 @@ namespace i2p { i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "TunnelLayerIVKey", noiseState.m_CK); memcpy (ivKey, noiseState.m_CK + 32, 32); - } + } else memcpy (ivKey, noiseState.m_CK , 32); @@ -593,7 +593,7 @@ namespace i2p i2p::transport::transports.IsTransitBandwidthExceeded ()) retCode = 30; if (!retCode) - { + { // create new transit tunnel auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -604,13 +604,13 @@ namespace i2p clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); } - + // encrypt reply uint8_t nonce[12]; memset (nonce, 0, 12); uint8_t * reply = buf + 1; for (int j = 0; j < num; j++) - { + { nonce[4] = j; // nonce is record # if (j == i) { @@ -621,29 +621,29 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); return; - } + } } else i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply); - reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } // send reply if (isEndpoint) - { + { auto replyMsg = NewI2NPShortMessage (); replyMsg->Concat (buf, len); replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local? { - i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; memcpy (&tag, noiseState.m_CK, 8); // we send it to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); - } + } else { // IBGW is local @@ -653,18 +653,18 @@ namespace i2p tunnel->SendTunnelDataMsg (replyMsg); else LogPrint (eLogWarning, "I2NP: Tunnel ", tunnelID, " not found for short tunnel build reply"); - } - } - else + } + } + else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); return; - } + } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - } - + } + } + std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { auto msg = NewI2NPTunnelMessage (false); @@ -781,13 +781,13 @@ namespace i2p break; case eI2NPShortTunnelBuild: HandleShortTunnelBuildMsg (msgID, buf, size); - break; + break; case eI2NPVariableTunnelBuildReply: HandleTunnelBuildReplyMsg (msgID, buf, size, false); break; case eI2NPShortTunnelBuildReply: HandleTunnelBuildReplyMsg (msgID, buf, size, true); - break; + break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); break; @@ -844,8 +844,8 @@ namespace i2p case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: - case eI2NPShortTunnelBuild: - case eI2NPShortTunnelBuildReply: + case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); break; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 95f6a150..c6447b5f 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1040,6 +1040,8 @@ namespace stream m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip), m_PendingIncomingTimer (m_Owner->GetService ()) { + if (m_Gzip) + m_Deflator.reset (new i2p::data::GzipDeflator); } StreamingDestination::~StreamingDestination () @@ -1296,13 +1298,17 @@ namespace stream std::shared_ptr StreamingDestination::CreateDataMessage ( const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { + size_t size; auto msg = m_I2NPMsgsPool.AcquireShared (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for lengthlength msg->len += 4; - size_t size = (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE)? - i2p::data::GzipNoCompression (payload, len, buf, msg->maxLen - msg->len): - m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + + if (m_Gzip && m_Deflator) + size = m_Deflator->Deflate (payload, len, buf, msg->maxLen - msg->len); + else + size = i2p::data::GzipNoCompression (payload, len, buf, msg->maxLen - msg->len); + if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 51fb03ab..189b1a64 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -312,7 +312,7 @@ namespace stream public: i2p::data::GzipInflator m_Inflator; - i2p::data::GzipDeflator m_Deflator; + std::unique_ptr m_Deflator; // for HTTP only const decltype(m_Streams)& GetStreams () const { return m_Streams; }; From 3dd9e812968f7f75a4730b1287d42483f8eecd99 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 Sep 2021 02:53:30 +0300 Subject: [PATCH 168/186] [addressbook] check domain ending when processing subscriptions Signed-off-by: R4SAS --- libi2pd_client/AddressBook.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index ba2d8276..3d5c83c0 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -470,6 +470,20 @@ namespace client if (pos != std::string::npos) addr = addr.substr(0, pos); // remove comments + pos = name.find(".b32.i2p"); + if (pos != std::string::npos) + { + LogPrint (eLogError, "Addressbook: skipped adding of b32 address: ", name); + continue; + } + + pos = name.find(".i2p"); + if (pos == std::string::npos) + { + LogPrint (eLogError, "Addressbook: malformed domain: ", name); + continue; + } + auto ident = std::make_shared (); if (!ident->FromBase64(addr)) { LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name); From 5b2b9e00a2d5ddb673ea443c73d381251e54e4ea Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Sep 2021 21:52:39 -0400 Subject: [PATCH 169/186] reuse receive buffer --- libi2pd/NTCP2.cpp | 35 ++++++++++++++++++++++++++++++----- libi2pd/NTCP2.h | 8 ++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ed84b8e7..5b542187 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -332,8 +332,8 @@ namespace transport m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), - m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false), - m_NextPaddingSize (16) + m_NextReceivedBufferSize (0), m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), + m_IsSending (false), m_IsReceiving (false), m_NextPaddingSize (16) { if (in_RemoteRouter) // Alice { @@ -405,7 +405,30 @@ namespace transport htole64buf (nonce + 4, seqn); } + void NTCP2Session::CreateNextReceivedBuffer (size_t size) + { + if (m_NextReceivedBuffer) + { + if (size <= m_NextReceivedBufferSize) + return; // buffer is good, do nothing + else + delete[] m_NextReceivedBuffer; + } + m_NextReceivedBuffer = new uint8_t[size]; + m_NextReceivedBufferSize = size; + } + void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts) + { + if (m_NextReceivedBuffer && !m_IsReceiving && + ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT) + { + delete[] m_NextReceivedBuffer; + m_NextReceivedBuffer = nullptr; + m_NextReceivedBufferSize = 0; + } + } + void NTCP2Session::KeyDerivationFunctionDataPhase () { uint8_t k[64]; @@ -759,8 +782,7 @@ namespace transport LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen); if (m_NextReceivedLen >= 16) { - if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer; - m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen]; + CreateNextReceivedBuffer (m_NextReceivedLen); boost::system::error_code ec; size_t moreBytes = m_Socket.available(ec); if (!ec && moreBytes >= m_NextReceivedLen) @@ -787,6 +809,7 @@ namespace transport const int one = 1; setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); #endif + m_IsReceiving = true; boost::asio::async_read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -810,7 +833,7 @@ namespace transport { LogPrint (eLogDebug, "NTCP2: received message decrypted"); ProcessNextFrame (m_NextReceivedBuffer, m_NextReceivedLen-16); - delete[] m_NextReceivedBuffer; m_NextReceivedBuffer = nullptr; // we don't need received buffer anymore + m_IsReceiving = false; ReceiveLength (); } else @@ -1448,6 +1471,8 @@ namespace transport LogPrint (eLogDebug, "NTCP2: No activity for ", session->GetTerminationTimeout (), " seconds"); session->TerminateByTimeout (); // it doesn't change m_NTCP2Session right a way } + else + it.second->DeleteNextReceiveBuffer (ts); // pending for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index bcee1b09..b54c1634 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -34,6 +34,7 @@ namespace transport const int NTCP2_ESTABLISH_TIMEOUT = 10; // 10 seconds const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds + const int NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT = 3; // 3 seconds const int NTCP2_ROUTERINFO_RESEND_INTERVAL = 25*60; // 25 minuntes in seconds const int NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD = 25*60; // 25 minuntes @@ -132,7 +133,8 @@ namespace transport void TerminateByTimeout (); void Done (); void Close () { m_Socket.close (); }; // for accept - + void DeleteNextReceiveBuffer (uint64_t ts); + boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; const boost::asio::ip::tcp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; void SetRemoteEndpoint (const boost::asio::ip::tcp::endpoint& ep) { m_RemoteEndpoint = ep; }; @@ -151,6 +153,7 @@ namespace transport void Established (); void CreateNonce (uint64_t seqn, uint8_t * nonce); + void CreateNextReceivedBuffer (size_t size); void KeyDerivationFunctionDataPhase (); void SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey); @@ -206,6 +209,7 @@ namespace transport #endif uint16_t m_NextReceivedLen; uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; + size_t m_NextReceivedBufferSize; union { uint8_t buf[8]; @@ -215,7 +219,7 @@ namespace transport i2p::I2NPMessagesHandler m_Handler; - bool m_IsSending; + bool m_IsSending, m_IsReceiving; std::list > m_SendQueue; uint64_t m_NextRouterInfoResendTime; // seconds since epoch From 317d8cdc48c2e7934fe14406190d23fdb8e3030d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Sep 2021 15:44:43 -0400 Subject: [PATCH 170/186] don't allocate separate buffers for SessionRequest and SessionCreated --- libi2pd/NTCP2.cpp | 18 ++++++------------ libi2pd/NTCP2.h | 9 ++++++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 5b542187..05d68203 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -32,14 +32,12 @@ namespace i2p namespace transport { NTCP2Establisher::NTCP2Establisher (): - m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) + m_SessionConfirmedBuffer (nullptr) { } NTCP2Establisher::~NTCP2Establisher () { - delete[] m_SessionRequestBuffer; - delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; } @@ -112,9 +110,8 @@ namespace transport void NTCP2Establisher::CreateSessionRequestMessage () { // create buffer and fill padding - auto paddingLength = rand () % (287 - 64); // message length doesn't exceed 287 bytes + auto paddingLength = rand () % (NTCP2_SESSION_REQUEST_MAX_SIZE - 64); // message length doesn't exceed 287 bytes m_SessionRequestBufferLen = paddingLength + 64; - m_SessionRequestBuffer = new uint8_t[m_SessionRequestBufferLen]; RAND_bytes (m_SessionRequestBuffer + 64, paddingLength); // encrypt X i2p::crypto::CBCEncryption encryption; @@ -152,9 +149,8 @@ namespace transport void NTCP2Establisher::CreateSessionCreatedMessage () { - auto paddingLen = rand () % (287 - 64); + auto paddingLen = rand () % (NTCP2_SESSION_CREATED_MAX_SIZE - 64); m_SessionCreatedBufferLen = paddingLen + 64; - m_SessionCreatedBuffer = new uint8_t[m_SessionCreatedBufferLen]; RAND_bytes (m_SessionCreatedBuffer + 64, paddingLen); // encrypt Y i2p::crypto::CBCEncryption encryption; @@ -463,7 +459,6 @@ namespace transport } else { - m_Establisher->m_SessionCreatedBuffer = new uint8_t[287]; // TODO: determine actual max size // we receive first 64 bytes (32 Y, and 32 ChaCha/Poly frame) first boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionCreatedReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -486,7 +481,7 @@ namespace transport { if (paddingLen > 0) { - if (paddingLen <= 287 - 64) // session request is 287 bytes max + if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max { boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer + 64, paddingLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -539,7 +534,7 @@ namespace transport { if (paddingLen > 0) { - if (paddingLen <= 287 - 64) // session created is 287 bytes max + if (paddingLen <= NTCP2_SESSION_CREATED_MAX_SIZE - 64) // session created is 287 bytes max { boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer + 64, paddingLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionCreatedPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -742,7 +737,6 @@ namespace transport void NTCP2Session::ServerLogin () { m_Establisher->CreateEphemeralKey (); - m_Establisher->m_SessionRequestBuffer = new uint8_t[287]; // 287 bytes max for now boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index b54c1634..f9f3e751 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -28,6 +28,8 @@ namespace transport { const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519; + const size_t NTCP2_SESSION_REQUEST_MAX_SIZE = 287; + const size_t NTCP2_SESSION_CREATED_MAX_SIZE = 287; const int NTCP2_MAX_PADDING_RATIO = 6; // in % const int NTCP2_CONNECT_TIMEOUT = 5; // 5 seconds @@ -40,7 +42,7 @@ namespace transport const int NTCP2_CLOCK_SKEW = 60; // in seconds const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up - + enum NTCP2BlockType { eNTCP2BlkDateTime = 0, @@ -116,7 +118,8 @@ namespace transport i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len; - uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer; + uint8_t m_SessionRequestBuffer[NTCP2_SESSION_REQUEST_MAX_SIZE], + m_SessionCreatedBuffer[NTCP2_SESSION_CREATED_MAX_SIZE], * m_SessionConfirmedBuffer; size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen; }; From 31bdce1f1f37d6fafb83cb202b0b6f759b00e470 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Sep 2021 19:01:22 -0400 Subject: [PATCH 171/186] cleanup received messages list by timestamp --- libi2pd/SSUData.cpp | 19 +++++++++++++++---- libi2pd/SSUData.h | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 2c6f72e1..7d048799 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -246,8 +246,8 @@ namespace transport { if (!m_ReceivedMessages.count (msgID)) { - m_ReceivedMessages.insert (msgID); m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); + m_ReceivedMessages.emplace (msgID, m_LastMessageReceivedTime); if (!msg->IsExpired ()) { m_Handler.PutNextMessage (msg); @@ -511,10 +511,21 @@ namespace transport else ++it; } - // decay - if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || - i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) + + if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) + // decay m_ReceivedMessages.clear (); + else + { + // delete old received messages + for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) + { + if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) + it = m_ReceivedMessages.erase (it); + else + ++it; + } + } ScheduleIncompleteMessagesCleanup (); } diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 1eb98b1d..3dcff1d4 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -40,6 +40,7 @@ namespace transport const int MAX_NUM_RESENDS = 5; const int DECAY_INTERVAL = 20; // in seconds const int INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds + const int RECEIVED_MESSAGES_CLEANUP_TIMEOUT = 40; // in seconds const unsigned int MAX_NUM_RECEIVED_MESSAGES = 1000; // how many msgID we store for duplicates check const int MAX_OUTGOING_WINDOW_SIZE = 200; // how many unacked message we can store // data flags @@ -128,7 +129,7 @@ namespace transport SSUSession& m_Session; std::unordered_map > m_IncompleteMessages; std::unordered_map > m_SentMessages; - std::unordered_set m_ReceivedMessages; + std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; From 8debdc264c863ed81380b3b2e010ffe1612ad0d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Sep 2021 22:13:34 -0400 Subject: [PATCH 172/186] use common cleanup timer for all SSU sessions --- libi2pd/SSU.cpp | 4 +++ libi2pd/SSUData.cpp | 63 +++++++++++++++--------------------------- libi2pd/SSUData.h | 10 ++----- libi2pd/SSUSession.cpp | 6 ++++ libi2pd/SSUSession.h | 3 +- 5 files changed, 38 insertions(+), 48 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 86e76b8e..7b129811 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -952,6 +952,8 @@ namespace transport session->Failed (); }); } + else + it.second->CleanUp (); ScheduleTermination (); } } @@ -980,6 +982,8 @@ namespace transport session->Failed (); }); } + else + it.second->CleanUp (); ScheduleTerminationV6 (); } } diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 7d048799..0468956b 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -33,7 +33,6 @@ namespace transport SSUData::SSUData (SSUSession& session): m_Session (session), m_ResendTimer (session.GetService ()), - m_IncompleteMessagesCleanupTimer (session.GetService ()), m_MaxPacketSize (session.IsV6 () ? SSU_V6_MAX_PACKET_SIZE : SSU_V4_MAX_PACKET_SIZE), m_PacketSize (m_MaxPacketSize), m_LastMessageReceivedTime (0) { @@ -45,13 +44,11 @@ namespace transport void SSUData::Start () { - ScheduleIncompleteMessagesCleanup (); } void SSUData::Stop () { m_ResendTimer.cancel (); - m_IncompleteMessagesCleanupTimer.cancel (); m_IncompleteMessages.clear (); m_SentMessages.clear (); m_ReceivedMessages.clear (); @@ -487,48 +484,34 @@ namespace transport } } - void SSUData::ScheduleIncompleteMessagesCleanup () + void SSUData::CleanUp () { - m_IncompleteMessagesCleanupTimer.cancel (); - m_IncompleteMessagesCleanupTimer.expires_from_now (boost::posix_time::seconds(INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT)); - auto s = m_Session.shared_from_this(); - m_IncompleteMessagesCleanupTimer.async_wait ([s](const boost::system::error_code& ecode) - { s->m_Data.HandleIncompleteMessagesCleanupTimer (ecode); }); - } - - void SSUData::HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) + if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) { - if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) - { - LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); - it = m_IncompleteMessages.erase (it); - } + LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); + it = m_IncompleteMessages.erase (it); + } + else + ++it; + } + + if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) + // decay + m_ReceivedMessages.clear (); + else + { + // delete old received messages + for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) + { + if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) + it = m_ReceivedMessages.erase (it); else ++it; - } - - if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) - // decay - m_ReceivedMessages.clear (); - else - { - // delete old received messages - for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) - { - if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) - it = m_ReceivedMessages.erase (it); - else - ++it; - } } - - ScheduleIncompleteMessagesCleanup (); - } - } + } + } } } diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 3dcff1d4..590a538c 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include "I2NPProtocol.h" @@ -101,7 +100,8 @@ namespace transport void Start (); void Stop (); - + void CleanUp (); + void ProcessMessage (uint8_t * buf, size_t len); void FlushReceivedMessage (); void Send (std::shared_ptr msg); @@ -120,17 +120,13 @@ namespace transport void ScheduleResend (); void HandleResendTimer (const boost::system::error_code& ecode); - void ScheduleIncompleteMessagesCleanup (); - void HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode); - - private: SSUSession& m_Session; std::unordered_map > m_IncompleteMessages; std::unordered_map > m_SentMessages; std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds - boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; + boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; uint32_t m_LastMessageReceivedTime; // in second diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 59ee578b..e01b0c0e 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1004,6 +1004,12 @@ namespace transport } } + void SSUSession::CleanUp () + { + m_Data.CleanUp (); + // TODO: clean up m_RelayRequests + } + void SSUSession::ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) { uint32_t nonce = bufbe32toh (buf); // 4 bytes diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 462afc35..acf232b9 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -106,6 +106,7 @@ namespace transport void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers void FlushData (); + void CleanUp (); private: From 18b6ba80f2cfaa52c2c5609ac54a1a96360db422 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Sep 2021 19:09:56 -0400 Subject: [PATCH 173/186] cleanup RelayRequests --- libi2pd/SSU.cpp | 10 ++++++---- libi2pd/SSUData.cpp | 3 +-- libi2pd/SSUData.h | 2 +- libi2pd/SSUSession.cpp | 17 ++++++++++++----- libi2pd/SSUSession.h | 4 ++-- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 7b129811..9e814303 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -930,7 +930,8 @@ namespace transport void SSUServer::ScheduleTermination () { - m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT)); + uint64_t timeout = SSU_TERMINATION_CHECK_TIMEOUT + (rand () % SSU_TERMINATION_CHECK_TIMEOUT)/5; + m_TerminationTimer.expires_from_now (boost::posix_time::seconds(timeout)); m_TerminationTimer.async_wait (std::bind (&SSUServer::HandleTerminationTimer, this, std::placeholders::_1)); } @@ -953,14 +954,15 @@ namespace transport }); } else - it.second->CleanUp (); + it.second->CleanUp (ts); ScheduleTermination (); } } void SSUServer::ScheduleTerminationV6 () { - m_TerminationTimerV6.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT)); + uint64_t timeout = SSU_TERMINATION_CHECK_TIMEOUT + (rand () % SSU_TERMINATION_CHECK_TIMEOUT)/5; + m_TerminationTimerV6.expires_from_now (boost::posix_time::seconds(timeout)); m_TerminationTimerV6.async_wait (std::bind (&SSUServer::HandleTerminationTimerV6, this, std::placeholders::_1)); } @@ -983,7 +985,7 @@ namespace transport }); } else - it.second->CleanUp (); + it.second->CleanUp (ts); ScheduleTerminationV6 (); } } diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 0468956b..18621fe0 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -484,9 +484,8 @@ namespace transport } } - void SSUData::CleanUp () + void SSUData::CleanUp (uint64_t ts) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) { if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 590a538c..35311bb6 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -100,7 +100,7 @@ namespace transport void Start (); void Stop (); - void CleanUp (); + void CleanUp (uint64_t ts); void ProcessMessage (uint8_t * buf, size_t len); void FlushReceivedMessage (); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index e01b0c0e..3e4eecb8 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -730,7 +730,7 @@ namespace transport (remoteIP.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch // we assume that HolePunch has been sent by this time and our SessionRequest will go through - m_Server.CreateDirectSession (it->second, remoteEndpoint, false); + m_Server.CreateDirectSession (it->second.first, remoteEndpoint, false); } // delete request m_RelayRequests.erase (it); @@ -905,7 +905,8 @@ namespace transport } uint32_t nonce; RAND_bytes ((uint8_t *)&nonce, 4); - m_RelayRequests[nonce] = to; + auto ts = i2p::util::GetSecondsSinceEpoch (); + m_RelayRequests.emplace (nonce, std::make_pair (to, ts)); SendRelayRequest (introducer, nonce); } @@ -1004,10 +1005,16 @@ namespace transport } } - void SSUSession::CleanUp () + void SSUSession::CleanUp (uint64_t ts) { - m_Data.CleanUp (); - // TODO: clean up m_RelayRequests + m_Data.CleanUp (ts); + for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();) + { + if (ts > it->second.second + SSU_CONNECT_TIMEOUT) + it = m_RelayRequests.erase (it); + else + ++it; + } } void SSUSession::ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index acf232b9..95697a91 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -106,7 +106,7 @@ namespace transport void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers void FlushData (); - void CleanUp (); + void CleanUp (uint64_t ts); private: @@ -170,7 +170,7 @@ namespace transport SSUData m_Data; bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only - std::map > m_RelayRequests; // nonce->Charlie + std::unordered_map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } From 518e53a61c2491a1f97fcc317aee871f343ece12 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Sep 2021 14:23:39 -0400 Subject: [PATCH 174/186] use flat_map for smaller tables --- libi2pd/SSU.cpp | 2 +- libi2pd/SSU.h | 2 +- libi2pd/SSUData.cpp | 2 +- libi2pd/SSUData.h | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 9e814303..be263370 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -218,7 +218,7 @@ namespace transport void SSUServer::AddRelay (uint32_t tag, std::shared_ptr relay) { - m_Relays[tag] = relay; + m_Relays.emplace (tag, relay); } void SSUServer::RemoveRelay (uint32_t tag) diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index b97cacb4..4b561be0 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -139,7 +139,7 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to std::map > m_Sessions, m_SessionsV6; std::map > m_Relays; // we are introducer - std::map m_PeerTests; // nonce -> creation time in milliseconds + boost::container::flat_map m_PeerTests; // nonce -> creation time in milliseconds i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 18621fe0..ccc89b41 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -310,7 +310,7 @@ namespace transport if (m_SentMessages.empty ()) // schedule resend at first message only ScheduleResend (); - auto ret = m_SentMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ())); + auto ret = m_SentMessages.emplace (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ()); auto& sentMessage = ret.first->second; if (ret.second) { diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 35311bb6..fa6aa92c 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -11,10 +11,10 @@ #include #include -#include #include #include #include +#include #include "I2NPProtocol.h" #include "Identity.h" #include "RouterInfo.h" @@ -123,9 +123,9 @@ namespace transport private: SSUSession& m_Session; - std::unordered_map > m_IncompleteMessages; - std::unordered_map > m_SentMessages; - std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds + boost::container::flat_map > m_IncompleteMessages; + boost::container::flat_map > m_SentMessages; + boost::container::flat_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; From b9dd4aee8d58de3051a0883a2484555227541b74 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Sep 2021 19:12:12 -0400 Subject: [PATCH 175/186] use flat_map for incompete messages --- libi2pd/TunnelEndpoint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index f9878165..aa87537a 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -10,9 +10,9 @@ #define TUNNEL_ENDPOINT_H__ #include -#include #include #include +#include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -59,8 +59,8 @@ namespace tunnel private: - std::unordered_map m_IncompleteMessages; - std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + boost::container::flat_map m_IncompleteMessages; + boost::container::flat_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From 1bb1d89fab14577be5fe1d33eaab630d05ede136 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 25 Sep 2021 18:30:17 -0400 Subject: [PATCH 176/186] change back to map and unodered_map --- libi2pd/SSU.h | 2 +- libi2pd/SSUData.h | 9 +++++---- libi2pd/SSUSession.h | 2 +- libi2pd/TunnelEndpoint.h | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 4b561be0..b97cacb4 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -139,7 +139,7 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to std::map > m_Sessions, m_SessionsV6; std::map > m_Relays; // we are introducer - boost::container::flat_map m_PeerTests; // nonce -> creation time in milliseconds + std::map m_PeerTests; // nonce -> creation time in milliseconds i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index fa6aa92c..8fe33a33 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -12,9 +12,10 @@ #include #include #include +#include +#include #include #include -#include #include "I2NPProtocol.h" #include "Identity.h" #include "RouterInfo.h" @@ -123,9 +124,9 @@ namespace transport private: SSUSession& m_Session; - boost::container::flat_map > m_IncompleteMessages; - boost::container::flat_map > m_SentMessages; - boost::container::flat_map m_ReceivedMessages; // msgID -> timestamp in seconds + std::map > m_IncompleteMessages; + std::map > m_SentMessages; + std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 95697a91..bd4b4b93 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -170,7 +170,7 @@ namespace transport SSUData m_Data; bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only - std::unordered_map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) + std::map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index aa87537a..e5a6bbc8 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -59,8 +59,8 @@ namespace tunnel private: - boost::container::flat_map m_IncompleteMessages; - boost::container::flat_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + std::unordered_map m_IncompleteMessages; + std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From b10e5ce35819397d105b122396ce4c6f8cfc7716 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Sep 2021 11:20:20 -0400 Subject: [PATCH 177/186] send ping --- libi2pd/Streaming.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++- libi2pd/Streaming.h | 4 +++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index c6447b5f..be3d09d8 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -490,7 +490,7 @@ namespace stream handler(boost::system::error_code ()); m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ())); } - + void Stream::SendBuffer () { int numMsgs = m_WindowSize - m_SentPackets.size (); @@ -665,6 +665,42 @@ namespace stream LogPrint (eLogDebug, "Streaming: Quick Ack sent. ", (int)numNacks, " NACKs"); } + void Stream::SendPing () + { + Packet p; + uint8_t * packet = p.GetBuffer (); + size_t size = 0; + htobe32buf (packet, m_RecvStreamID); + size += 4; // sendStreamID + memset (packet + size, 0, 14); + size += 14; // all zeroes + uint16_t flags = PACKET_FLAG_ECHO | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_FROM_INCLUDED; + bool isOfflineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().IsOfflineSignature (); + if (isOfflineSignature) flags |= PACKET_FLAG_OFFLINE_SIGNATURE; + htobe16buf (packet + size, flags); + size += 2; // flags + size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen (); + size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); + uint8_t * optionsSize = packet + size; // set options size later + size += 2; // options size + m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); + size += identityLen; // from + if (isOfflineSignature) + { + const auto& offlineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetOfflineSignature (); + memcpy (packet + size, offlineSignature.data (), offlineSignature.size ()); + size += offlineSignature.size (); // offline signature + } + uint8_t * signature = packet + size; // set it later + memset (signature, 0, signatureLen); // zeroes for now + size += signatureLen; // signature + htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size + m_LocalDestination.GetOwner ()->Sign (packet, size, signature); + p.len = size; + SendPackets (std::vector { &p }); + LogPrint (eLogDebug, "Streaming: Ping of ", p.len, " bytes sent"); + } + void Stream::Close () { LogPrint(eLogDebug, "Streaming: closing stream with sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID, ", status=", m_Status); @@ -1103,6 +1139,13 @@ namespace stream } else { + if (packet->IsEcho ()) + { + // pong + LogPrint (eLogInfo, "Streaming: Pong received rSID=", packet->GetReceiveStreamID ()); + DeletePacket (packet); + return; + } if (packet->IsSYN () && !packet->GetSeqn ()) // new incoming stream { uint32_t receiveStreamID = packet->GetReceiveStreamID (); @@ -1197,6 +1240,12 @@ namespace stream return s; } + void StreamingDestination::SendPing (std::shared_ptr remote) + { + auto s = std::make_shared (m_Owner->GetService (), *this, remote, 0); + s->SendPing (); + } + std::shared_ptr StreamingDestination::CreateNewIncomingStream (uint32_t receiveStreamID) { auto s = std::make_shared (m_Owner->GetService (), *this); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 189b1a64..c13dcab1 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -179,7 +179,8 @@ namespace stream void HandlePing (Packet * packet); size_t Send (const uint8_t * buf, size_t len); void AsyncSend (const uint8_t * buf, size_t len, SendHandler handler); - + void SendPing (); + template void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0); size_t ReadSome (uint8_t * buf, size_t len) { return ConcatenatePackets (buf, len); }; @@ -268,6 +269,7 @@ namespace stream void Stop (); std::shared_ptr CreateNewOutgoingStream (std::shared_ptr remote, int port = 0); + void SendPing (std::shared_ptr remote); void DeleteStream (std::shared_ptr stream); bool DeleteStream (uint32_t recvStreamID); void SetAcceptor (const Acceptor& acceptor); From 2eded7cdd7cec2ce964e2695daf3ef56072064db Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Sep 2021 16:25:12 -0400 Subject: [PATCH 178/186] send ping every keealive interval for client tunnels --- libi2pd/Destination.cpp | 25 ++++++++++++++++++++ libi2pd/Destination.h | 2 ++ libi2pd_client/ClientContext.cpp | 9 +++++++- libi2pd_client/ClientContext.h | 3 ++- libi2pd_client/I2PTunnel.cpp | 39 ++++++++++++++++++++++++++++++-- libi2pd_client/I2PTunnel.h | 10 ++++++-- 6 files changed, 82 insertions(+), 6 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 438b3f19..dd811593 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1096,6 +1096,31 @@ namespace client return nullptr; } + void ClientDestination::SendPing (const i2p::data::IdentHash& to) + { + if (m_StreamingDestination) + { + auto leaseSet = FindLeaseSet (to); + if (leaseSet) + m_StreamingDestination->SendPing (leaseSet); + else + RequestDestination (to, + [s = m_StreamingDestination](std::shared_ptr ls) + { + if (ls) s->SendPing (ls); + }); + } + } + + void ClientDestination::SendPing (std::shared_ptr to) + { + RequestDestinationWithEncryptedLeaseSet (to, + [s = m_StreamingDestination](std::shared_ptr ls) + { + if (ls) s->SendPing (ls); + }); + } + std::shared_ptr ClientDestination::GetStreamingDestination (int port) const { if (port) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 0dc5450b..54df8706 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -243,6 +243,8 @@ namespace client void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0); void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port = 0); std::shared_ptr CreateStream (std::shared_ptr remote, int port = 0); + void SendPing (const i2p::data::IdentHash& to); + void SendPing (std::shared_ptr to); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); void StopAcceptingStreams (); bool IsAcceptingStreams () const; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 4eab189f..d6871fbe 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -652,6 +652,13 @@ namespace client auto tun = std::make_shared (name, dest, address, port, localDestination, destinationPort); clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); + + uint32_t keepAlive = section.second.get(I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL, 0); + if (keepAlive) + { + tun->SetKeepAliveInterval (keepAlive); + LogPrint(eLogInfo, "Clients: I2P Client tunnel keep alive interval set to ", keepAlive); + } } uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 801dc0cd..cb28e40e 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -48,6 +48,7 @@ namespace client const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels"; const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; + const char I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL[] = "keepaliveinterval"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_PORT[] = "port"; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index c01f0fe3..f70ebb8f 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -532,7 +532,7 @@ namespace client I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), - m_DestinationPort (destinationPort) + m_DestinationPort (destinationPort), m_KeepAliveInterval (0) { } @@ -540,14 +540,24 @@ namespace client { TCPIPAcceptor::Start (); GetAddress (); + if (m_KeepAliveInterval) + ScheduleKeepAliveTimer (); } void I2PClientTunnel::Stop () { TCPIPAcceptor::Stop(); m_Address = nullptr; + if (m_KeepAliveTimer) m_KeepAliveTimer->cancel (); } + void I2PClientTunnel::SetKeepAliveInterval (uint32_t keepAliveInterval) + { + m_KeepAliveInterval = keepAliveInterval; + if (m_KeepAliveInterval) + m_KeepAliveTimer.reset (new boost::asio::deadline_timer (GetLocalDestination ()->GetService ())); + } + /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ std::shared_ptr I2PClientTunnel::GetAddress () { @@ -569,6 +579,31 @@ namespace client return nullptr; } + void I2PClientTunnel::ScheduleKeepAliveTimer () + { + if (m_KeepAliveTimer) + { + m_KeepAliveTimer->expires_from_now (boost::posix_time::seconds(m_KeepAliveInterval)); + m_KeepAliveTimer->async_wait (std::bind (&I2PClientTunnel::HandleKeepAliveTimer, + this, std::placeholders::_1)); + } + } + + void I2PClientTunnel::HandleKeepAliveTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + if (m_Address && m_Address->IsValid ()) + { + if (m_Address->IsIdentHash ()) + GetLocalDestination ()->SendPing (m_Address->identHash); + else + GetLocalDestination ()->SendPing (m_Address->blindedPublicKey); + } + ScheduleKeepAliveTimer (); + } + } + I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 1db34b6c..d21b2e11 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -153,16 +153,22 @@ namespace client void Stop (); const char* GetName() { return m_Name.c_str (); } - + void SetKeepAliveInterval (uint32_t keepAliveInterval); + private: std::shared_ptr GetAddress (); + + void ScheduleKeepAliveTimer (); + void HandleKeepAliveTimer (const boost::system::error_code& ecode); private: std::string m_Name, m_Destination; std::shared_ptr m_Address; int m_DestinationPort; + uint32_t m_KeepAliveInterval; + std::unique_ptr m_KeepAliveTimer; }; From cc75efcbca2673a33ca6dfcc76b03e09a54278a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Sep 2021 18:25:15 -0400 Subject: [PATCH 179/186] fixed build for C++11 --- libi2pd/Destination.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index dd811593..54137664 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1104,18 +1104,22 @@ namespace client if (leaseSet) m_StreamingDestination->SendPing (leaseSet); else + { + auto s = m_StreamingDestination; RequestDestination (to, - [s = m_StreamingDestination](std::shared_ptr ls) + [s](std::shared_ptr ls) { if (ls) s->SendPing (ls); }); + } } } void ClientDestination::SendPing (std::shared_ptr to) { + auto s = m_StreamingDestination; RequestDestinationWithEncryptedLeaseSet (to, - [s = m_StreamingDestination](std::shared_ptr ls) + [s](std::shared_ptr ls) { if (ls) s->SendPing (ls); }); From d723faaaa3a3539bc1b09ca52351c73297a38680 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 28 Sep 2021 14:27:22 +0300 Subject: [PATCH 180/186] [UDPTunnel] restart local listener on error Signed-off-by: R4SAS --- libi2pd_client/I2PTunnel.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index f70ebb8f..b97270e4 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -964,7 +964,8 @@ namespace client RemotePort(remotePort), m_LastPort (0), m_cancel_resolve(false) { - m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU )); + m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU)); + m_LocalSocket.set_option (boost::asio::socket_base::reuse_address (true)); auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, @@ -991,7 +992,8 @@ namespace client void I2PUDPClientTunnel::HandleRecvFromLocal(const boost::system::error_code & ec, std::size_t transferred) { if(ec) { - LogPrint(eLogError, "UDP Client: ", ec.message()); + LogPrint(eLogError, "UDP Client: Reading from socket error: ", ec.message(), ". Restarting listener..."); + RecvFromLocal(); // Restart listener and continue work return; } if(!m_RemoteIdent) { @@ -1016,7 +1018,7 @@ namespace client auto ts = i2p::util::GetMillisecondsSinceEpoch(); LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); - if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) + if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); else m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); From af133f4968946d3074e8a70799ba8f9a776b1896 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Sep 2021 12:38:38 -0400 Subject: [PATCH 181/186] fixed crash if incorrect blinded signature type --- libi2pd/LeaseSet.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 75187cfe..f6734b10 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -912,6 +912,11 @@ namespace data uint8_t blindedPriv[64], blindedPub[128]; // 64 and 128 max size_t publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); std::unique_ptr blindedSigner (i2p::data::PrivateKeys::CreateSigner (blindedKey.GetBlindedSigType (), blindedPriv)); + if (!blindedSigner) + { + LogPrint (eLogError, "LeaseSet2: Can't create blinded signer for signature type ", blindedKey.GetSigType ()); + return; + } auto offset = 1; htobe16buf (m_Buffer + offset, blindedKey.GetBlindedSigType ()); offset += 2; // Blinded Public Key Sig Type memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key From e6bcd04a36a705cd24956534a6df28024f664b39 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Oct 2021 19:38:33 -0400 Subject: [PATCH 182/186] short build message for re-created tunnels and far end transports --- libi2pd/RouterInfo.h | 13 ++++++++----- libi2pd/Tunnel.cpp | 13 ++++++++----- libi2pd/Tunnel.h | 3 +++ libi2pd/TunnelConfig.h | 18 +++++++++++++----- libi2pd/TunnelPool.cpp | 19 ++++++++++++++----- libi2pd/TunnelPool.h | 1 + 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 8ffd81cd..c16f8e5f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -67,7 +67,8 @@ namespace data eSSUV6 = 0x08, eNTCP2V6Mesh = 0x10 }; - + typedef uint8_t CompatibleTransports; + enum Caps { eFloodfill = 0x01, @@ -206,9 +207,10 @@ namespace data void EnableMesh (); void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; - bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; - bool IsReachableBy (uint8_t transports) const { return m_ReachableTransports & transports; }; - bool HasValidAddresses () const { return m_SupportedTransports; }; + bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; + bool IsReachableBy (CompatibleTransports transports) const { return m_ReachableTransports & transports; }; + CompatibleTransports GetCompatibleTransports (bool incoming) const { return incoming ? m_ReachableTransports : m_SupportedTransports; }; + bool HasValidAddresses () const { return m_SupportedTransports; }; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; @@ -273,7 +275,8 @@ namespace data boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; - uint8_t m_SupportedTransports, m_ReachableTransports, m_Caps; + CompatibleTransports m_SupportedTransports, m_ReachableTransports; + uint8_t m_Caps; int m_Version; mutable std::shared_ptr m_Profile; }; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 76504e1f..1f69470c 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -31,8 +31,9 @@ namespace tunnel { Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), - m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false), - m_Latency (0) + m_Config (config), m_IsShortBuildMessage (false), m_Pool (nullptr), + m_State (eTunnelStatePending), m_FarEndTransports (0), + m_IsRecreated (false), m_Latency (0) { } @@ -180,6 +181,8 @@ namespace tunnel m_Hops.push_back (std::unique_ptr(tunnelHop)); hop = hop->prev; } + m_IsShortBuildMessage = m_Config->IsShort (); + m_FarEndTransports = m_Config->GetFarEndTransports (); m_Config = nullptr; } if (established) m_State = eTunnelStateEstablished; @@ -715,7 +718,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); CreateTunnel ( std::make_shared (std::vector > { router->GetRouterIdentity () }, - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()), nullptr + inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), false), nullptr ); } } @@ -791,7 +794,7 @@ namespace tunnel } LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel"); CreateTunnel ( - std::make_shared (std::vector > { router->GetRouterIdentity () }), nullptr + std::make_shared (std::vector > { router->GetRouterIdentity () }, false), nullptr ); } } @@ -897,7 +900,7 @@ namespace tunnel { // build symmetric outbound tunnel CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), - newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), nullptr, + newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash (), false), nullptr, GetNextOutboundTunnel ()); } else diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a1fd247a..2e1c9534 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -71,6 +71,7 @@ namespace tunnel std::shared_ptr GetTunnelConfig () const { return m_Config; } std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; + bool IsShortBuildMessage () const { return m_IsShortBuildMessage; }; TunnelState GetState () const { return m_State; }; void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; @@ -109,8 +110,10 @@ namespace tunnel std::shared_ptr m_Config; std::vector > m_Hops; + bool m_IsShortBuildMessage; std::shared_ptr m_Pool; // pool, tunnel belongs to, or null TunnelState m_State; + i2p::data::RouterInfo::CompatibleTransports m_FarEndTransports; bool m_IsRecreated; // if tunnel is replaced by new, or new tunnel requested to replace uint64_t m_Latency; // in milliseconds }; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 8cb46d09..f198dffd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -82,16 +82,17 @@ namespace tunnel public: TunnelConfig (const std::vector >& peers, - bool isShort = false): // inbound - m_IsShort (isShort) + bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // inbound + m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } TunnelConfig (const std::vector >& peers, - uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort = false): // outbound - m_IsShort (isShort) + uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, + i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // outbound + m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); m_FirstHop->isGateway = false; @@ -112,6 +113,11 @@ namespace tunnel bool IsShort () const { return m_IsShort; } + i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const + { + return m_FarEndTransports; + } + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -178,7 +184,8 @@ namespace tunnel protected: // this constructor can't be called from outside - TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false) + TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false), + m_FarEndTransports (0) { } @@ -190,6 +197,7 @@ namespace tunnel TunnelHopConfig * m_FirstHop, * m_LastHop; bool m_IsShort; + i2p::data::RouterInfo::CompatibleTransports m_FarEndTransports; }; class ZeroHopsTunnelConfig: public TunnelConfig diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7a5721fb..b349ada6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -495,6 +495,8 @@ namespace tunnel } prevHop = hop; path.Add (hop); + if (i == numHops - 1) + path.farEndTransports = hop->GetCompatibleTransports (inbound); } return true; } @@ -527,7 +529,11 @@ namespace tunnel if (r) { if (r->IsECIES ()) + { path.Add (r); + if (i == numHops - 1) + path.farEndTransports = r->GetCompatibleTransports (isInbound); + } else { LogPrint (eLogError, "Tunnels: ElGamal router ", ident.ToBase64 (), " is not supported"); @@ -557,7 +563,7 @@ namespace tunnel if (m_NumInboundHops > 0) { path.Reverse (); - config = std::make_shared (path.peers, path.isShort); + config = std::make_shared (path.peers, path.isShort, path.farEndTransports); } auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops @@ -581,7 +587,7 @@ namespace tunnel std::shared_ptr config; if (m_NumInboundHops > 0 && tunnel->GetPeers().size()) { - config = std::make_shared(tunnel->GetPeers ()); + config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage ()); } if (!m_NumInboundHops || config) { @@ -606,7 +612,8 @@ namespace tunnel { std::shared_ptr config; if (m_NumOutboundHops > 0) - config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort); + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); std::shared_ptr tunnel; if (path.isShort) @@ -643,7 +650,8 @@ namespace tunnel std::shared_ptr config; if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) { - config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); + config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage ()); } if (!m_NumOutboundHops || config) { @@ -660,7 +668,8 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); auto tunnel = tunnels.CreateInboundTunnel ( - m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers ()) : nullptr, + m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers (), + outboundTunnel->IsShortBuildMessage ()) : nullptr, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 97ca0419..875a9955 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -40,6 +40,7 @@ namespace tunnel { std::vector peers; bool isShort = true; + i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0; void Add (std::shared_ptr r); void Reverse (); From 49e8cf89d83339ae44ec8f155d8e40dfef1da2aa Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Oct 2021 12:42:32 -0400 Subject: [PATCH 183/186] don't send short tunnel build messages for ElGamal only destinations --- libi2pd/TunnelPool.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b349ada6..5ed330c8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -610,6 +610,9 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { + if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + path.isShort = false; // because can't handle ECIES encrypted reply + std::shared_ptr config; if (m_NumOutboundHops > 0) config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), From 48131f4597dcb9a62e539d9a713e9dadaf493d7d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 7 Oct 2021 15:08:33 -0400 Subject: [PATCH 184/186] don't store full path with RouterInfo --- libi2pd/NetDb.cpp | 3 ++- libi2pd/RouterInfo.cpp | 26 +++++++++++++------------- libi2pd/RouterInfo.h | 8 ++++---- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9c079d57..8d0025ec 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -963,7 +963,8 @@ namespace data if (router) { LogPrint (eLogDebug, "NetDb: requested RouterInfo ", key, " found"); - router->LoadBuffer (); + if (!router->GetBuffer ()) + router->LoadBuffer (m_Storage.Path (router->GetIdentHashBase64 ())); if (router->GetBuffer ()) replyMsg = CreateDatabaseStoreMsg (router); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 5d66e0e4..f2eefcd6 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -35,12 +35,12 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), - m_SupportedTransports (0), m_ReachableTransports (0), m_Caps (0), m_Version (0) + m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), + m_ReachableTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - ReadFromFile (); + ReadFromFile (fullPath); } RouterInfo::RouterInfo (const uint8_t * buf, int len): @@ -113,16 +113,16 @@ namespace data m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); } - bool RouterInfo::LoadFile () + bool RouterInfo::LoadFile (const std::string& fullPath) { - std::ifstream s(m_FullPath, std::ifstream::binary); + std::ifstream s(fullPath, std::ifstream::binary); if (s.is_open ()) { s.seekg (0,std::ios::end); m_BufferLen = s.tellg (); if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE) { - LogPrint(eLogError, "RouterInfo: File", m_FullPath, " is malformed"); + LogPrint(eLogError, "RouterInfo: File", fullPath, " is malformed"); return false; } s.seekg(0, std::ios::beg); @@ -131,15 +131,15 @@ namespace data } else { - LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath); + LogPrint (eLogError, "RouterInfo: Can't open file ", fullPath); return false; } return true; } - void RouterInfo::ReadFromFile () + void RouterInfo::ReadFromFile (const std::string& fullPath) { - if (LoadFile ()) + if (LoadFile (fullPath)) ReadFromBuffer (false); else m_IsUnreachable = true; @@ -748,11 +748,11 @@ namespace data return bufbe64toh (buf + size) > m_Timestamp; } - const uint8_t * RouterInfo::LoadBuffer () + const uint8_t * RouterInfo::LoadBuffer (const std::string& fullPath) { if (!m_Buffer) { - if (LoadFile ()) + if (LoadFile (fullPath)) LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file"); } return m_Buffer; @@ -783,8 +783,8 @@ namespace data bool RouterInfo::SaveToFile (const std::string& fullPath) { - m_FullPath = fullPath; - if (!m_Buffer) { + if (!m_Buffer) + { LogPrint (eLogError, "RouterInfo: Can't save, m_Buffer == NULL"); return false; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index c16f8e5f..38acbb16 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -226,7 +226,7 @@ namespace data bool IsUnreachable () const { return m_IsUnreachable; }; const uint8_t * GetBuffer () const { return m_Buffer; }; - const uint8_t * LoadBuffer (); // load if necessary + const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary int GetBufferLen () const { return m_BufferLen; }; void CreateBuffer (const PrivateKeys& privateKeys); @@ -252,8 +252,8 @@ namespace data private: - bool LoadFile (); - void ReadFromFile (); + bool LoadFile (const std::string& fullPath); + void ReadFromFile (const std::string& fullPath); void ReadFromStream (std::istream& s); void ReadFromBuffer (bool verifySignature); void WriteToStream (std::ostream& s) const; @@ -267,7 +267,7 @@ namespace data private: - std::string m_FullPath, m_Family; + std::string m_Family; std::shared_ptr m_RouterIdentity; uint8_t * m_Buffer; size_t m_BufferLen; From 7def2fa6a34d85dde1bdb436862a9b24a163b2e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Oct 2021 09:53:21 -0400 Subject: [PATCH 185/186] use std::vector for address list --- libi2pd/RouterInfo.cpp | 1 + libi2pd/RouterInfo.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index f2eefcd6..7747736c 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -194,6 +194,7 @@ namespace data auto addresses = boost::make_shared(); uint8_t numAddresses; s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return; + addresses->reserve (numAddresses); for (int i = 0; i < numAddresses; i++) { uint8_t supportedTransports = 0; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 38acbb16..b2b883dc 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -157,7 +156,7 @@ namespace data bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); }; bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); }; }; - typedef std::list > Addresses; + typedef std::vector > Addresses; RouterInfo (); RouterInfo (const std::string& fullPath); From 44e01b41f8cf166d26fd3555f79690260792ba51 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Oct 2021 13:28:16 -0400 Subject: [PATCH 186/186] reserve address for 3 introducers --- libi2pd/RouterInfo.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 7747736c..cb5a3db7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -187,13 +187,14 @@ namespace data void RouterInfo::ReadFromStream (std::istream& s) { + if (!s) return; m_Caps = 0; s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); m_Timestamp = be64toh (m_Timestamp); // read addresses auto addresses = boost::make_shared(); uint8_t numAddresses; - s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return; + s.read ((char *)&numAddresses, sizeof (numAddresses)); addresses->reserve (numAddresses); for (int i = 0; i < numAddresses; i++) { @@ -282,7 +283,11 @@ namespace data if (s) continue; else return; } if (index >= address->ssu->introducers.size ()) + { + if (address->ssu->introducers.empty ()) // first time + address->ssu->introducers.reserve (3); address->ssu->introducers.resize (index + 1); + } Introducer& introducer = address->ssu->introducers.at (index); if (!strcmp (key, "ihost")) {