mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-29 12:17:49 +02:00
Merge remote-tracking branch 'upstream/openssl' into fix_docker_2
This commit is contained in:
commit
1c659d6ef6
18 changed files with 188 additions and 289 deletions
4
android/.gitignore
vendored
4
android/.gitignore
vendored
|
@ -6,7 +6,3 @@ local.properties
|
||||||
build.sh
|
build.sh
|
||||||
bin
|
bin
|
||||||
log*
|
log*
|
||||||
.gradle*
|
|
||||||
build
|
|
||||||
assets
|
|
||||||
gradle-app.setting
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 25
|
||||||
buildToolsVersion "25.0.0"
|
buildToolsVersion "25.0.2"
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.purplei2p.i2pd"
|
applicationId "org.purplei2p.i2pd"
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "2.17.2e"
|
versionName "2.17.1"
|
||||||
}
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
|
@ -26,7 +26,6 @@ android {
|
||||||
java.srcDirs = ['src']
|
java.srcDirs = ['src']
|
||||||
res.srcDirs = ['res']
|
res.srcDirs = ['res']
|
||||||
jniLibs.srcDirs = ['libs']
|
jniLibs.srcDirs = ['libs']
|
||||||
assets.srcDirs = ['assets']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
@ -46,22 +45,3 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
|
||||||
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
|
|
||||||
options.deprecation = true
|
|
||||||
}
|
|
||||||
|
|
||||||
task zipCerts(type:Zip) {
|
|
||||||
from (files('../contrib/'))
|
|
||||||
include 'certificates/**/*.crt'
|
|
||||||
destinationDir file('assets')
|
|
||||||
archiveName 'certificates.zip'
|
|
||||||
entryCompression ZipEntryCompression.STORED
|
|
||||||
}
|
|
||||||
preBuild.dependsOn zipCerts
|
|
||||||
|
|
||||||
task clean(type: Delete,overwrite: true) {
|
|
||||||
delete 'build'
|
|
||||||
delete 'assets'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
org.gradle.jvmargs=-Xmx2048M -XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
|
|
@ -126,11 +126,12 @@ namespace android
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
static DaemonAndroidImpl daemon;
|
static DaemonAndroidImpl daemon;
|
||||||
|
static char* argv[1]={strdup("tmp")};
|
||||||
/**
|
/**
|
||||||
* returns error details if failed
|
* returns error details if failed
|
||||||
* returns "ok" if daemon initialized and started okay
|
* returns "ok" if daemon initialized and started okay
|
||||||
*/
|
*/
|
||||||
std::string start(int argc, char* argv[])
|
std::string start(/*int argc, char* argv[]*/)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -138,7 +139,7 @@ namespace android
|
||||||
|
|
||||||
{
|
{
|
||||||
//Log.d(TAG"Initialising the daemon...");
|
//Log.d(TAG"Initialising the daemon...");
|
||||||
bool daemonInitSuccess = daemon.init(argc,argv);
|
bool daemonInitSuccess = daemon.init(1,argv);
|
||||||
if(!daemonInitSuccess)
|
if(!daemonInitSuccess)
|
||||||
{
|
{
|
||||||
//QMessageBox::critical(0, "Error", "Daemon init failed");
|
//QMessageBox::critical(0, "Error", "Daemon init failed");
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace android
|
||||||
* returns "ok" if daemon init failed
|
* returns "ok" if daemon init failed
|
||||||
* returns errinfo if daemon initialized and started okay
|
* returns errinfo if daemon initialized and started okay
|
||||||
*/
|
*/
|
||||||
std::string start(int argc, char* argv[]);
|
std::string start();
|
||||||
|
|
||||||
// stops the daemon
|
// stops the daemon
|
||||||
void stop();
|
void stop();
|
||||||
|
|
|
@ -44,24 +44,8 @@ JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
||||||
(JNIEnv * env, jclass clazz, jobjectArray args) {
|
(JNIEnv * env, jclass clazz) {
|
||||||
int argc = env->GetArrayLength(args);
|
return env->NewStringUTF(i2p::android::start().c_str());
|
||||||
typedef char *pchar;
|
|
||||||
pchar* argv = new pchar[argc];
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
jstring arg = (jstring) env->GetObjectArrayElement(args, i);
|
|
||||||
const char *argStr = env->GetStringUTFChars(arg, 0);
|
|
||||||
size_t len = strlen(argStr);
|
|
||||||
argv[i] = new char[len + 1];
|
|
||||||
strcpy(argv[i], argStr);
|
|
||||||
env->ReleaseStringUTFChars(arg, argStr);
|
|
||||||
}
|
|
||||||
const char* result = i2p::android::start(argc,argv).c_str();
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
delete [] argv[i];
|
|
||||||
}
|
|
||||||
delete [] argv;
|
|
||||||
return env->NewStringUTF(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
||||||
|
|
|
@ -16,7 +16,7 @@ JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
||||||
(JNIEnv *, jclass, jobjectArray args);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
|
@ -38,8 +38,7 @@ public class DaemonSingleton {
|
||||||
|
|
||||||
public State getState() { return state; }
|
public State getState() { return state; }
|
||||||
|
|
||||||
public synchronized void start(final String confDir, final String dataDir) {
|
public synchronized void start() {
|
||||||
|
|
||||||
if(state != State.uninitialized)return;
|
if(state != State.uninitialized)return;
|
||||||
state = State.starting;
|
state = State.starting;
|
||||||
fireStateUpdate();
|
fireStateUpdate();
|
||||||
|
@ -63,15 +62,7 @@ public class DaemonSingleton {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
synchronized (DaemonSingleton.this) {
|
synchronized (DaemonSingleton.this) {
|
||||||
|
daemonStartResult = I2PD_JNI.startDaemon();
|
||||||
String args[] = new String[] {
|
|
||||||
"i2pd", "--service", "--daemon",
|
|
||||||
"--datadir=" + dataDir,
|
|
||||||
"--conf=" + confDir + "/i2pd.conf",
|
|
||||||
"--tunconf=" + confDir + "/tunnels.conf"
|
|
||||||
};
|
|
||||||
|
|
||||||
daemonStartResult = I2PD_JNI.startDaemon(args);
|
|
||||||
if("ok".equals(daemonStartResult)){
|
if("ok".equals(daemonStartResult)){
|
||||||
state=State.startedOkay;
|
state=State.startedOkay;
|
||||||
setStartedOkay(true);
|
setStartedOkay(true);
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.purplei2p.i2pd;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class Decompress {
|
|
||||||
private static final int BUFFER_SIZE = 1024 * 10;
|
|
||||||
private static final String TAG = "Decompress";
|
|
||||||
|
|
||||||
public static void unzipFromAssets(Context context, String zipFile, String destination) {
|
|
||||||
try {
|
|
||||||
if (destination == null || destination.length() == 0)
|
|
||||||
destination = context.getFilesDir().getAbsolutePath();
|
|
||||||
InputStream stream = context.getAssets().open(zipFile);
|
|
||||||
unzip(stream, destination);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void unzip(String zipFile, String location) {
|
|
||||||
try {
|
|
||||||
FileInputStream fin = new FileInputStream(zipFile);
|
|
||||||
unzip(fin, location);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void unzip(InputStream stream, String destination) {
|
|
||||||
dirChecker(destination, "");
|
|
||||||
byte[] buffer = new byte[BUFFER_SIZE];
|
|
||||||
try {
|
|
||||||
ZipInputStream zin = new ZipInputStream(stream);
|
|
||||||
ZipEntry ze = null;
|
|
||||||
|
|
||||||
while ((ze = zin.getNextEntry()) != null) {
|
|
||||||
Log.v(TAG, "Unzipping " + ze.getName());
|
|
||||||
|
|
||||||
if (ze.isDirectory()) {
|
|
||||||
dirChecker(destination, ze.getName());
|
|
||||||
} else {
|
|
||||||
File f = new File(destination + ze.getName());
|
|
||||||
if (!f.exists()) {
|
|
||||||
FileOutputStream fout = new FileOutputStream(destination + ze.getName());
|
|
||||||
int count;
|
|
||||||
while ((count = zin.read(buffer)) != -1) {
|
|
||||||
fout.write(buffer, 0, count);
|
|
||||||
}
|
|
||||||
zin.closeEntry();
|
|
||||||
fout.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
zin.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "unzip", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dirChecker(String destination, String dir) {
|
|
||||||
File f = new File(destination + dir);
|
|
||||||
|
|
||||||
if (!f.isDirectory()) {
|
|
||||||
boolean success = f.mkdirs();
|
|
||||||
if (!success) {
|
|
||||||
Log.w(TAG, "Failed to create folder " + f.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,8 +5,6 @@ import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -30,20 +28,13 @@ public class ForegroundService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String dataDir;
|
|
||||||
private String confDir;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||||
dataDir = this.getDir("data", Context.MODE_PRIVATE).toString();
|
|
||||||
confDir = Environment.getExternalStoragePublicDirectory("i2pd").toString();
|
|
||||||
|
|
||||||
// Display a notification about us starting. We put an icon in the status bar.
|
// Display a notification about us starting. We put an icon in the status bar.
|
||||||
showNotification();
|
showNotification();
|
||||||
|
daemon.start();
|
||||||
Log.i("ForegroundService", "About to start daemon with dataDir: " + dataDir + ", confDir: " + confDir);
|
|
||||||
daemon.start(confDir, dataDir);
|
|
||||||
// Tell the user we started.
|
// Tell the user we started.
|
||||||
Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
@ -51,7 +42,7 @@ public class ForegroundService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
||||||
daemon.start(confDir, dataDir);
|
daemon.start();
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,6 @@ package org.purplei2p.i2pd;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
@ -65,9 +58,6 @@ public class I2PD extends Activity {
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
//install certs every time
|
|
||||||
Decompress.unzipFromAssets(this, "certificates.zip", this.getDir("data", Context.MODE_PRIVATE).toString() + "/" );
|
|
||||||
|
|
||||||
textView = new TextView(this);
|
textView = new TextView(this);
|
||||||
setContentView(textView);
|
setContentView(textView);
|
||||||
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
||||||
|
|
|
@ -6,7 +6,7 @@ public class I2PD_JNI {
|
||||||
* returns error info if failed
|
* returns error info if failed
|
||||||
* returns "ok" if daemon initialized and started okay
|
* returns "ok" if daemon initialized and started okay
|
||||||
*/
|
*/
|
||||||
public static native String startDaemon(String args[]);
|
public static native String startDaemon();
|
||||||
//should only be called after startDaemon() success
|
//should only be called after startDaemon() success
|
||||||
public static native void stopDaemon();
|
public static native void stopDaemon();
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
if (Daemon.start())
|
if (Daemon.start())
|
||||||
Daemon.run ();
|
Daemon.run ();
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
Daemon.stop();
|
Daemon.stop();
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -207,7 +207,7 @@ namespace client
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
|
AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
|
||||||
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
m_NumRetries (0), m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,9 +486,13 @@ namespace client
|
||||||
void AddressBook::DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified)
|
void AddressBook::DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified)
|
||||||
{
|
{
|
||||||
m_IsDownloading = false;
|
m_IsDownloading = false;
|
||||||
int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
|
m_NumRetries++;
|
||||||
|
int nextUpdateTimeout = m_NumRetries*CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
|
||||||
|
if (m_NumRetries > CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES || nextUpdateTimeout > CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT)
|
||||||
|
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
m_NumRetries = 0;
|
||||||
if (m_DefaultSubscription) m_DefaultSubscription = nullptr;
|
if (m_DefaultSubscription) m_DefaultSubscription = nullptr;
|
||||||
if (m_IsLoaded)
|
if (m_IsLoaded)
|
||||||
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
|
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
|
||||||
|
@ -749,7 +753,7 @@ namespace client
|
||||||
end = true;
|
end = true;
|
||||||
newDataReceived.notify_all ();
|
newDataReceived.notify_all ();
|
||||||
},
|
},
|
||||||
30); // wait for 30 seconds
|
SUBSCRIPTION_REQUEST_TIMEOUT);
|
||||||
std::unique_lock<std::mutex> l(newDataReceivedMutex);
|
std::unique_lock<std::mutex> l(newDataReceivedMutex);
|
||||||
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
|
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,8 @@ namespace client
|
||||||
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
||||||
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
||||||
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
||||||
const int SUBSCRIPTION_REQUEST_TIMEOUT = 60; //in second
|
const int CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES = 10; // then update timeout
|
||||||
|
const int SUBSCRIPTION_REQUEST_TIMEOUT = 120; //in second
|
||||||
|
|
||||||
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
||||||
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
||||||
|
@ -97,6 +98,7 @@ namespace client
|
||||||
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
||||||
AddressBookStorage * m_Storage;
|
AddressBookStorage * m_Storage;
|
||||||
volatile bool m_IsLoaded, m_IsDownloading;
|
volatile bool m_IsLoaded, m_IsDownloading;
|
||||||
|
int m_NumRetries;
|
||||||
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||||
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
||||||
|
|
|
@ -35,87 +35,18 @@ namespace client
|
||||||
|
|
||||||
void ClientContext::Start ()
|
void ClientContext::Start ()
|
||||||
{
|
{
|
||||||
|
// shared local destination
|
||||||
if (!m_SharedLocalDestination)
|
if (!m_SharedLocalDestination)
|
||||||
{
|
CreateNewSharedLocalDestination ();
|
||||||
m_SharedLocalDestination = CreateNewLocalDestination (); // non-public, DSA
|
|
||||||
m_SharedLocalDestination->Acquire ();
|
|
||||||
m_Destinations[m_SharedLocalDestination->GetIdentity ()->GetIdentHash ()] = m_SharedLocalDestination;
|
|
||||||
m_SharedLocalDestination->Start ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
// addressbook
|
||||||
m_AddressBook.Start ();
|
m_AddressBook.Start ();
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> localDestination;
|
// HTTP proxy
|
||||||
bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy);
|
ReadHttpProxy ();
|
||||||
if (httproxy)
|
|
||||||
{
|
|
||||||
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
|
||||||
std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
|
||||||
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
|
||||||
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
|
||||||
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
|
||||||
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
|
||||||
if (httpProxyKeys.length () > 0)
|
|
||||||
{
|
|
||||||
i2p::data::PrivateKeys keys;
|
|
||||||
if(LoadPrivateKeys (keys, httpProxyKeys, sigType))
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string> params;
|
|
||||||
ReadI2CPOptionsFromConfig ("httpproxy.", params);
|
|
||||||
localDestination = CreateNewLocalDestination (keys, false, ¶ms);
|
|
||||||
localDestination->Acquire ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint(eLogError, "Clients: failed to load HTTP Proxy key");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination);
|
|
||||||
m_HttpProxy->Start();
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
localDestination = nullptr;
|
// SOCKS proxy
|
||||||
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
|
ReadSocksProxy ();
|
||||||
if (socksproxy)
|
|
||||||
{
|
|
||||||
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
|
|
||||||
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);
|
|
||||||
uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort);
|
|
||||||
bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy);
|
|
||||||
std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr);
|
|
||||||
uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort);
|
|
||||||
i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType);
|
|
||||||
LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort);
|
|
||||||
if (socksProxyKeys.length () > 0)
|
|
||||||
{
|
|
||||||
i2p::data::PrivateKeys keys;
|
|
||||||
if (LoadPrivateKeys (keys, socksProxyKeys, sigType))
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string> params;
|
|
||||||
ReadI2CPOptionsFromConfig ("socksproxy.", params);
|
|
||||||
localDestination = CreateNewLocalDestination (keys, false, ¶ms);
|
|
||||||
localDestination->Acquire ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort,
|
|
||||||
socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
|
||||||
m_SocksProxy->Start();
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// I2P tunnels
|
// I2P tunnels
|
||||||
ReadTunnels ();
|
ReadTunnels ();
|
||||||
|
@ -267,6 +198,26 @@ namespace client
|
||||||
// delete not updated tunnels (not in config anymore)
|
// delete not updated tunnels (not in config anymore)
|
||||||
VisitTunnels ([](I2PService * s)->bool { return s->isUpdated; });
|
VisitTunnels ([](I2PService * s)->bool { return s->isUpdated; });
|
||||||
|
|
||||||
|
// change shared local destination
|
||||||
|
m_SharedLocalDestination->Release ();
|
||||||
|
CreateNewSharedLocalDestination ();
|
||||||
|
|
||||||
|
// recreate HTTP proxy
|
||||||
|
if (m_HttpProxy)
|
||||||
|
{
|
||||||
|
m_HttpProxy->Stop ();
|
||||||
|
m_HttpProxy = nullptr;
|
||||||
|
}
|
||||||
|
ReadHttpProxy ();
|
||||||
|
|
||||||
|
// recreate SOCKS proxy
|
||||||
|
if (m_SocksProxy)
|
||||||
|
{
|
||||||
|
m_SocksProxy->Stop ();
|
||||||
|
m_SocksProxy = nullptr;
|
||||||
|
}
|
||||||
|
ReadSocksProxy ();
|
||||||
|
|
||||||
// delete unused destinations
|
// delete unused destinations
|
||||||
std::unique_lock<std::mutex> l(m_DestinationsMutex);
|
std::unique_lock<std::mutex> l(m_DestinationsMutex);
|
||||||
for (auto it = m_Destinations.begin (); it != m_Destinations.end ();)
|
for (auto it = m_Destinations.begin (); it != m_Destinations.end ();)
|
||||||
|
@ -407,6 +358,14 @@ namespace client
|
||||||
return localDestination;
|
return localDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientContext::CreateNewSharedLocalDestination ()
|
||||||
|
{
|
||||||
|
m_SharedLocalDestination = CreateNewLocalDestination (); // non-public, DSA
|
||||||
|
m_SharedLocalDestination->Acquire ();
|
||||||
|
m_Destinations[m_SharedLocalDestination->GetIdentity ()->GetIdentHash ()] = m_SharedLocalDestination;
|
||||||
|
m_SharedLocalDestination->Start ();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> ClientContext::FindLocalDestination (const i2p::data::IdentHash& destination) const
|
std::shared_ptr<ClientDestination> ClientContext::FindLocalDestination (const i2p::data::IdentHash& destination) const
|
||||||
{
|
{
|
||||||
auto it = m_Destinations.find (destination);
|
auto it = m_Destinations.find (destination);
|
||||||
|
@ -716,6 +675,83 @@ namespace client
|
||||||
LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created");
|
LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientContext::ReadHttpProxy ()
|
||||||
|
{
|
||||||
|
std::shared_ptr<ClientDestination> localDestination;
|
||||||
|
bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy);
|
||||||
|
if (httproxy)
|
||||||
|
{
|
||||||
|
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
||||||
|
std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
||||||
|
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
||||||
|
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
||||||
|
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
||||||
|
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
||||||
|
if (httpProxyKeys.length () > 0)
|
||||||
|
{
|
||||||
|
i2p::data::PrivateKeys keys;
|
||||||
|
if(LoadPrivateKeys (keys, httpProxyKeys, sigType))
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
ReadI2CPOptionsFromConfig ("httpproxy.", params);
|
||||||
|
localDestination = CreateNewLocalDestination (keys, false, ¶ms);
|
||||||
|
localDestination->Acquire ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "Clients: failed to load HTTP Proxy key");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination);
|
||||||
|
m_HttpProxy->Start();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientContext::ReadSocksProxy ()
|
||||||
|
{
|
||||||
|
std::shared_ptr<ClientDestination> localDestination;
|
||||||
|
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
|
||||||
|
if (socksproxy)
|
||||||
|
{
|
||||||
|
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
|
||||||
|
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);
|
||||||
|
uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort);
|
||||||
|
bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy);
|
||||||
|
std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr);
|
||||||
|
uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort);
|
||||||
|
i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType);
|
||||||
|
LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort);
|
||||||
|
if (socksProxyKeys.length () > 0)
|
||||||
|
{
|
||||||
|
i2p::data::PrivateKeys keys;
|
||||||
|
if (LoadPrivateKeys (keys, socksProxyKeys, sigType))
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
ReadI2CPOptionsFromConfig ("socksproxy.", params);
|
||||||
|
localDestination = CreateNewLocalDestination (keys, false, ¶ms);
|
||||||
|
localDestination->Acquire ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort,
|
||||||
|
socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
||||||
|
m_SocksProxy->Start();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientContext::ScheduleCleanupUDP()
|
void ClientContext::ScheduleCleanupUDP()
|
||||||
{
|
{
|
||||||
if (m_CleanupUDPTimer)
|
if (m_CleanupUDPTimer)
|
||||||
|
|
|
@ -87,6 +87,8 @@ namespace client
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadTunnels ();
|
void ReadTunnels ();
|
||||||
|
void ReadHttpProxy ();
|
||||||
|
void ReadSocksProxy ();
|
||||||
template<typename Section, typename Type>
|
template<typename Section, typename Type>
|
||||||
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
|
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
|
||||||
template<typename Section>
|
template<typename Section>
|
||||||
|
@ -99,6 +101,8 @@ namespace client
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain
|
void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain
|
||||||
|
|
||||||
|
void CreateNewSharedLocalDestination ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex m_DestinationsMutex;
|
std::mutex m_DestinationsMutex;
|
||||||
|
|
|
@ -280,6 +280,8 @@ namespace client
|
||||||
void TCPIPAcceptor::Start ()
|
void TCPIPAcceptor::Start ()
|
||||||
{
|
{
|
||||||
m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint));
|
m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint));
|
||||||
|
//update the local end point in case port has been set zero and got updated now
|
||||||
|
m_LocalEndpoint = m_Acceptor->local_endpoint();
|
||||||
m_Acceptor->listen ();
|
m_Acceptor->listen ();
|
||||||
Accept ();
|
Accept ();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue