Compare commits

..

103 Commits

Author SHA1 Message Date
orignal
b6e75e9c5a Update changelog 2018-01-30 11:14:29 -05:00
orignal
4901434209 2.18.0 2018-01-30 10:41:35 -05:00
R4SAS
13d174c09c add tunconf in systemctl service file 2018-01-30 18:14:54 +03:00
l-n-s
5363c063d1 Merge pull request #1067 from l-n-s/rpm_updates
Update rpm spec and systemd unit
2018-01-30 15:12:54 +00:00
R4SAS
32d300248e update building stuff 2018-01-30 18:09:26 +03:00
Darknet Villain
3426906a4f [rpm] Fix changelogs to comply with guidelines, add tunconf key to systemd package 2018-01-30 10:03:53 -05:00
R4SAS
3aaa942c94 Merge pull request #1082 from PurpleI2P/apparmor-homedir
add users homedir to apparmor profile
2018-01-30 17:31:22 +03:00
R4SAS
95d8887ab0 update profile 2018-01-30 17:30:01 +03:00
R4SAS
6272e15b47 add users homedir to profile 2018-01-29 04:13:33 +03:00
R4SAS
20b4f6b24d update apparmor profile 2018-01-29 03:47:43 +03:00
Darknet Villain
6ee279d83e [rpm] Merge i2pd-systemd with i2pd package + changelog 2018-01-27 10:54:03 -05:00
orignal
b00ff43be7 Update README.md 2018-01-26 19:52:11 -05:00
orignal
dfbefee477 graceful shutdown complete if no transit tunnels anymore 2018-01-26 14:34:05 -05:00
orignal
8c2de4973c rollback 2018-01-26 14:33:06 -05:00
orignal
e1527dc137 update LeaseSet if a tunnel was deleted 2018-01-26 14:07:51 -05:00
R4SAS
0957f6b143 Merge pull request #1055 from yangfl/upstream
replace non-working CheckLibcxxAtomic
2018-01-26 15:33:39 +03:00
orignal
7db2e9dc4a don't verify signature twice 2018-01-25 10:32:08 -05:00
orignal
b1c701085b don't verify signature twice 2018-01-25 10:09:34 -05:00
orignal
e8d6c803cd Merge pull request #1076 from majestrate/fix-streaming-race-2018-01-25
try streaming race condition fix
2018-01-25 09:35:58 -05:00
Jeff Becker
f4a2dda94e try streaming race condition fix 2018-01-25 09:00:00 -05:00
l-n-s
c4216379ed Merge pull request #1074 from l-n-s/fix_docker_2
Fix docker 2
2018-01-24 19:46:38 +00:00
Darknet Villain
52195bf296 Merge remote-tracking branch 'upstream/openssl' into fix_docker_2 2018-01-24 14:42:55 -05:00
orignal
10fe75ed87 Merge pull request #1073 from majestrate/fix-netdb-ls-publish-2018-01-24
check for valid LS before updating
2018-01-24 13:00:30 -05:00
Darknet Villain
1c659d6ef6 Merge remote-tracking branch 'upstream/openssl' into fix_docker_2 2018-01-24 12:48:57 -05:00
Darknet Villain
3ac86db038 Fix Docker image error 2018-01-24 12:48:05 -05:00
Jeff Becker
4a77a03033 * Add LeaseSetBufferValidate which checks lease validity and extracts timestamp
* check for leases with LeaseSetBufferValidate before update in floodfill code as to prevent malicous nodes removing good LS
2018-01-24 10:16:51 -05:00
Jeff Becker
3820b51960 Revert "check for valid LS before updating"
This reverts commit e070ce4e34.
2018-01-24 09:44:55 -05:00
Jeff Becker
e070ce4e34 check for valid LS before updating 2018-01-24 09:36:09 -05:00
R4SAS
0bb0adbf3e fix addressbook fetch timeout 2018-01-24 15:34:32 +03:00
orignal
ddd25f0945 limit number of retries for subscriptions 2018-01-23 15:50:28 -05:00
orignal
162bd592f8 recreate http and socks proxy upon reload 2018-01-23 15:13:43 -05:00
orignal
85fa728d41 change shared local destination upon reload 2018-01-23 14:40:05 -05:00
orignal
c7db9010ad fixed #1047. Return EXIT_FAILURE 2018-01-23 11:01:50 -05:00
orignal
be16545063 Merge pull request #1070 from vmon/f--port-0-for-TCPAcceptor
the change allows when an TCPIPAcceptor is constructed by setting por…
2018-01-23 06:48:18 -05:00
Veggie Monster
c730839989 the change allows when an TCPIPAcceptor is constructed by setting port = 0, the random port chosen by asio can be retrieved using TCPIPAcceptor::GetLocalEndpoint().port() 2018-01-22 20:47:31 -05:00
Darknet Villain
4ee364640d Update rpm spec and systemd unit 2018-01-22 13:55:12 -05:00
orignal
56dd0db001 Merge pull request #1066 from PurpleI2P/revert-1065-openssl
Revert " Fixes for #1024 , #1018 #1064 "
2018-01-22 13:00:15 -05:00
orignal
626ed720a6 Revert " Fixes for #1024 , #1018 #1064 " 2018-01-22 12:59:34 -05:00
orignal
b8fd9ba83f Merge pull request #1065 from unlnown542a/openssl
Fixes for #1024 , #1018 #1064
2018-01-22 07:08:34 -05:00
unlnown542a
316a4457af Merge github.com:unlnown542a/i2pd into openssl 2018-01-22 01:39:51 +03:00
unlnown542a
347a2c2150 fixing conflicts 2018-01-22 01:30:21 +03:00
orignal
42d3770b14 fixed layout 2018-01-21 11:28:16 -05:00
orignal
39ca07bcc6 Merge pull request #1058 from majestrate/streaming_race_fix_2018_01_15
Streaming race fix 2018 01 15
2018-01-21 11:15:44 -05:00
orignal
914566ece0 removed unused Java router certificates 2018-01-21 10:27:41 -05:00
orignal
f537e7b2c6 removed unused cert 2018-01-21 08:09:01 -05:00
Jeff Becker
06020b8f54 re-enable packet pool 2018-01-20 13:06:08 -05:00
orignal
b486d1cd27 rollback
non buildable under x64
2018-01-20 12:07:57 -05:00
Jeff Becker
b3b38015c2 check max buffer size in Stream::Send 2018-01-20 07:31:58 -05:00
unlnown542a
4c6988e3bc code cleanup 2018-01-18 19:35:37 +03:00
unlnown542a
0bd4db4cc7 less lines 2018-01-18 16:41:02 +03:00
unlnown542a
bc72800fef moved hard code into java side and successfully passed back to native 2018-01-17 20:58:56 +03:00
yangfl
951f8972c7 replace non-working CheckLibcxxAtomic 2018-01-17 16:12:46 +08:00
Jeff
38b694a055 Merge pull request #1060 from inetic/openssl
Inherit _publicly_ from shared_from_this in I2PService
2018-01-15 11:58:27 -05:00
Jeff
44a9c3ca0c Merge pull request #1059 from K1773R/fix-headers-rn
removed redundant \r\n in HTTP header builder
2018-01-15 10:36:42 -05:00
K1773R
6bf823fb15 removed \r\n in header builder which was redundant and caused the further headers to be ignored 2018-01-15 16:30:01 +01:00
Jeff Becker
43a751ee0b Merge remote-tracking branch 'purple/openssl' into streaming_race_fix_2018_01_15 2018-01-15 08:25:58 -05:00
Jeff Becker
207212557e fix sam race conditions 2018-01-15 08:19:57 -05:00
R4SAS
fd1aeeac92 Merge pull request #1045 from yangfl/upstream
code cleanup
2018-01-13 18:11:19 +03:00
yangfl
50ba52756f fix mixing tabs and spaces 2018-01-13 22:51:02 +08:00
Peter Jankuliak
e630b8f8a8 Inherit _publicly_ from shared_from_this in I2PService 2018-01-12 11:04:26 +01:00
unlnown542a
cf5081d300 fixed creating certificates.zip when target zip did not include the directory certificates, so they were bein unpacked into datadir. Added entryCompression ZipEntryCompression.STORED since final APK is being compressed as well. Put all custom tasks under android plugin definitions 2018-01-07 19:30:32 +03:00
unlnown542a
8864cbf80a return to strdup() when filling argv[] for i2p::android::start(argc,argv).c_str() 2018-01-07 00:40:17 +03:00
unknown542a
81d7a832c0 netDB and certificates in internal storage 2018-01-07 00:08:07 +03:00
unknown542a
d41fabbc9f netDB and certificates in internal storage 2018-01-06 23:59:22 +03:00
yangfl
46f62e1af9 remove trailing whitespaces 2018-01-06 22:24:03 +08:00
Jeff
b91efaa973 Merge pull request #1044 from yangfl/upstream
update Makefile and CMakeLists
2018-01-06 09:22:11 -05:00
yangfl
e3238ff75c CMakeLists: autodetect libatomic 2018-01-06 22:06:44 +08:00
yangfl
9cc4e8d03a Makefile: get target platform from compiler 2018-01-06 22:06:28 +08:00
orignal
34c98e03c1 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2018-01-03 12:53:05 -05:00
orignal
41e40bbc0d fixed typo 2018-01-03 12:52:29 -05:00
orignal
ca49944c85 Merge pull request #1041 from majestrate/fix-streaming-race
fix race condition
2018-01-01 09:26:21 -05:00
Jeff Becker
d5e9fc7677 fix race condition 2018-01-01 08:28:42 -05:00
orignal
6db7c5733d use outbound.nickname as tunnel name if inbound.nickname is not set 2017-12-20 11:38:35 -05:00
orignal
418f86ecbd Merge pull request #1039 from majestrate/fix-arm-compile-latomic
Fix arm compile latomic
2017-12-20 10:48:45 -05:00
Jeff Becker
c68c5af856 fix lib name 2017-12-20 08:56:39 -05:00
Jeff Becker
950dffbe06 update gitignore 2017-12-20 08:54:41 -05:00
Jeff Becker
5d557003b6 include cmake stuff 2017-12-20 08:54:02 -05:00
Jeff Becker
3b8c3c1346 try fixing issue #897 2017-12-20 08:49:47 -05:00
orignal
1853263f6c Merge pull request #1038 from PurpleI2P/master
Master
2017-12-18 08:59:19 -05:00
orignal
b0f6d81f57 Merge pull request #1037 from PurpleI2P/openssl
recent changes
2017-12-15 22:00:09 -05:00
orignal
9ba0329432 Merge pull request #1036 from KenanSulayman/patch-1
Fix typo (confrimed -> confirmed)
2017-12-15 21:56:09 -05:00
Kenan Sulayman
614101c4b8 Fix typo (confrimed -> confirmed) 2017-12-16 02:36:01 +01:00
R4SAS
50e4fb138a close #1032 (#1034) 2017-12-13 15:17:45 +03:00
orignal
6dba0c6e0e Merge pull request #1031 from AMDmi3/boost-asio-fix
Don't use deprecated boost::asio::ssl::context ctor
2017-12-11 15:30:39 -05:00
Dmitry Marakasov
0f2d2156e6 Don't use deprecated boost::asio::ssl::context ctor
This was removed in boost 1.66, in prior versions the service
argument was not used
2017-12-11 22:34:48 +03:00
orignal
13b17c5a93 Merge pull request #1030 from AMDmi3/freebsd_kernel
Reorder preprocessor conditions in libi2pd/I2PEndian.h
2017-12-11 12:37:08 -05:00
Dmitry Marakasov
511499d950 Reorder preprocessor conditions in libi2pd/I2PEndian.h
The problem is that __FreeBSD_kernel__ may be defined on FreeBSD as
well, while it always needs <sys/endian.h>
2017-12-11 19:59:06 +03:00
orignal
6632b71273 gradle relese build 2017-12-10 09:01:13 -05:00
orignal
60ef70cee4 gradle build added 2017-12-10 08:46:13 -05:00
orignal
b3ba0a7241 Merge pull request #1027 from majestrate/transient-by-default
Use transient destinations
2017-12-09 07:49:43 -05:00
Jeff Becker
fc73dabc0b Use transient destinations by default instead of shared local destination 2017-12-09 07:42:32 -05:00
orignal
1121d45eb6 Merge pull request #1025 from yangfl/pr
fix typo
2017-12-07 09:09:42 -05:00
yangfl
18b6353803 fix typo 2017-12-07 21:26:28 +08:00
R4SAS
c0c0642bd1 temporary disable osx build due to of big waiting time of VM 2017-12-06 02:16:01 +03:00
orignal
3cf26a84dc Merge pull request #1022 from AMDmi3/patch-1
Don't meddle with stdlib
2017-12-05 10:14:31 -05:00
Dmitry Marakasov
44d6d4405e Don't meddle with stdlib
Forgotten part of #1014: -stdlib should not be changed. It breaks build on e.g. FreeBSD where libc++ is used.
2017-12-05 13:45:22 +03:00
orignal
cafa027f0b Merge pull request #1021 from PurpleI2P/openssl
2.17.0
2017-12-04 13:42:04 -05:00
orignal
276a78cb2e Merge pull request #1019 from PurpleI2P/openssl
recent changes
2017-12-01 12:55:45 -05:00
orignal
1008510750 Merge pull request #997 from PurpleI2P/openssl
recent changes
2017-11-13 11:23:32 -05:00
orignal
42483b6f32 Merge pull request #986 from PurpleI2P/openssl
recent changes
2017-11-02 14:45:47 -04:00
orignal
c21c1f5225 Merge pull request #920 from PurpleI2P/openssl
2.15.0
2017-08-17 14:20:41 -04:00
orignal
14ca3fc2f3 Merge pull request #896 from PurpleI2P/openssl
recent changes
2017-06-23 07:41:31 -04:00
orignal
36afef3498 Merge pull request #889 from PurpleI2P/openssl
recent changes
2017-06-05 09:02:42 -04:00
153 changed files with 4003 additions and 3628 deletions

View File

@@ -3,7 +3,7 @@ cache:
apt: true apt: true
os: os:
- linux - linux
- osx #- osx
dist: trusty dist: trusty
sudo: required sudo: required
compiler: compiler:

View File

@@ -1,6 +1,23 @@
# 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.18.0] - 2018-01-30
### Added
- Show tunnel nicknames for I2CP destination in WebUI
- Re-create HTTP and SOCKS proxy by tunnel reload
- Graceful shutdown as soon as no more transit tunnels
### Changed
- Regenerate shared local destination by tunnel reload
- Use transient local destination by default if not specified
- Return correct code if pid file can't be created
- Timing and number of attempts for adressbook requests
- Certificates list
### Fixed
- Malformed addressbook subsctiption request
- Build with boost 1.66
- Few race conditions for SAM
- Check LeaseSet's signature before update
## [2.17.0] - 2017-12-04 ## [2.17.0] - 2017-12-04
### Added ### Added
- Reseed through HTTP and SOCKS proxy - Reseed through HTTP and SOCKS proxy
@@ -162,12 +179,12 @@
- Configurable limit of transit tunnels - Configurable limit of transit tunnels
### Changed ### Changed
- Speed-up of assymetric crypto for non-x64 platforms - Speed-up of asymmetric crypto for non-x64 platforms
- Refactoring of web-console - Refactoring of web-console
## [2.6.0] - 2016-03-31 ## [2.6.0] - 2016-03-31
### Added ### Added
- Gracefull shutdown on SIGINT - Graceful shutdown on SIGINT
- Numeric bandwidth limits (was: by router class) - Numeric bandwidth limits (was: by router class)
- Jumpservices in web-console - Jumpservices in web-console
- Logging to syslog - Logging to syslog

View File

@@ -1,9 +1,9 @@
UNAME := $(shell uname -s) SYS := $(shell $(CXX) -dumpmachine)
SHLIB := libi2pd.so SHLIB := libi2pd.so
ARLIB := libi2pd.a ARLIB := libi2pd.a
SHLIB_CLIENT := libi2pdclient.so SHLIB_CLIENT := libi2pdclient.so
ARLIB_CLIENT := libi2pdclient.a ARLIB_CLIENT := libi2pdclient.a
I2PD := i2pd I2PD := i2pd
GREP := grep GREP := grep
DEPS := obj/make.dep DEPS := obj/make.dep
@@ -23,22 +23,24 @@ ifeq ($(WEBSOCKETS),1)
NEEDED_CXXFLAGS += -DWITH_EVENTS NEEDED_CXXFLAGS += -DWITH_EVENTS
endif endif
ifeq ($(UNAME),Darwin) ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
ifeq ($(HOMEBREW),1) ifeq ($(HOMEBREW),1)
include Makefile.homebrew include Makefile.homebrew
else else
include Makefile.osx include Makefile.osx
endif endif
else ifeq ($(shell echo $(UNAME) | $(GREP) -Ec '(Free|Open)BSD'),1) else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.bsd include Makefile.bsd
else ifeq ($(UNAME),Linux) else ifneq (, $(findstring linux, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.linux include Makefile.linux
else else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
include Makefile.mingw include Makefile.mingw
else # not supported
$(error Not supported platform)
endif endif
ifeq ($(USE_MESHNET),yes) ifeq ($(USE_MESHNET),yes)

View File

@@ -1,5 +1,5 @@
CXX = clang++ CXX = clang++
CXXFLAGS = -O2 CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time ## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
## **without** overwriting the CXXFLAGS which we need in order to build. ## **without** overwriting the CXXFLAGS which we need in order to build.
## For example, when adding 'hardening flags' to the build ## For example, when adding 'hardening flags' to the build

View File

@@ -24,7 +24,7 @@ else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0
else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 ubuntu else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 ubuntu
NEEDED_CXXFLAGS += -std=c++11 NEEDED_CXXFLAGS += -std=c++11
else # not supported else # not supported
$(error Compiler too old) $(error Compiler too old)
endif endif
NEEDED_CXXFLAGS += -fPIC NEEDED_CXXFLAGS += -fPIC

View File

@@ -70,12 +70,11 @@ See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and
Donations Donations
--------- ---------
BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59 LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
DOGE: DNXLQKziRPAsD9H3DFNjk4fLQrdaSX893Y ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
License License

View File

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

View File

@@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd" package="org.purplei2p.i2pd"
android:versionCode="1" android:versionCode="1"
android:versionName="2.17.0" android:versionName="2.18.0"
android:installLocation="auto"> android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

47
android/build.gradle Normal file
View File

@@ -0,0 +1,47 @@
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "org.purplei2p.i2pd"
targetSdkVersion 25
minSdkVersion 14
versionCode 1
versionName "2.17.1"
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
jniLibs.srcDirs = ['libs']
}
}
signingConfigs {
orignal {
storeFile file("i2pdapk.jks")
storePassword "android"
keyAlias "i2pdapk"
keyPassword "android"
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.orignal
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
}

View File

@@ -11,7 +11,7 @@ NDK_TOOLCHAIN_VERSION := 4.9
# APP_STL := stlport_shared --> does not seem to contain C++11 features # APP_STL := stlport_shared --> does not seem to contain C++11 features
APP_STL := gnustl_shared APP_STL := gnustl_shared
# Enable c++11 extentions in source code # Enable c++11 extensions in source code
APP_CPPFLAGS += -std=c++11 APP_CPPFLAGS += -std=c++11
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP

View File

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

1
build/.gitignore vendored
View File

@@ -8,6 +8,7 @@
/CPackConfig.cmake /CPackConfig.cmake
/CPackSourceConfig.cmake /CPackSourceConfig.cmake
/install_manifest.txt /install_manifest.txt
/arch.c
# windows build script # windows build script
i2pd*.zip i2pd*.zip
build*.log build*.log

View File

@@ -26,6 +26,10 @@ option(WITH_WEBSOCKETS "Build with websocket ui" OFF)
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
set ( CMAKE_SOURCE_DIR ".." ) set ( CMAKE_SOURCE_DIR ".." )
# architecture
include(TargetArch)
target_architecture(ARCHITECTURE)
set(LIBI2PD_SRC_DIR ../libi2pd) set(LIBI2PD_SRC_DIR ../libi2pd)
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
@@ -79,7 +83,7 @@ if (WITH_WEBSOCKETS)
find_package(websocketpp REQUIRED) find_package(websocketpp REQUIRED)
endif () endif ()
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS) if (WIN32 OR MSYS)
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
endif () endif ()
@@ -190,20 +194,14 @@ if (WITH_HARDENING AND MSVC)
endif () endif ()
# compiler flags customization (by system) # compiler flags customization (by system)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (UNIX)
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8 if (NOT (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) # "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" )
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") endif ()
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8 elseif (WIN32 OR MSYS)
add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp")
if (WITH_GUI) if (WITH_GUI)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp")
set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp" set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp"
@@ -366,11 +364,13 @@ if (NOT ZLIB_FOUND )
if (NOT WITH_STATIC) if (NOT WITH_STATIC)
set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE) set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE)
endif () endif ()
link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib)
else()
link_directories(${ZLIB_ROOT}/lib)
endif () endif ()
if (WITH_STATIC AND (MSVC OR MSYS)) if (WITH_STATIC AND (MSVC OR MSYS))
set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE) set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE)
endif () endif ()
link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib ${ZLIB_ROOT}/lib)
# load includes # load includes
include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
@@ -382,6 +382,8 @@ if (WITH_MESHNET)
message(WARNING "This build will NOT work on mainline i2p") message(WARNING "This build will NOT work on mainline i2p")
endif() endif()
include(CheckAtomic)
# show summary # show summary
message(STATUS "---------------------------------------") message(STATUS "---------------------------------------")
@@ -389,6 +391,7 @@ message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}") message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}") message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}")
message(STATUS "Architecture : ${ARCHITECTURE}")
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}") message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Options:") message(STATUS "Options:")
message(STATUS " AESNI : ${WITH_AESNI}") message(STATUS " AESNI : ${WITH_AESNI}")
@@ -448,7 +451,7 @@ if (WITH_BINARY)
if (WITH_STATIC) if (WITH_STATIC)
set(DL_LIB ${CMAKE_DL_LIBS}) set(DL_LIB ${CMAKE_DL_LIBS})
endif() endif()
target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB}) target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
@@ -461,12 +464,6 @@ if (WITH_BINARY)
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\") fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
" COMPONENT Runtime) " COMPONENT Runtime)
endif () endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (NOT (MSVC OR MSYS OR APPLE)) # for Clang build on Linux
target_link_libraries("${PROJECT_NAME}" stdc++)
endif()
endif()
endif () endif ()
install(FILES ../LICENSE install(FILES ../LICENSE

View File

@@ -6,7 +6,7 @@ REM Copyright (c) 2013-2017, The PurpleI2P Project
REM This file is part of Purple i2pd project and licensed under BSD3 REM This file is part of Purple i2pd project and licensed under BSD3
REM See full license text in LICENSE file at top of project tree REM See full license text in LICENSE file at top of project tree
REM To use that script, you must have installed in your MSYS installation theese packages: REM To use that script, you must have installed in your MSYS installation these packages:
REM Base: git make zip REM Base: git make zip
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
@@ -58,6 +58,7 @@ pause
exit /b 0 exit /b 0
:BUILDING :BUILDING
%xSH% "make clean" >> nul
echo Building i2pd %tag% for win%bitness%: echo Building i2pd %tag% for win%bitness%:
echo Build AVX+AESNI... echo Build AVX+AESNI...
%xSH% "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1 %xSH% "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1

View File

@@ -0,0 +1,106 @@
# atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles)
# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.
function(check_working_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
std::atomic<int> x;
int main() {
return x;
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_working_cxx_atomics)
function(check_working_cxx_atomics64 varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
#include <cstdint>
std::atomic<uint64_t> x (0);
int main() {
uint64_t i = x.load(std::memory_order_relaxed);
return 0;
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_working_cxx_atomics64)
# This isn't necessary on MSVC, so avoid command-line switch annoyance
# by only running on GCC-like hosts.
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
# First check if atomics work without the library.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
if( HAVE_LIBATOMIC )
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()
endif()
# Check for 64 bit atomic operations.
if(MSVC)
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
else()
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
endif()
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
if(HAVE_CXX_LIBATOMICS64)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()
## TODO: This define is only used for the legacy atomic operations in
## llvm's Atomic.h, which should be replaced. Other code simply
## assumes C++11 <atomic> works.
CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER
#include <Intrin.h> /* Workaround for PR19898. */
#include <windows.h>
#endif
int main() {
#ifdef _MSC_VER
volatile LONG val = 1;
MemoryBarrier();
InterlockedCompareExchange(&val, 0, 1);
InterlockedIncrement(&val);
InterlockedDecrement(&val);
#else
volatile unsigned long val = 1;
__sync_synchronize();
__sync_val_compare_and_swap(&val, 1, 0);
__sync_add_and_fetch(&val, 1);
__sync_sub_and_fetch(&val, 1);
#endif
return 0;
}
" LLVM_HAS_ATOMICS)
if( NOT LLVM_HAS_ATOMICS )
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
endif()

View File

@@ -0,0 +1,134 @@
# Based on the Qt 5 processor detection code, so should be very accurate
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
# Regarding POWER/PowerPC, just as is noted in the Qt source,
# "There are many more known variants/revisions that we do not handle/detect."
set(archdetect_c_code "
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
#error cmake_ARCH armv7
#elif defined(__ARM_ARCH_6__) \\
|| defined(__ARM_ARCH_6J__) \\
|| defined(__ARM_ARCH_6T2__) \\
|| defined(__ARM_ARCH_6Z__) \\
|| defined(__ARM_ARCH_6K__) \\
|| defined(__ARM_ARCH_6ZK__) \\
|| defined(__ARM_ARCH_6M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
#error cmake_ARCH armv6
#elif defined(__ARM_ARCH_5TEJ__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
#error cmake_ARCH armv5
#else
#error cmake_ARCH arm
#endif
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#error cmake_ARCH ppc64
#else
#error cmake_ARCH ppc
#endif
#endif
#error cmake_ARCH unknown
")
# Set ppc_support to TRUE before including this file or ppc and ppc64
# will be treated as invalid architectures since they are no longer supported by Apple
function(target_architecture output_var)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
endforeach()
# Now add all the architectures in our normalized order
if(osx_arch_ppc)
list(APPEND ARCH ppc)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
if(osx_arch_x86_64)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/arch.c"
COMPILE_OUTPUT_VARIABLE ARCH
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
)
# Parse the architecture name from the compiler output
string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
# Get rid of the value marker leaving just the architecture name
string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
# If we are compiling with an unknown architecture this variable should
# already be set to "unknown" but in the case that it's empty (i.e. due
# to a typo in the code), then set it to unknown
if (NOT ARCH)
set(ARCH unknown)
endif()
endif()
set(${output_var} "${ARCH}" PARENT_SCOPE)
endfunction()

View File

@@ -28,7 +28,7 @@ Options are set via docker environment variables. This can be set at run with -e
**Logging** **Logging**
Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automaticly forward the log to say, kibana or greylog without manual setup. :) Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :)

View File

@@ -21,10 +21,14 @@
# path specific (feel free to modify if you have another paths) # path specific (feel free to modify if you have another paths)
/etc/i2pd/** r, /etc/i2pd/** r,
/run/i2pd/i2pd.pid rw,
/var/lib/i2pd/** rw, /var/lib/i2pd/** rw,
/var/log/i2pd.log w, /var/log/i2pd/i2pd.log w,
/var/run/i2pd/i2pd.pid rw, /var/run/i2pd/i2pd.pid rw,
/usr/sbin/i2pd mr, /usr/sbin/i2pd mr,
/usr/share/i2pd/** r,
# user homedir (if started not by init.d or systemd)
owner @{HOME}/.i2pd/ rw,
owner @{HOME}/.i2pd/** rwk,
} }

View File

@@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFxzCCA6+gAwIBAgIQZfqn0yiJL3dGgCjeOeWS6DANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQ
aG90dHVuYUBtYWlsLmkycDAeFw0xNjExMDkwMzE1MzJaFw0yNjExMDkwMzE1MzJa
MHAxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNV
BAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQD
DBBob3R0dW5hQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEA21Bfgcc9VVH4l2u1YvYlTw2OPUyQb16X2IOW0PzdsUO5W78Loueu974BkiKi
84lQZanLr0OwEopdfutGc6gegSLmwaWx5YCG5uwpLOPkDiObfX+nptH6As/B1cn+
mzejYdVKRnWd7EtHW0iseSsILBK1YbGw4AGpXJ8k18DJSzUt2+spOkpBW6XqectN
8y2JDSTns8yiNxietVeRN/clolDXT9ZwWHkd+QMHTKhgl3Uz1knOffU0L9l4ij4E
oFgPfQo8NL63kLM24hF1hM/At7XvE4iOlObFwPXE+H5EGZpT5+A7Oezepvd/VMzM
tCJ49hM0OlR393tKFONye5GCYeSDJGdPEB6+rBptpRrlch63tG9ktpCRrg2wQWgC
e3aOE1xVRrmwiTZ+jpfsOCbZrrSA/C4Bmp6AfGchyHuDGGkRU/FJwa1YLJe0dkWG
ITLWeh4zeVuAS5mctdv9NQ5wflSGz9S8HjsPBS5+CDOFHh4cexXRG3ITfk6aLhuY
KTMlkIO4SHKmnwAvy1sFlsqj6PbfVjpHPLg625fdNxBpe57TLxtIdBB3C7ccQSRW
+UG6Cmbcmh80PbsSR132NLMlzLhbaOjxeCWWJRo6cLuHBptAFMNwqsXt8xVf9M0N
NdJoKUmblyvjnq0N8aMEqtQ1uGMTaCB39cutHQq+reD/uzsCAwEAAaNdMFswDgYD
VR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNV
HRMBAf8EBTADAQH/MBkGA1UdDgQSBBBob3R0dW5hQG1haWwuaTJwMA0GCSqGSIb3
DQEBCwUAA4ICAQCibFV8t4pajP176u3jx31x1kgqX6Nd+0YFARPZQjq99kUyoZer
GyHGsMWgM281RxiZkveHxR7Hm7pEd1nkhG3rm+d7GdJ2p2hujr9xUvl0zEqAAqtm
lkYI6uJ13WBjFc9/QuRIdeIeSUN+eazSXNg2nJhoV4pF9n2Q2xDc9dH4GWO93cMX
JPKVGujT3s0b7LWsEguZBPdaPW7wwZd902Cg/M5fE1hZQ8/SIAGUtylb/ZilVeTS
spxWP1gX3NT1SSvv0s6oL7eADCgtggWaMxEjZhi6WMnPUeeFY8X+6trkTlnF9+r/
HiVvvzQKrPPtB3j1xfQCAF6gUKN4iY+2AOExv4rl/l+JJbPhpd/FuvD8AVkLMZ8X
uPe0Ew2xv30cc8JjGDzQvoSpBmVTra4f+xqH+w8UEmxnx97Ye2aUCtnPykACnFte
oT97K5052B1zq+4fu4xaHZnEzPYVK5POzOufNLPgciJsWrR5GDWtHd+ht/ZD37+b
+j1BXpeBWUBQgluFv+lNMVNPJxc2OMELR1EtEwXD7mTuuUEtF5Pi63IerQ5LzD3G
KBvXhMB0XhpE6WG6pBwAvkGf5zVv/CxClJH4BQbdZwj9HYddfEQlPl0z/XFR2M0+
9/8nBfGSPYIt6KeHBCeyQWTdE9gqSzMwTMFsennXmaT8gyc7eKqKF6adqw==
-----END CERTIFICATE-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFhTCCA22gAwIBAgIELuRWgDANBgkqhkiG9w0BAQ0FADBzMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEcMBoGA1UEAwwTa2lsbHlvdXJ0dkBt
YWlsLmkycDAeFw0xMzEwMDYyMTM5MzFaFw0yMzEwMDYyMTM5MzFaMHMxCzAJBgNV
BAYTAlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBB
bm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRwwGgYDVQQDDBNraWxseW91
cnR2QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAig3u
niLWm0y/TFJtciHgmWUt20FOdQrxkiSZ87G8xjuGfq7TbGIiVDn7pQZcHidpq+Dk
47sm+Swqhb4psSijj0AXUEVKlV39jF5IZE+VUgmEtMqQbnBkWudaTJPWcEe9T/Kd
8Oz2jgsnrD/EGVTMKBBjt/gk8VqTWvpCdCF1GhqcCeUTFHzjhN9jtoRCaJ2DClpO
Px+86+d3s9PqUFo8gcD/dbbyJCMqUCMBLtIy/Ooouxb9cfWtXfyOlphU+enmdvuA
0BDewb9pOJg2/kVd9/9moDWcBGChLOlfSlxpDwyUtcclcpvwnG7c6o4or6gqLeOf
AbCpse623utV7fWlFWG7M4AQ/2emhhe4YoMJQnflydzV8bPRJxRTeW1j/9UfpvLT
nO5LHp0oBXE0GqAPjxuAr+r5IDXFbkKYNjK5oWQB/Ul3LkexulYdCzHWbGd1Ja5b
sbiOy6t/hH6G8DD75HYb+PQZaNZWBv90EyOq1JDSUPw6nxVbhiBldi3ipc8/1X51
FbzBqJ+QO1XKrKqxWxBKoTekuy38KRzsmkSCpY+WJ9f0gLOKtxzVO2HNNqqVFGQf
RGIbrNA0JSRQ1fgelccfrcRIXIZ3B8Tk/wxCIzCY6Yvg2jezz2xJkVdqOUsznS2v
+xJe67PYIAeMVtcfO4kmuCvyIYhsUEpob2n/5lkCAwEAAaMhMB8wHQYDVR0OBBYE
FCLneov6QMtvra5FSoSLhdymi++rMA0GCSqGSIb3DQEBDQUAA4ICAQAIcqbiwjdQ
M9VlGBiHe5eVsL6OM9zfRqR1wnRg4Q6ce65XDfEOYleBWaaNJA4BdykcA4fkUN1h
M2D9FDQScsyPTOuzJ6o75TYh0JOtF51yCi9iuemcosxAwsm90ZXGuMDfDYeyND5c
PAkWfyCP+jwLYbNo/hkNqyv+XWHXPQmT2adRnPXINVUQuBxVPC//C9wv2uDYWhgS
f8M425VPp4/R/uks9mlzTx08DwacvouD0YOC+HZE4sWq+2smgeBInMiyr/THYzl+
baMtYgVs8IKUD2gtjfXZoaQNg3eq5SedSf/5F0S/LCdu9/ccQ8CzSEoVTiQFtO78
SaU37xai8+QTSVpPuINigxCoXmkubBd+voEmWRcBd/XB5L+u+MFU/jXyyBj2BXVj
6agqVzY53KVYt23/63QliAUWyxT+ns9gRxVN1jrMhHdiDwsdT4NbzHxg1Su4eiHv
C/wjD3Dga0BRTEGylpHZGzb1U1rZRHM3ho3f1QkmRPPLcBUMTyUTxJm+GEeuhPvp
+TBf3Kg/YkdpnEMlagqcyHuIrf3m8Z/pTmpOIbekJWbbA7tluvWbMWw2ARB7dUOE
fHYVISh0DTw2oVXxM82/q8XXHnhEXv2nW3K40x1VabxUN+sF4M/7YA8nJqwsPJei
749STYJRfZXdIe69M9zpM5unxENAsiPJgQ==
-----END CERTIFICATE-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFezCCA2OgAwIBAgIEHLJfZzANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOc3RyNGRAbWFpbC5p
MnAwHhcNMTMxMDI2MTExODQxWhcNMjMxMDI2MTExODQxWjBuMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOc3RyNGRAbWFpbC5p
MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvw0vTay1IPOgxvwe8
yt5jGakha20kw9qDb6zbEL87EWEkeOzdu7iUC69lkxVP9Ws8EbLtkeMf/CXg6CC1
e+w8WpOHj5prOsiOlrIO+2I1tKMaMUuJDX2wK4I5ZSw/Kieimh9xqOBZknDmtwjw
2HPW8rpxMqrScaGAP6sQD8Gh4XKKkLogfxYPzF8NnC6O8vBkFKVU2WSVZ0jPAQfv
6luPdA+5lES+5UPWr9Yhv/CX4siGKUTxchqJRf2VU4o5BzzXae4asVA/NY7lKgEw
eDDufbm0mRFWP4mbmXRlODuJ8GMnJbMQkNcAvZUnUcvpSTnGnIvxyxtXP5P6ic8V
3b9HV2eIsbfO1xrgyr6/9qgGpXcdDJejhvNg6fZgQeO40bOGQYwV8bNvsNQHqnZl
KsVhsMQkOubMxcHTBadcifi8PmdeJ5hxyyqJmyrwkmg2ijnN521M6YkoBzl+8VAi
zLmqKZfvN5t+pb9PZ3U3jHfkeIEwDRYRAOsvVqch5+ZfSv8x/Te6o15zDKPJQtWK
ty42GV1vERw30oSZQdrRRy/+4+HSRs3/Zb368OdAbcr+f/xPvwceYGWPeNNIoZ/x
xkIQE3xgEK+eJyPM9McjlCAezZZclT7fWfiEYNJAiS3fGALi+a+cGYWWULxCXpz+
y397OHhZBhnh7D9K8aPePB8tCwIDAQABoyEwHzAdBgNVHQ4EFgQUezvGHq3h1gbC
Hs2LLVoll5fIUWMwDQYJKoZIhvcNAQENBQADggIBAF7SG1WBcE1r5eyTp/BLFZfG
iPtvqu+B1L2HutPum/Xf8A5fxR4kcKAKpVdu6vnDzCRAsAC9YvyETgAzI2nfVgLk
l9YZ31tSi6qxnMsQsV5o9lt/q2Rvsf2Zi/Ir8AlWtvnP8YG0Aj/8AG8MyhMLaIdj
M2FuakPs8RqEjoJL9dTOC9VTQpNTwBH9guP9UalWYwlkaXDzMoyO4nswT/GpCpg8
4m4RO6grzdsEIamD/PCBM5f/vq+y08GaqfXpX9+8CbaX3tdzd3x48wPphmdpkptk
aRELIpLJZiK+Mos7W+0ZS8SHxGDIosjqVsgbZPmk12+VBcVgLOr8W1D7osS4OY59
2GMUVV/GhoDh8wR/Td5wpZlcPE0NWmljjVg9+1E8ePAyMZy+U1KCiMlRVdRy518O
dOzzUUQGqGQHosRrH0ypS3MGbMLmbuWFRiz7q/3mUmW2xikH9I1t/6ZMNUvh+IWL
kGAaEf2JIv/D8+QsC0Un1W09DgvYz7qmKSeHhBixlLe68vgXtz/Fa+rRMsmPrueo
4wk/u/VyILo0BJP860APJMZbm+DPfGhV9DF9L5Gx9+d/BlduBVGHc+AQSWbU70dS
eH4/rgUYRikWlgwUxjY8/QQTlfx5xl28tG0xdO9libN22z7UwTGfm48BQIdrTyER
hqQ7usTy3oaWD85MbJ0q
-----END CERTIFICATE-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFdzCCA1+gAwIBAgIEcwrwsjANBgkqhkiG9w0BAQ0FADBsMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEVMBMGA1UEAwwMenp6QG1haWwuaTJw
MB4XDTEzMDkzMDE3NDEyNVoXDTIzMDkzMDE3NDEyNVowbDELMAkGA1UEBhMCWFgx
CzAJBgNVBAgTAlhYMQswCQYDVQQHEwJYWDEeMBwGA1UEChMVSTJQIEFub255bW91
cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxFTATBgNVBAMMDHp6ekBtYWlsLmkycDCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJV4ptvhlfrcize9/ARz4lUy
iLtLMSvSST1BdZjLJTwus05EUs0oiqnv9qXYIWGRB97aKlAmqSxsn4ZgBttCgmev
IkuiZ8kbdqI5YaT98yKW5P2Prt9p9cPbnz5/qjwZ5L9W+k/Itx7bv2pkNEP0NLYo
NrgHHTb1hsyRxc0lfPYk2BwsIi8hIWBHNrRpR41EWFXfqPcdsxS8cQhxVj4zLG/R
aMm4H8T+V1R1Khl4R4qqRgXBP305xqqRoawHmZ/S9/RkF0Ji6IYwBq9iWthWol6W
sMDn1xhZk9765fk+ohAC2XWuGSFCr02JOILRV3x/8OUxT1GYgYjc7FfyWIekg/pZ
yotlhL2I3SMWOH3PdG58iDY121hq/LsSKM9aP20rwtvssnw+8Aex01YDkI3bM6yO
HNi+tRojaJcJciBWv6cuiFKvQdxj/mOhOr0u0lHLlJ4jqES8uvVJkS7X/C4BB7ra
bJYQgumZMYvVQJFIjo8vZxMXue53o65FRidvAUT29ay54UTiL7jRV9w1wHnzLapU
xT1v7kWpWJcZ1zzC8coJjW+6ijkk38cVLb80u1Q4kEbmP2rDxw6jRvmqg6DcCKjK
oqDt+XQ6P5grxAxLT+VMfB404WHHwNs6BB841//4ZnXvy3msMONY/5y0fsblURgh
IS2UG1TAjR+x7+XikGx9AgMBAAGjITAfMB0GA1UdDgQWBBSvx/fCCP8UeHwjN65p
EoHjgRfiIzANBgkqhkiG9w0BAQ0FAAOCAgEAYgVE1Aa/Ok5k+Jvujbx72bktRWXo
Y4UfbWH/426VdgqXt3n9XtJUNM2oI4ODwITM4O15SyXQTLJhnvJz5ELcJV8nqviZ
RjK2HNX1BW7IEta3tacCvVnjzZ265kCT59uW+qmd+5PiaAYI5lYUn8P6pe+6neSa
HW6ecXCrdxJetSYfUUuKeV6YHpdzfjtZClLmwl91sJUBKcjK+Q9G/cE6HnwcDH1s
uXr7SgkBt/qc/OlNuu4fnTqUA58TAumdq9cD+eLBilDFrux1HsUZMuBUp64x5oPi
gme+3VewsczfFEtrxaG6+l6UA40Lerdx9XECZcDCcFsK6MS1uQ2HYjsyZcWnNT3l
6eDNUbjrllwxDdRAk0cbWiMuc21CFq/1v2QMXk88EiBjEajqzyXUPmKzwFhit6pr
5kfjfXNq+pxQSCoaqjpzVKjb3CqMhSlC8cLgrPw6HEgGnjCy4cTLFHlVmD64M778
tj6rE7CntcmUi8GKmZKyaMyUo3QQUcrjO5IQ4+3iGUgMkZuujyjrZiOJbvircPmK
4IQEXzJ/G00upqtqKstRybaWSbJ/k6iuturtA2n8MJiCBjhLy8dtTgDbFaDaNF7F
NHeqQjIJDLhYDy6mi4gya3A0ort777Inl/rWYLo067pYM+EWDw66GdpbEIB0Bp71
pwvcQcjIzbUzEK0=
-----END CERTIFICATE-----

View File

@@ -8,18 +8,18 @@ Group=i2pd
RuntimeDirectory=i2pd RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700 RuntimeDirectoryMode=0700
Type=simple Type=simple
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/var/run/i2pd/i2pd.pid PIDFile=/var/run/i2pd/i2pd.pid
### Uncomment, if auto restart needed ### Uncomment, if auto restart needed
#Restart=on-failure #Restart=on-failure
### Use SIGINT for gracefull stop daemon. ### Use SIGINT for graceful stop daemon.
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die. # i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
KillSignal=SIGINT KillSignal=SIGINT
TimeoutStopSec=10m TimeoutStopSec=10m
# If you have problems with hunging i2pd, you can try enable this # If you have problems with hanging i2pd, you can try enable this
#LimitNOFILE=4096 #LimitNOFILE=4096
PrivateDevices=yes PrivateDevices=yes

View File

@@ -35,7 +35,7 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boos
&& mv i2pd /usr/local/bin \ && mv i2pd /usr/local/bin \
&& cd /usr/local/bin \ && cd /usr/local/bin \
&& strip i2pd \ && strip i2pd \
&& rm -fr /tmp/build && apk --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \ && rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \ boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \
boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \ boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \
libtool g++ gcc pkgconfig libtool g++ gcc pkgconfig

View File

@@ -1,16 +1,27 @@
[Unit] [Unit]
Description=I2P router Description=I2P Router written in C++
After=network.target After=network.target
[Service] [Service]
User=i2pd User=i2pd
Group=i2pd Group=i2pd
RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
Type=simple Type=simple
ExecStart=/usr/bin/i2pd --service ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
PIDFile=/var/lib/i2pd/i2pd.pid ExecReload=/bin/kill -HUP $MAINPID
Restart=always PIDFile=/var/run/i2pd/i2pd.pid
PrivateTmp=true ### Uncomment, if auto restart needed
#Restart=on-failure
### Use SIGINT for graceful stop daemon.
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
KillSignal=SIGINT
TimeoutStopSec=10m
# If you have problems with hunging i2pd, you can try enable this
#LimitNOFILE=4096
PrivateDevices=yes
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,9 +1,10 @@
%define build_timestamp %(date +"%Y%m%d") %define build_timestamp %(date +"%Y%m%d")
Name: i2pd Name: i2pd
Version: 2.17.0 Version: 2.18.0
Release: %{build_timestamp}git%{?dist} Release: %{build_timestamp}git%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Obsoletes: %{name}-systemd
License: BSD License: BSD
URL: https://github.com/PurpleI2P/i2pd URL: https://github.com/PurpleI2P/i2pd
@@ -23,25 +24,12 @@ BuildRequires: openssl-devel
BuildRequires: miniupnpc-devel BuildRequires: miniupnpc-devel
BuildRequires: systemd-units BuildRequires: systemd-units
%description
C++ implementation of I2P.
%package systemd
Summary: Files to run I2P router under systemd
Requires: i2pd
Requires: systemd Requires: systemd
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
Obsoletes: %{name}-daemon
%description
%description systemd
C++ implementation of I2P. C++ implementation of I2P.
This package contains systemd unit file to run i2pd as a system service
using dedicated user's permissions.
%prep %prep
%setup -q %setup -q
@@ -68,114 +56,76 @@ make %{?_smp_mflags}
%install %install
cd build cd build
chrpath -d i2pd chrpath -d i2pd
install -D -m 755 i2pd %{buildroot}%{_bindir}/i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
install -d -m 755 %{buildroot}/%{_datadir}/i2pd
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}/%{_unitdir}/i2pd.service install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}/%{_unitdir}/i2pd.service
install -d -m 700 %{buildroot}/%{_sharedstatedir}/i2pd install -d -m 700 %{buildroot}/%{_sharedstatedir}/i2pd
install -d -m 700 %{buildroot}/%{_localstatedir}/log/i2pd
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/%{name}/certificates
%pre systemd %pre
getent group i2pd >/dev/null || %{_sbindir}/groupadd -r i2pd getent group i2pd >/dev/null || %{_sbindir}/groupadd -r i2pd
getent passwd i2pd >/dev/null || \ getent passwd i2pd >/dev/null || \
%{_sbindir}/useradd -r -g i2pd -s %{_sbindir}/nologin \ %{_sbindir}/useradd -r -g i2pd -s %{_sbindir}/nologin \
-d %{_sharedstatedir}/i2pd -c 'I2P Service' i2pd -d %{_sharedstatedir}/i2pd -c 'I2P Service' i2pd
%post systemd %post
%systemd_post i2pd.service %systemd_post i2pd.service
%preun systemd %preun
%systemd_preun i2pd.service %systemd_preun i2pd.service
%postun systemd %postun
%systemd_postun_with_restart i2pd.service %systemd_postun_with_restart i2pd.service
%files %files
%doc LICENSE README.md %doc LICENSE README.md
%_bindir/i2pd %{_sbindir}/i2pd
%{_datadir}/i2pd/certificates
%config(noreplace) %{_sysconfdir}/i2pd/*
%files systemd /%{_unitdir}/i2pd.service
/%_unitdir/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
%dir %attr(0700,i2pd,i2pd) %_sharedstatedir/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
%{_sharedstatedir}/i2pd/certificates
%changelog %changelog
* Tue Jan 30 2018 orignal <i2porignal@yandex.ru>> - 2.18.0
- update to 2.18.0
* Sat Jan 27 2018 l-n-s <supervillain@riseup.net> - 2.17.0-1
- Added certificates and default configuration files
- Merge i2pd with i2pd-systemd package
- Fixed package changelogs to comply with guidelines
* Mon Dec 04 2017 orignal <i2porignal@yandex.ru> - 2.17.0 * Mon Dec 04 2017 orignal <i2porignal@yandex.ru> - 2.17.0
- Added reseed through HTTP and SOCKS proxy - update to 2.17.0
- Added show status of client services through web console
- Added change log level through web connsole
- Added transient keys for tunnels
- Added i2p.streaming.initialAckDelay parameter
- Added CRYPTO_TYPE for SAM destination
- Added signature and crypto type for newkeys BOB command
- Changed - correct publication of ECIES destinations
- Changed - disable RSA signatures completely
- Fixed CVE-2017-17066
- Fixed possible buffer overflow for RSA-4096
- Fixed shutdown from web console for Windows
- Fixed web console page layout
* Mon Nov 13 2017 orignal <i2porignal@yandex.ru> - 2.16.0 * Mon Nov 13 2017 orignal <i2porignal@yandex.ru> - 2.16.0
- Added https and "Connect" method for HTTP proxy - update to 2.16.0
- Added outproxy for HTTP proxy
- Added initial support of ECIES crypto
- Added NTCP soft and hard descriptors limits
- Added support full timestamps in logs
- Changed faster implmentation of GOST R 34.11 hash
- Changed reject routers with RSA signtures
- Changed reload config and shudown from Windows GUI
- Changed update tunnels address(destination) without restart
- Fixed BOB crashes if destination is not set
- Fixed correct SAM tunnel name
- Fixed QT GUI issues
* Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0 * Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0
- Added QT GUI - update to 2.15.0
- Added ability add and remove I2P tunnels without restart
- Added ability to disable SOCKS outproxy option
- Changed strip-out Accept-* hedaers in HTTP proxy
- Changed peer test if nat=false
- Changed separate output of NTCP and SSU sessions in Transports tab
- Fixed handle lines with comments in hosts.txt file for address book
- Fixed run router with empty netdb for testnet
- Fixed skip expired introducers by iexp
* Thu Jun 01 2017 orignal <i2porignal@yandex.ru> - 2.14.0 * Thu Jun 01 2017 orignal <i2porignal@yandex.ru> - 2.14.0
- Added transit traffic bandwidth limitation - update to 2.14.0
- Added NTCP connections through HTTP and SOCKS proxies
- Added ability to disable address helper for HTTP proxy
- Changed reseed servers list
* Thu Apr 06 2017 orignal <i2porignal@yandex.ru> - 2.13.0 * Thu Apr 06 2017 orignal <i2porignal@yandex.ru> - 2.13.0
- Added persist local destination's tags - update to 2.13.0
- Added GOST signature types 9 and 10
- Added exploratory tunnels configuration
- Changed reseed servers list
- Changed inactive NTCP sockets get closed faster
- Changed some EdDSA speed up
- Fixed multiple acceptors for SAM
- Fixed follow on data after STREAM CREATE for SAM
- Fixed memory leaks
* Tue Feb 14 2017 orignal <i2porignal@yandex.ru> - 2.12.0 * Tue Feb 14 2017 orignal <i2porignal@yandex.ru> - 2.12.0
- Additional HTTP and SOCKS proxy tunnels - update to 2.12.0
- Reseed from ZIP archive
- 'X' bandwidth code
- Reduced memory and file descriptors usage
* Mon Dec 19 2016 orignal <i2porignal@yandex.ru> - 2.11.0 * Mon Dec 19 2016 orignal <i2porignal@yandex.ru> - 2.11.0
- Full support of zero-hops tunnels - update to 2.11.0
- Tunnel configuration for HTTP and SOCKS proxy
- Websockets support
- Multiple acceptors for SAM destination
- Routing path for UDP tunnels
- Reseed through a floodfill
- Use AVX instructions for DHT and HMAC if applicable
- Fixed UPnP discovery bug, producing excessive CPU usage
- Handle multiple lookups of the same LeaseSet correctly
* Thu Oct 20 2016 Anatolii Vorona <vorona.tolik@gmail.com> - 2.10.0-3 * Thu Oct 20 2016 Anatolii Vorona <vorona.tolik@gmail.com> - 2.10.0-3
- add support C7 - add support C7

View File

@@ -316,8 +316,9 @@ namespace http {
if (dest) if (dest)
{ {
auto ident = dest->GetIdentHash (); auto ident = dest->GetIdentHash ();
s << "<a href=\"/?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">"; auto& name = dest->GetNickname ();
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl; s << "<a href=\"/?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
s << name << " ]</a> &#8660; " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"<br>\r\n" << std::endl;
} }
} }
} }

View File

@@ -63,7 +63,7 @@ namespace http
private: private:
void Run (); void Run ();
void Accept (); void Accept ();
void HandleAccept(const boost::system::error_code& ecode, void HandleAccept(const boost::system::error_code& ecode,
std::shared_ptr<boost::asio::ip::tcp::socket> newSocket); std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);
void CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket); void CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);

View File

@@ -35,7 +35,7 @@ namespace client
I2PControlService::I2PControlService (const std::string& address, int port): I2PControlService::I2PControlService (const std::string& address, int port):
m_IsRunning (false), m_Thread (nullptr), m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
m_SSLContext (m_Service, boost::asio::ssl::context::sslv23), m_SSLContext (boost::asio::ssl::context::sslv23),
m_ShutdownTimer (m_Service) m_ShutdownTimer (m_Service)
{ {
i2p::config::GetOption("i2pcontrol.password", m_Password); i2p::config::GetOption("i2pcontrol.password", m_Password);
@@ -160,7 +160,7 @@ namespace client
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket) void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
{ {
socket->async_handshake(boost::asio::ssl::stream_base::server, socket->async_handshake(boost::asio::ssl::stream_base::server,
std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket)); std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket));
} }
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket) void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
@@ -187,7 +187,7 @@ namespace client
} }
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode, void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket, size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
std::shared_ptr<I2PControlBuffer> buf) std::shared_ptr<I2PControlBuffer> buf)
{ {
if (ecode) if (ecode)

View File

@@ -13,6 +13,7 @@
#include "Config.h" #include "Config.h"
#include "FS.h" #include "FS.h"
#include "Log.h" #include "Log.h"
#include "Tunnel.h"
#include "RouterContext.h" #include "RouterContext.h"
#include "ClientContext.h" #include "ClientContext.h"
@@ -183,7 +184,7 @@ namespace i2p
if (gracefulShutdownInterval) if (gracefulShutdownInterval)
{ {
gracefulShutdownInterval--; // - 1 second gracefulShutdownInterval--; // - 1 second
if (gracefulShutdownInterval <= 0) if (gracefulShutdownInterval <= 0 || i2p::tunnel::tunnels.CountTransitTunnels() <= 0)
{ {
LogPrint(eLogInfo, "Graceful shutdown"); LogPrint(eLogInfo, "Graceful shutdown");
return; return;

View File

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

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
i2pd (2.18.0-1) unstable; urgency=low
* updated to version 2.18.0/0.9.33
-- orignal <orignal@i2pmail.org> Tue, 30 Jan 2018 16:00:00 +0000
i2pd (2.17.0-1) unstable; urgency=low i2pd (2.17.0-1) unstable; urgency=low
* updated to version 2.17.0/0.9.32 * updated to version 2.17.0/0.9.32

4
debian/control vendored
View File

@@ -2,11 +2,11 @@ Source: i2pd
Section: net Section: net
Priority: optional Priority: optional
Maintainer: R4SAS <r4sas@i2pmail.org> Maintainer: R4SAS <r4sas@i2pmail.org>
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, libminiupnpc-dev, libssl-dev, zlib1g-dev, dh-apparmor Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev, dh-apparmor
Standards-Version: 3.9.6 Standards-Version: 3.9.6
Homepage: http://i2pd.website/ Homepage: http://i2pd.website/
Vcs-Git: git://github.com/PurpleI2P/i2pd.git Vcs-Git: git://github.com/PurpleI2P/i2pd.git
Vcs-Browser: https://github.com/PurpleI2P/i2pd.git Vcs-Browser: https://github.com/PurpleI2P/i2pd
Package: i2pd Package: i2pd
Architecture: any Architecture: any

44
debian/copyright vendored
View File

@@ -4,6 +4,22 @@ Source: https://github.com/PurpleI2P
Files: * Files: *
Copyright: 2013-2017 PurpleI2P Copyright: 2013-2017 PurpleI2P
License: BSD-3-clause
Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl
qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java
Copyright: 2011-2013 BogDan Vatra <bogdan@kde.org>
License: BSD-2-Clause
Files: debian/*
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
2014-2016 hagen <hagen@i2pmail.org>
2016-2017 R4SAS <r4sas@i2pmail.org>
2017-2018 Yangfl <mmyangfl@gmail.com>
License: GPL-2+
License: BSD-3-clause License: BSD-3-clause
Copyright (c) 2013-2017, The PurpleI2P Project Copyright (c) 2013-2017, The PurpleI2P Project
. .
@@ -33,11 +49,29 @@ License: BSD-3-clause
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Files: debian/* License: BSD-2-Clause
Copyright: 2016-2017 R4SAS <r4sas@i2pmail.org> Redistribution and use in source and binary forms, with or without
2014-2016 hagen <hagen@i2pmail.org> modification, are permitted provided that the following conditions
2013-2015 Kill Your TV <killyourtv@i2pmail.org> are met:
License: GPL-2.0+ 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: GPL-2+
This package is free software; you can redistribute it and/or modify This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or

2
debian/lintian-overrides vendored Normal file
View File

@@ -0,0 +1,2 @@
# GPL come from debian/
i2pd: possible-gpl-code-linked-with-openssl

View File

@@ -1,6 +1,5 @@
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index bdadfe0..2f71eec 100644 index bdadfe0..2f71eec 100644
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -9,10 +9,10 @@ DEPS := obj/make.dep @@ -9,10 +9,10 @@ DEPS := obj/make.dep

View File

@@ -1638,7 +1638,7 @@ EXTRA_PACKAGES =
# following commands have a special meaning inside the header: $title, # following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber, # $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, # $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
# for the replacement values of the other commands the user is refered to # for the replacement values of the other commands the user is referred to
# HTML_HEADER. # HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES. # This tag requires that the tag GENERATE_LATEX is set to YES.

View File

@@ -267,14 +267,14 @@ namespace data
if (pos < len) if (pos < len)
{ {
tmp <<= 8; tmp <<= 8;
tmp |= inBuf[pos] & 0xFF; tmp |= inBuf[pos] & 0xFF;
pos++; pos++;
bits += 8; bits += 8;
} }
else // last byte else // last byte
{ {
tmp <<= (5 - bits); tmp <<= (5 - bits);
bits = 5; bits = 5;
} }
} }

View File

@@ -47,7 +47,7 @@ namespace config {
* @brief Load and parse given config file * @brief Load and parse given config file
* @param path Path to config file * @param path Path to config file
* *
* If error occured when opening file path is points to, * If error occurred when opening file path is points to,
* we show the error message and terminate program. * we show the error message and terminate program.
* *
* In case of parameter misuse boost throws an exception. * In case of parameter misuse boost throws an exception.

View File

@@ -22,7 +22,7 @@ namespace crypto
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,

View File

@@ -106,7 +106,7 @@ namespace datagram
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner); DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner);
~DatagramDestination (); ~DatagramDestination ();
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };

View File

@@ -59,7 +59,13 @@ namespace client
} }
} }
it = params->find (I2CP_PARAM_INBOUND_NICKNAME); it = params->find (I2CP_PARAM_INBOUND_NICKNAME);
if (it != params->end ()) m_Nickname = it->second; // otherwise we set deafult nickname in Start when we know local address if (it != params->end ()) m_Nickname = it->second;
else // try outbound
{
it = params->find (I2CP_PARAM_OUTBOUND_NICKNAME);
if (it != params->end ()) m_Nickname = it->second;
// otherwise we set deafult nickname in Start when we know local address
}
} }
} }
catch (std::exception & ex) catch (std::exception & ex)
@@ -774,7 +780,7 @@ namespace client
delete m_DatagramDestination; delete m_DatagramDestination;
m_DatagramDestination = nullptr; m_DatagramDestination = nullptr;
} }
return true; return true;
} }
else else
return false; return false;

View File

@@ -29,7 +29,7 @@ namespace client
const uint8_t PROTOCOL_TYPE_DATAGRAM = 17; const uint8_t PROTOCOL_TYPE_DATAGRAM = 17;
const uint8_t PROTOCOL_TYPE_RAW = 18; const uint8_t PROTOCOL_TYPE_RAW = 18;
const int PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds const int PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
const int PUBLISH_VERIFICATION_TIMEOUT = 10; // in seconds after successfull publish const int PUBLISH_VERIFICATION_TIMEOUT = 10; // in seconds after successful publish
const int PUBLISH_MIN_INTERVAL = 20; // in seconds const int PUBLISH_MIN_INTERVAL = 20; // in seconds
const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically
const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds
@@ -51,6 +51,7 @@ namespace client
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend"; const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
const int DEFAULT_TAGS_TO_SEND = 40; const int DEFAULT_TAGS_TO_SEND = 40;
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname";
// latency // latency
const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min";
@@ -238,7 +239,7 @@ namespace client
int m_StreamingAckDelay; int m_StreamingAckDelay;
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts; std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
i2p::datagram::DatagramDestination * m_DatagramDestination; i2p::datagram::DatagramDestination * m_DatagramDestination;
int m_RefCounter; // how many clients(tunnels) use this destination int m_RefCounter; // how many clients(tunnels) use this destination
boost::asio::deadline_timer m_ReadyChecker; boost::asio::deadline_timer m_ReadyChecker;

View File

@@ -96,7 +96,7 @@ namespace fs {
boost::filesystem::create_directory(destinations); boost::filesystem::create_directory(destinations);
std::string tags = DataDirPath("tags"); std::string tags = DataDirPath("tags");
if (!boost::filesystem::exists(tags)) if (!boost::filesystem::exists(tags))
boost::filesystem::create_directory(tags); boost::filesystem::create_directory(tags);
else else
i2p::garlic::CleanUpTagsFiles (); i2p::garlic::CleanUpTagsFiles ();
@@ -136,7 +136,7 @@ namespace fs {
return boost::filesystem::remove(path); return boost::filesystem::remove(path);
} }
bool CreateDirectory (const std::string& path) bool CreateDirectory (const std::string& path)
{ {
if (boost::filesystem::exists(path) && if (boost::filesystem::exists(path) &&
boost::filesystem::is_directory (boost::filesystem::status (path))) return true; boost::filesystem::is_directory (boost::filesystem::status (path))) return true;

View File

@@ -125,7 +125,7 @@ namespace garlic
m_LeaseSetUpdateMsgID = 0; m_LeaseSetUpdateMsgID = 0;
} }
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
} }
bool GarlicRoutingSession::CleanupUnconfirmedTags () bool GarlicRoutingSession::CleanupUnconfirmedTags ()
{ {
@@ -548,7 +548,7 @@ namespace garlic
case eGarlicDeliveryTypeDestination: case eGarlicDeliveryTypeDestination:
LogPrint (eLogDebug, "Garlic: type destination"); LogPrint (eLogDebug, "Garlic: type destination");
buf += 32; // destination. check it later or for multiple destinations buf += 32; // destination. check it later or for multiple destinations
offset = buf1 - buf; offset = buf - buf1;
if (offset > (int)len) if (offset > (int)len)
{ {
LogPrint (eLogError, "Garlic: message is too short"); LogPrint (eLogError, "Garlic: message is too short");
@@ -562,7 +562,7 @@ namespace garlic
// gwHash and gwTunnel sequence is reverted // gwHash and gwTunnel sequence is reverted
uint8_t * gwHash = buf; uint8_t * gwHash = buf;
buf += 32; buf += 32;
offset = buf1 - buf; offset = buf - buf1;
if (offset + 4 > (int)len) if (offset + 4 > (int)len)
{ {
LogPrint (eLogError, "Garlic: message is too short"); LogPrint (eLogError, "Garlic: message is too short");
@@ -591,7 +591,7 @@ namespace garlic
{ {
uint8_t * ident = buf; uint8_t * ident = buf;
buf += 32; buf += 32;
offset = buf1 - buf; offset = buf - buf1;
if (!from) // received directly if (!from) // received directly
{ {
if (offset > (int)len) if (offset > (int)len)
@@ -618,7 +618,7 @@ namespace garlic
buf += 4; // CloveID buf += 4; // CloveID
buf += 8; // Date buf += 8; // Date
buf += 3; // Certificate buf += 3; // Certificate
offset = buf1 - buf; offset = buf - buf1;
if (offset > (int)len) if (offset > (int)len)
{ {
LogPrint (eLogError, "Garlic: clove is too long"); LogPrint (eLogError, "Garlic: clove is too long");

View File

@@ -272,7 +272,7 @@ namespace http {
{ {
o << method << " " << uri << " " << version << CRLF; o << method << " " << uri << " " << version << CRLF;
for (auto & h : headers) for (auto & h : headers)
o << h.first << ": " << h.second << CRLF; o << h.first << ": " << h.second << CRLF;
o << CRLF; o << CRLF;
} }

View File

@@ -3,10 +3,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) #if defined(__FreeBSD__)
#include <endian.h>
#elif __FreeBSD__
#include <sys/endian.h> #include <sys/endian.h>
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#include <endian.h>
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
#include <libkern/OSByteOrder.h> #include <libkern/OSByteOrder.h>

View File

@@ -542,7 +542,7 @@ namespace data
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{ {
if (!m_Signer) if (!m_Signer)
CreateSigner(); CreateSigner();
m_Signer->Sign (buf, len, signature); m_Signer->Sign (buf, len, signature);
} }

View File

@@ -91,11 +91,11 @@ namespace data
size_t ToBuffer (uint8_t * buf, size_t len) const; size_t ToBuffer (uint8_t * buf, size_t len) const;
size_t FromBase64(const std::string& s); size_t FromBase64(const std::string& s);
std::string ToBase64 () const; std::string ToBase64 () const;
const Identity& GetStandardIdentity () const { return m_StandardIdentity; }; const Identity& GetStandardIdentity () const { return m_StandardIdentity; };
const IdentHash& GetIdentHash () const { return m_IdentHash; }; const IdentHash& GetIdentHash () const { return m_IdentHash; };
const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; }; const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; };
uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; }; uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; };
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const; std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const;
size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; };
size_t GetSigningPublicKeyLen () const; size_t GetSigningPublicKeyLen () const;
@@ -141,7 +141,7 @@ namespace data
const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
uint8_t * GetPadding(); uint8_t * GetPadding();
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
void Sign (const uint8_t * buf, int len, uint8_t * signature) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); }; size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };

View File

@@ -21,7 +21,7 @@ namespace data
ReadFromBuffer (); ReadFromBuffer ();
} }
void LeaseSet::Update (const uint8_t * buf, size_t len) void LeaseSet::Update (const uint8_t * buf, size_t len, bool verifySignature)
{ {
if (len > m_BufferLen) if (len > m_BufferLen)
{ {
@@ -31,7 +31,7 @@ namespace data
} }
memcpy (m_Buffer, buf, len); memcpy (m_Buffer, buf, len);
m_BufferLen = len; m_BufferLen = len;
ReadFromBuffer (false); ReadFromBuffer (false, verifySignature);
} }
void LeaseSet::PopulateLeases () void LeaseSet::PopulateLeases ()
@@ -40,7 +40,7 @@ namespace data
ReadFromBuffer (false); ReadFromBuffer (false);
} }
void LeaseSet::ReadFromBuffer (bool readIdentity) void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature)
{ {
if (readIdentity || !m_Identity) if (readIdentity || !m_Identity)
m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen); m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
@@ -128,7 +128,7 @@ namespace data
} }
// verify // verify
if (!m_Identity->Verify (m_Buffer, leases - m_Buffer, leases)) if (verifySignature && !m_Identity->Verify (m_Buffer, leases - m_Buffer, leases))
{ {
LogPrint (eLogWarning, "LeaseSet: verification failed"); LogPrint (eLogWarning, "LeaseSet: verification failed");
m_IsValid = false; m_IsValid = false;
@@ -194,12 +194,12 @@ namespace data
} }
bool LeaseSet::HasExpiredLeases () const bool LeaseSet::HasExpiredLeases () const
{ {
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();
for (const auto& it: m_Leases) for (const auto& it: m_Leases)
if (ts >= it->endDate) return true; if (ts >= it->endDate) return true;
return false; return false;
} }
bool LeaseSet::IsExpired () const bool LeaseSet::IsExpired () const
{ {
@@ -265,5 +265,39 @@ namespace data
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();
return ts > m_ExpirationTime; return ts > m_ExpirationTime;
} }
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires)
{
IdentityEx ident(ptr, sz);
size_t size = ident.GetFullLen ();
if (size > sz)
{
LogPrint (eLogError, "LeaseSet: identity length ", size, " exceeds buffer size ", sz);
return false;
}
// encryption key
size += 256;
// signing key (unused)
size += ident.GetSigningPublicKeyLen ();
uint8_t numLeases = ptr[size];
++size;
if (!numLeases || numLeases > MAX_NUM_LEASES)
{
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)numLeases);
return false;
}
const uint8_t * leases = ptr + size;
expires = 0;
/** find lease with the max expiration timestamp */
for (int i = 0; i < numLeases; i++)
{
leases += 36; // gateway + tunnel ID
uint64_t endDate = bufbe64toh (leases);
leases += 8; // end date
if(endDate > expires)
expires = endDate;
}
return ident.Verify(ptr, leases - ptr, leases);
}
} }
} }

View File

@@ -38,7 +38,7 @@ namespace data
struct LeaseCmp struct LeaseCmp
{ {
bool operator() (std::shared_ptr<const Lease> l1, std::shared_ptr<const Lease> l2) const bool operator() (std::shared_ptr<const Lease> l1, std::shared_ptr<const Lease> l2) const
{ {
if (l1->tunnelID != l2->tunnelID) if (l1->tunnelID != l2->tunnelID)
return l1->tunnelID < l2->tunnelID; return l1->tunnelID < l2->tunnelID;
else else
@@ -57,7 +57,7 @@ namespace data
LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true); LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true);
~LeaseSet () { delete[] m_Buffer; }; ~LeaseSet () { delete[] m_Buffer; };
void Update (const uint8_t * buf, size_t len); void Update (const uint8_t * buf, size_t len, bool verifySignature = true);
bool IsNewer (const uint8_t * buf, size_t len) const; bool IsNewer (const uint8_t * buf, size_t len) const;
void PopulateLeases (); // from buffer void PopulateLeases (); // from buffer
@@ -81,8 +81,8 @@ namespace data
private: private:
void ReadFromBuffer (bool readIdentity = true); void ReadFromBuffer (bool readIdentity = true, bool verifySignature = true);
uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // min expiration time uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time
private: private:
@@ -95,6 +95,12 @@ namespace data
size_t m_BufferLen; size_t m_BufferLen;
}; };
/**
validate lease set buffer signature and extract expiration timestamp
@returns true if the leaseset is well formed and signature is valid
*/
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
class LocalLeaseSet class LocalLeaseSet
{ {
public: public:

View File

@@ -237,22 +237,20 @@ namespace data
auto it = m_LeaseSets.find(ident); auto it = m_LeaseSets.find(ident);
if (it != m_LeaseSets.end ()) if (it != m_LeaseSets.end ())
{ {
if (it->second->IsNewer (buf, len)) uint64_t expires;
if(LeaseSetBufferValidate(buf, len, expires))
{ {
it->second->Update (buf, len); if(it->second->GetExpirationTime() < expires)
if (it->second->IsValid ())
{ {
it->second->Update (buf, len, false); // signature is verified already
LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32()); LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32());
updated = true; updated = true;
} }
else else
{ LogPrint(eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32());
LogPrint (eLogWarning, "NetDb: LeaseSet update failed: ", ident.ToBase32());
m_LeaseSets.erase (it);
}
} }
else else
LogPrint (eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32()); LogPrint(eLogError, "NetDb: LeaseSet is invalid: ", ident.ToBase32());
} }
else else
{ {
@@ -655,7 +653,7 @@ namespace data
std::set<IdentHash> excluded; std::set<IdentHash> excluded;
excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself
excluded.insert (ident); // don't flood back excluded.insert (ident); // don't flood back
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
auto floodfill = GetClosestFloodfill (ident, excluded); auto floodfill = GetClosestFloodfill (ident, excluded);
if (floodfill) if (floodfill)
@@ -783,7 +781,7 @@ namespace data
uint8_t flag = buf[64]; uint8_t flag = buf[64];
LogPrint (eLogDebug, "NetDb: DatabaseLookup for ", key, " recieved flags=", (int)flag); LogPrint (eLogDebug, "NetDb: DatabaseLookup for ", key, " received flags=", (int)flag);
uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK; uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK;
const uint8_t * excluded = buf + 65; const uint8_t * excluded = buf + 65;
uint32_t replyTunnelID = 0; uint32_t replyTunnelID = 0;
@@ -866,7 +864,7 @@ namespace data
if (closestFloodfills.empty ()) if (closestFloodfills.empty ())
LogPrint (eLogWarning, "NetDb: Requested ", key, " not found, ", numExcluded, " peers excluded"); LogPrint (eLogWarning, "NetDb: Requested ", key, " not found, ", numExcluded, " peers excluded");
replyMsg = CreateDatabaseSearchReply (ident, closestFloodfills); replyMsg = CreateDatabaseSearchReply (ident, closestFloodfills);
} }
} }
excluded += numExcluded * 32; excluded += numExcluded * 32;
if (replyMsg) if (replyMsg)

View File

@@ -320,7 +320,7 @@ namespace data
s.seekg (pos, std::ios::beg); // back to compressed data s.seekg (pos, std::ios::beg); // back to compressed data
} }
LogPrint (eLogDebug, "Reseed: Proccessing file ", localFileName, " ", compressedSize, " bytes"); LogPrint (eLogDebug, "Reseed: Processing file ", localFileName, " ", compressedSize, " bytes");
if (!compressedSize) if (!compressedSize)
{ {
LogPrint (eLogWarning, "Reseed: Unexpected size 0. Skipped"); LogPrint (eLogWarning, "Reseed: Unexpected size 0. Skipped");
@@ -522,7 +522,7 @@ namespace data
boost::asio::io_service service; boost::asio::io_service service;
boost::system::error_code ecode; boost::system::error_code ecode;
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23); boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.set_verify_mode(boost::asio::ssl::context::verify_none); ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx); boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);

View File

@@ -224,7 +224,7 @@ namespace data
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4; supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4;
else else
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6; supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6;
} }
} }
else if (!strcmp (key, "port")) else if (!strcmp (key, "port"))
address->port = boost::lexical_cast<int>(value); address->port = boost::lexical_cast<int>(value);

View File

@@ -181,8 +181,8 @@ namespace data
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
bool IsNewer (const uint8_t * buf, size_t len) const; bool IsNewer (const uint8_t * buf, size_t len) const;
/** return true if we are in a router family and the signature is valid */ /** return true if we are in a router family and the signature is valid */
bool IsFamily(const std::string & fam) const; bool IsFamily(const std::string & fam) const;
// implements RoutingDestination // implements RoutingDestination
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; }; std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };

View File

@@ -86,7 +86,7 @@ namespace transport
DeleteAllSessions (); DeleteAllSessions ();
m_IsRunning = false; m_IsRunning = false;
m_TerminationTimer.cancel (); m_TerminationTimer.cancel ();
m_TerminationTimerV6.cancel (); m_TerminationTimerV6.cancel ();
m_Service.stop (); m_Service.stop ();
m_Socket.close (); m_Socket.close ();
m_ServiceV6.stop (); m_ServiceV6.stop ();
@@ -357,7 +357,7 @@ namespace transport
{ {
if (!router) return nullptr; if (!router) return nullptr;
auto address = router->GetSSUAddress (true); // v4 only auto address = router->GetSSUAddress (true); // v4 only
if (!address) return nullptr; if (!address) return nullptr;
auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port)); auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
if (session || !context.SupportsV6 ()) if (session || !context.SupportsV6 ())
return session; return session;
@@ -747,7 +747,7 @@ namespace transport
{ {
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto& it: m_Sessions) for (auto& it: m_Sessions)
if (it.second->IsTerminationTimeoutExpired (ts)) if (it.second->IsTerminationTimeoutExpired (ts))
{ {
auto session = it.second; auto session = it.second;
m_Service.post ([session] m_Service.post ([session]
@@ -773,7 +773,7 @@ namespace transport
{ {
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto& it: m_SessionsV6) for (auto& it: m_SessionsV6)
if (it.second->IsTerminationTimeoutExpired (ts)) if (it.second->IsTerminationTimeoutExpired (ts))
{ {
auto session = it.second; auto session = it.second;
m_ServiceV6.post ([session] m_ServiceV6.post ([session]

View File

@@ -81,7 +81,7 @@ namespace transport
void SSUData::UpdatePacketSize (const i2p::data::IdentHash& remoteIdent) void SSUData::UpdatePacketSize (const i2p::data::IdentHash& remoteIdent)
{ {
auto routerInfo = i2p::data::netdb.FindRouter (remoteIdent); auto routerInfo = i2p::data::netdb.FindRouter (remoteIdent);
if (routerInfo) if (routerInfo)
AdjustPacketSize (routerInfo); AdjustPacketSize (routerInfo);
} }

View File

@@ -57,7 +57,7 @@ namespace transport
struct FragmentCmp struct FragmentCmp
{ {
bool operator() (const std::unique_ptr<Fragment>& f1, const std::unique_ptr<Fragment>& f2) const bool operator() (const std::unique_ptr<Fragment>& f1, const std::unique_ptr<Fragment>& f2) const
{ {
return f1->fragmentNum < f2->fragmentNum; return f1->fragmentNum < f2->fragmentNum;
}; };
}; };

View File

@@ -378,9 +378,15 @@ namespace stream
size_t Stream::Send (const uint8_t * buf, size_t len) size_t Stream::Send (const uint8_t * buf, size_t len)
{ {
// TODO: check max buffer size size_t sent = len;
while(len > MAX_PACKET_SIZE)
{
AsyncSend (buf, MAX_PACKET_SIZE, nullptr);
buf += MAX_PACKET_SIZE;
len -= MAX_PACKET_SIZE;
}
AsyncSend (buf, len, nullptr); AsyncSend (buf, len, nullptr);
return len; return sent;
} }
void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler) void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler)
@@ -572,7 +578,9 @@ namespace stream
if (m_SentPackets.empty () && m_SendBuffer.IsEmpty ()) // nothing to send if (m_SentPackets.empty () && m_SendBuffer.IsEmpty ()) // nothing to send
{ {
m_Status = eStreamStatusClosed; m_Status = eStreamStatusClosed;
SendClose (); // close could be called from another thread so do SendClose from the destination thread
// this is so m_LocalDestination.NewPacket () does not trigger a race condition
m_Service.post(std::bind(&Stream::SendClose, shared_from_this()));
} }
break; break;
case eStreamStatusClosed: case eStreamStatusClosed:
@@ -725,7 +733,7 @@ namespace stream
if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT) if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT)
{ {
// LeaseSet was not confirmed, should try other tunnels // LeaseSet was not confirmed, should try other tunnels
LogPrint (eLogWarning, "Streaming: LeaseSet was not confrimed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit"); LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit");
m_RoutingSession->SetSharedRoutingPath (nullptr); m_RoutingSession->SetSharedRoutingPath (nullptr);
m_CurrentOutboundTunnel = nullptr; m_CurrentOutboundTunnel = nullptr;
m_CurrentRemoteLease = nullptr; m_CurrentRemoteLease = nullptr;

View File

@@ -98,7 +98,7 @@ namespace stream
struct PacketCmp struct PacketCmp
{ {
bool operator() (const Packet * p1, const Packet * p2) const bool operator() (const Packet * p1, const Packet * p2) const
{ {
return p1->GetSeqn () < p2->GetSeqn (); return p1->GetSeqn () < p2->GetSeqn ();
}; };
}; };
@@ -276,10 +276,9 @@ namespace stream
/** set max connections per minute per destination */ /** set max connections per minute per destination */
void SetMaxConnsPerMinute(const uint32_t conns); void SetMaxConnsPerMinute(const uint32_t conns);
Packet * NewPacket () { return m_PacketsPool.Acquire (); } Packet * NewPacket () { return m_PacketsPool.Acquire(); }
void DeletePacket (Packet * p) { m_PacketsPool.Release (p); } void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); }
private:
void AcceptOnceAcceptor (std::shared_ptr<Stream> stream, Acceptor acceptor, Acceptor prev); void AcceptOnceAcceptor (std::shared_ptr<Stream> stream, Acceptor acceptor, Acceptor prev);
@@ -334,16 +333,21 @@ namespace stream
void Stream::AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout) void Stream::AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout)
{ {
auto s = shared_from_this(); auto s = shared_from_this();
m_Service.post ([=](void) m_Service.post ([s, buffer, handler, timeout](void)
{ {
if (!m_ReceiveQueue.empty () || m_Status == eStreamStatusReset) if (!s->m_ReceiveQueue.empty () || s->m_Status == eStreamStatusReset)
s->HandleReceiveTimer (boost::asio::error::make_error_code (boost::asio::error::operation_aborted), buffer, handler, 0); s->HandleReceiveTimer (boost::asio::error::make_error_code (boost::asio::error::operation_aborted), buffer, handler, 0);
else else
{ {
int t = (timeout > MAX_RECEIVE_TIMEOUT) ? MAX_RECEIVE_TIMEOUT : timeout; int t = (timeout > MAX_RECEIVE_TIMEOUT) ? MAX_RECEIVE_TIMEOUT : timeout;
s->m_ReceiveTimer.expires_from_now (boost::posix_time::seconds(t)); s->m_ReceiveTimer.expires_from_now (boost::posix_time::seconds(t));
s->m_ReceiveTimer.async_wait ([=](const boost::system::error_code& ecode) int left = timeout - t;
{ s->HandleReceiveTimer (ecode, buffer, handler, timeout - t); }); auto self = s->shared_from_this();
self->m_ReceiveTimer.async_wait (
[self, buffer, handler, left](const boost::system::error_code & ec)
{
self->HandleReceiveTimer(ec, buffer, handler, left);
});
} }
}); });
} }

View File

@@ -11,19 +11,19 @@ namespace util
inline uint64_t GetMillisecondsSinceEpoch () inline uint64_t GetMillisecondsSinceEpoch ()
{ {
return std::chrono::duration_cast<std::chrono::milliseconds>( return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count (); std::chrono::system_clock::now().time_since_epoch()).count ();
} }
inline uint32_t GetHoursSinceEpoch () inline uint32_t GetHoursSinceEpoch ()
{ {
return std::chrono::duration_cast<std::chrono::hours>( return std::chrono::duration_cast<std::chrono::hours>(
std::chrono::system_clock::now().time_since_epoch()).count (); std::chrono::system_clock::now().time_since_epoch()).count ();
} }
inline uint64_t GetSecondsSinceEpoch () inline uint64_t GetSecondsSinceEpoch ()
{ {
return std::chrono::duration_cast<std::chrono::seconds>( return std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()).count (); std::chrono::system_clock::now().time_since_epoch()).count ();
} }
} }
} }

View File

@@ -20,8 +20,8 @@ namespace tunnel
public: public:
TransitTunnel (uint32_t receiveTunnelID, TransitTunnel (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey); const uint8_t * layerKey,const uint8_t * ivKey);
virtual size_t GetNumTransmittedBytes () const { return 0; }; virtual size_t GetNumTransmittedBytes () const { return 0; };
@@ -39,8 +39,8 @@ namespace tunnel
public: public:
TransitTunnelParticipant (uint32_t receiveTunnelID, TransitTunnelParticipant (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey): const uint8_t * layerKey,const uint8_t * ivKey):
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
layerKey, ivKey), m_NumTransmittedBytes (0) {}; layerKey, ivKey), m_NumTransmittedBytes (0) {};
~TransitTunnelParticipant (); ~TransitTunnelParticipant ();
@@ -60,8 +60,8 @@ namespace tunnel
public: public:
TransitTunnelGateway (uint32_t receiveTunnelID, TransitTunnelGateway (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey): const uint8_t * layerKey,const uint8_t * ivKey):
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
layerKey, ivKey), m_Gateway(this) {}; layerKey, ivKey), m_Gateway(this) {};
@@ -80,8 +80,8 @@ namespace tunnel
public: public:
TransitTunnelEndpoint (uint32_t receiveTunnelID, TransitTunnelEndpoint (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey): const uint8_t * layerKey,const uint8_t * ivKey):
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey),
m_Endpoint (false) {}; // transit endpoint is always outbound m_Endpoint (false) {}; // transit endpoint is always outbound
@@ -97,7 +97,7 @@ namespace tunnel
std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID, std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey, const uint8_t * layerKey,const uint8_t * ivKey,
bool isGateway, bool isEndpoint); bool isGateway, bool isEndpoint);
} }
} }

View File

@@ -63,7 +63,7 @@ namespace transport
else else
{ {
std::unique_lock<std::mutex> l(m_AcquiredMutex); std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Acquired.wait (l); // wait for element gets aquired m_Acquired.wait (l); // wait for element gets acquired
} }
} }
} }
@@ -119,7 +119,7 @@ namespace transport
m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0),
m_LastTransitBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) m_LastTransitBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0)
{ {
@@ -144,7 +144,7 @@ namespace transport
m_Service = new boost::asio::io_service (); m_Service = new boost::asio::io_service ();
m_Work = new boost::asio::io_service::work (*m_Service); m_Work = new boost::asio::io_service::work (*m_Service);
m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service); m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service);
m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service); m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service);
} }
i2p::config::GetOption("nat", m_IsNAT); i2p::config::GetOption("nat", m_IsNAT);
@@ -623,7 +623,7 @@ namespace transport
void Transports::DetectExternalIP () void Transports::DetectExternalIP ()
{ {
if (RoutesRestricted()) if (RoutesRestricted())
{ {
LogPrint(eLogInfo, "Transports: restricted routes enabled, not detecting ip"); LogPrint(eLogInfo, "Transports: restricted routes enabled, not detecting ip");
i2p::context.SetStatus (eRouterStatusOK); i2p::context.SetStatus (eRouterStatusOK);
return; return;

View File

@@ -136,10 +136,10 @@ namespace transport
void NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident); void NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident);
void HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, void HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver); i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
void SSUResolve (const std::string& addr, const i2p::data::IdentHash& ident); void SSUResolve (const std::string& addr, const i2p::data::IdentHash& ident);
void HandleSSUResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, void HandleSSUResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver); i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
void UpdateBandwidth (); void UpdateBandwidth ();
void DetectExternalIP (); void DetectExternalIP ();

View File

@@ -60,7 +60,7 @@ namespace tunnel
struct TunnelCreationTimeCmp struct TunnelCreationTimeCmp
{ {
bool operator() (std::shared_ptr<const TunnelBase> t1, std::shared_ptr<const TunnelBase> t2) const bool operator() (std::shared_ptr<const TunnelBase> t1, std::shared_ptr<const TunnelBase> t2) const
{ {
if (t1->GetCreationTime () != t2->GetCreationTime ()) if (t1->GetCreationTime () != t2->GetCreationTime ())
return t1->GetCreationTime () > t2->GetCreationTime (); return t1->GetCreationTime () > t2->GetCreationTime ();
else else

View File

@@ -54,7 +54,7 @@ namespace tunnel
{ {
case eDeliveryTypeLocal: // 0 case eDeliveryTypeLocal: // 0
break; break;
case eDeliveryTypeTunnel: // 1 case eDeliveryTypeTunnel: // 1
m.tunnelID = bufbe32toh (fragment); m.tunnelID = bufbe32toh (fragment);
fragment += 4; // tunnelID fragment += 4; // tunnelID
m.hash = i2p::data::IdentHash (fragment); m.hash = i2p::data::IdentHash (fragment);

View File

@@ -298,13 +298,13 @@ namespace tunnel
} }
if (!failed) if (!failed)
{ {
uint32_t msgID; uint32_t msgID;
RAND_bytes ((uint8_t *)&msgID, 4); RAND_bytes ((uint8_t *)&msgID, 4);
{ {
std::unique_lock<std::mutex> l(m_TestsMutex); std::unique_lock<std::mutex> l(m_TestsMutex);
m_Tests[msgID] = std::make_pair (*it1, *it2); m_Tests[msgID] = std::make_pair (*it1, *it2);
} }
(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
CreateDeliveryStatusMsg (msgID)); CreateDeliveryStatusMsg (msgID));
++it1; ++it2; ++it1; ++it2;
} }

View File

@@ -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 17 #define I2PD_VERSION_MINOR 18
#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 32 #define I2P_VERSION_MICRO 33
#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)

View File

@@ -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;
@@ -692,7 +696,7 @@ namespace client
std::unique_lock<std::mutex> l(newDataReceivedMutex); std::unique_lock<std::mutex> l(newDataReceivedMutex);
i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident, i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident,
[&newDataReceived, &leaseSet, &newDataReceivedMutex](std::shared_ptr<i2p::data::LeaseSet> ls) [&newDataReceived, &leaseSet, &newDataReceivedMutex](std::shared_ptr<i2p::data::LeaseSet> ls)
{ {
leaseSet = ls; leaseSet = ls;
std::unique_lock<std::mutex> l1(newDataReceivedMutex); std::unique_lock<std::mutex> l1(newDataReceivedMutex);
newDataReceived.notify_all (); newDataReceived.notify_all ();
@@ -720,7 +724,7 @@ namespace client
i2p::http::HTTPReq req; i2p::http::HTTPReq req;
req.AddHeader("Host", dest_host); req.AddHeader("Host", dest_host);
req.AddHeader("User-Agent", "Wget/1.11.4"); req.AddHeader("User-Agent", "Wget/1.11.4");
req.AddHeader("X-Accept-Encoding", "x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n"); req.AddHeader("X-Accept-Encoding", "x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0");
req.AddHeader("Connection", "close"); req.AddHeader("Connection", "close");
if (!m_Etag.empty()) if (!m_Etag.empty())
req.AddHeader("If-None-Match", m_Etag); req.AddHeader("If-None-Match", m_Etag);
@@ -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)
{ {

View File

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

View File

@@ -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, &params);
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, &params);
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 ();
@@ -158,7 +89,7 @@ namespace client
try try
{ {
m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort);
m_I2CPServer->Start (); m_I2CPServer->Start ();
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@@ -235,7 +166,7 @@ namespace client
LogPrint(eLogInfo, "Clients: stopping AddressBook"); LogPrint(eLogInfo, "Clients: stopping AddressBook");
m_AddressBook.Stop (); m_AddressBook.Stop ();
{ {
std::lock_guard<std::mutex> lock(m_ForwardsMutex); std::lock_guard<std::mutex> lock(m_ForwardsMutex);
m_ServerForwards.clear(); m_ServerForwards.clear();
m_ClientForwards.clear(); m_ClientForwards.clear();
@@ -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 ();)
@@ -350,7 +301,7 @@ namespace client
} }
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic, std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic,
i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType, i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType,
const std::map<std::string, std::string> * params) const std::map<std::string, std::string> * params)
{ {
i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType);
@@ -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);
@@ -495,7 +454,7 @@ namespace client
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT); int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
// optional params // optional params
bool matchTunnels = section.second.get(I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false); bool matchTunnels = section.second.get(I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false);
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "transient");
std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
@@ -653,11 +612,11 @@ namespace client
I2PServerTunnel * serverTunnel; I2PServerTunnel * serverTunnel;
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP) if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
serverTunnel = new I2PServerTunnelHTTP (name, host, port, localDestination, hostOverride, inPort, gzip); serverTunnel = new I2PServerTunnelHTTP (name, host, port, localDestination, hostOverride, inPort, gzip);
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC) else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
serverTunnel = new I2PServerTunnelIRC (name, host, port, localDestination, webircpass, inPort, gzip); serverTunnel = new I2PServerTunnelIRC (name, host, port, localDestination, webircpass, inPort, gzip);
else // regular server tunnel by default else // regular server tunnel by default
serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip); serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip);
LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns); LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns);
serverTunnel->SetMaxConnsPerMinute(maxConns); serverTunnel->SetMaxConnsPerMinute(maxConns);
@@ -665,7 +624,7 @@ namespace client
{ {
LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
serverTunnel->SetUniqueLocal(isUniqueLocal); serverTunnel->SetUniqueLocal(isUniqueLocal);
} }
if (accessList.length () > 0) if (accessList.length () > 0)
{ {
@@ -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, &params);
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, &params);
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)

View File

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

View File

@@ -280,7 +280,7 @@ namespace client
buf[I2CP_HEADER_TYPE_OFFSET] = type; buf[I2CP_HEADER_TYPE_OFFSET] = type;
memcpy (buf + I2CP_HEADER_SIZE, payload, len); memcpy (buf + I2CP_HEADER_SIZE, payload, len);
boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, buf)); std::placeholders::_1, std::placeholders::_2, buf));
} }
else else
@@ -480,14 +480,14 @@ namespace client
offset += 4; offset += 4;
uint32_t nonce = bufbe32toh (buf + offset + payloadLen); uint32_t nonce = bufbe32toh (buf + offset + payloadLen);
if (m_IsSendAccepted) if (m_IsSendAccepted)
SendMessageStatusMessage (nonce, eI2CPMessageStatusAccepted); // accepted SendMessageStatusMessage (nonce, eI2CPMessageStatusAccepted); // accepted
m_Destination->SendMsgTo (buf + offset, payloadLen, identity.GetIdentHash (), nonce); m_Destination->SendMsgTo (buf + offset, payloadLen, identity.GetIdentHash (), nonce);
} }
else else
LogPrint(eLogError, "I2CP: cannot send message, too big"); LogPrint(eLogError, "I2CP: cannot send message, too big");
} }
else else
LogPrint(eLogError, "I2CP: invalid identity"); LogPrint(eLogError, "I2CP: invalid identity");
} }
} }
else else
@@ -634,7 +634,7 @@ namespace client
htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); htobe32buf (buf + I2CP_HEADER_SIZE + 6, len);
memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len);
boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, buf)); std::placeholders::_1, std::placeholders::_2, buf));
} }

View File

@@ -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 ();
} }

View File

@@ -14,7 +14,7 @@ namespace i2p
namespace client namespace client
{ {
class I2PServiceHandler; class I2PServiceHandler;
class I2PService : std::enable_shared_from_this<I2PService> class I2PService : public std::enable_shared_from_this<I2PService>
{ {
public: public:
typedef std::function<void(const boost::system::error_code &)> ReadyCallback; typedef std::function<void(const boost::system::error_code &)> ReadyCallback;

View File

@@ -93,7 +93,7 @@ namespace client
MapToLoopback(m_Socket, ident); MapToLoopback(m_Socket, ident);
} }
#endif #endif
m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect, m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect,
shared_from_this (), std::placeholders::_1)); shared_from_this (), std::placeholders::_1));
} }
} }
@@ -844,7 +844,7 @@ namespace client
LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort);
} }
else else
LogPrint(eLogWarning, "UDP Client: unwarrented traffic from ", from.GetIdentHash().ToBase32()); LogPrint(eLogWarning, "UDP Client: unwarranted traffic from ", from.GetIdentHash().ToBase32());
} }
I2PUDPClientTunnel::~I2PUDPClientTunnel() { I2PUDPClientTunnel::~I2PUDPClientTunnel() {

View File

@@ -15,31 +15,22 @@ namespace i2p
{ {
namespace client namespace client
{ {
SAMSocket::SAMSocket (SAMBridge& owner): SAMSocket::SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> socket):
m_Owner (owner), m_Socket (m_Owner.GetService ()), m_Timer (m_Owner.GetService ()), m_Owner (owner), m_Socket(socket), m_Timer (m_Owner.GetService ()),
m_BufferOffset (0), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false), m_BufferOffset (0),
m_IsAccepting (false), m_Stream (nullptr), m_Session (nullptr) m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false),
m_IsAccepting (false), m_Stream (nullptr)
{ {
} }
SAMSocket::~SAMSocket () SAMSocket::~SAMSocket ()
{ {
Terminate ("~SAMSocket()"); if(m_Stream)
}
void SAMSocket::CloseStream (const char* reason)
{
LogPrint (eLogDebug, "SAMSocket::CloseStream, reason: ", reason);
if (m_Stream)
{ {
m_Stream->Close (); m_Stream->Close ();
m_Stream.reset (); m_Stream.reset ();
} }
} auto Session = m_Owner.FindSession(m_ID);
void SAMSocket::Terminate (const char* reason)
{
CloseStream (reason);
switch (m_SocketType) switch (m_SocketType)
{ {
@@ -48,17 +39,17 @@ namespace client
break; break;
case eSAMSocketTypeStream: case eSAMSocketTypeStream:
{ {
if (m_Session) if (Session)
m_Session->DelSocket (shared_from_this ()); Session->DelSocket (this);
break; break;
} }
case eSAMSocketTypeAcceptor: case eSAMSocketTypeAcceptor:
{ {
if (m_Session) if (Session)
{ {
m_Session->DelSocket (shared_from_this ()); Session->DelSocket (this);
if (m_IsAccepting && m_Session->localDestination) if (m_IsAccepting && Session->localDestination)
m_Session->localDestination->StopAcceptingStreams (); Session->localDestination->StopAcceptingStreams ();
} }
break; break;
} }
@@ -66,15 +57,54 @@ namespace client
; ;
} }
m_SocketType = eSAMSocketTypeTerminated; m_SocketType = eSAMSocketTypeTerminated;
if (m_Socket.is_open()) m_Socket.close (); if (m_Socket && m_Socket->is_open()) m_Socket->close ();
m_Session = nullptr; m_Socket.reset ();
}
void SAMSocket::Terminate (const char* reason)
{
if(m_Stream)
{
m_Stream->Close ();
m_Stream.reset ();
}
auto Session = m_Owner.FindSession(m_ID);
switch (m_SocketType)
{
case eSAMSocketTypeSession:
m_Owner.CloseSession (m_ID);
break;
case eSAMSocketTypeStream:
{
if (Session)
Session->DelSocket (this);
break;
}
case eSAMSocketTypeAcceptor:
{
if (Session)
{
Session->DelSocket (this);
if (m_IsAccepting && Session->localDestination)
Session->localDestination->StopAcceptingStreams ();
}
break;
}
default:
;
}
m_SocketType = eSAMSocketTypeTerminated;
if (m_Socket && m_Socket->is_open()) m_Socket->close ();
m_Socket.reset ();
} }
void SAMSocket::ReceiveHandshake () void SAMSocket::ReceiveHandshake ()
{ {
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE), if(m_Socket)
std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (), m_Socket->async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
std::placeholders::_1, std::placeholders::_2)); std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
} }
void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@@ -121,7 +151,7 @@ namespace client
#else #else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#endif #endif
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (), boost::asio::async_write (*m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
@@ -144,9 +174,9 @@ namespace client
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: handshake reply send error"); Terminate ("SAM: handshake reply send error");
} }
else else if(m_Socket)
{ {
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE), m_Socket->async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
std::bind(&SAMSocket::HandleMessage, shared_from_this (), std::bind(&SAMSocket::HandleMessage, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
@@ -157,7 +187,7 @@ namespace client
LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg); LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg);
if (!m_IsSilent) if (!m_IsSilent)
boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (), boost::asio::async_write (*m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (), std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, close)); std::placeholders::_1, std::placeholders::_2, close));
else else
@@ -306,19 +336,19 @@ namespace client
} }
// create destination // create destination
m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params); auto session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params);
if (m_Session) if (session)
{ {
m_SocketType = eSAMSocketTypeSession; m_SocketType = eSAMSocketTypeSession;
if (style == SAM_VALUE_DATAGRAM) if (style == SAM_VALUE_DATAGRAM)
{ {
m_Session->UDPEndpoint = forward; session->UDPEndpoint = forward;
auto dest = m_Session->localDestination->CreateDatagramDestination (); auto dest = session->localDestination->CreateDatagramDestination ();
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
} }
if (m_Session->localDestination->IsReady ()) if (session->localDestination->IsReady ())
SendSessionCreateReplyOk (); SendSessionCreateReplyOk ();
else else
{ {
@@ -335,30 +365,38 @@ namespace client
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
{ {
if (m_Session->localDestination->IsReady ()) auto session = m_Owner.FindSession(m_ID);
SendSessionCreateReplyOk (); if(session)
else
{ {
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL)); if (session->localDestination->IsReady ())
m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer, SendSessionCreateReplyOk ();
shared_from_this (), std::placeholders::_1)); else
{
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
shared_from_this (), std::placeholders::_1));
}
} }
} }
} }
void SAMSocket::SendSessionCreateReplyOk () void SAMSocket::SendSessionCreateReplyOk ()
{ {
uint8_t buf[1024]; auto session = m_Owner.FindSession(m_ID);
char priv[1024]; if (session)
size_t l = m_Session->localDestination->GetPrivateKeys ().ToBuffer (buf, 1024); {
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024); uint8_t buf[1024];
priv[l1] = 0; char priv[1024];
size_t l = session->localDestination->GetPrivateKeys ().ToBuffer (buf, 1024);
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024);
priv[l1] = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
size_t l2 = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv); size_t l2 = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv);
#else #else
size_t l2 = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv); size_t l2 = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv);
#endif #endif
SendMessageReply (m_Buffer, l2, false); SendMessageReply (m_Buffer, l2, false);
}
} }
void SAMSocket::ProcessStreamConnect (char * buf, size_t len, size_t rem) void SAMSocket::ProcessStreamConnect (char * buf, size_t len, size_t rem)
@@ -371,8 +409,8 @@ namespace client
std::string& silent = params[SAM_PARAM_SILENT]; std::string& silent = params[SAM_PARAM_SILENT];
if (silent == SAM_VALUE_TRUE) m_IsSilent = true; if (silent == SAM_VALUE_TRUE) m_IsSilent = true;
m_ID = id; m_ID = id;
m_Session = m_Owner.FindSession (id); auto session = m_Owner.FindSession (id);
if (m_Session) if (session)
{ {
if (rem > 0) // handle follow on data if (rem > 0) // handle follow on data
{ {
@@ -387,12 +425,12 @@ namespace client
if (l > 0) if (l > 0)
{ {
context.GetAddressBook().InsertAddress(dest); context.GetAddressBook().InsertAddress(dest);
auto leaseSet = m_Session->localDestination->FindLeaseSet(dest->GetIdentHash()); auto leaseSet = session->localDestination->FindLeaseSet(dest->GetIdentHash());
if (leaseSet) if (leaseSet)
Connect(leaseSet); Connect(leaseSet);
else else
{ {
m_Session->localDestination->RequestDestination(dest->GetIdentHash(), session->localDestination->RequestDestination(dest->GetIdentHash(),
std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete,
shared_from_this(), std::placeholders::_1)); shared_from_this(), std::placeholders::_1));
} }
@@ -406,13 +444,17 @@ namespace client
void SAMSocket::Connect (std::shared_ptr<const i2p::data::LeaseSet> remote) void SAMSocket::Connect (std::shared_ptr<const i2p::data::LeaseSet> remote)
{ {
m_SocketType = eSAMSocketTypeStream; auto session = m_Owner.FindSession(m_ID);
m_Session->AddSocket (shared_from_this ()); if(session)
m_Stream = m_Session->localDestination->CreateStream (remote); {
m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send m_SocketType = eSAMSocketTypeStream;
m_BufferOffset = 0; session->AddSocket (shared_from_this ());
I2PReceive (); m_Stream = session->localDestination->CreateStream (remote);
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send
m_BufferOffset = 0;
I2PReceive ();
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
}
} }
void SAMSocket::HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet) void SAMSocket::HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet)
@@ -435,15 +477,15 @@ namespace client
std::string& silent = params[SAM_PARAM_SILENT]; std::string& silent = params[SAM_PARAM_SILENT];
if (silent == SAM_VALUE_TRUE) m_IsSilent = true; if (silent == SAM_VALUE_TRUE) m_IsSilent = true;
m_ID = id; m_ID = id;
m_Session = m_Owner.FindSession (id); auto session = m_Owner.FindSession (id);
if (m_Session) if (session)
{ {
m_SocketType = eSAMSocketTypeAcceptor; m_SocketType = eSAMSocketTypeAcceptor;
m_Session->AddSocket (shared_from_this ()); session->AddSocket (shared_from_this ());
if (!m_Session->localDestination->IsAcceptingStreams ()) if (!session->localDestination->IsAcceptingStreams ())
{ {
m_IsAccepting = true; m_IsAccepting = true;
m_Session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
} }
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
} }
@@ -459,9 +501,10 @@ namespace client
size_t size = std::stoi(params[SAM_PARAM_SIZE]), offset = data - buf; size_t size = std::stoi(params[SAM_PARAM_SIZE]), offset = data - buf;
if (offset + size <= len) if (offset + size <= len)
{ {
if (m_Session) auto session = m_Owner.FindSession(m_ID);
if (session)
{ {
auto d = m_Session->localDestination->GetDatagramDestination (); auto d = session->localDestination->GetDatagramDestination ();
if (d) if (d)
{ {
i2p::data::IdentityEx dest; i2p::data::IdentityEx dest;
@@ -516,7 +559,8 @@ namespace client
std::string& name = params[SAM_PARAM_NAME]; std::string& name = params[SAM_PARAM_NAME];
std::shared_ptr<const i2p::data::IdentityEx> identity; std::shared_ptr<const i2p::data::IdentityEx> identity;
i2p::data::IdentHash ident; i2p::data::IdentHash ident;
auto dest = m_Session == nullptr ? context.GetSharedLocalDestination() : m_Session->localDestination; auto session = m_Owner.FindSession(m_ID);
auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->localDestination;
if (name == "ME") if (name == "ME")
SendNamingLookupReply (dest->GetIdentity ()); SendNamingLookupReply (dest->GetIdentity ());
else if ((identity = context.GetAddressBook ().GetAddress (name)) != nullptr) else if ((identity = context.GetAddressBook ().GetAddress (name)) != nullptr)
@@ -612,16 +656,18 @@ namespace client
LogPrint (eLogError, "SAM: Buffer is full, terminate"); LogPrint (eLogError, "SAM: Buffer is full, terminate");
Terminate ("Buffer is full"); Terminate ("Buffer is full");
return; return;
} } else if (m_Socket)
m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset), m_Socket->async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage, std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage,
shared_from_this (), std::placeholders::_1, std::placeholders::_2)); shared_from_this (), std::placeholders::_1, std::placeholders::_2));
else
LogPrint(eLogError, "SAM: receive with no native socket");
} }
void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{ {
if (ecode) if (ecode)
{ {
LogPrint (eLogError, "SAM: read error: ", ecode.message ()); LogPrint (eLogError, "SAM: read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
Terminate ("read error"); Terminate ("read error");
@@ -637,7 +683,7 @@ namespace client
[s](const boost::system::error_code& ecode) [s](const boost::system::error_code& ecode)
{ {
if (!ecode) if (!ecode)
s->Receive (); s->m_Owner.GetService ().post ([s] { s->Receive (); });
else else
s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); }); s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); });
}); });
@@ -650,21 +696,21 @@ namespace client
if (m_Stream) if (m_Stream)
{ {
if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew || if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew ||
m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular
{ {
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE), m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE),
std::bind (&SAMSocket::HandleI2PReceive, shared_from_this (), std::bind (&SAMSocket::HandleI2PReceive, shared_from_this(),
std::placeholders::_1, std::placeholders::_2), std::placeholders::_1, std::placeholders::_2),
SAM_SOCKET_CONNECTION_MAX_IDLE); SAM_SOCKET_CONNECTION_MAX_IDLE);
} }
else // closed by peer else // closed by peer
{ {
uint8_t * buff = new uint8_t[SAM_SOCKET_BUFFER_SIZE];
// get remaning data // get remaning data
auto len = m_Stream->ReadSome (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE); auto len = m_Stream->ReadSome (buff, SAM_SOCKET_BUFFER_SIZE);
if (len > 0) // still some data if (len > 0) // still some data
{ {
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len), WriteI2PDataImmediate(buff, len);
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1));
} }
else // no more data else // no more data
Terminate ("no more data"); Terminate ("no more data");
@@ -672,6 +718,30 @@ namespace client
} }
} }
void SAMSocket::WriteI2PDataImmediate(uint8_t * buff, size_t sz)
{
if(m_Socket)
boost::asio::async_write (
*m_Socket,
boost::asio::buffer (buff, sz),
boost::asio::transfer_all(),
std::bind (&SAMSocket::HandleWriteI2PDataImmediate, shared_from_this (), std::placeholders::_1, buff)); // postpone termination
else
LogPrint(eLogError, "SAM: no native socket");
}
void SAMSocket::HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff)
{
delete [] buff;
}
void SAMSocket::WriteI2PData(size_t sz)
{
uint8_t * sendbuff = new uint8_t[sz];
memcpy(sendbuff, m_StreamBuffer, sz);
WriteI2PDataImmediate(sendbuff, sz);
}
void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{ {
if (ecode) if (ecode)
@@ -680,8 +750,9 @@ namespace client
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
{ {
if (bytes_transferred > 0) if (bytes_transferred > 0)
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), {
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); // postpone termination WriteI2PData(bytes_transferred);
}
else else
{ {
auto s = shared_from_this (); auto s = shared_from_this ();
@@ -696,13 +767,18 @@ namespace client
} }
else else
{ {
if (m_SocketType != eSAMSocketTypeTerminated) // check for possible race condition with Terminate() if (m_SocketType != eSAMSocketTypeTerminated)
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), {
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); if (bytes_transferred > 0)
{
WriteI2PData(bytes_transferred);
}
I2PReceive();
}
} }
} }
void SAMSocket::HandleWriteI2PData (const boost::system::error_code& ecode) void SAMSocket::HandleWriteI2PData (const boost::system::error_code& ecode, size_t bytes_transferred)
{ {
if (ecode) if (ecode)
{ {
@@ -711,7 +787,9 @@ namespace client
Terminate ("socket write error at HandleWriteI2PData"); Terminate ("socket write error at HandleWriteI2PData");
} }
else else
{
I2PReceive (); I2PReceive ();
}
} }
void SAMSocket::HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream) void SAMSocket::HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream)
@@ -760,39 +838,42 @@ namespace client
{ {
LogPrint (eLogDebug, "SAM: datagram received ", len); LogPrint (eLogDebug, "SAM: datagram received ", len);
auto base64 = from.ToBase64 (); auto base64 = from.ToBase64 ();
auto ep = m_Session->UDPEndpoint; auto session = m_Owner.FindSession(m_ID);
if (ep) if(session)
{ {
// udp forward enabled auto ep = session->UDPEndpoint;
size_t bsz = base64.size(); if (ep)
size_t sz = bsz + 1 + len;
// build datagram body
uint8_t * data = new uint8_t[sz];
// Destination
memcpy(data, base64.c_str(), bsz);
// linefeed
data[bsz] = '\n';
// Payload
memcpy(data+bsz+1, buf, len);
// send to remote endpoint
m_Owner.SendTo(data, sz, ep);
delete [] data;
}
else
{
#ifdef _MSC_VER
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#else
size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#endif
if (len < SAM_SOCKET_BUFFER_SIZE - l)
{ {
memcpy (m_StreamBuffer + l, buf, len); // udp forward enabled
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len + l), size_t bsz = base64.size();
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); size_t sz = bsz + 1 + len;
// build datagram body
uint8_t * data = new uint8_t[sz];
// Destination
memcpy(data, base64.c_str(), bsz);
// linefeed
data[bsz] = '\n';
// Payload
memcpy(data+bsz+1, buf, len);
// send to remote endpoint
m_Owner.SendTo(data, sz, ep);
delete [] data;
} }
else else
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer"); {
#ifdef _MSC_VER
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#else
size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#endif
if (len < SAM_SOCKET_BUFFER_SIZE - l)
{
memcpy (m_StreamBuffer + l, buf, len);
WriteI2PData(len + l);
}
else
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer");
}
} }
} }
@@ -875,8 +956,9 @@ namespace client
void SAMBridge::Accept () void SAMBridge::Accept ()
{ {
auto newSocket = std::make_shared<SAMSocket> (*this); auto native = std::make_shared<boost::asio::ip::tcp::socket>(m_Service);
m_Acceptor.async_accept (newSocket->GetSocket (), std::bind (&SAMBridge::HandleAccept, this, auto newSocket = std::make_shared<SAMSocket> (*this, native);
m_Acceptor.async_accept (*native, std::bind (&SAMBridge::HandleAccept, this,
std::placeholders::_1, newSocket)); std::placeholders::_1, newSocket));
} }

View File

@@ -79,18 +79,18 @@ namespace client
{ {
public: public:
SAMSocket (SAMBridge& owner); typedef boost::asio::ip::tcp::socket Socket_t;
SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> socket);
~SAMSocket (); ~SAMSocket ();
void CloseStream (const char* reason); // TODO: implement it better
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; boost::asio::ip::tcp::socket& GetSocket () { return *m_Socket; };
void ReceiveHandshake (); void ReceiveHandshake ();
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; }; void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
SAMSocketType GetSocketType () const { return m_SocketType; }; SAMSocketType GetSocketType () const { return m_SocketType; };
void Terminate (const char* reason); void Terminate (const char* reason);
private: private:
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
@@ -103,7 +103,7 @@ namespace client
void I2PReceive (); void I2PReceive ();
void HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream); void HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream);
void HandleWriteI2PData (const boost::system::error_code& ecode); void HandleWriteI2PData (const boost::system::error_code& ecode, size_t sz);
void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
void ProcessSessionCreate (char * buf, size_t len); void ProcessSessionCreate (char * buf, size_t len);
@@ -122,10 +122,14 @@ namespace client
void HandleSessionReadinessCheckTimer (const boost::system::error_code& ecode); void HandleSessionReadinessCheckTimer (const boost::system::error_code& ecode);
void SendSessionCreateReplyOk (); void SendSessionCreateReplyOk ();
void WriteI2PData(size_t sz);
void WriteI2PDataImmediate(uint8_t * ptr, size_t sz);
void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff);
private: private:
SAMBridge& m_Owner; SAMBridge& m_Owner;
boost::asio::ip::tcp::socket m_Socket; std::shared_ptr<Socket_t> m_Socket;
boost::asio::deadline_timer m_Timer; boost::asio::deadline_timer m_Timer;
char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1]; char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1];
size_t m_BufferOffset; size_t m_BufferOffset;
@@ -135,7 +139,6 @@ namespace client
bool m_IsSilent; bool m_IsSilent;
bool m_IsAccepting; // for eSAMSocketTypeAcceptor only bool m_IsAccepting; // for eSAMSocketTypeAcceptor only
std::shared_ptr<i2p::stream::Stream> m_Stream; std::shared_ptr<i2p::stream::Stream> m_Stream;
std::shared_ptr<SAMSession> m_Session;
}; };
struct SAMSession struct SAMSession
@@ -146,15 +149,15 @@ namespace client
std::mutex m_SocketsMutex; std::mutex m_SocketsMutex;
/** safely add a socket to this session */ /** safely add a socket to this session */
void AddSocket(const std::shared_ptr<SAMSocket> & sock) { void AddSocket(std::shared_ptr<SAMSocket> sock) {
std::lock_guard<std::mutex> lock(m_SocketsMutex); std::lock_guard<std::mutex> lock(m_SocketsMutex);
m_Sockets.push_back(sock); m_Sockets.push_back(sock);
} }
/** safely remove a socket from this session */ /** safely remove a socket from this session */
void DelSocket(const std::shared_ptr<SAMSocket> & sock) { void DelSocket(SAMSocket * sock) {
std::lock_guard<std::mutex> lock(m_SocketsMutex); std::lock_guard<std::mutex> lock(m_SocketsMutex);
m_Sockets.remove(sock); m_Sockets.remove_if([sock](const std::shared_ptr<SAMSocket> s) -> bool { return s.get() == sock; });
} }
/** get a list holding a copy of all sam sockets from this session */ /** get a list holding a copy of all sam sockets from this session */

View File

@@ -554,7 +554,7 @@ namespace proxy
void SOCKSHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len) void SOCKSHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
{ {
LogPrint(eLogDebug, "SOCKS: recieved ", len, " bytes"); LogPrint(eLogDebug, "SOCKS: received ", len, " bytes");
if(ecode) if(ecode)
{ {
LogPrint(eLogWarning, "SOCKS: recv got error: ", ecode); LogPrint(eLogWarning, "SOCKS: recv got error: ", ecode);

View File

@@ -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.17.0" android:versionCode="2" android:installLocation="auto"> <manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.18.0" android:versionCode="2" 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" -->