Browse Source

Merge pull request #1229 from PurpleI2P/openssl

2.20
pull/1268/head
orignal 6 years ago committed by GitHub
parent
commit
73b6338f62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      ChangeLog
  2. 14
      Makefile.osx
  3. 2
      Win32/installer.iss
  4. 2
      android/AndroidManifest.xml
  5. 5
      android/assets/i2pd.conf
  6. 2
      android/build.gradle
  7. 4
      android/jni/Android.mk
  8. 4
      android/jni/Application.mk
  9. 20
      android/jni/DaemonAndroid.cpp
  10. 84
      android/src/org/purplei2p/i2pd/I2PDActivity.java
  11. 4
      android_binary_only/jni/Android.mk
  12. 2
      appveyor.yml
  13. 2
      contrib/docker/Dockerfile
  14. 2
      contrib/rpm/i2pd-git.spec
  15. 5
      contrib/rpm/i2pd.spec
  16. 28
      daemon/HTTPServer.cpp
  17. 4
      daemon/UPnP.cpp
  18. 6
      debian/changelog
  19. 2
      libi2pd/Config.cpp
  20. 246
      libi2pd/NTCP2.cpp
  21. 17
      libi2pd/NTCP2.h
  22. 4
      libi2pd/NTCPSession.cpp
  23. 2
      libi2pd/RouterContext.cpp
  24. 4
      libi2pd/RouterInfo.cpp
  25. 4
      libi2pd/version.h
  26. 2
      qt/i2pd_qt/android/AndroidManifest.xml

11
ChangeLog

@ -1,6 +1,17 @@
# for this file format description, # for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog # see https://github.com/olivierlacan/keep-a-changelog
## [2.20.0] - 2018-08-23
### Added
- Full implementation of NTCP2
- Assets for android
### Changed
- armeabi-v7a and x86 in one apk for android
- NTCP2 is enabled by default
- Show lease's expiration time in readable format in the web console
### Fixed
- Correct names for transports in the web console
## [2.19.0] - 2018-06-26 ## [2.19.0] - 2018-06-26
### Added ### Added
- ECIES support for RouterInfo - ECIES support for RouterInfo

14
Makefile.osx vendored

@ -31,6 +31,14 @@ endif
# Disabled, since it will be the default make rule. I think its better # Disabled, since it will be the default make rule. I think its better
# to define the default rule in Makefile and not Makefile.<ostype> - torkel # to define the default rule in Makefile and not Makefile.<ostype> - torkel
#install: all install-brew: all
# test -d ${PREFIX} || mkdir -p ${PREFIX}/ install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
# cp -r i2p ${PREFIX}/ install -m 755 ${I2PD} ${PREFIX}/bin/
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
@gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf

2
Win32/installer.iss

@ -1,5 +1,5 @@
#define I2Pd_AppName "i2pd" #define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.19.0" #define I2Pd_ver "2.20.0"
#define I2Pd_Publisher "PurpleI2P" #define I2Pd_Publisher "PurpleI2P"
[Setup] [Setup]

2
android/AndroidManifest.xml

@ -3,7 +3,7 @@
package="org.purplei2p.i2pd" package="org.purplei2p.i2pd"
android:installLocation="auto" android:installLocation="auto"
android:versionCode="1" android:versionCode="1"
android:versionName="2.19.0"> android:versionName="2.20.0">
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="14"

5
android/assets/i2pd.conf

@ -15,12 +15,15 @@ ipv6 = false
# ntcpproxy = http://127.0.0.1:8118 # ntcpproxy = http://127.0.0.1:8118
# ssu = true # ssu = true
bandwidth = O bandwidth = L
# share = 100 # share = 100
# notransit = true # notransit = true
# floodfill = true # floodfill = true
[ntcp2]
enabled = true
[http] [http]
enabled = true enabled = true
address = 127.0.0.1 address = 127.0.0.1

2
android/build.gradle

@ -25,7 +25,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
minSdkVersion 14 minSdkVersion 14
versionCode 1 versionCode 1
versionName "2.19.0" versionName "2.20.0"
ndk { ndk {
abiFilters 'armeabi-v7a' abiFilters 'armeabi-v7a'
abiFilters 'x86' abiFilters 'x86'

4
android/jni/Android.mk

@ -68,6 +68,6 @@ include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)

4
android/jni/Application.mk

@ -1,8 +1,8 @@
#APP_ABI := all #APP_ABI := all
#APP_ABI := armeabi-v7a x86 APP_ABI := armeabi-v7a x86
#APP_ABI := x86 #APP_ABI := x86
#APP_ABI := x86_64 #APP_ABI := x86_64
APP_ABI := armeabi-v7a #APP_ABI := armeabi-v7a
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there. #can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
APP_PLATFORM := android-14 APP_PLATFORM := android-14

20
android/jni/DaemonAndroid.cpp

@ -1,10 +1,13 @@
#include "DaemonAndroid.h"
#include "Daemon.h"
#include <iostream> #include <iostream>
#include <chrono>
#include <thread>
#include <exception>
#include <boost/exception/diagnostic_information.hpp> #include <boost/exception/diagnostic_information.hpp>
#include <boost/exception_ptr.hpp> #include <boost/exception_ptr.hpp>
#include <exception>
//#include "mainwindow.h" //#include "mainwindow.h"
#include "FS.h"
#include "DaemonAndroid.h"
#include "Daemon.h"
namespace i2p namespace i2p
{ {
@ -80,6 +83,17 @@ namespace android
//mutex=new QMutex(QMutex::Recursive); //mutex=new QMutex(QMutex::Recursive);
//setRunningCallback(0); //setRunningCallback(0);
//m_IsRunning=false; //m_IsRunning=false;
// make sure assets are ready before proceed
i2p::fs::DetectDataDir("", false);
int numAttempts = 0;
do
{
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
numAttempts++;
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
}
while (numAttempts <= 10); // 10 seconds max
return Daemon.init(argc,argv); return Daemon.init(argc,argv);
} }

84
android/src/org/purplei2p/i2pd/I2PDActivity.java

@ -1,6 +1,9 @@
package org.purplei2p.i2pd; package org.purplei2p.i2pd;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -25,19 +28,25 @@ import android.view.MenuItem;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
// For future package update checking
import org.purplei2p.i2pd.BuildConfig;
public class I2PDActivity extends Activity { public class I2PDActivity extends Activity {
private static final String TAG = "i2pdActvt"; private static final String TAG = "i2pdActvt";
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
private TextView textView; private TextView textView;
private boolean assetsCopied;
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
new DaemonSingleton.StateUpdateListener() { new DaemonSingleton.StateUpdateListener() {
@Override @Override
public void daemonStateUpdate() { public void daemonStateUpdate()
{
processAssets();
runOnUiThread(new Runnable(){ runOnUiThread(new Runnable(){
@Override @Override
@ -79,12 +88,6 @@ public class I2PDActivity extends Activity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// copy assets
copyAsset("certificates");
copyAsset("i2pd.conf");
copyAsset("subsciptions.txt");
copyAsset("tunnels.conf");
textView = new TextView(this); textView = new TextView(this);
setContentView(textView); setContentView(textView);
daemon.addStateChangeListener(daemonStateUpdatedListener); daemon.addStateChangeListener(daemonStateUpdatedListener);
@ -159,7 +162,6 @@ public class I2PDActivity extends Activity {
} }
}; };
private static volatile boolean mIsBound; private static volatile boolean mIsBound;
private void doBindService() { private void doBindService() {
@ -320,7 +322,7 @@ public class I2PDActivity extends Activity {
throw new IOException(); throw new IOException();
// Make the directory. // Make the directory.
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/", path); File dir = new File(i2pdpath, path);
dir.mkdirs(); dir.mkdirs();
// Recurse on the contents. // Recurse on the contents.
@ -340,8 +342,8 @@ public class I2PDActivity extends Activity {
* Path to asset, relative to app's assets directory. * Path to asset, relative to app's assets directory.
*/ */
private void copyFileAsset(String path) { private void copyFileAsset(String path) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/", path); File file = new File(i2pdpath, path);
try { if(!file.exists()) try {
InputStream in = getAssets().open(path); InputStream in = getAssets().open(path);
OutputStream out = new FileOutputStream(file); OutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
@ -356,4 +358,62 @@ public class I2PDActivity extends Activity {
Log.e(TAG, "", e); Log.e(TAG, "", e);
} }
} }
private void deleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
for (File child : fileOrDirectory.listFiles()) {
deleteRecursive(child);
}
}
fileOrDirectory.delete();
}
private void processAssets() {
if (!assetsCopied) try {
assetsCopied = true; // prevent from running on every state update
File holderfile = new File(i2pdpath, "assets.ready");
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
StringBuilder text = new StringBuilder();
if (holderfile.exists()) try { // if holder file exists, read assets version string
BufferedReader br = new BufferedReader(new FileReader(holderfile));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
}
br.close();
}
catch (IOException e) {
Log.e(TAG, "", e);
}
// if version differs from current app version or null, try to delete certificates folder
if (!text.toString().contains(versionName)) try {
holderfile.delete();
File certpath = new File(i2pdpath, "certificates");
deleteRecursive(certpath);
}
catch (Throwable tr) {
Log.e(TAG, "", tr);
}
// copy assets. If processed file exists, it won't be overwrited
copyAsset("certificates");
copyAsset("i2pd.conf");
copyAsset("subscriptions.txt");
copyAsset("tunnels.conf");
// update holder file about successful copying
FileWriter writer = new FileWriter(holderfile);
writer.append(versionName);
writer.flush();
writer.close();
}
catch (Throwable tr)
{
Log.e(TAG,"copy assets",tr);
}
}
} }

4
android_binary_only/jni/Android.mk

@ -69,6 +69,6 @@ include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)

2
appveyor.yml

@ -1,4 +1,4 @@
version: 2.19.{build} version: 2.20.{build}
pull_requests: pull_requests:
do_not_increment_build_number: true do_not_increment_build_number: true
branches: branches:

2
contrib/docker/Dockerfile

@ -2,7 +2,7 @@ FROM alpine:latest
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>" LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
# Expose git branch, tag and URL variables as arguments # Expose git branch, tag and URL variables as arguments
ARG GIT_BRANCH="master" ARG GIT_BRANCH="openssl"
ENV GIT_BRANCH=${GIT_BRANCH} ENV GIT_BRANCH=${GIT_BRANCH}
ARG GIT_TAG="" ARG GIT_TAG=""
ENV GIT_TAG=${GIT_TAG} ENV GIT_TAG=${GIT_TAG}

2
contrib/rpm/i2pd-git.spec

@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7) %define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git Name: i2pd-git
Version: 2.19.0 Version: 2.20.0
Release: git%{git_hash}%{?dist} Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd Conflicts: i2pd

5
contrib/rpm/i2pd.spec

@ -1,5 +1,5 @@
Name: i2pd Name: i2pd
Version: 2.19.0 Version: 2.20.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd-git Conflicts: i2pd-git
@ -96,6 +96,9 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* Thu Aug 23 2018 orignal <i2porignal@yandex.ru> - 2.20.0
- update to 2.20.0
* Tue Jun 26 2018 orignal <i2porignal@yandex.ru> - 2.19.0 * Tue Jun 26 2018 orignal <i2porignal@yandex.ru> - 2.19.0
- update to 2.19.0 - update to 2.19.0

28
daemon/HTTPServer.cpp

@ -92,6 +92,8 @@ namespace http {
const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_PARAM_ADDRESS[] = "address"; const char HTTP_PARAM_ADDRESS[] = "address";
static std::string ConvertTime (uint64_t time);
static void ShowUptime (std::stringstream& s, int seconds) static void ShowUptime (std::stringstream& s, int seconds)
{ {
int num; int num;
@ -262,7 +264,9 @@ namespace http {
{ {
if (address->IsNTCP2 () && !address->IsPublishedNTCP2 ()) if (address->IsNTCP2 () && !address->IsPublishedNTCP2 ())
{ {
s << "NTCP2&nbsp;&nbsp; supported <br>\r\n"; s << "NTCP2";
if (address->host.is_v6 ()) s << "v6";
s << "&nbsp;&nbsp; supported <br>\r\n";
continue; continue;
} }
switch (address->transportStyle) switch (address->transportStyle)
@ -271,13 +275,13 @@ namespace http {
{ {
s << "NTCP"; s << "NTCP";
if (address->IsPublishedNTCP2 ()) s << "2"; if (address->IsPublishedNTCP2 ()) s << "2";
if (address->host.is_v6 ()) s << "6"; if (address->host.is_v6 ()) s << "v6";
s << "&nbsp;&nbsp;"; s << "&nbsp;&nbsp;";
break; break;
} }
case i2p::data::RouterInfo::eTransportSSU: case i2p::data::RouterInfo::eTransportSSU:
if (address->host.is_v6 ()) if (address->host.is_v6 ())
s << "SSU6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; s << "SSUv6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
else else
s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
break; break;
@ -462,14 +466,14 @@ namespace http {
s << "<div class='invalid'>!! Invalid !! </div>\r\n"; s << "<div class='invalid'>!! Invalid !! </div>\r\n";
s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n"; s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n";
s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<p class='content'>\r\n"; s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<p class='content'>\r\n";
s << "<b>Expires:</b> " << ls.GetExpirationTime() << "<br>\r\n"; s << "<b>Expires:</b> " << ConvertTime(ls.GetExpirationTime()) << "<br>\r\n";
auto leases = ls.GetNonExpiredLeases(); auto leases = ls.GetNonExpiredLeases();
s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n"; s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
for ( auto & l : leases ) for ( auto & l : leases )
{ {
s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n"; s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n"; s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
s << "<b>EndDate:</b> " << l->endDate << "<br>\r\n"; s << "<b>EndDate:</b> " << ConvertTime(l->endDate) << "<br>\r\n";
} }
s << "</p>\r\n</div>\r\n</div>\r\n"; s << "</p>\r\n</div>\r\n</div>\r\n";
} }
@ -583,7 +587,7 @@ namespace http {
} }
if (!tmp_s6.str ().empty ()) if (!tmp_s6.str ().empty ())
{ {
s << "<div class='slide'><label for='slide_ntcp6'><b>" << name << "6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_ntcp6'/>\r\n<p class='content'>"; s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "v6'><b>" << name << "v6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_" << boost::algorithm::to_lower_copy(name) << "v6'/>\r\n<p class='content'>";
s << tmp_s6.str () << "</p>\r\n</div>\r\n"; s << tmp_s6.str () << "</p>\r\n</div>\r\n";
} }
} }
@ -628,7 +632,7 @@ namespace http {
auto sessions6 = ssuServer->GetSessionsV6 (); auto sessions6 = ssuServer->GetSessionsV6 ();
if (!sessions6.empty ()) if (!sessions6.empty ())
{ {
s << "<div class='slide'><label for='slide_ssu6'><b>SSU6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssu6'/>\r\n<p class='content'>"; s << "<div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssuv6'/>\r\n<p class='content'>";
for (const auto& it: sessions6) for (const auto& it: sessions6)
{ {
auto endpoint = it.second->GetRemoteEndpoint (); auto endpoint = it.second->GetRemoteEndpoint ();
@ -763,6 +767,16 @@ namespace http {
} }
} }
std::string ConvertTime (uint64_t time)
{
ldiv_t divTime = ldiv(time,1000);
time_t t = divTime.quot;
struct tm *tm = localtime(&t);
char date[128];
snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03ld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem);
return date;
}
HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket): HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0), m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0),
expected_host(hostname) expected_host(hostname)

4
daemon/UPnP.cpp

@ -131,7 +131,7 @@ namespace transport
const auto& a = context.GetRouterInfo().GetAddresses(); const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a) for (const auto& address : a)
{ {
if (!address->host.is_v6 ()) if (!address->host.is_v6 () && address->port)
TryPortMapping (address); TryPortMapping (address);
} }
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
@ -148,7 +148,7 @@ namespace transport
const auto& a = context.GetRouterInfo().GetAddresses(); const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a) for (const auto& address : a)
{ {
if (!address->host.is_v6 ()) if (!address->host.is_v6 () && address->port)
CloseMapping (address); CloseMapping (address);
} }
} }

6
debian/changelog vendored

@ -1,3 +1,9 @@
i2pd (2.20.0-1) unstable; urgency=medium
* updated to version 2.20.0/0.9.36
-- orignal <orignal@i2pmail.org> Thu, 23 Aug 2018 16:00:00 +0000
i2pd (2.19.0-1) unstable; urgency=medium i2pd (2.19.0-1) unstable; urgency=medium
* updated to version 2.19.0/0.9.35 * updated to version 2.19.0/0.9.35

2
libi2pd/Config.cpp

@ -233,7 +233,7 @@ namespace config {
options_description ntcp2("NTCP2 Options"); options_description ntcp2("NTCP2 Options");
ntcp2.add_options() ntcp2.add_options()
("ntcp2.enabled", value<bool>()->default_value(false), "Enable NTCP2 (default: disabled)") ("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
("ntcp2.published", value<bool>()->default_value(false), "Publish NTCP2 (default: disabled)") ("ntcp2.published", value<bool>()->default_value(false), "Publish NTCP2 (default: disabled)")
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
; ;

246
libi2pd/NTCP2.cpp

@ -1,3 +1,14 @@
/*
* Copyright (c) 2013-2018, 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
*
* Kovri go write your own code
*
*/
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
@ -244,6 +255,140 @@ namespace transport
SHA256_Final (m_H, &ctx); //h = SHA256(h || ciphertext) SHA256_Final (m_H, &ctx); //h = SHA256(h || ciphertext)
} }
bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen)
{
// decrypt X
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (i2p::context.GetIdentHash ());
decryption.SetIV (i2p::context.GetNTCP2IV ());
decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ());
decryption.GetIV (m_IV); // save IV for SessionCreated
// decryption key for next block
KDF1Bob ();
// verify MAC and decrypt options block (32 bytes), use m_H as AD
uint8_t nonce[12], options[16];
memset (nonce, 0, 12); // set nonce to zero
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, m_H, 32, m_K, nonce, options, 16, false)) // decrypt
{
// options
if (options[1] == 2) // ver is always 2
{
paddingLen = bufbe16toh (options + 2);
m_SessionRequestBufferLen = paddingLen + 64;
m3p2Len = bufbe16toh (options + 4);
if (m3p2Len < 16)
{
LogPrint (eLogWarning, "NTCP2: SessionRequest m3p2len=", m3p2Len, " is too short");
return false;
}
// check timestamp
auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t tsA = bufbe32toh (options + 8);
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
{
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
return false;
}
}
else
{
LogPrint (eLogWarning, "NTCP2: SessionRequest version mismatch ", (int)options[1]);
return false;
}
}
else
{
LogPrint (eLogWarning, "NTCP2: SessionRequest AEAD verification failed ");
return false;
}
return true;
}
bool NTCP2Establisher::ProcessSessionCreatedMessage (uint16_t& paddingLen)
{
m_SessionCreatedBufferLen = 64;
// decrypt Y
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (m_RemoteIdentHash);
decryption.SetIV (m_IV);
decryption.Decrypt (m_SessionCreatedBuffer, 32, GetRemotePub ());
// decryption key for next block (m_K)
KDF2Alice ();
// decrypt and verify MAC
uint8_t payload[16];
uint8_t nonce[12];
memset (nonce, 0, 12); // set nonce to zero
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, m_H, 32, m_K, nonce, payload, 16, false)) // decrypt
{
// options
paddingLen = bufbe16toh(payload + 2);
// check timestamp
auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t tsB = bufbe32toh (payload + 8);
if (tsB < ts - NTCP2_CLOCK_SKEW || tsB > ts + NTCP2_CLOCK_SKEW)
{
LogPrint (eLogWarning, "NTCP2: SessionCreated time difference ", (int)(ts - tsB), " exceeds clock skew");
return false;
}
}
else
{
LogPrint (eLogWarning, "NTCP2: SessionCreated AEAD verification failed ");
return false;
}
return true;
}
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce)
{
// update AD
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256_Final (m_H, &ctx);
int paddingLength = m_SessionCreatedBufferLen - 64;
if (paddingLength > 0)
{
SHA256_CTX ctx1;
SHA256_Init (&ctx1);
SHA256_Update (&ctx1, m_H, 32);
SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength);
SHA256_Final (m_H, &ctx1);
}
if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed ");
return false;
}
return true;
}
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf)
{
// update AD again
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48);
SHA256_Final (m_H, &ctx);
KDF3Bob ();
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt
{
// caclulate new h again for KDF data
memcpy (m_SessionConfirmedBuffer + 16, m_H, 32); // h || ciphertext
SHA256 (m_SessionConfirmedBuffer + 16, m3p2Len + 32, m_H); //h = SHA256(h || ciphertext);
}
else
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 AEAD verification failed ");
return false;
}
return true;
}
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter): NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT), TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
m_Server (server), m_Socket (m_Server.GetService ()), m_Server (server), m_Socket (m_Server.GetService ()),
@ -368,25 +513,10 @@ namespace transport
} }
else else
{ {
// decrypt X LogPrint (eLogDebug, "NTCP2: SessionRequest received ", bytes_transferred);
i2p::crypto::CBCDecryption decryption; uint16_t paddingLen = 0;
decryption.SetKey (i2p::context.GetIdentHash ()); if (m_Establisher->ProcessSessionRequestMessage (paddingLen))
decryption.SetIV (i2p::context.GetNTCP2IV ());
decryption.Decrypt (m_Establisher->m_SessionRequestBuffer, 32, m_Establisher->GetRemotePub ());
decryption.GetIV (m_Establisher->m_IV); // save IV for SessionCreated
// decryption key for next block
m_Establisher->KDF1Bob ();
// verify MAC and decrypt options block (32 bytes), use m_H as AD
uint8_t nonce[12], options[16];
memset (nonce, 0, 12); // set nonce to zero
if (i2p::crypto::AEADChaCha20Poly1305 (m_Establisher->m_SessionRequestBuffer + 32, 16, m_Establisher->GetH (), 32, m_Establisher->GetK (), nonce, options, 16, false)) // decrypt
{ {
if (options[1] == 2)
{
uint16_t paddingLen = bufbe16toh (options + 2);
m_Establisher->m_SessionRequestBufferLen = paddingLen + 64;
m_Establisher->m3p2Len = bufbe16toh (options + 4);
// TODO: check tsA
if (paddingLen > 0) if (paddingLen > 0)
{ {
if (paddingLen <= 287 - 64) // session request is 287 bytes max if (paddingLen <= 287 - 64) // session request is 287 bytes max
@ -404,18 +534,9 @@ namespace transport
SendSessionCreated (); SendSessionCreated ();
} }
else else
{
LogPrint (eLogWarning, "NTCP2: SessionRequest version mismatch ", (int)options[1]);
Terminate (); Terminate ();
} }
} }
else
{
LogPrint (eLogWarning, "NTCP2: SessionRequest AEAD verification failed ");
Terminate ();
}
}
}
void NTCP2Session::HandleSessionRequestPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) void NTCP2Session::HandleSessionRequestPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{ {
@ -446,23 +567,9 @@ namespace transport
else else
{ {
LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred); LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred);
m_Establisher->m_SessionCreatedBufferLen = 64; uint16_t paddingLen = 0;
// decrypt Y if (m_Establisher->ProcessSessionCreatedMessage (paddingLen))
i2p::crypto::CBCDecryption decryption;
decryption.SetKey (GetRemoteIdentity ()->GetIdentHash ());
decryption.SetIV (m_Establisher->m_IV);
decryption.Decrypt (m_Establisher->m_SessionCreatedBuffer, 32, m_Establisher->GetRemotePub ());
// decryption key for next block (m_K)
m_Establisher->KDF2Alice ();
// decrypt and verify MAC
uint8_t payload[16];
uint8_t nonce[12];
memset (nonce, 0, 12); // set nonce to zero
if (i2p::crypto::AEADChaCha20Poly1305 (m_Establisher->m_SessionCreatedBuffer + 32, 16, m_Establisher->GetH (), 32, m_Establisher->GetK (), nonce, payload, 16, false)) // decrypt
{ {
uint16_t paddingLen = bufbe16toh(payload + 2);
LogPrint (eLogDebug, "NTCP2: padding length ", paddingLen);
// TODO: check tsB
if (paddingLen > 0) if (paddingLen > 0)
{ {
if (paddingLen <= 287 - 64) // session created is 287 bytes max if (paddingLen <= 287 - 64) // session created is 287 bytes max
@ -480,12 +587,9 @@ namespace transport
SendSessionConfirmed (); SendSessionConfirmed ();
} }
else else
{
LogPrint (eLogWarning, "NTCP2: SessionCreated AEAD verification failed ");
Terminate (); Terminate ();
} }
} }
}
void NTCP2Session::HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) void NTCP2Session::HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{ {
@ -559,38 +663,16 @@ namespace transport
else else
{ {
LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); LogPrint (eLogDebug, "NTCP2: SessionConfirmed received");
// update AD
uint8_t h[80];
memcpy (h, m_Establisher->GetH (), 32);
memcpy (h + 32, m_Establisher->m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256 (h, 64, h);
int paddingLength = m_Establisher->m_SessionCreatedBufferLen - 64;
if (paddingLength > 0)
{
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, h, 32);
SHA256_Update (&ctx, m_Establisher->m_SessionCreatedBuffer + 64, paddingLength);
SHA256_Final (h, &ctx);
}
// part 1 // part 1
uint8_t nonce[12]; uint8_t nonce[12];
CreateNonce (1, nonce); CreateNonce (1, nonce);
if (i2p::crypto::AEADChaCha20Poly1305 (m_Establisher->m_SessionConfirmedBuffer, 32, h, 32, m_Establisher->GetK (), nonce, m_Establisher->m_RemoteStaticKey, 32, false)) // decrypt S if (m_Establisher->ProcessSessionConfirmedMessagePart1 (nonce))
{ {
// part 2 // part 2
// update AD again
memcpy (h + 32, m_Establisher->m_SessionConfirmedBuffer, 48);
SHA256 (h, 80, m_Establisher->m_H);
std::vector<uint8_t> buf(m_Establisher->m3p2Len - 16); // -MAC std::vector<uint8_t> buf(m_Establisher->m3p2Len - 16); // -MAC
m_Establisher->KDF3Bob ();
memset (nonce, 0, 12); // set nonce to 0 again memset (nonce, 0, 12); // set nonce to 0 again
if (i2p::crypto::AEADChaCha20Poly1305 (m_Establisher->m_SessionConfirmedBuffer + 48, m_Establisher->m3p2Len - 16, m_Establisher->GetH (), 32, m_Establisher->GetK (), nonce, buf.data (), m_Establisher->m3p2Len - 16, false)) // decrypt if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf.data ()))
{ {
// caclulate new h again for KDF data
memcpy (m_Establisher->m_SessionConfirmedBuffer + 16, m_Establisher->GetH (), 32); // h || ciphertext
SHA256 (m_Establisher->m_SessionConfirmedBuffer + 16, m_Establisher->m3p2Len + 32, m_Establisher->m_H); //h = SHA256(h || ciphertext);
KeyDerivationFunctionDataPhase (); KeyDerivationFunctionDataPhase ();
// Bob data phase keys // Bob data phase keys
m_SendKey = m_Kba; m_SendKey = m_Kba;
@ -599,7 +681,7 @@ namespace transport
m_ReceiveSipKey = m_Sipkeysab; m_ReceiveSipKey = m_Sipkeysab;
memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8);
memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8);
// payload
// process RI // process RI
if (buf[0] != eNTCP2BlkRouterInfo) if (buf[0] != eNTCP2BlkRouterInfo)
{ {
@ -647,18 +729,12 @@ namespace transport
ReceiveLength (); ReceiveLength ();
} }
else else
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 AEAD verification failed ");
Terminate (); Terminate ();
} }
}
else else
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed ");
Terminate (); Terminate ();
} }
} }
}
void NTCP2Session::ClientLogin () void NTCP2Session::ClientLogin ()
{ {
@ -691,13 +767,21 @@ namespace transport
else else
{ {
i2p::crypto::Siphash<8> (m_ReceiveIV.buf, m_ReceiveIV.buf, 8, m_ReceiveSipKey); i2p::crypto::Siphash<8> (m_ReceiveIV.buf, m_ReceiveIV.buf, 8, m_ReceiveSipKey);
// m_NextRecivedLen comes from the network in BigEndian // m_NextReceivedLen comes from the network in BigEndian
m_NextReceivedLen = be16toh (m_NextReceivedLen) ^ le16toh (m_ReceiveIV.key); m_NextReceivedLen = be16toh (m_NextReceivedLen) ^ le16toh (m_ReceiveIV.key);
LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen); LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen);
if (m_NextReceivedLen >= 16)
{
if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer; if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer;
m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen]; m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen];
Receive (); Receive ();
} }
else
{
LogPrint (eLogError, "NTCP2: received length ", m_NextReceivedLen, " is too short");
Terminate ();
}
}
} }
void NTCP2Session::Receive () void NTCP2Session::Receive ()
@ -865,7 +949,7 @@ namespace transport
payload[s] = eNTCP2BlkPadding; // blk payload[s] = eNTCP2BlkPadding; // blk
htobe16buf (payload + s + 1, paddingSize); // size htobe16buf (payload + s + 1, paddingSize); // size
s += 3; s += 3;
RAND_bytes (payload + s, paddingSize); memset (payload + s, 0, paddingSize);
s += paddingSize; s += paddingSize;
// send // send
SendNextFrame (payload, s); SendNextFrame (payload, s);
@ -875,6 +959,7 @@ namespace transport
void NTCP2Session::SendRouterInfo () void NTCP2Session::SendRouterInfo ()
{ {
if (!IsEstablished ()) return;
auto riLen = i2p::context.GetRouterInfo ().GetBufferLen (); auto riLen = i2p::context.GetRouterInfo ().GetBufferLen ();
int paddingSize = (riLen*NTCP2_MAX_PADDING_RATIO)/100; int paddingSize = (riLen*NTCP2_MAX_PADDING_RATIO)/100;
size_t payloadLen = riLen + paddingSize + 7; // 7 = 2*3 bytes header + 1 byte RI flag size_t payloadLen = riLen + paddingSize + 7; // 7 = 2*3 bytes header + 1 byte RI flag
@ -892,6 +977,7 @@ namespace transport
void NTCP2Session::SendTermination (NTCP2TerminationReason reason) void NTCP2Session::SendTermination (NTCP2TerminationReason reason)
{ {
if (!IsEstablished ()) return;
uint8_t payload[12] = { eNTCP2BlkTermination, 0, 9 }; uint8_t payload[12] = { eNTCP2BlkTermination, 0, 9 };
htobe64buf (payload + 3, m_ReceiveSequenceNumber); htobe64buf (payload + 3, m_ReceiveSequenceNumber);
payload[11] = (uint8_t)reason; payload[11] = (uint8_t)reason;
@ -921,7 +1007,7 @@ namespace transport
void NTCP2Session::SendLocalRouterInfo () void NTCP2Session::SendLocalRouterInfo ()
{ {
if (!IsOutgoing ()) // we send it in SessionConfirmed if (!IsOutgoing ()) // we send it in SessionConfirmed
SendRouterInfo (); m_Server.GetService ().post (std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ()));
} }
NTCP2Server::NTCP2Server (): NTCP2Server::NTCP2Server ():

17
libi2pd/NTCP2.h

@ -1,3 +1,13 @@
/*
* Copyright (c) 2013-2018, 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
*
* Kovri go write your own code
*
*/
#ifndef NTCP2_H__ #ifndef NTCP2_H__
#define NTCP2_H__ #define NTCP2_H__
@ -26,6 +36,8 @@ namespace transport
const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes
const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
const int NTCP2_CLOCK_SKEW = 60; // in seconds
enum NTCP2BlockType enum NTCP2BlockType
{ {
eNTCP2BlkDateTime = 0, eNTCP2BlkDateTime = 0,
@ -91,6 +103,11 @@ namespace transport
void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce); void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce);
void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce); void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce);
bool ProcessSessionRequestMessage (uint16_t& paddingLen);
bool ProcessSessionCreatedMessage (uint16_t& paddingLen);
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
BN_CTX * m_Ctx; BN_CTX * m_Ctx;
uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/; uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/;

4
libi2pd/NTCPSession.cpp

@ -402,7 +402,7 @@ namespace transport
uint32_t tsA1 = be32toh (tsA); uint32_t tsA1 = be32toh (tsA);
if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW) if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW)
{ {
LogPrint (eLogError, "NTCP: Phase3 time difference ", ts - tsA1, " exceeds clock skew"); LogPrint (eLogError, "NTCP: Phase3 time difference ", (int)(ts - tsA1), " exceeds clock skew");
Terminate (); Terminate ();
return; return;
} }
@ -485,7 +485,7 @@ namespace transport
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW) if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW)
{ {
LogPrint (eLogError, "NTCP: Phase4 time difference ", ts - tsB, " exceeds clock skew"); LogPrint (eLogError, "NTCP: Phase4 time difference ", (int)(ts - tsB), " exceeds clock skew");
Terminate (); Terminate ();
return; return;
} }

2
libi2pd/RouterContext.cpp

@ -164,6 +164,7 @@ namespace i2p
void RouterContext::PublishNTCP2Address (int port, bool publish) void RouterContext::PublishNTCP2Address (int port, bool publish)
{ {
if (!m_NTCP2Keys) return;
if (!port) if (!port)
port = rand () % (30777 - 9111) + 9111; // I2P network ports range port = rand () % (30777 - 9111) + 9111; // I2P network ports range
bool updated = false; bool updated = false;
@ -173,6 +174,7 @@ namespace i2p
{ {
address->port = port; address->port = port;
address->ntcp2->isPublished = publish; address->ntcp2->isPublished = publish;
address->ntcp2->iv = m_NTCP2Keys->iv;
updated = true; updated = true;
} }
} }

4
libi2pd/RouterInfo.cpp

@ -668,7 +668,7 @@ namespace data
addr->host = boost::asio::ip::address::from_string (host); addr->host = boost::asio::ip::address::from_string (host);
addr->port = port; addr->port = port;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = 2; addr->cost = 6;
addr->date = 0; addr->date = 0;
for (const auto& it: *m_Addresses) // don't insert same address twice for (const auto& it: *m_Addresses) // don't insert same address twice
if (*it == *addr) return; if (*it == *addr) return;
@ -703,7 +703,7 @@ namespace data
auto addr = std::make_shared<Address>(); auto addr = std::make_shared<Address>();
addr->port = 0; addr->port = 0;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = 14; addr->cost = 3;
addr->date = 0; addr->date = 0;
addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2.reset (new NTCP2Ext ());
addr->ntcp2->isNTCP2Only = true; // NTCP2 only address addr->ntcp2->isNTCP2Only = true; // NTCP2 only address

4
libi2pd/version.h

@ -7,7 +7,7 @@
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
#define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MAJOR 2
#define I2PD_VERSION_MINOR 19 #define I2PD_VERSION_MINOR 20
#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_MICRO 0
#define I2PD_VERSION_PATCH 0 #define I2PD_VERSION_PATCH 0
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
@ -21,7 +21,7 @@
#define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MAJOR 0
#define I2P_VERSION_MINOR 9 #define I2P_VERSION_MINOR 9
#define I2P_VERSION_MICRO 35 #define I2P_VERSION_MICRO 36
#define I2P_VERSION_PATCH 0 #define I2P_VERSION_PATCH 0
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)

2
qt/i2pd_qt/android/AndroidManifest.xml

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.19.0" android:versionCode="2" android:installLocation="auto"> <manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.20.0" android:versionCode="1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/> <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- <application android:hardwareAccelerated="true" --> <!-- <application android:hardwareAccelerated="true" -->

Loading…
Cancel
Save