diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 00000000..9763f75b
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,29 @@
+name: Build on Windows
+
+on: [push, pull_request]
+
+defaults:
+ run:
+ shell: msys2 {0}
+
+jobs:
+ build:
+ name: Building for ${{ matrix.arch }}
+ runs-on: windows-latest
+ strategy:
+ fail-fast: true
+ matrix:
+ include: [
+ { msystem: MINGW64, arch: x86_64 },
+ { msystem: MINGW32, arch: i686 }
+ ]
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: ${{ matrix.msystem }}
+ install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc
+ update: true
+ - name: build application
+ run: make USE_UPNP=yes DEBUG=no -j3
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..ba6acbf8
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,21 @@
+name: Build on Ubuntu with make
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ name: Building with USE_UPNP=${{ matrix.with_upnp }} flag
+ runs-on: ubuntu-16.04
+ strategy:
+ fail-fast: true
+ matrix:
+ with_upnp: ['yes', 'no']
+ steps:
+ - uses: actions/checkout@v2
+ - name: install packages
+ run: |
+ sudo add-apt-repository ppa:mhier/libboost-latest
+ sudo apt-get update
+ sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
+ - name: build application
+ run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3
diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java
index 8295e9f1..777ca748 100755
--- a/android/src/org/purplei2p/i2pd/I2PDActivity.java
+++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java
@@ -15,6 +15,7 @@ import java.util.TimerTask;
import android.Manifest;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
@@ -25,6 +26,10 @@ import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Bundle;
import android.os.Build;
@@ -41,6 +46,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@@ -63,6 +69,7 @@ public class I2PDActivity extends Activity {
private TextView textView;
private boolean assetsCopied;
+ private NetworkStateCallback networkCallback;
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
//private ConfigParser parser = new ConfigParser(i2pdpath); // TODO:
@@ -116,7 +123,7 @@ public class I2PDActivity extends Activity {
daemonStateUpdatedListener.daemonStateUpdate();
// request permissions
- if (Build.VERSION.SDK_INT >= 23) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
@@ -137,6 +144,10 @@ public class I2PDActivity extends Activity {
}
openBatteryOptimizationDialogIfNeeded();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ registerNetworkCallback();
+ }
}
@Override
@@ -244,7 +255,7 @@ public class I2PDActivity extends Activity {
}
private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() {
- return android.os.Build.VERSION.SDK_INT >= 23;
+ return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
@Override
@@ -631,6 +642,33 @@ public class I2PDActivity extends Activity {
return "show_battery_optimization" + (device == null ? "" : device);
}
+ @TargetApi(Build.VERSION_CODES.M)
+ private void registerNetworkCallback() {
+ ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ .build();
+ networkCallback = new NetworkStateCallback();
+ connectivityManager.registerNetworkCallback(request, networkCallback);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+ private final class NetworkStateCallback extends ConnectivityManager.NetworkCallback {
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ I2PD_JNI.onNetworkStateChanged(true);
+ Log.i(TAG, "NetworkCallback.onAvailable");
+ }
+
+ @Override
+ public void onLost(Network network) {
+ super.onLost(network);
+ I2PD_JNI.onNetworkStateChanged(false);
+ Log.i(TAG, " NetworkCallback.onLost");
+ }
+ }
+
private void quit() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/appveyor.yml b/appveyor.yml
index 10165e5f..3cf51c2b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,46 +9,49 @@ 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
- MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc
- MSYS_BITNESS: 64
- MSYSTEM: MINGW32
- MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc
- MSYS_BITNESS: 32
+
+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"
+# 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"
-# disable inaccessible miror (something block sed from changing files, so rewrite them) - https://github.com/msys2/MINGW-packages/issues/7084
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64"
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32"
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys"
# 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
-# rewrite mirrorlist again because pacman update can rewrite it
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64"
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32"
-- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys"
# update packages and install required
-- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}"
+- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc"
build_script:
-- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS%
-- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3"
-- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe
+- 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-mingw-win*.zip
+- path: i2pd-*.zip
diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt
index 4825855b..827e20d3 100644
--- a/build/CMakeLists.txt
+++ b/build/CMakeLists.txt
@@ -85,6 +85,7 @@ set(LIBI2PD_SRC
"${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp"
"${LIBI2PD_SRC_DIR}/TunnelGateway.cpp"
"${LIBI2PD_SRC_DIR}/TunnelPool.cpp"
+ "${LIBI2PD_SRC_DIR}/TunnelConfig.cpp"
"${LIBI2PD_SRC_DIR}/util.cpp"
)
diff --git a/build/appveyor-msys2-upgrade.bash b/build/appveyor-msys2-upgrade.bash
deleted file mode 100644
index 20c6af69..00000000
--- a/build/appveyor-msys2-upgrade.bash
+++ /dev/null
@@ -1,10 +0,0 @@
-set -e -x
-
-base_url='http://repo.msys2.org/msys/x86_64/'
-packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz"
-for p in $packages
-do
- curl "${base_url}$p" -o "$p"
-done
-pacman -U --noconfirm $packages
-rm -f $packages
diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp
index 1b9c0a2c..0317704a 100644
--- a/daemon/Daemon.cpp
+++ b/daemon/Daemon.cpp
@@ -299,14 +299,16 @@ namespace i2p
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu; i2p::config::GetOption("ssu", ssu);
+ bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
LogPrint(eLogInfo, "Daemon: starting Transports");
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
+ i2p::transport::transports.SetCheckReserved(checkInReserved);
i2p::transport::transports.Start(ntcp2, ssu);
- if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
+ if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
LogPrint(eLogInfo, "Daemon: Transports started");
- else
+ else
{
LogPrint(eLogError, "Daemon: failed to start Transports");
/** shut down netdb right away */
diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp
index 19734038..3b9f6eaa 100644
--- a/daemon/HTTPServer.cpp
+++ b/daemon/HTTPServer.cpp
@@ -257,7 +257,10 @@ namespace http {
switch (i2p::context.GetError ())
{
case eRouterErrorClockSkew:
- s << "
Clock skew";
+ s << " - Clock skew";
+ break;
+ case eRouterErrorOffline:
+ s << " - Offline";
break;
default: ;
}
diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp
index 1c565083..fc479532 100644
--- a/libi2pd/Config.cpp
+++ b/libi2pd/Config.cpp
@@ -51,6 +51,7 @@ namespace config {
("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)")
("ipv4", value()->default_value(true), "Enable communication through ipv4 (default: enabled)")
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
+ ("reservedrange", value()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)")
("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
@@ -107,8 +108,8 @@ namespace config {
("httpproxy.latency.max", value()->default_value("0"), "HTTP proxy max latency for tunnels")
("httpproxy.outproxy", value()->default_value(""), "HTTP proxy upstream out proxy url")
("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper")
- ("httpproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type")
- ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type")
+ ("httpproxy.i2cp.leaseSetType", value()->default_value("3"), "Local destination's LeaseSet type")
+ ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0,4"), "Local destination's LeaseSet encryption type")
;
options_description socksproxy("SOCKS Proxy options");
@@ -128,8 +129,8 @@ namespace config {
("socksproxy.outproxy.enabled", value()->default_value(false), "Enable or disable SOCKS outproxy")
("socksproxy.outproxy", value()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
- ("socksproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type")
- ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type")
+ ("socksproxy.i2cp.leaseSetType", value()->default_value("3"), "Local destination's LeaseSet type")
+ ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0,4"), "Local destination's LeaseSet encryption type")
;
options_description sam("SAM bridge options");
diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h
deleted file mode 100644
index 27b012e7..00000000
--- a/libi2pd/CryptoWorker.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-* 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 CRYPTO_WORKER_H_
-#define CRYPTO_WORKER_H_
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace i2p
-{
-namespace worker
-{
- template
- struct ThreadPool
- {
- typedef std::function ResultFunc;
- typedef std::function WorkFunc;
- typedef std::pair, WorkFunc> Job;
- typedef std::mutex mtx_t;
- typedef std::unique_lock lock_t;
- typedef std::condition_variable cond_t;
- ThreadPool(int workers)
- {
- stop = false;
- if(workers > 0)
- {
- while(workers--)
- {
- threads.emplace_back([this] {
- for (;;)
- {
- Job job;
- {
- lock_t lock(this->queue_mutex);
- this->condition.wait(
- lock, [this] { return this->stop || !this->jobs.empty(); });
- if (this->stop && this->jobs.empty()) return;
- job = std::move(this->jobs.front());
- this->jobs.pop_front();
- }
- ResultFunc result = job.second();
- job.first->GetService().post(result);
- }
- });
- }
- }
- };
-
- void Offer(const Job & job)
- {
- {
- lock_t lock(queue_mutex);
- if (stop) return;
- jobs.emplace_back(job);
- }
- condition.notify_one();
- }
-
- ~ThreadPool()
- {
- {
- lock_t lock(queue_mutex);
- stop = true;
- }
- condition.notify_all();
- for(auto &t: threads) t.join();
- }
-
- std::vector threads;
- std::deque jobs;
- mtx_t queue_mutex;
- cond_t condition;
- bool stop;
- };
-}
-}
-
-#endif
diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp
index 669fd791..927e98a0 100644
--- a/libi2pd/Destination.cpp
+++ b/libi2pd/Destination.cpp
@@ -559,7 +559,9 @@ namespace client
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
- auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound));
+ auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound);
+ if (floodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented
+ msg = WrapMessage (floodfill, msg);
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
shared_from_this (), std::placeholders::_1));
@@ -754,9 +756,10 @@ namespace client
else
AddSessionKey (replyKey, replyTag);
- auto msg = WrapMessage (nextFloodfill,
- CreateLeaseSetDatabaseLookupMsg (dest, request->excluded,
- request->replyTunnel, replyKey, replyTag, isECIES));
+ auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded,
+ request->replyTunnel, replyKey, replyTag, isECIES);
+ if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented
+ msg = WrapMessage (nextFloodfill, msg);
request->outboundTunnel->SendTunnelDataMsg (
{
i2p::tunnel::TunnelMessageBlock
diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp
index 429a2092..5f76bca1 100644
--- a/libi2pd/Garlic.cpp
+++ b/libi2pd/Garlic.cpp
@@ -740,7 +740,8 @@ namespace garlic
session = std::make_shared (this, true);
session->SetRemoteStaticKey (staticKey);
}
- session->SetDestination (destination->GetIdentHash ()); // TODO: remove
+ if (destination->IsDestination ())
+ session->SetDestination (destination->GetIdentHash ()); // TODO: remove
return session;
}
else
diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp
index 4f7b03a1..484f4c0c 100644
--- a/libi2pd/HTTP.cpp
+++ b/libi2pd/HTTP.cpp
@@ -16,8 +16,8 @@
namespace i2p {
namespace http {
const std::vector HTTP_METHODS = {
- "GET", "HEAD", "POST", "PUT", "PATCH",
- "DELETE", "OPTIONS", "CONNECT", "PROPFIND"
+ "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "CONNECT", // HTTP basic methods
+ "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK", "SEARCH" // WebDAV methods, for SEARCH see rfc5323
};
const std::vector HTTP_VERSIONS = {
"HTTP/1.0", "HTTP/1.1"
diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h
index fe5ca968..03f0f439 100644
--- a/libi2pd/I2NPProtocol.h
+++ b/libi2pd/I2NPProtocol.h
@@ -81,6 +81,25 @@ namespace i2p
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;
+ const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4;
+ const size_t ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32;
+ const size_t ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32;
+ const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32;
+ const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32;
+ const size_t ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16;
+ const size_t ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET = ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET + 1;
+ const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET + 3;
+ const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4;
+ const size_t ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4;
+ const size_t ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET = ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4;
+ const size_t ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 464;
+
+ // ECIES BuildResponseRecord
+ const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511;
+
enum I2NPMessageType
{
eI2NPDummyMsg = 0,
diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp
index b2b5f2b4..490b8692 100644
--- a/libi2pd/Identity.cpp
+++ b/libi2pd/Identity.cpp
@@ -48,7 +48,13 @@ namespace data
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType)
{
- memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of
+ if (cryptoType == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)
+ {
+ memcpy (m_StandardIdentity.publicKey, publicKey, 32);
+ RAND_bytes (m_StandardIdentity.publicKey, 224);
+ }
+ else
+ memcpy (m_StandardIdentity.publicKey, publicKey, 256);
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
{
size_t excessLen = 0;
diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp
index 4ce839ee..318db953 100644
--- a/libi2pd/NetDb.cpp
+++ b/libi2pd/NetDb.cpp
@@ -125,7 +125,8 @@ namespace data
}
}
if (!m_IsRunning) break;
-
+ if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline
+
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts - lastManageRequest >= 15) // manage requests every 15 seconds
{
diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h
index a576d6b6..37e1791d 100644
--- a/libi2pd/RouterContext.h
+++ b/libi2pd/RouterContext.h
@@ -37,7 +37,8 @@ namespace i2p
enum RouterError
{
eRouterErrorNone = 0,
- eRouterErrorClockSkew = 1
+ eRouterErrorClockSkew = 1,
+ eRouterErrorOffline = 2
};
class RouterContext: public i2p::garlic::GarlicDestination
diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp
index 0f4526bd..07c95a7a 100644
--- a/libi2pd/SSU.cpp
+++ b/libi2pd/SSU.cpp
@@ -19,27 +19,25 @@ namespace transport
{
SSUServer::SSUServer (const boost::asio::ip::address & addr, int port):
- m_OnlyV6(true), m_IsRunning(false),
- m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
- m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
+ m_OnlyV6(true), m_IsRunning(false), m_Thread (nullptr),
+ m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service),
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint),
m_SocketV6 (m_ReceiversServiceV6), m_IntroducersUpdateTimer (m_Service),
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service),
- m_TerminationTimerV6 (m_ServiceV6)
+ m_TerminationTimerV6 (m_Service)
{
OpenSocketV6 ();
}
SSUServer::SSUServer (int port):
- m_OnlyV6(false), m_IsRunning(false),
- m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
- m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
+ m_OnlyV6(false), m_IsRunning(false), m_Thread (nullptr),
+ m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service),
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
- m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6)
+ m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service)
{
OpenSocket ();
if (context.SupportsV6 ())
@@ -98,7 +96,8 @@ namespace transport
if (context.SupportsV6 ())
{
m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this));
- m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this));
+ if (!m_Thread)
+ m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this));
ScheduleTerminationV6 ();
}
@@ -114,7 +113,6 @@ namespace transport
m_TerminationTimerV6.cancel ();
m_Service.stop ();
m_Socket.close ();
- m_ServiceV6.stop ();
m_SocketV6.close ();
m_ReceiversService.stop ();
m_ReceiversServiceV6.stop ();
@@ -136,12 +134,6 @@ namespace transport
delete m_ReceiversThreadV6;
m_ReceiversThreadV6 = nullptr;
}
- if (m_ThreadV6)
- {
- m_ThreadV6->join ();
- delete m_ThreadV6;
- m_ThreadV6 = nullptr;
- }
}
void SSUServer::Run ()
@@ -159,21 +151,6 @@ namespace transport
}
}
- void SSUServer::RunV6 ()
- {
- while (m_IsRunning)
- {
- try
- {
- m_ServiceV6.run ();
- }
- catch (std::exception& ex)
- {
- LogPrint (eLogError, "SSU: v6 server runtime exception: ", ex.what ());
- }
- }
- }
-
void SSUServer::RunReceivers ()
{
while (m_IsRunning)
@@ -242,10 +219,16 @@ namespace transport
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to)
{
+ boost::system::error_code ec;
if (to.protocol () == boost::asio::ip::udp::v4())
- m_Socket.send_to (boost::asio::buffer (buf, len), to);
+ m_Socket.send_to (boost::asio::buffer (buf, len), to, 0, ec);
else
- m_SocketV6.send_to (boost::asio::buffer (buf, len), to);
+ m_SocketV6.send_to (boost::asio::buffer (buf, len), to, 0, ec);
+
+ if (ec)
+ {
+ LogPrint (eLogError, "SSU: send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")");
+ }
}
void SSUServer::Receive ()
@@ -264,7 +247,13 @@ namespace transport
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
- if (!ecode)
+ if (!ecode ||
+ ecode == boost::asio::error::connection_refused ||
+ ecode == boost::asio::error::connection_reset ||
+ ecode == boost::asio::error::network_unreachable ||
+ ecode == boost::asio::error::host_unreachable)
+ // just try continue reading when received ICMP response otherwise socket can crash,
+ // but better to find out which host were sent it and mark that router as unreachable
{
packet->len = bytes_transferred;
std::vector packets;
@@ -286,7 +275,7 @@ namespace transport
}
else
{
- LogPrint (eLogError, "SSU: receive_from error: ", ec.message ());
+ LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet;
break;
}
@@ -301,7 +290,7 @@ namespace transport
delete packet;
if (ecode != boost::asio::error::operation_aborted)
{
- LogPrint (eLogError, "SSU: receive error: ", ecode.message ());
+ LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ());
m_Socket.close ();
OpenSocket ();
Receive ();
@@ -311,7 +300,13 @@ namespace transport
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
- if (!ecode)
+ if (!ecode ||
+ ecode == boost::asio::error::connection_refused ||
+ ecode == boost::asio::error::connection_reset ||
+ ecode == boost::asio::error::network_unreachable ||
+ ecode == boost::asio::error::host_unreachable)
+ // just try continue reading when received ICMP response otherwise socket can crash,
+ // but better to find out which host were sent it and mark that router as unreachable
{
packet->len = bytes_transferred;
std::vector packets;
@@ -333,14 +328,14 @@ namespace transport
}
else
{
- LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ());
+ LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet;
break;
}
}
}
- m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6));
+ m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6));
ReceiveV6 ();
}
else
@@ -348,7 +343,7 @@ namespace transport
delete packet;
if (ecode != boost::asio::error::operation_aborted)
{
- LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ());
+ LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ());
m_SocketV6.close ();
OpenSocketV6 ();
ReceiveV6 ();
@@ -438,8 +433,7 @@ namespace transport
else
{
boost::asio::ip::udp::endpoint remoteEndpoint (addr, port);
- auto& s = addr.is_v6 () ? m_ServiceV6 : m_Service;
- s.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest));
+ m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest));
}
}
}
@@ -459,6 +453,7 @@ namespace transport
// otherwise create new session
auto session = std::make_shared (*this, remoteEndpoint, router, peerTest);
sessions[remoteEndpoint] = session;
+
// connect
LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
@@ -822,7 +817,7 @@ namespace transport
auto session = it.second;
if (it.first != session->GetRemoteEndpoint ())
LogPrint (eLogWarning, "SSU: remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first);
- m_ServiceV6.post ([session]
+ m_Service.post ([session]
{
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
session->Failed ();
diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h
index 6a79f754..213f379f 100644
--- a/libi2pd/SSU.h
+++ b/libi2pd/SSU.h
@@ -64,7 +64,6 @@ namespace transport
void DeleteAllSessions ();
boost::asio::io_service& GetService () { return m_Service; };
- boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; };
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
void AddRelay (uint32_t tag, std::shared_ptr relay);
@@ -82,7 +81,6 @@ namespace transport
void OpenSocket ();
void OpenSocketV6 ();
void Run ();
- void RunV6 ();
void RunReceivers ();
void RunReceiversV6 ();
void Receive ();
@@ -122,9 +120,9 @@ namespace transport
bool m_OnlyV6;
bool m_IsRunning;
- std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread, * m_ReceiversThreadV6;
- boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService, m_ReceiversServiceV6;
- boost::asio::io_service::work m_Work, m_WorkV6, m_ReceiversWork, m_ReceiversWorkV6;
+ std::thread * m_Thread, * m_ReceiversThread, * m_ReceiversThreadV6;
+ boost::asio::io_service m_Service, m_ReceiversService, m_ReceiversServiceV6;
+ boost::asio::io_service::work m_Work, m_ReceiversWork, m_ReceiversWorkV6;
boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6;
boost::asio::ip::udp::socket m_Socket, m_SocketV6;
boost::asio::deadline_timer m_IntroducersUpdateTimer, m_PeerTestsCleanupTimer,
diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp
index 399b2fc7..860c2be3 100644
--- a/libi2pd/SSUSession.cpp
+++ b/libi2pd/SSUSession.cpp
@@ -49,7 +49,7 @@ namespace transport
boost::asio::io_service& SSUSession::GetService ()
{
- return IsV6 () ? m_Server.GetServiceV6 () : m_Server.GetService ();
+ return m_Server.GetService ();
}
void SSUSession::CreateAESandMacKey (const uint8_t * pubKey)
@@ -224,7 +224,11 @@ namespace transport
return;
}
if (!m_DHKeysPair)
- m_DHKeysPair = transports.GetNextDHKeysPair ();
+ {
+ auto pair = std::make_shared ();
+ pair->GenerateKeys ();
+ m_DHKeysPair = pair;
+ }
CreateAESandMacKey (buf + headerSize);
SendSessionCreated (buf + headerSize, sendRelayTag);
}
@@ -826,9 +830,9 @@ namespace transport
{
if (m_State == eSessionStateUnknown)
{
- // set connect timer
- ScheduleConnectTimer ();
- m_DHKeysPair = transports.GetNextDHKeysPair ();
+ ScheduleConnectTimer (); // set connect timer
+ m_DHKeysPair = std::make_shared ();
+ m_DHKeysPair->GenerateKeys ();
SendSessionRequest ();
}
}
diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h
index ea820517..3aa04638 100644
--- a/libi2pd/SSUSession.h
+++ b/libi2pd/SSUSession.h
@@ -166,6 +166,7 @@ namespace transport
bool m_IsDataReceived;
std::unique_ptr m_SignedData; // we need it for SessionConfirmed only
std::map > m_RelayRequests; // nonce->Charlie
+ std::shared_ptr m_DHKeysPair; // X - for client and Y - for server
};
}
}
diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp
index 4362a878..45684333 100644
--- a/libi2pd/Timestamp.cpp
+++ b/libi2pd/Timestamp.cpp
@@ -35,15 +35,21 @@ namespace util
std::chrono::system_clock::now().time_since_epoch()).count ();
}
- static uint32_t GetLocalHoursSinceEpoch ()
+ static uint64_t GetLocalSecondsSinceEpoch ()
{
- return std::chrono::duration_cast(
+ return std::chrono::duration_cast(
std::chrono::system_clock::now().time_since_epoch()).count ();
}
- static uint64_t GetLocalSecondsSinceEpoch ()
+ static uint32_t GetLocalMinutesSinceEpoch ()
{
- return std::chrono::duration_cast(
+ return std::chrono::duration_cast(
+ std::chrono::system_clock::now().time_since_epoch()).count ();
+ }
+
+ static uint32_t GetLocalHoursSinceEpoch ()
+ {
+ return std::chrono::duration_cast(
std::chrono::system_clock::now().time_since_epoch()).count ();
}
@@ -178,14 +184,19 @@ namespace util
return GetLocalMillisecondsSinceEpoch () + g_TimeOffset*1000;
}
- uint32_t GetHoursSinceEpoch ()
- {
- return GetLocalHoursSinceEpoch () + g_TimeOffset/3600;
- }
-
uint64_t GetSecondsSinceEpoch ()
{
return GetLocalSecondsSinceEpoch () + g_TimeOffset;
+ }
+
+ uint32_t GetMinutesSinceEpoch ()
+ {
+ return GetLocalMinutesSinceEpoch () + g_TimeOffset/60;
+ }
+
+ uint32_t GetHoursSinceEpoch ()
+ {
+ return GetLocalHoursSinceEpoch () + g_TimeOffset/3600;
}
void GetCurrentDate (char * date)
diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h
index 91175a49..b46f423d 100644
--- a/libi2pd/Timestamp.h
+++ b/libi2pd/Timestamp.h
@@ -20,8 +20,9 @@ namespace i2p
namespace util
{
uint64_t GetMillisecondsSinceEpoch ();
- uint32_t GetHoursSinceEpoch ();
uint64_t GetSecondsSinceEpoch ();
+ uint32_t GetMinutesSinceEpoch ();
+ uint32_t GetHoursSinceEpoch ();
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h
index a97f246f..12d4894b 100644
--- a/libi2pd/TransportSession.h
+++ b/libi2pd/TransportSession.h
@@ -64,7 +64,7 @@ namespace transport
public:
TransportSession (std::shared_ptr router, int terminationTimeout):
- m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
+ m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ())
{
if (router)
@@ -103,7 +103,6 @@ namespace transport
std::shared_ptr m_RemoteIdentity;
mutable std::mutex m_RemoteIdentityMutex;
- std::shared_ptr m_DHKeysPair; // X - for client and Y - for server
size_t m_NumSentBytes, m_NumReceivedBytes;
bool m_IsOutgoing;
int m_TerminationTimeout;
diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp
index 19e17f52..c6e90ad2 100644
--- a/libi2pd/Transports.cpp
+++ b/libi2pd/Transports.cpp
@@ -27,20 +27,20 @@ namespace transport
{
}
- template
+ template
EphemeralKeysSupplier::~EphemeralKeysSupplier ()
{
Stop ();
}
- template
+ template
void EphemeralKeysSupplier::Start ()
{
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier::Run, this));
}
- template
+ template
void EphemeralKeysSupplier::Stop ()
{
{
@@ -56,7 +56,7 @@ namespace transport
}
}
- template
+ template
void EphemeralKeysSupplier::Run ()
{
while (m_IsRunning)
@@ -81,7 +81,7 @@ namespace transport
}
}
- template
+ template
void EphemeralKeysSupplier::CreateEphemeralKeys (int num)
{
if (num > 0)
@@ -96,7 +96,7 @@ namespace transport
}
}
- template
+ template
std::shared_ptr EphemeralKeysSupplier::Acquire ()
{
{
@@ -115,7 +115,7 @@ namespace transport
return pair;
}
- template
+ template
void EphemeralKeysSupplier::Return (std::shared_ptr pair)
{
if (pair)
@@ -131,10 +131,10 @@ namespace transport
Transports transports;
Transports::Transports ():
- m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr),
- m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
+ m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr),
+ m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_SSUServer (nullptr), m_NTCP2Server (nullptr),
- m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys
+ m_X25519KeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0),
@@ -165,12 +165,11 @@ namespace transport
}
i2p::config::GetOption("nat", m_IsNAT);
- m_DHKeysPairSupplier.Start ();
m_X25519KeysPairSupplier.Start ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Transports::Run, this));
std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
- i2p::http::URL proxyurl;
+ i2p::http::URL proxyurl;
// create NTCP2. TODO: move to acceptor
if (enableNTCP2)
{
@@ -252,7 +251,7 @@ namespace transport
delete m_SSUServer;
m_SSUServer = nullptr;
}
-
+
if (m_NTCP2Server)
{
m_NTCP2Server->Stop ();
@@ -260,7 +259,6 @@ namespace transport
m_NTCP2Server = nullptr;
}
- m_DHKeysPairSupplier.Stop ();
m_X25519KeysPairSupplier.Stop ();
m_IsRunning = false;
if (m_Service) m_Service->stop ();
@@ -321,7 +319,8 @@ namespace transport
void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg)
{
- SendMessages (ident, std::vector > {msg });
+ if (m_IsOnline)
+ SendMessages (ident, std::vector > {msg });
}
void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs)
@@ -371,7 +370,7 @@ namespace transport
}
else
{
- LogPrint (eLogWarning, "Transports: delayed messages queue size to ",
+ LogPrint (eLogWarning, "Transports: delayed messages queue size to ",
ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES);
std::unique_lock l(m_PeersMutex);
m_Peers.erase (it);
@@ -392,7 +391,7 @@ namespace transport
{
// NTCP2 have priority over NTCP
auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only
- if (address && !peer.router->IsUnreachable ())
+ if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host)))
{
auto s = std::make_shared (*m_NTCP2Server, peer.router);
@@ -418,8 +417,11 @@ namespace transport
if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ()))
{
auto address = peer.router->GetSSUAddress (!context.SupportsV6 ());
- m_SSUServer->CreateSession (peer.router, address->host, address->port);
- return true;
+ if (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))
+ {
+ m_SSUServer->CreateSession (peer.router, address->host, address->port);
+ return true;
+ }
}
}
LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available");
@@ -499,7 +501,7 @@ namespace transport
{
auto addr = router->GetSSUV6Address ();
if (addr)
- m_SSUServer->GetServiceV6 ().post ([this, router, addr]
+ m_SSUServer->GetService ().post ([this, router, addr]
{
m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false);
});
@@ -536,16 +538,6 @@ namespace transport
}
}
- std::shared_ptr Transports::GetNextDHKeysPair ()
- {
- return m_DHKeysPairSupplier.Acquire ();
- }
-
- void Transports::ReuseDHKeysPair (std::shared_ptr pair)
- {
- m_DHKeysPairSupplier.Return (pair);
- }
-
std::shared_ptr Transports::GetNextX25519KeysPair ()
{
return m_X25519KeysPairSupplier.Acquire ();
@@ -555,7 +547,7 @@ namespace transport
{
m_X25519KeysPairSupplier.Return (pair);
}
-
+
void Transports::PeerConnected (std::shared_ptr session)
{
m_Service->post([session, this]()
@@ -756,5 +748,17 @@ namespace transport
}
return false;
}
+
+ void Transports::SetOnline (bool online)
+ {
+ if (m_IsOnline != online)
+ {
+ m_IsOnline = online;
+ if (online)
+ PeerTest ();
+ else
+ i2p::context.SetError (eRouterErrorOffline);
+ }
+ }
}
}
diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h
index c3008b09..d480840a 100644
--- a/libi2pd/Transports.h
+++ b/libi2pd/Transports.h
@@ -59,7 +59,6 @@ namespace transport
std::condition_variable m_Acquired;
std::mutex m_AcquiredMutex;
};
- typedef EphemeralKeysSupplier DHKeysPairSupplier;
typedef EphemeralKeysSupplier X25519KeysPairSupplier;
struct Peer
@@ -94,11 +93,9 @@ namespace transport
bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; }
bool IsOnline() const { return m_IsOnline; };
- void SetOnline (bool online) { m_IsOnline = online; };
+ void SetOnline (bool online);
boost::asio::io_service& GetService () { return *m_Service; };
- std::shared_ptr GetNextDHKeysPair ();
- void ReuseDHKeysPair (std::shared_ptr pair);
std::shared_ptr GetNextX25519KeysPair ();
void ReuseX25519KeysPair (std::shared_ptr pair);
@@ -136,6 +133,9 @@ namespace transport
void PeerTest ();
+ void SetCheckReserved (bool check) { m_CheckReserved = check; };
+ bool IsCheckReserved () { return m_CheckReserved; };
+
private:
void Run ();
@@ -151,7 +151,8 @@ namespace transport
private:
- bool m_IsOnline, m_IsRunning, m_IsNAT;
+ volatile bool m_IsOnline;
+ bool m_IsRunning, m_IsNAT, m_CheckReserved;
std::thread * m_Thread;
boost::asio::io_service * m_Service;
boost::asio::io_service::work * m_Work;
@@ -162,7 +163,6 @@ namespace transport
mutable std::mutex m_PeersMutex;
std::unordered_map m_Peers;
- DHKeysPairSupplier m_DHKeysPairSupplier;
X25519KeysPairSupplier m_X25519KeysPairSupplier;
std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes;
diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp
index fe7e36af..bfe466e3 100644
--- a/libi2pd/Tunnel.cpp
+++ b/libi2pd/Tunnel.cpp
@@ -111,7 +111,7 @@ namespace tunnel
while (hop)
{
decryption.SetKey (hop->replyKey);
- // decrypt records before and including current hop
+ // decrypt records before and current hop
TunnelHopConfig * hop1 = hop;
while (hop1)
{
@@ -119,8 +119,22 @@ namespace tunnel
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);
+ if (hop1 == hop && hop1->IsECIES ())
+ {
+ uint8_t nonce[12];
+ memset (nonce, 0, 12);
+ if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16,
+ hop->h, 32, hop->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);
+ }
}
else
LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range");
@@ -134,7 +148,7 @@ namespace tunnel
while (hop)
{
const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE;
- uint8_t ret = record[BUILD_RESPONSE_RECORD_RET_OFFSET];
+ uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET];
LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret);
auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
if (profile)
@@ -303,6 +317,7 @@ namespace tunnel
{
for (auto& msg : msgs)
{
+ if (!msg.data) continue;
switch (msg.deliveryType)
{
case eDeliveryTypeLocal:
@@ -521,7 +536,7 @@ namespace tunnel
}
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
- if (ts - lastTs >= 15) // manage tunnels every 15 seconds
+ if (ts - lastTs >= 15 && i2p::transport::transports.IsOnline()) // manage tunnels every 15 seconds
{
ManageTunnels ();
lastTs = ts;
diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp
new file mode 100644
index 00000000..5c2cbd53
--- /dev/null
+++ b/libi2pd/TunnelConfig.cpp
@@ -0,0 +1,166 @@
+/*
+* 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
+#include
+#include
+#include "Crypto.h"
+#include "Log.h"
+#include "Transports.h"
+#include "Timestamp.h"
+#include "I2PEndian.h"
+#include "I2NPProtocol.h"
+#include "TunnelConfig.h"
+
+namespace i2p
+{
+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;
+ isEndpoint = true;
+ ident = r;
+ //nextRouter = nullptr;
+ nextTunnelID = 0;
+
+ next = nullptr;
+ prev = nullptr;
+ }
+
+ void TunnelHopConfig::SetNextIdent (const i2p::data::IdentHash& ident)
+ {
+ nextIdent = ident;
+ isEndpoint = false;
+ RAND_bytes ((uint8_t *)&nextTunnelID, 4);
+ if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero
+ }
+
+ void TunnelHopConfig::SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent)
+ {
+ nextIdent = replyIdent;
+ nextTunnelID = replyTunnelID;
+ isEndpoint = true;
+ }
+
+ void TunnelHopConfig::SetNext (TunnelHopConfig * n)
+ {
+ next = n;
+ if (next)
+ {
+ next->prev = this;
+ next->isGateway = false;
+ isEndpoint = false;
+ nextIdent = next->ident->GetIdentHash ();
+ nextTunnelID = next->tunnelID;
+ }
+ }
+
+ void TunnelHopConfig::SetPrev (TunnelHopConfig * p)
+ {
+ prev = p;
+ if (prev)
+ {
+ prev->next = this;
+ prev->isEndpoint = false;
+ isGateway = false;
+ }
+ }
+
+ void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx)
+ {
+ uint8_t flag = 0;
+ if (isGateway) flag |= 0x80;
+ if (isEndpoint) flag |= 0x40;
+ 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);
+ }
+ memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
+ }
+
+ void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor,
+ const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx)
+ {
+ static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
+ memcpy (ck, protocolName, 32); // ck = h = protocol_name || 0
+ SHA256 (ck, 32, h); // h = SHA256(h);
+ uint8_t hepk[32];
+ encryptor->Encrypt (nullptr, hepk, nullptr, false);
+ MixHash (hepk, 32); // h = SHA256(h || hepk)
+ 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)
+ uint8_t keydata[64];
+ i2p::crypto::HKDF (ck, sharedSecret, 32, "", keydata);
+ memcpy (ck, keydata, 32);
+ uint8_t nonce[12];
+ memset (nonce, 0, 12);
+ if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, h, 32,
+ keydata + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 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)
+ }
+
+ void TunnelHopConfig::MixHash (const uint8_t * buf, size_t len)
+ {
+ SHA256_CTX ctx;
+ SHA256_Init (&ctx);
+ SHA256_Update (&ctx, h, 32);
+ SHA256_Update (&ctx, buf, len);
+ SHA256_Final (h, &ctx);
+ }
+}
+}
\ No newline at end of file
diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h
index 0bd8a842..0e757071 100644
--- a/libi2pd/TunnelConfig.h
+++ b/libi2pd/TunnelConfig.h
@@ -9,13 +9,9 @@
#ifndef TUNNEL_CONFIG_H__
#define TUNNEL_CONFIG_H__
-#include
-#include
#include
-#include
#include "Identity.h"
#include "RouterContext.h"
-#include "Timestamp.h"
namespace i2p
{
@@ -34,87 +30,20 @@ namespace tunnel
TunnelHopConfig * next, * prev;
int recordIndex; // record # in tunnel build message
-
- 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;
- isEndpoint = true;
- ident = r;
- //nextRouter = nullptr;
- nextTunnelID = 0;
-
- next = nullptr;
- prev = nullptr;
- }
-
- void SetNextIdent (const i2p::data::IdentHash& ident)
- {
- nextIdent = ident;
- isEndpoint = false;
- RAND_bytes ((uint8_t *)&nextTunnelID, 4);
- if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero
- }
-
- void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent)
- {
- nextIdent = replyIdent;
- nextTunnelID = replyTunnelID;
- isEndpoint = true;
- }
-
- void SetNext (TunnelHopConfig * n)
- {
- next = n;
- if (next)
- {
- next->prev = this;
- next->isGateway = false;
- isEndpoint = false;
- nextIdent = next->ident->GetIdentHash ();
- nextTunnelID = next->tunnelID;
- }
- }
-
- void SetPrev (TunnelHopConfig * p)
- {
- prev = p;
- if (prev)
- {
- prev->next = this;
- prev->isEndpoint = false;
- isGateway = false;
- }
- }
-
- void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const
- {
- 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);
- uint8_t flag = 0;
- if (isGateway) flag |= 0x80;
- if (isEndpoint) flag |= 0x40;
- 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);
- auto encryptor = ident->CreateEncryptor (nullptr);
- 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);
- }
+ uint8_t ck[32], h[32]; // for ECIES
+
+ TunnelHopConfig (std::shared_ptr r);
+
+ 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_RATCHET; };
+ 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);
+ void MixHash (const uint8_t * buf, size_t len);
};
class TunnelConfig
diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp
index f5204a50..2cc101c7 100644
--- a/libi2pd/util.cpp
+++ b/libi2pd/util.cpp
@@ -61,6 +61,9 @@ int inet_pton_xp(int af, const char *src, void *dst)
#include
#endif
+#define address_pair_v4(a,b) { boost::asio::ip::address_v4::from_string (a).to_ulong (), boost::asio::ip::address_v4::from_string (b).to_ulong () }
+#define address_pair_v6(a,b) { boost::asio::ip::address_v6::from_string (a).to_bytes (), boost::asio::ip::address_v6::from_string (b).to_bytes () }
+
namespace i2p
{
namespace util
@@ -391,6 +394,50 @@ namespace net
return boost::asio::ip::address::from_string(fallback);
#endif
}
-}
+
+ bool IsInReservedRange(const boost::asio::ip::address& host) {
+ // https://en.wikipedia.org/wiki/Reserved_IP_addresses
+ if(host.is_v4())
+ {
+ static const std::vector< std::pair > reservedIPv4Ranges {
+ address_pair_v4("0.0.0.0", "0.255.255.255"),
+ address_pair_v4("10.0.0.0", "10.255.255.255"),
+ address_pair_v4("100.64.0.0", "100.127.255.255"),
+ address_pair_v4("127.0.0.0", "127.255.255.255"),
+ address_pair_v4("169.254.0.0", "169.254.255.255"),
+ address_pair_v4("172.16.0.0", "172.31.255.255"),
+ address_pair_v4("192.0.0.0", "192.0.0.255"),
+ address_pair_v4("192.0.2.0", "192.0.2.255"),
+ address_pair_v4("192.88.99.0", "192.88.99.255"),
+ address_pair_v4("192.168.0.0", "192.168.255.255"),
+ address_pair_v4("198.18.0.0", "192.19.255.255"),
+ address_pair_v4("198.51.100.0", "198.51.100.255"),
+ address_pair_v4("203.0.113.0", "203.0.113.255"),
+ address_pair_v4("224.0.0.0", "255.255.255.255")
+ };
+
+ uint32_t ipv4_address = host.to_v4 ().to_ulong ();
+ for(const auto& it : reservedIPv4Ranges) {
+ if (ipv4_address >= it.first && ipv4_address <= it.second)
+ return true;
+ }
+ }
+ if(host.is_v6())
+ {
+ 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")
+ };
+
+ boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes ();
+ for(const auto& it : reservedIPv6Ranges) {
+ if (ipv6_address >= it.first && ipv6_address <= it.second)
+ return true;
+ }
+ }
+ return false;
+ }
+} // net
} // util
} // i2p
diff --git a/libi2pd/util.h b/libi2pd/util.h
index cb8fd8f1..56ce1e08 100644
--- a/libi2pd/util.h
+++ b/libi2pd/util.h
@@ -172,6 +172,7 @@ namespace util
{
int GetMTU (const boost::asio::ip::address& localAddress);
const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false);
+ bool IsInReservedRange(const boost::asio::ip::address& host);
}
}
}
diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp
index 04f50e6f..ab868916 100644
--- a/libi2pd_client/ClientContext.cpp
+++ b/libi2pd_client/ClientContext.cpp
@@ -456,7 +456,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, "");
+ std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, isServer ? "" : "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;
diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp
index 24c2496b..80274d86 100644
--- a/libi2pd_client/I2CP.cpp
+++ b/libi2pd_client/I2CP.cpp
@@ -226,14 +226,13 @@ namespace client
}
I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket):
- m_Owner (owner), m_Socket (socket), m_Payload (nullptr),
- m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true)
+ m_Owner (owner), m_Socket (socket), m_SessionID (0xFFFF),
+ m_MessageID (0), m_IsSendAccepted (true)
{
}
I2CPSession::~I2CPSession ()
{
- delete[] m_Payload;
}
void I2CPSession::Start ()
@@ -264,6 +263,11 @@ namespace client
void I2CPSession::ReceiveHeader ()
{
+ if (!m_Socket)
+ {
+ LogPrint (eLogError, "I2CP: Can't receive header");
+ return;
+ }
boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Header, I2CP_HEADER_SIZE),
boost::asio::transfer_all (),
std::bind (&I2CPSession::HandleReceivedHeader, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
@@ -279,10 +283,7 @@ namespace client
if (m_PayloadLen > 0)
{
if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH)
- {
- m_Payload = new uint8_t[m_PayloadLen];
ReceivePayload ();
- }
else
{
LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen);
@@ -299,6 +300,11 @@ namespace client
void I2CPSession::ReceivePayload ()
{
+ if (!m_Socket)
+ {
+ LogPrint (eLogError, "I2CP: Can't receive payload");
+ return;
+ }
boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Payload, m_PayloadLen),
boost::asio::transfer_all (),
std::bind (&I2CPSession::HandleReceivedPayload, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
@@ -311,8 +317,6 @@ namespace client
else
{
HandleMessage ();
- delete[] m_Payload;
- m_Payload = nullptr;
m_PayloadLen = 0;
ReceiveHeader (); // next message
}
@@ -345,6 +349,11 @@ namespace client
void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len)
{
+ if (len > I2CP_MAX_MESSAGE_LENGTH)
+ {
+ LogPrint (eLogError, "I2CP: Message to send is too long ", len);
+ return;
+ }
auto socket = m_Socket;
if (socket)
{
diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h
index 4c6b7531..c5dc80e7 100644
--- a/libi2pd_client/I2CP.h
+++ b/libi2pd_client/I2CP.h
@@ -179,7 +179,7 @@ namespace client
I2CPServer& m_Owner;
std::shared_ptr m_Socket;
- uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload;
+ uint8_t m_Header[I2CP_HEADER_SIZE], m_Payload[I2CP_MAX_MESSAGE_LENGTH];
size_t m_PayloadLen;
std::shared_ptr m_Destination;
diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore
index f1d57c58..1f9d6012 100644
--- a/qt/i2pd_qt/.gitignore
+++ b/qt/i2pd_qt/.gitignore
@@ -8,4 +8,6 @@ Makefile*
object_script.*
i2pd_qt_plugin_import.cpp
i2pd_qt.pro.autosave*
+build*
+nohup.out
diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp
index 256d0510..fbfa74cb 100644
--- a/qt/i2pd_qt/ClientTunnelPane.cpp
+++ b/qt/i2pd_qt/ClientTunnelPane.cpp
@@ -168,6 +168,23 @@ int ClientTunnelPane::appendClientTunnelForm(
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
+ {
+ int cryptoType = tunnelConfig->getcryptoType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
+ cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
+ horizontalLayout_2->addWidget(cryptoTypeLabel);
+ ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
+ cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
+ cryptoTypeLineEdit->setText(QString::number(cryptoType));
+ cryptoTypeLineEdit->setMaximumWidth(80);
+ QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(cryptoTypeLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
{
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h
index c2e076b7..80d331de 100644
--- a/qt/i2pd_qt/ClientTunnelPane.h
+++ b/qt/i2pd_qt/ClientTunnelPane.h
@@ -53,6 +53,10 @@ private:
QLabel * sigTypeLabel;
QComboBox * sigTypeComboBox;
+ //cryptoType
+ QLabel * cryptoTypeLabel;
+ QLineEdit * cryptoTypeLineEdit;
+
protected slots:
virtual void setGroupBoxTitle(const QString & title);
@@ -61,6 +65,7 @@ private:
typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0));
destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0));
portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0));
+ cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0));
keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0));
destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0));
addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0));
@@ -86,6 +91,14 @@ protected:
}
ctc->setport(portInt);
+ auto cryptoTypeStr=cryptoTypeLineEdit->text();
+ int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
+ if(!ok){
+ highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
+ return false;
+ }
+ ctc->setcryptoType(cryptoTypeInt);
+
ctc->setkeys(keysLineEdit->text().toStdString());
ctc->setaddress(addressLineEdit->text().toStdString());
diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp
index bc6389a9..cd751f5d 100644
--- a/qt/i2pd_qt/ServerTunnelPane.cpp
+++ b/qt/i2pd_qt/ServerTunnelPane.cpp
@@ -235,6 +235,23 @@ int ServerTunnelPane::appendServerTunnelForm(
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
+ {
+ int cryptoType = tunnelConfig->getcryptoType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
+ cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
+ horizontalLayout_2->addWidget(cryptoTypeLabel);
+ ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
+ cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
+ cryptoTypeLineEdit->setText(QString::number(cryptoType));
+ cryptoTypeLineEdit->setMaximumWidth(80);
+ QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(cryptoTypeLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
{
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
appendControlsForI2CPParameters(i2cpParameters, gridIndex);
diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h
index 0a07267b..92ee4da5 100644
--- a/qt/i2pd_qt/ServerTunnelPane.h
+++ b/qt/i2pd_qt/ServerTunnelPane.h
@@ -65,6 +65,10 @@ private:
QLabel * inPortLabel;
QLineEdit * inPortLineEdit;
+ //cryptoType
+ QLabel * cryptoTypeLabel;
+ QLineEdit * cryptoTypeLineEdit;
+
//accessList
QLabel * accessListLabel;
QLineEdit * accessListLineEdit;
@@ -101,6 +105,7 @@ private:
portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0));
keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0));
inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0));
+ cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0));
accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0));
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
@@ -129,6 +134,14 @@ protected:
}
stc->setport(portInt);
+ auto cryptoTypeStr=cryptoTypeLineEdit->text();
+ int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
+ if(!ok){
+ highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
+ return false;
+ }
+ stc->setcryptoType(cryptoTypeInt);
+
stc->setkeys(keysLineEdit->text().toStdString());
auto str=inPortLineEdit->text();
diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp
index 8ed72930..a2cdf92b 100644
--- a/qt/i2pd_qt/TunnelConfig.cpp
+++ b/qt/i2pd_qt/TunnelConfig.cpp
@@ -24,6 +24,18 @@ void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) {
if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947
out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "="
<< i2cpParameters.getExplicitPeers().toStdString() << "\n";
+ out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "="
+ << i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n";
+ out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "="
+ << i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n";
+ out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "="
+ << i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n";
+ out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "="
+ << i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n";
+ out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "="
+ << (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n";
+ out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "="
+ << i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n";
out << "\n";
}
@@ -32,6 +44,7 @@ void ClientTunnelConfig::saveToStringStream(std::stringstream& out) {
<< "port=" << port << "\n"
<< "destination=" << dest << "\n"
<< "destinationport=" << destinationPort << "\n"
+ << "cryptoType=" << getcryptoType() << "\n"
<< "signaturetype=" << sigType << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
}
@@ -41,9 +54,10 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "host=" << host << "\n"
<< "port=" << port << "\n"
<< "signaturetype=" << sigType << "\n"
- << "inport=" << inPort << "\n"
- << "accesslist=" << accessList << "\n"
- << "gzip=" << (gzip?"true":"false") << "\n"
+ << "inport=" << inPort << "\n";
+ if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; }
+ out << "gzip=" << (gzip?"true":"false") << "\n"
+ << "cryptoType=" << getcryptoType() << "\n"
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
<< "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n"
diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h
index 059d48b5..530a525c 100644
--- a/qt/i2pd_qt/TunnelConfig.h
+++ b/qt/i2pd_qt/TunnelConfig.h
@@ -16,25 +16,49 @@ class I2CPParameters{
QString outbound_quantity; //number of outbound tunnels. 5 by default
QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building
QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset
+ QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
+ bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default
+ QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
+ QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
+ QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
+ QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
public:
I2CPParameters(): inbound_length(),
outbound_length(),
inbound_quantity(),
outbound_quantity(),
crypto_tagsToSend(),
- explicitPeers() {}
+ explicitPeers(),
+ i2p_streaming_initialAckDelay(),
+ i2p_streaming_answerPings(true),
+ i2cp_leaseSetType(),
+ i2cp_leaseSetEncType(),
+ i2cp_leaseSetPrivKey(),
+ i2cp_leaseSetAuthType() {}
const QString& getInbound_length(){return inbound_length;}
const QString& getOutbound_length(){return outbound_length;}
const QString& getInbound_quantity(){return inbound_quantity;}
const QString& getOutbound_quantity(){return outbound_quantity;}
const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;}
const QString& getExplicitPeers(){return explicitPeers;}
+ const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;}
+ bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;}
+ const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;}
+ const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;}
+ const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;}
+ const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;}
void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;}
void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;}
void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;}
void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;}
void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;}
void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;}
+ void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;}
+ void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;}
+ void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;}
+ void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;}
+ void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;}
+ void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;}
};
@@ -58,12 +82,14 @@ class TunnelConfig {
QString type;
std::string name;
TunnelPane* tunnelPane;
+ int cryptoType;
public:
- TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_):
- type(type_), name(name_), i2cpParameters(i2cpParameters_) {}
+ TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_):
+ type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {}
virtual ~TunnelConfig(){}
const QString& getType(){return type;}
const std::string& getName(){return name;}
+ int getcryptoType(){return cryptoType;}
void setType(const QString& type_){type=type_;}
void setName(const std::string& name_){name=name_;}
I2CPParameters& getI2cpParameters(){return i2cpParameters;}
@@ -74,6 +100,7 @@ public:
virtual ServerTunnelConfig* asServerTunnelConfig()=0;
void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;}
TunnelPane* getTunnelPane() {return tunnelPane;}
+ void setcryptoType(int cryptoType_){cryptoType=cryptoType_;}
private:
I2CPParameters i2cpParameters;
};
@@ -114,13 +141,14 @@ public:
std::string keys_,
std::string address_,
int destinationPort_,
- i2p::data::SigningKeyType sigType_): TunnelConfig(name_, type_, i2cpParameters_),
+ i2p::data::SigningKeyType sigType_,
+ int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
dest(dest_),
port(port_),
keys(keys_),
address(address_),
destinationPort(destinationPort_),
- sigType(sigType_){}
+ sigType(sigType_) {}
std::string& getdest(){return dest;}
int getport(){return port;}
std::string & getkeys(){return keys;}
@@ -188,7 +216,8 @@ public:
bool gzip_,
i2p::data::SigningKeyType sigType_,
std::string address_,
- bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_),
+ bool isUniqueLocal_,
+ int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
host(host_),
port(port_),
keys(keys_),
diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp
index c64b37ab..4b873ac1 100644
--- a/qt/i2pd_qt/TunnelPane.cpp
+++ b/qt/i2pd_qt/TunnelPane.cpp
@@ -31,7 +31,7 @@ void TunnelPane::setupTunnelPane(
this->gridLayoutWidget_2=gridLayoutWidget_2;
tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2);
tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout"));
- tunnelGridLayout->setContentsMargins(5, 5, 5, 5);
+ tunnelGridLayout->setContentsMargins(10, 25, 10, 10);
tunnelGridLayout->setSpacing(5);
//header
@@ -185,6 +185,153 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters,
tunnelGridLayout->addLayout(horizontalLayout_2);
}
+ {
+ //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset
+ const QString& value=i2cpParameters.getExplicitPeers();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
+ const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2p.streaming.answerPings -- enable sending pongs. true by default
+ const bool value=i2cpParameters.get_i2p_streaming_answerPings();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QCheckBox *_CheckBox;
+ i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2);
+ _CheckBox->setObjectName(QStringLiteral("_CheckBox"));
+ horizontalLayout_2->addWidget(_CheckBox);
+ _CheckBox->setChecked(value);
+ QObject::connect(_CheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(updated()));
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
+ const QString& value=i2cpParameters.get_i2cp_leaseSetType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
+ const QString& value=i2cpParameters.get_i2cp_leaseSetEncType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
+ const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ {
+ //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
+ const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ QLabel *_Label;
+ i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
+ _Label->setObjectName(QStringLiteral("_Label"));
+ horizontalLayout_2->addWidget(_Label);
+ QLineEdit *_LineEdit;
+ i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
+ _LineEdit->setObjectName(QStringLiteral("_LineEdit"));
+ _LineEdit->setText(value);
+ _LineEdit->setMaximumWidth(80);
+ QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(_LineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
retranslateI2CPParameters();
}
diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h
index 71331b4e..59303afd 100644
--- a/qt/i2pd_qt/TunnelPane.h
+++ b/qt/i2pd_qt/TunnelPane.h
@@ -11,6 +11,7 @@
#include "QLineEdit"
#include "QGroupBox"
#include "QVBoxLayout"
+#include "QCheckBox"
#include "TunnelConfig.h"
@@ -89,6 +90,27 @@ protected:
QLabel * crypto_tagsToSendLabel;
QLineEdit * crypto_tagsToSendLineEdit;
+ QLabel * explicitPeersLabel;
+ QLineEdit * explicitPeersLineEdit;
+
+ QLabel * i2p_streaming_initialAckDelayLabel;
+ QLineEdit * i2p_streaming_initialAckDelayLineEdit;
+
+ QCheckBox * i2p_streaming_answerPingsCheckBox;
+
+ QLabel * i2cp_leaseSetTypeLabel;
+ QLineEdit * i2cp_leaseSetTypeLineEdit;
+
+ QLabel * i2cp_leaseSetEncTypeLabel;
+ QLineEdit * i2cp_leaseSetEncTypeLineEdit;
+
+ QLabel * i2cp_leaseSetPrivKeyLabel;
+ QLineEdit * i2cp_leaseSetPrivKeyLineEdit;
+
+ QLabel * i2cp_leaseSetAuthTypeLabel;
+ QLineEdit * i2cp_leaseSetAuthTypeLineEdit;
+
+
QString readTunnelTypeComboboxData();
//should be created by factory
@@ -105,6 +127,12 @@ public:
i2cpParams.setOutbound_length(outbound_lengthLineEdit->text());
i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text());
i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text());
+ i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text());
+ i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text());
+ i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text());
+ i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text());
+ i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked());
+ i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text());
return true;
}
protected:
@@ -133,6 +161,13 @@ private:
inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));;
outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));;
crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));;
+ explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));;
+ i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0));
+ i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0));
+ i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0));
+ i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0));
+ i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0));
+ i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0));
}
};
diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui
index 9e59132f..7a35c0a5 100644
--- a/qt/i2pd_qt/generalsettingswidget.ui
+++ b/qt/i2pd_qt/generalsettingswidget.ui
@@ -7,7 +7,7 @@
0
0
679
- 3033
+ 4152
@@ -19,23 +19,62 @@
GeneralSettingsContentsForm
+
+ QGroupBox {
+ font: bold;
+ border: 1px solid silver;
+ border-radius: 6px;
+ margin-top: 6px;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ left: 7px;
+ padding: 0px 5px 0px 5px;
+}
+
+
0
0
679
- 3052
+ 4434
-
+
- QLayout::SetMinAndMaxSize
+ QLayout::SetDefaultConstraint
- -
+
-
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ General options
+
+
+
+ -
-
+
0
0
@@ -43,132 +82,158 @@
0
- 51
+ 80
16777215
- 51
+ 80
+
+ QGroupBox {
+ font: bold;
+ border: 1px solid silver;
+ border-radius: 6px;
+ margin-top: 6px;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ left: 7px;
+ padding: 0px 5px 0px 5px;
+}
+
+
Configuration file:
-
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
- 0
- 18
- 661
- 31
+ 12
+ 19
+ 651
+ 51
-
-
- QLayout::SetMaximumSize
-
-
-
-
-
+
-
-
-
-
- 0
- 0
-
+
+
+ QLayout::SetMinAndMaxSize
-
-
- 0
- 27
-
+
+ 10
-
-
- 16777215
- 27
-
+
+ 10
-
- Browse…
+
+ 10
-
+
+ 10
+
+
-
+
+
+ -
+
+
+
+ 0
+ 27
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 27
+
+
+
+ Browse…
+
+
+
+
- -
-
-
-
- 0
- 0
-
-
+
-
+
0
- 51
+ 80
16777215
- 51
+ 80
- Tunnels configuration file:
+ Data folder (for storage of i2pd data — RI, keys, peer profiles, …):
-
+
- 0
- 18
- 661
- 31
+ 12
+ 19
+ 651
+ 51
-
-
- QLayout::SetMaximumSize
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 10
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 27
-
-
-
-
- 16777215
- 27
-
-
-
- Browse…
+
+
+ QLayout::SetMaximumSize
-
+
-
+
+
+ -
+
+
+ Browse…
+
+
+
+
- -
+
-
@@ -179,265 +244,200 @@
0
- 51
+ 80
16777215
- 51
+ 80
Pid file:
-
+
- 0
- 18
- 661
- 31
+ 12
+ 19
+ 651
+ 51
-
-
- QLayout::SetMaximumSize
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 10
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 27
-
-
-
-
- 16777215
- 27
-
-
-
- Browse…
+
+
+ QLayout::SetMaximumSize
-
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 27
+
+
+
+
+ 16777215
+ 27
+
+
+
+ Browse…
+
+
+
+
- -
-
+
-
+
+
+
+ 0
+ 0
+
+
0
- 98
+ 80
16777215
- 98
+ 80
- SAM interface
+ Tunnels configuration file:
-
+
- 0
- 20
- 97
- 22
+ 12
+ 19
+ 651
+ 51
-
- Enabled
-
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
-
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 27
+
+
+
+
+ 16777215
+ 27
+
+
+
+ Browse…
+
+
+
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 130
+
+
+
+
+ 16777215
+ 130
+
+
+
+ Logging
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+
- 0
- 40
+ -1
+ 19
661
- 31
+ 91
-
-
-
-
-
- IP address to listen on:
-
-
-
- -
-
-
+
+
+ QLayout::SetMinAndMaxSize
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
-
- 0
- 70
- 661
- 31
-
-
-
- -
-
-
- Port to listen on:
-
-
-
- -
-
-
-
- 80
- 16777215
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
- -
-
-
-
- 0
- 60
-
-
-
-
- 16777215
- 60
-
-
-
-
- 13
-
-
-
- Windows-specific options
-
-
-
- -
-
-
-
- 0
- 44
-
-
-
-
- 16777215
- 44
-
-
-
- Cryptography
-
-
-
-
- 0
- 20
- 661
- 22
-
-
-
- Use ElGamal precomputed tables
-
-
-
-
- -
-
-
-
- 0
- 107
-
-
-
-
- 16777215
- 107
-
-
-
- Logging
-
-
- Qt::AlignJustify|Qt::AlignTop
-
-
-
-
- -1
- 19
- 661
- 91
-
-
-
-
- QLayout::SetMinimumSize
-
-
-
-
-
- QLayout::SetMaximumSize
+
+
+ QLayout::SetMaximumSize
-
@@ -539,204 +539,267 @@
+ -
+
+
+ Write full CLF-formatted date and time to log
+
+
+
- -
-
+
-
+
+
+
+ 0
+ 0
+
+
0
- 68
+ 417
16777215
- 68
+ 417
- UPnP
+ Router options
-
+
0
20
- 97
- 22
-
-
-
- Enable
-
-
-
-
-
- 0
- 40
661
- 31
+ 397
-
+
-
-
+
- Name i2pd appears in UPnP forwardings list:
+ Enable communication through ipv4
-
-
+
+
+ Enable communication through ipv6
+
+
-
-
-
- Qt::Horizontal
+
+
+ Router will not accept transit tunnels at startup
-
-
- 40
- 20
-
+
+
+ -
+
+
+ Router will be floodfill
-
+
-
-
-
-
- -
-
-
-
- 0
- 98
-
-
-
-
- 16777215
- 98
-
-
-
- I2CP interface
-
-
-
-
- 0
- 20
- 97
- 22
-
-
-
- Enabled
-
-
-
-
-
- 0
- 40
- 661
- 31
-
-
-
-
-
+
- IP address to listen on:
+ Enable SSU transport protocol (use UDP)
-
-
+
+
+ Assume we are behind NAT
+
+
-
-
-
- Qt::Horizontal
+
+
+ Check remote RI for being in blacklist of reserved IP ranges
-
-
- 40
- 20
-
-
-
+
-
-
-
-
-
- 0
- 70
- 661
- 31
-
-
-
-
-
-
- Port to listen on:
-
-
+
+
-
+
+
+ Bandwidth limit (integer or a letter):
+
+
+
+ -
+
+
+ -
+
+
+ KBps
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ Family (name of a family router belongs to):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
+
+
+ QLayout::SetMaximumSize
-
+
-
+
+
+ NetID (network ID router belongs to. The main I2P ID is 2):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Network interface to bind to for IPv4:
+
+
+
+ -
+
+
+
+
+ -
+
+
-
+
+
+ Network interface to bind to for IPv6:
+
+
+
+ -
+
+
+
+
+ -
+
+
-
+
+
+ Max % of bandwidth limit for transit. 0-100:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
- -
-
+
-
+
0
- 98
+ 230
16777215
- 98
+ 230
- BOB interface
+ HTTP webconsole
-
+
0
@@ -749,7 +812,7 @@
Enabled
-
+
0
@@ -758,19 +821,19 @@
31
-
+
-
-
+
IP address to listen on:
-
-
+
-
-
+
Qt::Horizontal
@@ -784,7 +847,7 @@
-
+
0
@@ -793,16 +856,16 @@
31
-
+
-
-
+
Port to listen on:
-
-
+
80
@@ -812,7 +875,7 @@
-
-
+
Qt::Horizontal
@@ -826,143 +889,140 @@
-
-
- -
-
-
-
- 0
- 60
-
-
-
-
- 16777215
- 60
-
-
-
-
- 13
-
-
-
- General options
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 98
-
-
-
-
- 16777215
- 98
-
-
-
- Router external address (for incoming connections)
-
-
- Qt::AlignJustify|Qt::AlignTop
-
-
+
0
- 20
- 661
- 81
+ 100
+ 321
+ 22
-
-
- QLayout::SetMinAndMaxSize
-
+
+ Enable basic HTTP auth
+
+
+
+
+
+ 60
+ 120
+ 601
+ 31
+
+
+
-
-
-
- QLayout::SetMinAndMaxSize
+
+
+ Username:
-
-
-
-
- Host:
-
-
-
- -
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
-
-
-
- QLayout::SetMinAndMaxSize
+
+
+ -
+
+
+ Qt::Horizontal
-
-
-
-
- Port (leave 0 to auto-assign):
-
-
-
- -
-
-
-
- 80
- 16777215
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 60
+ 150
+ 601
+ 31
+
+
+
+ -
+
+
+ Password:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 1
+ 182
+ 661
+ 21
+
+
+
+ Enable strict host checking on web UI
+
+
+
+
+
+ -1
+ 200
+ 661
+ 27
+
+
+
+ -
+
+
+ Expected hostname for web UI:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
- -
+
-
@@ -1025,37 +1085,37 @@
- -
-
+
-
+
0
- 280
+ 190
16777215
- 280
+ 190
- HTTP proxy
+ Reseeding
-
+
0
20
- 97
+ 661
22
- Enabled
+ Request SU3 signature verification
-
+
0
@@ -1064,138 +1124,105 @@
31
-
+
-
-
+
- IP address to listen on:
+ SU3 file to reseed from:
-
-
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
+
+
+ Browse…
-
+
-
+
0
- 70
+ 100
661
31
-
+
-
-
+
- Port to listen on:
-
-
-
- -
-
-
-
- 80
- 16777215
-
+ Reseed URLs, separated by comma:
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
-
+
0
- 100
+ 70
661
31
-
+
-
-
+
- Keys file:
+ Path to local .zip file to reseed from:
-
-
+
-
-
+
- Browse…
+ Browse...
-
+
0
- 160
+ 130
661
31
-
+
-
-
+
- Inbound tunnels length:
+ Minimum number of known routers before requesting reseed:
-
-
-
-
- 80
- 16777215
-
-
-
+
-
-
+
Qt::Horizontal
- 40
+ 50
20
@@ -1203,77 +1230,82 @@
-
+
0
- 190
+ 160
661
31
-
+
-
-
+
- Inbound tunnels quantity:
-
-
-
- -
-
-
-
- 80
- 16777215
-
+ URL for https/socks reseed proxy:
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
-
+
+
+ -
+
+
+
+ 0
+ 68
+
+
+
+
+ 16777215
+ 68
+
+
+
+ UPnP
+
+
0
- 220
+ 20
+ 97
+ 22
+
+
+
+ Enable
+
+
+
+
+
+ 0
+ 40
661
31
-
+
-
-
+
- Outbound tunnels length:
+ Name i2pd appears in UPnP forwardings list:
-
-
-
-
- 80
- 16777215
-
-
-
+
-
-
+
Qt::Horizontal
@@ -1287,35 +1319,60 @@
-
+
+
+ -
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ BOB interface
+
+
0
- 250
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
661
31
-
+
-
-
+
- Outbound tunnels quantity:
+ IP address to listen on:
-
-
-
-
- 80
- 16777215
-
-
-
+
-
-
+
Qt::Horizontal
@@ -1329,35 +1386,35 @@
-
+
0
- 130
+ 70
661
31
-
+
-
-
+
- Signature type:
+ Port to listen on:
-
-
-
- -
-
-
- Edit
+
+
+
+ 80
+ 16777215
+
-
-
+
Qt::Horizontal
@@ -1373,262 +1430,193 @@
- -
-
+
-
+
0
- 60
+ 170
16777215
- 60
+ 170
-
-
- 13
-
-
-
- Various options
+
+ Trust options
+
+
+
+ 0
+ 20
+ 661
+ 21
+
+
+
+ Enable explicit trust options
+
+
+
+
+
+ 390
+ 40
+ 271
+ 23
+
+
+
+
+
+
+ 0
+ 40
+ 391
+ 42
+
+
+
+ Make direct I2P connections only to
+routers in specified Family:
+
+
+
+
+
+ 0
+ 82
+ 661
+ 42
+
+
+
+ Make direct I2P connections only to routers specified here.
+Comma separated list of base64 identities:
+
+
+
+
+
+ 0
+ 124
+ 661
+ 23
+
+
+
+
+
+
+ 0
+ 147
+ 661
+ 21
+
+
+
+ Should we hide our router from other routers?
+
+
- -
-
+
-
+
0
- 51
+ 400
16777215
- 51
+ 400
- Data folder (for storage of i2pd data — RI, keys, peer profiles, …):
+ HTTP proxy
-
+
0
20
- 661
- 31
+ 97
+ 22
-
-
- QLayout::SetMaximumSize
-
-
-
-
-
- -
-
-
- Browse…
-
-
-
-
+
+ Enabled
+
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 215
-
-
-
-
- 16777215
- 215
-
-
-
- Router options
-
-
+
0
- 20
+ 40
661
- 188
+ 31
-
+
-
-
+
- Enable communication through ipv6
+ IP address to listen on:
-
-
-
- Router will not accept transit tunnels at startup
-
-
+
-
-
-
- Router will be floodfill
+
+
+ Qt::Horizontal
-
-
- -
-
-
-
-
-
- Bandwidth limit (integer or a letter):
-
-
-
- -
-
-
- -
-
-
- KBps
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
-
-
-
- Family (name of a family router belongs to):
-
-
-
- -
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- QLayout::SetMaximumSize
+
+
+ 40
+ 20
+
-
-
-
-
- NetID (network ID router belongs to. The main I2P ID is 2):
-
-
-
- -
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
-
-
- -
-
-
-
- 0
- 108
-
-
-
-
- 16777215
- 108
-
-
-
- Limits
-
-
+
0
- 20
+ 70
661
31
-
+
-
-
+
- Maximum number of transit tunnels:
+ Port to listen on:
-
-
+
+
+
+ 80
+ 16777215
+
+
+
-
-
+
Qt::Horizontal
@@ -1642,63 +1630,64 @@
-
+
0
- 50
+ 100
661
31
-
+
-
-
+
- Maximum number of open files (0 — use system limit):
+ Keys file:
-
-
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
+
+
+ Browse…
-
+
-
+
0
- 80
+ 160
661
31
-
+
-
-
+
- Maximum size of core file in Kb (0 — use system limit):
+ Inbound tunnels length:
-
-
+
+
+
+ 80
+ 16777215
+
+
+
-
-
+
Qt::Horizontal
@@ -1712,279 +1701,540 @@
-
-
- -
-
-
-
- 0
- 98
-
-
-
-
- 16777215
- 98
-
-
-
- Reseeding
-
-
+
0
- 20
+ 190
661
- 22
+ 31
-
- Request SU3 signature verification
-
+
+
-
+
+
+ Inbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
0
- 40
+ 220
661
31
-
+
-
-
+
- SU3 file to reseed from:
+ Outbound tunnels length:
-
-
+
+
+
+ 80
+ 16777215
+
+
+
-
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 250
+ 661
+ 31
+
+
+
+ -
+
- Browse…
+ Outbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
-
+
0
- 70
+ 130
661
31
-
+
-
-
+
- Reseed URLs, separated by comma:
+ Signature type:
-
-
+
+
+ -
+
+
+ Edit
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 280
+ 661
+ 23
+
+
+
+ Enable address helper (jump)
+
+
+
+
+
+ 0
+ 300
+ 661
+ 95
+
+
+
+ -
+
+
-
+
+
+ HTTP proxy upstream out proxy URL (like http://false.i2p):
+
+
+
+ -
+
+
+
+
+ -
+
+
-
+
+
+ Type of LeaseSet to be sent. 1, 3 or 5:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Comma-separated encryption types to be used in LeaseSet type 3 or 5:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
- -
-
+
-
+
0
- 170
+ 121
16777215
- 170
+ 121
- Trust options
+ SAM interface
-
+
0
20
- 661
- 21
+ 97
+ 22
- Enable explicit trust options
-
-
-
-
-
- 390
- 40
- 271
- 23
-
+ Enabled
-
+
0
40
- 391
- 42
+ 661
+ 31
-
- Make direct I2P connections only to
-routers in specified Family:
-
-
-
-
-
- 0
- 82
- 661
- 42
-
-
-
- Make direct I2P connections only to routers specified here.
-Comma separated list of base64 identities:
-
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
0
- 124
+ 70
661
- 23
+ 31
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
0
- 147
- 661
- 21
+ 100
+ 621
+ 23
- Should we hide our router from other routers?
+ Single thread for all SAM sessions
- -
-
-
-
- 0
- 60
-
-
-
-
- 16777215
- 60
-
-
-
-
- 13
-
-
-
- Ports
+
-
+
+
+
+ 0
+ 0
+
-
-
- -
-
0
- 22
+ 98
16777215
- 22
+ 98
-
- Insomnia (prevent system from sleeping)
+
+ Router external address (for incoming connections)
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+
+
+ 0
+ 20
+ 661
+ 81
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ Host:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ Port (leave 0 to auto-assign):
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
- -
-
+
-
+
0
- 189
+ 108
16777215
- 189
+ 108
- I2PControl interface
+ Limits
-
+
0
20
- 97
- 22
-
-
-
- Enabled
-
-
-
-
-
- 0
- 40
661
31
-
+
-
-
+
- IP address to listen on:
+ Maximum number of transit tunnels:
-
-
+
-
-
+
Qt::Horizontal
@@ -1998,35 +2248,28 @@ Comma separated list of base64 identities:
-
+
0
- 70
+ 50
661
31
-
+
-
-
+
- Port to listen on:
+ Maximum number of open files (0 — use system limit):
-
-
-
-
- 80
- 16777215
-
-
-
+
-
-
+
Qt::Horizontal
@@ -2040,28 +2283,28 @@ Comma separated list of base64 identities:
-
+
0
- 100
+ 80
661
31
-
+
-
-
+
- Password:
+ Maximum size of core file in Kb (0 — use system limit):
-
-
+
-
-
+
Qt::Horizontal
@@ -2075,59 +2318,245 @@ Comma separated list of base64 identities:
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 128
+
+
+
+
+ 16777215
+ 128
+
+
+
+ Nettime options
+
+
0
- 130
- 661
- 31
+ 20
+ 671
+ 101
-
+
+
+ QLayout::SetMinAndMaxSize
+
-
-
+
- Certificate file:
+ Enable NTP sync
-
-
+
+
-
+
+
+ Comma-separated list of NTP servers:
+
+
+
+ -
+
+
+
-
-
-
- Browse…
-
-
+
+
-
+
+
+ NTP time sync interval in hours:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 225
+
+
+
+
+ 16777215
+ 225
+
+
+
+ NTCP2 options
+
+
- 0
- 160
- 661
- 31
+ -1
+ 19
+ 671
+ 191
-
+
+
+ QLayout::SetMinAndMaxSize
+
-
-
+
- Key file:
+ Enable NTCP2
-
-
+
+
+ Enable incoming NTCP2 connections
+
+
-
-
+
+
-
+
+
+ Port to listen for incoming NTCP2 connections:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ External IPv6 address for incoming connections:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Specify proxy server for NTCP2:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
- Browse…
+ Proxy server should be http://address:port or socks://address:port
@@ -2135,24 +2564,24 @@ Comma separated list of base64 identities:
- -
-
+
-
+
0
- 179
+ 189
16777215
- 179
+ 189
- HTTP webconsole
+ I2PControl interface
-
+
0
@@ -2165,7 +2594,7 @@ Comma separated list of base64 identities:
Enabled
-
+
0
@@ -2174,19 +2603,19 @@ Comma separated list of base64 identities:
31
-
+
-
-
+
IP address to listen on:
-
-
+
-
-
+
Qt::Horizontal
@@ -2200,7 +2629,7 @@ Comma separated list of base64 identities:
-
+
0
@@ -2209,16 +2638,16 @@ Comma separated list of base64 identities:
31
-
+
-
-
+
Port to listen on:
-
-
+
80
@@ -2228,7 +2657,7 @@ Comma separated list of base64 identities:
-
-
+
Qt::Horizontal
@@ -2242,41 +2671,28 @@ Comma separated list of base64 identities:
-
+
0
100
- 321
- 22
-
-
-
- Enable basic HTTP auth
-
-
-
-
-
- 60
- 120
- 601
+ 661
31
-
+
-
-
+
- Username:
+ Password:
-
-
+
-
-
+
Qt::Horizontal
@@ -2290,61 +2706,116 @@ Comma separated list of base64 identities:
-
+
- 60
- 150
- 601
+ 0
+ 130
+ 661
31
-
+
-
-
+
- Password:
+ Certificate file:
-
-
+
-
-
-
- Qt::Horizontal
+
+
+ Browse…
-
-
- 40
- 20
-
+
+
+
+
+
+
+
+ 0
+ 160
+ 661
+ 31
+
+
+
+ -
+
+
+ Key file:
-
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
- -
-
+
-
+
0
- 335
+ 44
16777215
- 335
+ 44
- Socks proxy
+ Cryptography
+
+
+
+
+ 0
+ 20
+ 661
+ 22
+
+
+
+ Use ElGamal precomputed tables
+
+
+
+
+ -
+
+
+
+ 0
+ 121
+
+
+
+
+ 16777215
+ 121
+
+
+
+ I2CP interface
-
+
0
@@ -2357,7 +2828,7 @@ Comma separated list of base64 identities:
Enabled
-
+
0
@@ -2366,19 +2837,19 @@ Comma separated list of base64 identities:
31
-
+
-
-
+
IP address to listen on:
-
-
+
-
-
+
Qt::Horizontal
@@ -2392,7 +2863,7 @@ Comma separated list of base64 identities:
-
+
0
@@ -2401,16 +2872,16 @@ Comma separated list of base64 identities:
31
-
+
-
-
+
Port to listen on:
-
-
+
80
@@ -2420,7 +2891,7 @@ Comma separated list of base64 identities:
-
-
+
Qt::Horizontal
@@ -2434,324 +2905,898 @@ Comma separated list of base64 identities:
-
+
0
100
- 661
- 31
+ 651
+ 23
-
- -
-
-
- Keys file:
-
-
-
- -
-
-
- -
-
-
- Browse…
-
-
-
-
+
+ Single thread for all I2CP sessions
+
-
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Ports
+
+
+
+ -
+
+
+
+ 0
+ 500
+
+
+
+
+ 16777215
+ 500
+
+
+
+ Socks proxy
+
+
- 0
- 160
+ 9
+ 20
661
- 31
+ 470
-
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
-
-
+
- Inbound tunnels length:
+ Enabled
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+
-
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
-
- 0
- 190
- 661
- 31
-
-
-
-
-
-
- Inbound tunnels quantity:
-
-
+
+
-
+
+
+ Keys file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ Signature type:
+
+
+
+ -
+
+
+ -
+
+
+ Edit
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+
-
+
+
+ Inbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
-
- 0
- 220
- 661
- 31
-
-
-
-
-
-
- Outbound tunnels length:
-
-
+
+
-
+
+
+ Inbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ Outbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
+
+
-
+
+
+ Outbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
-
-
- 40
- 20
-
+
+ 0
-
+
-
+
+
+ Outproxy enabled
+
+
+
+
+
+ -
+
+
-
+
+
+ Outproxy address:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Outproxy port:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Type of LeaseSet to be sent. 1, 3 or 5:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Comma-separated encryption types to be used in LeaseSet type 3 or 5:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 145
+
+
+
+
+ 16777215
+ 300
+
+
+
+ Websocket Server
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
- 0
- 250
- 661
- 31
+ -1
+ 19
+ 681
+ 124
-
+
+
+ QLayout::SetDefaultConstraint
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
-
-
+
- Outbound tunnels quantity:
+ Enable websocket server
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ Address to bind websocket server on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+
-
+
+
+ Port to bind websocket server on:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Various options
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 160
+
+
+
+
+ 16777215
+ 160
+
+
+
+ Exploratory Tunnels
+
+
- 0
- 280
- 661
- 31
+ -1
+ 19
+ 671
+ 131
-
-
-
-
-
- Outproxy address:
-
-
-
- -
-
-
+
+
+ QLayout::SetMinAndMaxSize
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+
-
+
+
+ Exploratory inbound tunnels length:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
-
- 0
- 310
- 661
- 31
-
-
-
-
-
-
- Outproxy port:
-
-
+
+
-
+
+
+ Exploratory inbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
-
- 80
- 16777215
-
-
-
+
+
-
+
+
+ Exploratory outbound tunnels length:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+
-
+
+
+ Exploratory outbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 56
+
+
+
+
+ 16777215
+ 56
+
+
+
+ Persist profiles
+
+
0
- 130
- 661
+ 20
+ 681
31
-
-
-
-
-
- Signature type:
-
-
-
- -
-
-
+
+
+ QLayout::SetMinAndMaxSize
+
-
-
+
- Edit
+ Enable peer profile persisting to disk
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Windows-specific options
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 22
+
+
+
+
+ 16777215
+ 22
+
+
+
+ Insomnia (prevent system from sleeping)
+
+
+
diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro
index 468d2d00..534d5f5a 100644
--- a/qt/i2pd_qt/i2pd_qt.pro
+++ b/qt/i2pd_qt/i2pd_qt.pro
@@ -4,7 +4,8 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = i2pd_qt
TEMPLATE = app
-QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized
+QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized
+CONFIG += strict_c++ c++11
DEFINES += USE_UPNP
@@ -59,6 +60,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
../../libi2pd/TunnelEndpoint.cpp \
../../libi2pd/TunnelGateway.cpp \
../../libi2pd/TunnelPool.cpp \
+ ../../libi2pd/TunnelConfig.cpp \
../../libi2pd/util.cpp \
../../libi2pd/Elligator.cpp \
../../libi2pd/ECIESX25519AEADRatchetSession.cpp \
@@ -103,7 +105,6 @@ HEADERS += DaemonQT.h mainwindow.h \
../../libi2pd/CPU.h \
../../libi2pd/Crypto.h \
../../libi2pd/CryptoKey.h \
- ../../libi2pd/CryptoWorker.h \
../../libi2pd/Datagram.h \
../../libi2pd/Destination.h \
../../libi2pd/Ed25519.h \
diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp
index 0ce0e2f8..89178ee0 100644
--- a/qt/i2pd_qt/mainwindow.cpp
+++ b/qt/i2pd_qt/mainwindow.cpp
@@ -81,10 +81,10 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
onResize();
ui->stackedWidget->setCurrentIndex(0);
- ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380);
+ ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380);
//QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar();
int w = 683;
- int h = 3060;
+ int h = 4550;
ui->settingsContents->setFixedSize(w, h);
ui->settingsContents->setGeometry(QRect(0,0,w,h));
@@ -159,12 +159,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
# define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option))
initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton);
- initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton);
initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton);
-
initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton);
- daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";}));
- serviceOption=initNonGUIOption( OPTION("","service",[]{return "";}));
uiSettings->logDestinationComboBox->clear();
uiSettings->logDestinationComboBox->insertItems(0, QStringList()
@@ -176,20 +172,29 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton);
initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox);
-
+ initCheckBox( OPTION("","logclftime",[]{return "false";}), uiSettings->logclftimeCheckBox);//"Write full CLF-formatted date and time to log (default: write only time)"
+ initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton);
initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host"));
initTCPPortBox( OPTION("","port",[]{return "";}), uiSettings->routerExternalPortLineEdit, tr("Router external address -> Port"));
-
+ daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";}));
+ serviceOption=initNonGUIOption( OPTION("","service",[]{return "";}));
+ initStringBox( OPTION("","ifname4",[]{return "";}), uiSettings->ifname4LineEdit);//Network interface to bind to for IPv4
+ initStringBox( OPTION("","ifname6",[]{return "";}), uiSettings->ifname6LineEdit);//Network interface to bind to for IPv6
+ initCheckBox( OPTION("","nat",[]{return "true";}), uiSettings->natCheckBox);//If true, assume we are behind NAT. true by default
+ initCheckBox( OPTION("","ipv4",[]{return "true";}), uiSettings->ipv4CheckBox);//Enable communication through IPv4. true by default
initCheckBox( OPTION("","ipv6",[]{return "false";}), uiSettings->ipv6CheckBox);
initCheckBox( OPTION("","notransit",[]{return "false";}), uiSettings->notransitCheckBox);
initCheckBox( OPTION("","floodfill",[]{return "false";}), uiSettings->floodfillCheckBox);
initStringBox( OPTION("","bandwidth",[]{return "";}), uiSettings->bandwidthLineEdit);
+ initIntegerBox( OPTION("","share",[]{return "100";}), uiSettings->shareLineEdit, tr("Share"));//Max % of bandwidth limit for transit. 0-100. 100 by default
initStringBox( OPTION("","family",[]{return "";}), uiSettings->familyLineEdit);
initIntegerBox( OPTION("","netid",[]{return "2";}), uiSettings->netIdLineEdit, tr("NetID"));
+ initCheckBox( OPTION("","ssu",[]{return "true";}), uiSettings->ssuCheckBox);//Enable SSU transport protocol (use UDP). true by default
+ initCheckBox( OPTION("","reservedrange",[]{return "true";}), uiSettings->reservedrange_checkbox);
#ifdef Q_OS_WIN
- initCheckBox( OPTION("","insomnia",[]{return "";}), uiSettings->insomniaCheckBox);
initNonGUIOption( OPTION("","svcctl",[]{return "";}));
+ initCheckBox( OPTION("","insomnia",[]{return "";}), uiSettings->insomniaCheckBox);
initNonGUIOption( OPTION("","close",[]{return "";}));
#else
uiSettings->insomniaCheckBox->setEnabled(false);
@@ -201,17 +206,22 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initCheckBox( OPTION("http","auth",[]{return "";}), uiSettings->webconsoleBasicAuthCheckBox);
initStringBox( OPTION("http","user",[]{return "i2pd";}), uiSettings->webconsoleUserNameLineEditBasicAuth);
initStringBox( OPTION("http","pass",[]{return "";}), uiSettings->webconsolePasswordLineEditBasicAuth);
+ initCheckBox( OPTION("http","strictheaders",[]{return "true";}), uiSettings->httpStrictHeadersCheckBox);//Enable strict host checking on WebUI. true by default
+ initStringBox( OPTION("http","hostname",[]{return "localhost";}), uiSettings->httpHostnameLineEdit);//Expected hostname for WebUI (default: localhost)
initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), uiSettings->httpProxyEnabledCheckBox);
initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address"));
initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port"));
+ initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//Enable address helper (jump). true by default
initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton);
-
initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType);
initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit);
initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit);
initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), uiSettings->httpProxyOutBoundTunnLenLineEdit);
initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), uiSettings->httpProxyOutboundTunnQuantityLineEdit);
+ initStringBox( OPTION("httpproxy","outproxy",[]{return "";}), uiSettings->httpProxyOutproxyLineEdit);//HTTP proxy upstream out proxy url (like http://false.i2p)
+ initStringBox( OPTION("httpproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->httpProxyI2cpLeaseSetTypeLineEdit);//Type of LeaseSet to be sent. 1, 3 or 5. 1 by default
+ initStringBox( OPTION("httpproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->httpProxyI2cpLeaseSetEncTypeLineEdit);//Comma separated encryption types to be used in LeaseSet type 3 or 5
initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox);
initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address"));
@@ -222,12 +232,16 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit);
initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), uiSettings->socksProxyOutBoundTunnLenLineEdit);
initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit);
- initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address"));
- initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port"));
+ initCheckBox( OPTION("socksproxy","outproxy.enabled",[]{return "false";}), uiSettings->socksOutproxyEnabledCheckBox);
+ initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "127.0.0.1";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address"));
+ initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "9050";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port"));
+ initStringBox( OPTION("socksproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->socksProxyI2cpLeaseSetTypeLineEdit);//Type of LeaseSet to be sent. 1, 3 or 5. 1 by default
+ initStringBox( OPTION("socksproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->socksProxyI2cpLeaseSetEncTypeLineEdit);//Comma separated encryption types to be used in LeaseSet type 3 or 5
initCheckBox( OPTION("sam","enabled",[]{return "false";}), uiSettings->samEnabledCheckBox);
initIPAddressBox( OPTION("sam","address",[]{return "";}), uiSettings->samAddressLineEdit, tr("SAM -> IP address"));
initTCPPortBox( OPTION("sam","port",[]{return "7656";}), uiSettings->samPortLineEdit, tr("SAM -> Port"));
+ initCheckBox( OPTION("sam","singlethread",[]{return "true";}), uiSettings->samSingleThreadCheckBox);//If false every SAM session runs in own thread. true by default
initCheckBox( OPTION("bob","enabled",[]{return "false";}), uiSettings->bobEnabledCheckBox);
initIPAddressBox( OPTION("bob","address",[]{return "";}), uiSettings->bobAddressLineEdit, tr("BOB -> IP address"));
@@ -236,6 +250,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), uiSettings->i2cpEnabledCheckBox);
initIPAddressBox( OPTION("i2cp","address",[]{return "";}), uiSettings->i2cpAddressLineEdit, tr("I2CP -> IP address"));
initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), uiSettings->i2cpPortLineEdit, tr("I2CP -> Port"));
+ //initCheckBox( OPTION("i2cp","singlethread",[]{return "true";}), uiSettings->i2cpSingleThreadCheckBox);//If false every I2CP session runs in own thread. true by default
initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), uiSettings->i2pControlEnabledCheckBox);
initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address"));
@@ -252,6 +267,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox);
initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton);
initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit);
+ initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton); //Path to local .zip file to reseed from
+ initUInt16Box( OPTION("reseed","threshold",[]{return "25";}), uiSettings->reseedThresholdNumberLineEdit, tr("reseedThreshold")); //Minimum number of known routers before requesting reseed. 25 by default
+ initStringBox( OPTION("reseed","proxy",[]{return "";}), uiSettings->reseedProxyLineEdit);//URL for https/socks reseed proxy
initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), uiSettings->addressbookDefaultURLLineEdit);
initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), uiSettings->addressbookSubscriptionsURLslineEdit);
@@ -265,6 +283,26 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters);
initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden);
+ initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable); //Enable websocket server. Disabled by default
+ initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->websocketsAddressLineEdit, tr("Websockets -> IP address")); //Address to bind websocket server on. 127.0.0.1 by default
+ initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->websocketsPortLineEdit, tr("Websockets -> Port")); //Port to bind websocket server on. 7666 by default
+
+ initIntegerBox( OPTION("exploratory","inbound.length",[]{return "2";}), uiSettings->exploratoryInboundTunnelsLengthNumberLineEdit, tr("exploratoryInboundTunnelsLength"));//Exploratory inbound tunnels length. 2 by default
+ initIntegerBox( OPTION("exploratory","inbound.quantity",[]{return "3";}), uiSettings->exploratoryInboundTunnelsQuantityNumberLineEdit, tr("exploratoryInboundTunnelsQuantity"));//Exploratory inbound tunnels quantity. 3 by default
+ initIntegerBox( OPTION("exploratory","outbound.length",[]{return "2";}), uiSettings->exploratoryOutboundTunnelsLengthNumberLineEdit, tr("exploratoryOutboundTunnelsLength"));//Exploratory outbound tunnels length. 2 by default
+ initIntegerBox( OPTION("exploratory","outbound.quantity",[]{return "3";}), uiSettings->exploratoryOutboundTunnelsQuantityNumberLineEdit, tr("exploratoryOutboundTunnelsQuantity"));//Exploratory outbound tunnels length. 3 by default
+
+ initCheckBox( OPTION("ntcp2","enabled",[]{return "true";}), uiSettings->checkBoxNtcp2Enable); //Enable NTCP2. Enabled by default
+ initCheckBox( OPTION("ntcp2","published",[]{return "false";}), uiSettings->checkBoxNtcp2Published); //Enable incoming NTCP2 connections. Disabled by default
+ initTCPPortBox( OPTION("ntcp2","port",[]{return "0";}), uiSettings->ntcp2PortLineEdit, tr("NTCP2 -> Port")); //Port to listen for incoming NTCP2 connections (default: auto)
+ initIPAddressBox( OPTION("ntcp2","addressv6",[]{return "::";}), uiSettings->ntcp2AddressV6LineEdit, tr("NTCP2 -> IPv6 address")); //External IPv6 for incoming connections
+ initStringBox( OPTION("ntcp2","proxy",[]{return "";}), uiSettings->lineEditNtcp2Proxy); //Specify proxy server for NTCP2. Should be http://address:port or socks://address:port
+
+ initCheckBox( OPTION("nettime","enabled",[]{return "false";}), uiSettings->checkBoxNettimeEnable); //Enable NTP sync. Disabled by default
+ initStringBox( OPTION("nettime","ntpservers",[]{return "pool.ntp.org";}), uiSettings->lineEditNetTimeNtpServers); //Comma-separated list of NTP servers. pool.ntp.org by default
+ initIntegerBox( OPTION("nettime","ntpsyncinterval",[]{return "72";}), uiSettings->nettimeNtpSyncIntervalNumberLineEdit, tr("nettimeNtpSyncInterval")); //NTP time sync interval in hours. 72 by default
+
+ initCheckBox( OPTION("persist","profiles",[]{return "true";}), uiSettings->checkBoxPersistProfiles);//Enable peer profile persisting to disk. Enabled by default
# undef OPTION
//widgetlocks.add(new widgetlock(widget,lockbtn));
@@ -287,6 +325,18 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451));
+ ui->tunnelsScrollAreaWidgetContents->setStyleSheet("QGroupBox { " \
+ " font: bold;" \
+ " border: 1px solid silver;" \
+ " border-radius: 6px;" \
+ " margin-top: 6px;" \
+ "}" \
+ "QGroupBox::title {" \
+ " subcontrol-origin: margin;" \
+ " left: 7px;" \
+ " padding: 0px 5px 0px 5px;" \
+ "}");
+
appendTunnelForms("");
uiSettings->configFileLineEdit->setEnabled(false);
@@ -666,7 +716,7 @@ void MainWindow::layoutTunnels() {
int height=0;
ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0);
for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) {
- const std::string& name=it->first;
+ //const std::string& name=it->first;
TunnelConfig* tunconf = it->second;
TunnelPane * tunnelPane=tunconf->getTunnelPane();
if(!tunnelPane)continue;
diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h
index 91c99122..77c8826b 100644
--- a/qt/i2pd_qt/mainwindow.h
+++ b/qt/i2pd_qt/mainwindow.h
@@ -104,7 +104,8 @@ class MainWindowItem : public QObject {
QWidget* widgetToFocus;
QString requirementToBeValid;
public:
- MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {}
+ MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) :
+ option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {}
QWidget* getWidgetToFocus(){return widgetToFocus;}
QString& getRequirementToBeValid() { return requirementToBeValid; }
ConfigOption& getConfigOption() { return option; }
@@ -115,7 +116,7 @@ public:
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
- //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
+ qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
boost::any programOption;
i2p::config::GetOptionAsAny(optName, programOption);
optionValue=programOption.empty()?boost::any(std::string(""))
@@ -280,6 +281,7 @@ public:
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
+ qDebug() << "setting value for checkbox " << checkBox->text();
checkBox->setChecked(boost::any_cast(optionValue));
}
virtual void saveToStringStream(std::stringstream& out){
@@ -543,6 +545,18 @@ private:
void deleteTunnelForms();
void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf);
+ template
+ std::string GetI2CPOption (const Section& section, const std::string& name, const std::string& value) const
+ {
+ return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value);
+ }
+
+ template
+ std::string GetI2CPOption (const Section& section, const std::string& name, const char* value) const
+ {
+ return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::string (value));
+ }
+
template
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
{
@@ -563,6 +577,19 @@ private:
param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str()));
std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str()));
+ std::string _i2cp_leaseSetAuthType = options[I2CP_PARAM_LEASESET_AUTH_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0);
+ param.set_i2cp_leaseSetAuthType(QString(_i2cp_leaseSetAuthType.c_str()));
+ const char DEFAULT_LEASESET_ENCRYPTION_TYPE[] = "";
+ std::string _i2cp_leaseSetEncType = options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, DEFAULT_LEASESET_ENCRYPTION_TYPE);//todo Identity's type by default
+ param.set_i2cp_leaseSetEncType(QString(_i2cp_leaseSetEncType.c_str()));
+ std::string _i2cp_leaseSetPrivKey = options[I2CP_PARAM_LEASESET_PRIV_KEY] = GetI2CPOption (section, I2CP_PARAM_LEASESET_PRIV_KEY, "");
+ param.set_i2cp_leaseSetPrivKey(QString(_i2cp_leaseSetPrivKey.c_str()));
+ std::string _i2cp_leaseSetType = options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE);
+ param.set_i2cp_leaseSetType(QString(_i2cp_leaseSetType.c_str()));
+ std::string _i2p_streaming_answerPings= options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption (section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS);
+ param.set_i2p_streaming_answerPings((_i2p_streaming_answerPings.compare("true")==0)||(_i2p_streaming_answerPings.compare("yes")==0));
+ std::string _i2p_streaming_initialAckDelay = options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption (section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY);
+ param.set_i2p_streaming_initialAckDelay(QString(_i2p_streaming_initialAckDelay.c_str()));
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param
}
@@ -580,6 +607,17 @@ private:
param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY));
const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND;
param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND));
+ const int _i2cp_leaseSetAuthType = 0;
+ param.set_i2cp_leaseSetAuthType(QString::number(_i2cp_leaseSetAuthType));
+ const QString _i2cp_leaseSetEncType = "0,4"; //todo Identity's type by default
+ param.set_i2cp_leaseSetEncType(_i2cp_leaseSetEncType);
+ param.set_i2cp_leaseSetPrivKey("");
+ const int _i2cp_leaseSetType = DEFAULT_LEASESET_TYPE;
+ param.set_i2cp_leaseSetType(QString::number(_i2cp_leaseSetType));
+ bool _i2p_streaming_answerPings= DEFAULT_ANSWER_PINGS;
+ param.set_i2p_streaming_answerPings(_i2p_streaming_answerPings);
+ const int _i2p_streaming_initialAckDelay = DEFAULT_INITIAL_ACK_DELAY;
+ param.set_i2p_streaming_initialAckDelay(QString::number(_i2p_streaming_initialAckDelay));
}
@@ -613,6 +651,7 @@ private:
std::string keys = "";
std::string address = "127.0.0.1";
int destinationPort = 0;
+ int cryptoType = 0;
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
// I2CP
I2CPParameters i2cpParameters;
@@ -624,7 +663,8 @@ private:
keys,
address,
destinationPort,
- sigType);
+ sigType,
+ cryptoType);
saveAllConfigs(true, name);
}
@@ -643,6 +683,7 @@ private:
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
std::string address = "127.0.0.1";
bool isUniqueLocal = true;
+ int cryptoType = 0;
// I2CP
I2CPParameters i2cpParameters;
@@ -659,7 +700,8 @@ private:
gzip,
sigType,
address,
- isUniqueLocal);
+ isUniqueLocal,
+ cryptoType);
saveAllConfigs(true, name);
@@ -712,6 +754,7 @@ private:
// optional params
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
+ int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl;
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
@@ -726,7 +769,8 @@ private:
keys,
address,
destinationPort,
- sigType);
+ sigType,
+ cryptoType);
}
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
@@ -746,6 +790,7 @@ private:
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
+ int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
// I2CP
std::map options;
@@ -779,7 +824,8 @@ private:
gzip,
sigType,
address,
- isUniqueLocal);
+ isUniqueLocal,
+ cryptoType);
}
else
LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui