diff --git a/.gitignore b/.gitignore index d3dd8141..c472d88e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # i2pd -obj/*.o +*.o router.info router.keys i2p @@ -248,4 +248,10 @@ docs/generated *\#* # gdb files -.gdb_history \ No newline at end of file +.gdb_history + +# cmake makefile +build/Makefile + +# debian stuff +.pc/ \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index d3d30a91..47039dd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.14.0] - 2017-06-01 +### Added +- Transit traffic bandwidth limitation +- NTCP connections through HTTP and SOCKS proxies +- Ability to disable address helper for HTTP proxy +### Changed +- Reseed servers list +- Minimal required version is 4.0 for Android +### Fixed +- Ignore comments in addressbook feed + ## [2.13.0] - 2017-04-06 ### Added - Persist local destination's tags diff --git a/Makefile b/Makefile index acdc56d4..989f8586 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ I2PD := i2pd GREP := grep DEPS := obj/make.dep +LIB_SRC_DIR := libi2pd +LIB_CLIENT_SRC_DIR := libi2pd_client +DAEMON_SRC_DIR := daemon + include filelist.mk USE_AESNI := yes @@ -17,24 +21,23 @@ USE_UPNP := no ifeq ($(WEBSOCKETS),1) NEEDED_CXXFLAGS += -DWITH_EVENTS - DAEMON_SRC += Websocket.cpp endif ifeq ($(UNAME),Darwin) - DAEMON_SRC += DaemonLinux.cpp + DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) include Makefile.homebrew else include Makefile.osx endif else ifeq ($(shell echo $(UNAME) | $(GREP) -Ec '(Free|Open)BSD'),1) - DAEMON_SRC += DaemonLinux.cpp + DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp include Makefile.bsd else ifeq ($(UNAME),Linux) - DAEMON_SRC += DaemonLinux.cpp + DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp include Makefile.linux -else # win32 mingw - DAEMON_SRC += DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp +else + DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp include Makefile.mingw endif @@ -42,11 +45,16 @@ ifeq ($(USE_MESHNET),yes) NEEDED_CXXFLAGS += -DMESHNET endif +NEEDED_CXXFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) + all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) mk_obj_dir: @mkdir -p obj @mkdir -p obj/Win32 + @mkdir -p obj/$(LIB_SRC_DIR) + @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) + @mkdir -p obj/$(DAEMON_SRC_DIR) api: mk_obj_dir $(SHLIB) $(ARLIB) api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) @@ -70,7 +78,7 @@ obj/%.o: %.cpp DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) - $(CXX) -o $@ $^ $(LDLIBS) $(LDFLAGS) + $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) ifneq ($(USE_STATIC),yes) diff --git a/Makefile.homebrew b/Makefile.homebrew index 05fd8dcf..1cce3232 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -9,9 +9,9 @@ LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread ifeq ($(USE_UPNP),yes) - LDFLAGS += -ldl - CXXFLAGS += -DUSE_UPNP - LDLIBS += -lminiupnpc + LDFLAGS += -ldl + CXXFLAGS += -DUSE_UPNP + LDLIBS += -lminiupnpc endif # OSX Notes @@ -20,7 +20,7 @@ endif # Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic # note from psi: 2009 macbook does not have aesni #ifeq ($(USE_AESNI),yes) -# CXXFLAGS += -maes -DAESNI +# CXXFLAGS += -maes -DAESNI #endif # Disabled, since it will be the default make rule. I think its better diff --git a/Makefile.linux b/Makefile.linux index 8173b4a5..782b0203 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -31,27 +31,27 @@ ifeq ($(USE_STATIC),yes) # NOTE: on glibc you will get this warning: # Using 'getaddrinfo' in statically linked applications requires at runtime # the shared libraries from the glibc version used for linking - LIBDIR := /usr/lib - LDLIBS = $(LIBDIR)/libboost_system.a - LDLIBS += $(LIBDIR)/libboost_date_time.a - LDLIBS += $(LIBDIR)/libboost_filesystem.a - LDLIBS += $(LIBDIR)/libboost_program_options.a - LDLIBS += $(LIBDIR)/libssl.a - LDLIBS += $(LIBDIR)/libcrypto.a - LDLIBS += $(LIBDIR)/libz.a - LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl - USE_AESNI := no + LIBDIR := /usr/lib + LDLIBS = $(LIBDIR)/libboost_system.a + LDLIBS += $(LIBDIR)/libboost_date_time.a + LDLIBS += $(LIBDIR)/libboost_filesystem.a + LDLIBS += $(LIBDIR)/libboost_program_options.a + LDLIBS += $(LIBDIR)/libssl.a + LDLIBS += $(LIBDIR)/libcrypto.a + LDLIBS += $(LIBDIR)/libz.a + LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl + USE_AESNI := no else - LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread + LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread endif # UPNP Support (miniupnpc 1.5 and higher) ifeq ($(USE_UPNP),yes) - CXXFLAGS += -DUSE_UPNP + CXXFLAGS += -DUSE_UPNP ifeq ($(USE_STATIC),yes) - LDLIBS += $(LIBDIR)/libminiupnpc.a + LDLIBS += $(LIBDIR)/libminiupnpc.a else - LDLIBS += -lminiupnpc + LDLIBS += -lminiupnpc endif endif diff --git a/Makefile.mingw b/Makefile.mingw index 40cf14b3..d6fedd7b 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -4,31 +4,29 @@ WINDRES = windres CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN NEEDED_CXXFLAGS = -std=c++11 BOOST_SUFFIX = -mt -INCFLAGS = -I/usr/include/ -I/usr/local/include/ -LDFLAGS = -Wl,-rpath,/usr/local/lib \ - -L/usr/local/lib +INCFLAGS = -I/usr/include/ -I/usr/local/include/ -I. -Idaemon +LDFLAGS = -Wl,-rpath,/usr/local/lib -Wl,-Bstatic -static-libgcc -static-libstdc++ -L/usr/local/lib -# UPNP Support +# UPNP Support ifeq ($(USE_UPNP),yes) - CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB - LDLIBS = -Wl,-Bstatic -lminiupnpc + CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB + LDLIBS = -lminiupnpc endif LDLIBS += \ - -Wl,-Bstatic -lboost_system$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_date_time$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_filesystem$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_program_options$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lssl \ - -Wl,-Bstatic -lcrypto \ - -Wl,-Bstatic -lz \ - -Wl,-Bstatic -lwsock32 \ - -Wl,-Bstatic -lws2_32 \ - -Wl,-Bstatic -lgdi32 \ - -Wl,-Bstatic -liphlpapi \ - -static-libgcc -static-libstdc++ \ - -Wl,-Bstatic -lstdc++ \ - -Wl,-Bstatic -lpthread + -lboost_system$(BOOST_SUFFIX) \ + -lboost_date_time$(BOOST_SUFFIX) \ + -lboost_filesystem$(BOOST_SUFFIX) \ + -lboost_program_options$(BOOST_SUFFIX) \ + -lssl \ + -lcrypto \ + -lz \ + -lwsock32 \ + -lws2_32 \ + -lgdi32 \ + -liphlpapi \ + -lstdc++ \ + -lpthread ifeq ($(USE_WIN32_APP), yes) CXXFLAGS += -DWIN32_APP @@ -50,7 +48,7 @@ endif ifeq ($(USE_ASLR),yes) LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va \ - -Wl,--dynamicbase,--export-all-symbols + -Wl,--dynamicbase,--export-all-symbols endif obj/%.o : %.rc diff --git a/README.md b/README.md index 68b397a4..a475ddd2 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,9 @@ BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59 -ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z DOGE: DNXLQKziRPAsD9H3DFNjk4fLQrdaSX893Y +ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z +GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG License ------- diff --git a/DaemonWin32.cpp b/Win32/DaemonWin32.cpp similarity index 100% rename from DaemonWin32.cpp rename to Win32/DaemonWin32.cpp diff --git a/Win32/Resource.rc2 b/Win32/Resource.rc2 index 6b9e4aa7..b001be82 100644 --- a/Win32/Resource.rc2 +++ b/Win32/Resource.rc2 @@ -6,7 +6,7 @@ #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO_INVOKED -#include "../version.h" +#include "../libi2pd/version.h" ///////////////////////////////////////////////////////////////////////////// // diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 2be4cc02..8f0f7abd 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,13 +1,13 @@ #include #include #include -#include "../ClientContext.h" -#include "../Config.h" -#include "../NetDb.h" -#include "../RouterContext.h" -#include "../Transports.h" -#include "../Tunnel.h" -#include "../version.h" +#include "ClientContext.h" +#include "Config.h" +#include "NetDb.hpp" +#include "RouterContext.h" +#include "Transports.h" +#include "Tunnel.h" +#include "version.h" #include "resource.h" #include "Win32App.h" #include @@ -80,7 +80,7 @@ namespace win32 Shell_NotifyIcon (NIM_DELETE, &nid); } - static void ShowUptime (std::stringstream& s, int seconds) + static void ShowUptime (std::stringstream& s, int seconds) { int num; @@ -125,8 +125,8 @@ namespace win32 { case eRouterStatusOK: s << "OK"; break; case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - case eRouterStatusError: + case eRouterStatusFirewalled: s << "Firewalled"; break; + case eRouterStatusError: { switch (i2p::context.GetError()) { diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index 5a9a8789..48f4b456 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -7,8 +7,8 @@ #include #include -#include "../Daemon.h" -#include "../Log.h" +#include "Daemon.h" +#include "Log.h" I2PService *I2PService::s_service = NULL; @@ -100,7 +100,7 @@ I2PService::I2PService(PSTR pszServiceName, m_fStopping = FALSE; - // Create a manual-reset event that is not signaled at first to indicate + // Create a manual-reset event that is not signaled at first to indicate // the stopped signal of the service. m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hStoppedEvent == NULL) diff --git a/Win32/i2pd.vcxproj b/Win32/i2pd.vcxproj index a8f3b486..6426af09 100644 --- a/Win32/i2pd.vcxproj +++ b/Win32/i2pd.vcxproj @@ -83,7 +83,7 @@ - + diff --git a/Win32/i2pd.vcxproj.filters b/Win32/i2pd.vcxproj.filters index 5392e604..4402ec7a 100644 --- a/Win32/i2pd.vcxproj.filters +++ b/Win32/i2pd.vcxproj.filters @@ -158,7 +158,7 @@ Header Files - + Header Files diff --git a/Win32/installer.iss b/Win32/installer.iss index dd3e1da4..95c2bf42 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.13.0" +#define I2Pd_ver "2.14.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/.gitignore b/android/.gitignore index 1ecaafbe..d9fa5a57 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -1,6 +1,7 @@ gen tests .idea +ant.properties local.properties build.sh bin diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 3ff85fa8..d85d42b7 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,9 @@ - + android:versionName="2.14.0" + android:installLocation="auto"> + diff --git a/android/build.xml b/android/build.xml index 23e9f065..ed8196c3 100644 --- a/android/build.xml +++ b/android/build.xml @@ -93,5 +93,4 @@ --> - diff --git a/android/jni/Android.mk b/android/jni/Android.mk index ed1ed16a..d5a8f05f 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := i2pd LOCAL_CPP_FEATURES := rtti exceptions -LOCAL_C_INCLUDES += $(IFADDRS_PATH) ../.. +LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH) LOCAL_STATIC_LIBRARIES := \ boost_system \ boost_date_time \ @@ -12,59 +12,13 @@ LOCAL_STATIC_LIBRARIES := \ miniupnpc LOCAL_LDLIBS := -lz -LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp \ - $(IFADDRS_PATH)/ifaddrs.c \ - ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ - ../../AddressBook.cpp \ - ../../api.cpp \ - ../../Base.cpp \ - ../../BOB.cpp \ - ../../ClientContext.cpp \ - ../../Crypto.cpp \ - ../../Datagram.cpp \ - ../../Destination.cpp \ - ../../Family.cpp \ - ../../FS.cpp \ - ../../Garlic.cpp \ - ../../Gzip.cpp \ - ../../HTTP.cpp \ - ../../HTTPProxy.cpp \ - ../../I2CP.cpp \ - ../../I2NPProtocol.cpp \ - ../../I2PEndian.cpp \ - ../../I2PService.cpp \ - ../../I2PTunnel.cpp \ - ../../Identity.cpp \ - ../../LeaseSet.cpp \ - ../../Log.cpp \ - ../../NetDb.cpp \ - ../../NetDbRequests.cpp \ - ../../NTCPSession.cpp \ - ../../Profiling.cpp \ - ../../Reseed.cpp \ - ../../RouterContext.cpp \ - ../../RouterInfo.cpp \ - ../../SAM.cpp \ - ../../Signature.cpp \ - ../../SOCKS.cpp \ - ../../SSU.cpp \ - ../../SSUData.cpp \ - ../../SSUSession.cpp \ - ../../Streaming.cpp \ - ../../TransitTunnel.cpp \ - ../../Transports.cpp \ - ../../Tunnel.cpp \ - ../../TunnelEndpoint.cpp \ - ../../TunnelGateway.cpp \ - ../../TunnelPool.cpp \ - ../../Timestamp.cpp \ - ../../Event.cpp \ - ../../Gost.cpp \ - ../../WebSocks.cpp \ - ../../BloomFilter.cpp \ - ../../MatchedDestination.cpp \ - ../../util.cpp \ - ../../i2pd.cpp ../../UPnP.cpp +LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \ + $(wildcard $(LIB_SRC_PATH)/*.cpp)\ + $(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\ + $(DAEMON_SRC_PATH)/Daemon.cpp \ + $(DAEMON_SRC_PATH)/UPnP.cpp \ + $(DAEMON_SRC_PATH)/HTTPServer.cpp \ + $(DAEMON_SRC_PATH)/I2PControl.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index e8a51add..e4a2698a 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -3,7 +3,7 @@ #APP_ABI := x86 APP_ABI := armeabi-v7a #can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there. -APP_PLATFORM := android-9 +APP_PLATFORM := android-14 # http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse NDK_TOOLCHAIN_VERSION := 4.9 @@ -25,8 +25,15 @@ APP_OPTIM := debug # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own -I2PD_LIBS_PATH=/path/to/libraries +I2PD_LIBS_PATH = /path/to/libraries BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs + +# don't change me +I2PD_SRC_PATH = $(PWD)/.. + +LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd +LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client +DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index 038a07fa..75584740 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,5 +1,5 @@ #include "DaemonAndroid.h" -#include "../../Daemon.h" +#include "Daemon.h" #include #include #include @@ -191,4 +191,3 @@ namespace android } } } - diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index 201b668e..8791c90b 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -3,8 +3,8 @@ #include #include "org_purplei2p_i2pd_I2PD_JNI.h" #include "DaemonAndroid.h" -#include "../../RouterContext.h" -#include "../../Transports.h" +#include "RouterContext.h" +#include "Transports.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith (JNIEnv * env, jclass clazz) { @@ -59,8 +59,8 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels } JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv * env, jclass clazz, jboolean isConnected) + (JNIEnv * env, jclass clazz, jboolean isConnected) { bool isConnectedBool = (bool) isConnected; - i2p::transport::transports.SetOnline (isConnectedBool); + i2p::transport::transports.SetOnline (isConnectedBool); } diff --git a/android/libs/.gitignore b/android/libs/.gitignore deleted file mode 100644 index e4e4e6c1..00000000 --- a/android/libs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -armeabi-v7a diff --git a/android/libs/android-support-v4.jar b/android/libs/android-support-v4.jar deleted file mode 100644 index 2ff47f4f..00000000 Binary files a/android/libs/android-support-v4.jar and /dev/null differ diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index 6ff826c4..16155651 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -6,7 +6,6 @@ import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; -import android.support.v4.app.NotificationCompat; import android.util.Log; public class ForegroundService extends Service { @@ -72,7 +71,7 @@ public class ForegroundService extends Service { new Intent(this, I2PD.class), 0); // Set the info for the views that show in the notification panel. - Notification notification = new NotificationCompat.Builder(this) + Notification notification = new Notification.Builder(this) .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon .setTicker(text) // the status text .setWhen(System.currentTimeMillis()) // the time stamp @@ -85,4 +84,4 @@ public class ForegroundService extends Service { //mNM.notify(NOTIFICATION, notification); startForeground(NOTIFICATION, notification); } -} \ No newline at end of file +} diff --git a/appveyor.yml b/appveyor.yml index cb4d3057..b5542562 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.13.{build} +version: 2.14.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 0acf54ca..06e1c24f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -8,6 +8,7 @@ project ( "i2pd" ) # configurale options option(WITH_AESNI "Use AES-NI instructions set" OFF) +option(WITH_AVX "Use AVX instructions" OFF) option(WITH_HARDENING "Use hardening compiler flags" OFF) option(WITH_LIBRARY "Build library" ON) option(WITH_BINARY "Build binary" ON) @@ -25,44 +26,51 @@ option(WITH_WEBSOCKETS "Build with websocket ui" OFF) set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) set ( CMAKE_SOURCE_DIR ".." ) +set(LIBI2PD_SRC_DIR ../libi2pd) +set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) + +include_directories(${LIBI2PD_SRC_DIR}) +include_directories(${LIBI2PD_CLIENT_SRC_DIR}) + set (LIBI2PD_SRC - "${CMAKE_SOURCE_DIR}/BloomFilter.cpp" - "${CMAKE_SOURCE_DIR}/Config.cpp" - "${CMAKE_SOURCE_DIR}/Crypto.cpp" - "${CMAKE_SOURCE_DIR}/Garlic.cpp" - "${CMAKE_SOURCE_DIR}/Gzip.cpp" - "${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp" - "${CMAKE_SOURCE_DIR}/Identity.cpp" - "${CMAKE_SOURCE_DIR}/LeaseSet.cpp" - "${CMAKE_SOURCE_DIR}/FS.cpp" - "${CMAKE_SOURCE_DIR}/Log.cpp" - "${CMAKE_SOURCE_DIR}/NTCPSession.cpp" - "${CMAKE_SOURCE_DIR}/NetDbRequests.cpp" - "${CMAKE_SOURCE_DIR}/NetDb.cpp" - "${CMAKE_SOURCE_DIR}/Profiling.cpp" - "${CMAKE_SOURCE_DIR}/Reseed.cpp" - "${CMAKE_SOURCE_DIR}/RouterContext.cpp" - "${CMAKE_SOURCE_DIR}/RouterInfo.cpp" - "${CMAKE_SOURCE_DIR}/SSU.cpp" - "${CMAKE_SOURCE_DIR}/SSUData.cpp" - "${CMAKE_SOURCE_DIR}/SSUSession.cpp" - "${CMAKE_SOURCE_DIR}/Streaming.cpp" - "${CMAKE_SOURCE_DIR}/Destination.cpp" - "${CMAKE_SOURCE_DIR}/TransitTunnel.cpp" - "${CMAKE_SOURCE_DIR}/Tunnel.cpp" - "${CMAKE_SOURCE_DIR}/TunnelGateway.cpp" - "${CMAKE_SOURCE_DIR}/Transports.cpp" - "${CMAKE_SOURCE_DIR}/TunnelEndpoint.cpp" - "${CMAKE_SOURCE_DIR}/TunnelPool.cpp" - "${CMAKE_SOURCE_DIR}/Base.cpp" - "${CMAKE_SOURCE_DIR}/util.cpp" - "${CMAKE_SOURCE_DIR}/Datagram.cpp" - "${CMAKE_SOURCE_DIR}/Family.cpp" - "${CMAKE_SOURCE_DIR}/Signature.cpp" - "${CMAKE_SOURCE_DIR}/Timestamp.cpp" - "${CMAKE_SOURCE_DIR}/api.cpp" - "${CMAKE_SOURCE_DIR}/Event.cpp" - "${CMAKE_SOURCE_DIR}/Gost.cpp" + "${LIBI2PD_SRC_DIR}/BloomFilter.cpp" + "${LIBI2PD_SRC_DIR}/Config.cpp" + "${LIBI2PD_SRC_DIR}/Crypto.cpp" + "${LIBI2PD_SRC_DIR}/Garlic.cpp" + "${LIBI2PD_SRC_DIR}/Gzip.cpp" + "${LIBI2PD_SRC_DIR}/HTTP.cpp" + "${LIBI2PD_SRC_DIR}/I2NPProtocol.cpp" + "${LIBI2PD_SRC_DIR}/Identity.cpp" + "${LIBI2PD_SRC_DIR}/LeaseSet.cpp" + "${LIBI2PD_SRC_DIR}/FS.cpp" + "${LIBI2PD_SRC_DIR}/Log.cpp" + "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" + "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" + "${LIBI2PD_SRC_DIR}/NetDb.cpp" + "${LIBI2PD_SRC_DIR}/Profiling.cpp" + "${LIBI2PD_SRC_DIR}/Reseed.cpp" + "${LIBI2PD_SRC_DIR}/RouterContext.cpp" + "${LIBI2PD_SRC_DIR}/RouterInfo.cpp" + "${LIBI2PD_SRC_DIR}/SSU.cpp" + "${LIBI2PD_SRC_DIR}/SSUData.cpp" + "${LIBI2PD_SRC_DIR}/SSUSession.cpp" + "${LIBI2PD_SRC_DIR}/Streaming.cpp" + "${LIBI2PD_SRC_DIR}/Destination.cpp" + "${LIBI2PD_SRC_DIR}/TransitTunnel.cpp" + "${LIBI2PD_SRC_DIR}/Tunnel.cpp" + "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" + "${LIBI2PD_SRC_DIR}/Transports.cpp" + "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" + "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" + "${LIBI2PD_SRC_DIR}/Base.cpp" + "${LIBI2PD_SRC_DIR}/util.cpp" + "${LIBI2PD_SRC_DIR}/Datagram.cpp" + "${LIBI2PD_SRC_DIR}/Family.cpp" + "${LIBI2PD_SRC_DIR}/Signature.cpp" + "${LIBI2PD_SRC_DIR}/Timestamp.cpp" + "${LIBI2PD_SRC_DIR}/api.cpp" + "${LIBI2PD_SRC_DIR}/Event.cpp" + "${LIBI2PD_SRC_DIR}/Gost.cpp" ) if (WITH_WEBSOCKETS) @@ -89,31 +97,32 @@ install(TARGETS libi2pd # install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) set (CLIENT_SRC - "${CMAKE_SOURCE_DIR}/AddressBook.cpp" - "${CMAKE_SOURCE_DIR}/BOB.cpp" - "${CMAKE_SOURCE_DIR}/ClientContext.cpp" - "${CMAKE_SOURCE_DIR}/MatchedDestination.cpp" - "${CMAKE_SOURCE_DIR}/I2PTunnel.cpp" - "${CMAKE_SOURCE_DIR}/I2PService.cpp" - "${CMAKE_SOURCE_DIR}/SAM.cpp" - "${CMAKE_SOURCE_DIR}/SOCKS.cpp" - "${CMAKE_SOURCE_DIR}/HTTP.cpp" - "${CMAKE_SOURCE_DIR}/HTTPProxy.cpp" - "${CMAKE_SOURCE_DIR}/I2CP.cpp" - "${CMAKE_SOURCE_DIR}/WebSocks.cpp" - ) + "${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/MatchedDestination.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/I2PTunnel.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/I2PService.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/SAM.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp" + "${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp" +) if(WITH_WEBSOCKETS) - list (APPEND CLIENT_SRC "${CMAKE_SOURCE_DIR}/Websocket.cpp") + list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp") endif () add_library(i2pdclient ${CLIENT_SRC}) +set(DAEMON_SRC_DIR ../daemon) + set (DAEMON_SRC - "${CMAKE_SOURCE_DIR}/Daemon.cpp" - "${CMAKE_SOURCE_DIR}/HTTPServer.cpp" - "${CMAKE_SOURCE_DIR}/I2PControl.cpp" - "${CMAKE_SOURCE_DIR}/i2pd.cpp" - "${CMAKE_SOURCE_DIR}/UPnP.cpp" + "${DAEMON_SRC_DIR}/Daemon.cpp" + "${DAEMON_SRC_DIR}/HTTPServer.cpp" + "${DAEMON_SRC_DIR}/I2PControl.cpp" + "${DAEMON_SRC_DIR}/i2pd.cpp" + "${DAEMON_SRC_DIR}/UPnP.cpp" ) if (WITH_MESHNET) @@ -178,22 +187,22 @@ endif () # compiler flags customization (by system) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.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 add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.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 add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp") -elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp") -elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS) - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonWin32.cpp") + 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) list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp") - set_source_files_properties("${CMAKE_SOURCE_DIR}/DaemonWin32.cpp" + set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp" PROPERTIES COMPILE_DEFINITIONS WIN32_APP) endif () list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp") @@ -205,6 +214,10 @@ if (WITH_AESNI) add_definitions ( -DAESNI ) endif() +if (WITH_AVX) + set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx" ) +endif() + if (WITH_ADDRSANITIZER) if (NOT MSVC) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer" ) @@ -275,7 +288,7 @@ endif () if (WITH_PCH) include_directories(BEFORE ${CMAKE_BINARY_DIR}) - add_library(stdafx STATIC "${CMAKE_SOURCE_DIR}/stdafx.cpp") + add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp") if(MSVC) target_compile_options(stdafx PRIVATE /Ycstdafx.h /Zm155) add_custom_command(TARGET stdafx POST_BUILD @@ -291,10 +304,10 @@ if (WITH_PCH) get_directory_property(DEFS DEFINITIONS) string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") add_custom_command(TARGET stdafx PRE_BUILD - COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch + COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch ) - target_compile_options(libi2pd PRIVATE -include stdafx.h) - target_compile_options(i2pdclient PRIVATE -include stdafx.h) + target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) + target_compile_options(i2pdclient PRIVATE -include libi2pd/stdafx.h) endif() target_link_libraries(libi2pd stdafx) endif() @@ -371,6 +384,7 @@ message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}") message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}") message(STATUS "Options:") message(STATUS " AESNI : ${WITH_AESNI}") +message(STATUS " AVX : ${WITH_AVX}") message(STATUS " HARDENING : ${WITH_HARDENING}") message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " BINARY : ${WITH_BINARY}") @@ -402,7 +416,7 @@ if (WITH_BINARY) if (MSVC) target_compile_options("${PROJECT_NAME}" PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") else() - target_compile_options("${PROJECT_NAME}" PRIVATE -include stdafx.h) + target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h) endif() endif() @@ -453,7 +467,7 @@ install(FILES "C:/projects/openssl-$ENV{OPENSSL}/LICENSE" OPTIONAL # for local builds only! ) -file(GLOB_RECURSE I2PD_SOURCES "../*.cpp" "../build" "../Win32" "../Makefile*") +file(GLOB_RECURSE I2PD_SOURCES "../libi2pd/*.cpp" "../libi2pd_client/*.cpp" "../daemon/*.cpp" "../build" "../Win32" "../Makefile*") install(FILES ${I2PD_SOURCES} DESTINATION src/ COMPONENT Source) # install(DIRECTORY ../ DESTINATION src/ # # OPTIONAL @@ -462,7 +476,7 @@ install(FILES ${I2PD_SOURCES} DESTINATION src/ COMPONENT Source) # PATTERN "*.cpp" # ) -file(GLOB I2PD_HEADERS "../*.h") +file(GLOB I2PD_HEADERS "../libi2pd/*.h" "../libi2pd_client/*.h" "../daemon/*.h") install(FILES ${I2PD_HEADERS} DESTINATION src/ COMPONENT Headers) # install(DIRECTORY ../ DESTINATION src/ # # OPTIONAL @@ -475,7 +489,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Purple I2P, a C++ I2P daemon") set(CPACK_PACKAGE_VENDOR "Purple I2P") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE") -file(READ ../version.h version_h) +file(READ ../libi2pd/version.h version_h) string(REGEX REPLACE ".*I2PD_VERSION_MAJOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${version_h}") string(REGEX REPLACE ".*I2PD_VERSION_MINOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${version_h}") string(REGEX REPLACE ".*I2PD_VERSION_MICRO ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MICRO "${version_h}") diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index c852e0c9..eaca4103 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -69,7 +69,8 @@ ipv6 = false ## Default is X for floodfill, L for regular node # bandwidth = L -## Router will not accept transit tunnels at startup +## Router will not accept transit tunnels, disabling transit traffic completely +## (default = false) # notransit = true ## Router will be floodfill @@ -141,7 +142,7 @@ port = 4447 [sam] ## Uncomment and set to 'true' to enable SAM Bridge -# enabled = false +enabled = true ## Address and port service will listen on # address = 127.0.0.1 # port = 7656 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index a286349c..ce47b866 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,7 +1,7 @@ %define build_timestamp %(date +"%Y%m%d") Name: i2pd -Version: 2.12.0 +Version: 2.14.0 Release: %{build_timestamp}git%{?dist} Summary: I2P router written in C++ @@ -103,6 +103,23 @@ getent passwd i2pd >/dev/null || \ %changelog +* Thu Jun 01 2017 orignal - 2.14.0 +- Added transit traffic bandwidth limitation +- 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 - 2.13.0 +- Added persist local destination's tags +- 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 - 2.12.0 - Additional HTTP and SOCKS proxy tunnels - Reseed from ZIP archive @@ -120,7 +137,7 @@ getent passwd i2pd >/dev/null || \ - Fixed UPnP discovery bug, producing excessive CPU usage - Handle multiple lookups of the same LeaseSet correctly -* Tue Oct 20 2016 Anatolii Vorona - 2.10.0-3 +* Thu Oct 20 2016 Anatolii Vorona - 2.10.0-3 - add support C7 - move rpm-related files to contrib folder diff --git a/contrib/tunnels.conf b/contrib/tunnels.conf index fa92a56b..be8681dc 100644 --- a/contrib/tunnels.conf +++ b/contrib/tunnels.conf @@ -1,4 +1,4 @@ -[IRC] +[IRC-IRC2P] type = client address = 127.0.0.1 port = 6668 @@ -6,6 +6,14 @@ destination = irc.postman.i2p destinationport = 6667 keys = irc-keys.dat +#[IRC-ILITA] +#type = client +#address = 127.0.0.1 +#port = 6669 +#destination = irc.ilita.i2p +#destinationport = 6667 +#keys = irc-keys.dat + #[SMTP] #type = client #address = 127.0.0.1 @@ -22,12 +30,4 @@ keys = irc-keys.dat #destinationport = 110 #keys = pop3-keys.dat -#[MTN] -#type = client -#address = 127.0.0.1 -#port = 8998 -#destination = mtn.i2p-projekt.i2p -#destinationport = 4691 -#keys = mtn-keys.dat - # see more examples in /usr/share/doc/i2pd/configuration.md.gz diff --git a/Daemon.cpp b/daemon/Daemon.cpp similarity index 94% rename from Daemon.cpp rename to daemon/Daemon.cpp index c7aaa279..32595390 100644 --- a/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -14,7 +14,7 @@ #include "RouterContext.h" #include "Tunnel.h" #include "HTTP.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Garlic.h" #include "Streaming.h" #include "Destination.h" @@ -115,6 +115,12 @@ namespace i2p } LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); +#ifdef AESNI + LogPrint(eLogInfo, "AESNI enabled"); +#endif +#if defined(__AVX__) + LogPrint(eLogInfo, "AVX enabled"); +#endif LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); @@ -140,7 +146,7 @@ namespace i2p } i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - + bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); @@ -157,17 +163,17 @@ namespace i2p /* this section also honors 'floodfill' flag, if set above */ std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); if (bandwidth.length () > 0) - { - if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X') + { + if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X') { i2p::context.SetBandwidth (bandwidth[0]); LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); - } - else + } + else { auto value = std::atoi(bandwidth.c_str()); - if (value > 0) - { + if (value > 0) + { i2p::context.SetBandwidth (value); LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); } @@ -175,24 +181,27 @@ namespace i2p { LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'"); i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); - } - } - } - else if (isFloodfill) + } + } + } + else if (isFloodfill) { LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1); - } + } else { LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'"); i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); - } + } + + int shareRatio; i2p::config::GetOption("share", shareRatio); + i2p::context.SetShareRatio (shareRatio); std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); if (family.length () > 0) - LogPrint(eLogInfo, "Daemon: family set to ", family); + LogPrint(eLogInfo, "Daemon: family set to ", family); bool trust; i2p::config::GetOption("trust.enabled", trust); if (trust) @@ -211,7 +220,7 @@ namespace i2p fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); pos = comma + 1; } - while (comma != std::string::npos); + while (comma != std::string::npos); i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } @@ -222,11 +231,11 @@ namespace i2p { comma = routers.find (',', pos); i2p::data::IdentHash ident; - ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); + ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); idents.insert (ident); pos = comma + 1; } - while (comma != std::string::npos); + while (comma != std::string::npos); LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routesrs"); i2p::transport::transports.RestrictRoutesToRouters(idents); restricted = idents.size() > 0; @@ -242,7 +251,7 @@ namespace i2p } return true; } - + bool Daemon_Singleton::start() { i2p::log::Logger().Start(); @@ -260,6 +269,7 @@ namespace i2p LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled"); + i2p::transport::transports.Start(ntcp, ssu); if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU()) { LogPrint(eLogInfo, "Daemon: Transports started"); @@ -270,7 +280,7 @@ namespace i2p i2p::data::netdb.Stop(); return false; } - + bool http; i2p::config::GetOption("http.enabled", http); if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); @@ -280,7 +290,7 @@ namespace i2p d.httpServer->Start(); } - + LogPrint(eLogInfo, "Daemon: starting Tunnels"); i2p::tunnel::tunnels.Start(); diff --git a/Daemon.h b/daemon/Daemon.h similarity index 100% rename from Daemon.h rename to daemon/Daemon.h diff --git a/HTTPServer.cpp b/daemon/HTTPServer.cpp similarity index 98% rename from HTTPServer.cpp rename to daemon/HTTPServer.cpp index 154dce5e..363b365a 100644 --- a/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -11,9 +11,8 @@ #include "Log.h" #include "Config.h" #include "Tunnel.h" -#include "TransitTunnel.h" #include "Transports.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "HTTP.h" #include "LeaseSet.h" #include "Destination.h" @@ -109,6 +108,18 @@ namespace http { s << seconds << " seconds"; } + static void ShowTraffic (std::stringstream& s, uint64_t bytes) + { + s << std::fixed << std::setprecision(2); + auto numKBytes = (double) bytes / 1024; + if (numKBytes < 1024) + s << numKBytes << " KiB"; + else if (numKBytes < 1024 * 1024) + s << numKBytes / 1024 << " MiB"; + else + s << numKBytes / 1024 / 1024 << " GiB"; + } + static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, int bytes) { std::string state; @@ -212,24 +223,14 @@ namespace http { s << "Family: " << family << "
\r\n"; s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "Received: "; - s << std::fixed << std::setprecision(2); - auto numKBytesReceived = (double) i2p::transport::transports.GetTotalReceivedBytes () / 1024; - if (numKBytesReceived < 1024) - s << numKBytesReceived << " KiB"; - else if (numKBytesReceived < 1024 * 1024) - s << numKBytesReceived / 1024 << " MiB"; - else - s << numKBytesReceived / 1024 / 1024 << " GiB"; + ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Sent: "; - auto numKBytesSent = (double) i2p::transport::transports.GetTotalSentBytes () / 1024; - if (numKBytesSent < 1024) - s << numKBytesSent << " KiB"; - else if (numKBytesSent < 1024 * 1024) - s << numKBytesSent / 1024 << " MiB"; - else - s << numKBytesSent / 1024 / 1024 << " GiB"; + ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
\r\n"; + s << "Transit: "; + ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
\r\n\r\n

\r\n"; s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; diff --git a/HTTPServer.h b/daemon/HTTPServer.h similarity index 100% rename from HTTPServer.h rename to daemon/HTTPServer.h diff --git a/I2PControl.cpp b/daemon/I2PControl.cpp similarity index 99% rename from I2PControl.cpp rename to daemon/I2PControl.cpp index 3a65a11c..1d7023fb 100644 --- a/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -17,7 +17,7 @@ #include "FS.h" #include "Log.h" #include "Config.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "RouterContext.h" #include "Daemon.h" #include "Tunnel.h" diff --git a/I2PControl.h b/daemon/I2PControl.h similarity index 100% rename from I2PControl.h rename to daemon/I2PControl.h diff --git a/UPnP.cpp b/daemon/UPnP.cpp similarity index 99% rename from UPnP.cpp rename to daemon/UPnP.cpp index 20244786..d1a190d6 100644 --- a/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -10,7 +10,7 @@ #include "RouterContext.h" #include "UPnP.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "util.h" #include "RouterInfo.h" #include "Config.h" diff --git a/UPnP.h b/daemon/UPnP.h similarity index 100% rename from UPnP.h rename to daemon/UPnP.h diff --git a/DaemonLinux.cpp b/daemon/UnixDaemon.cpp similarity index 100% rename from DaemonLinux.cpp rename to daemon/UnixDaemon.cpp diff --git a/i2pd.cpp b/daemon/i2pd.cpp similarity index 100% rename from i2pd.cpp rename to daemon/i2pd.cpp diff --git a/debian/changelog b/debian/changelog index 4ffa1cf5..67773089 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +i2pd (2.14.0-1) unstable; urgency=low + + * updated to version 2.14.0/0.9.30 + * updated debian/control + * renamed logrotate to i2pd.logrotate + * fixed init.d script + + -- orignal Thu, 1 Jun 2017 14:00:00 +0000 + i2pd (2.13.0-1) unstable; urgency=low * updated to version 2.13.0/0.9.29 @@ -5,7 +14,7 @@ i2pd (2.13.0-1) unstable; urgency=low * renamed logrotate to i2pd.logrotate * fixed init.d script - -- orignal Tue, 6 Apr 2017 14:00:00 +0000 + -- orignal Thu, 6 Apr 2017 14:00:00 +0000 i2pd (2.12.0-1) unstable; urgency=low diff --git a/debian/control b/debian/control index b41e4624..62da41d2 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: i2pd Section: net Priority: optional Maintainer: R4SAS -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 +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 Standards-Version: 3.9.6 Homepage: http://i2pd.website/ Vcs-Git: git://github.com/PurpleI2P/i2pd.git @@ -13,7 +13,7 @@ Architecture: any Pre-Depends: adduser Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: tor, privoxy -Description: i2pd is a full-featured C++ implementation of I2P client. +Description: A full-featured C++ implementation of I2P client. I2P (Invisible Internet Protocol) is a universal anonymous network layer. All communications over I2P are anonymous and end-to-end encrypted, participants don't reveal their real IP addresses. diff --git a/filelist.mk b/filelist.mk index 5fb5ea1d..8d451dc9 100644 --- a/filelist.mk +++ b/filelist.mk @@ -1,16 +1,22 @@ -LIB_SRC = \ - BloomFilter.cpp Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \ - Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \ - Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \ - SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ - Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ - Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ - Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp Gost.cpp +#LIB_SRC = \ +# BloomFilter.cpp Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \ +# Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \ +# Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \ +# SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ +# Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ +# Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ +# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp Gost.cpp -LIB_CLIENT_SRC = \ - AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \ - SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp WebSocks.cpp +LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp) + +#LIB_CLIENT_SRC = \ +# AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \ +# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp WebSocks.cpp + +LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) # also: Daemon{Linux,Win32}.cpp will be added later -DAEMON_SRC = \ - HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp +#DAEMON_SRC = \ +# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp + +DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp) diff --git a/Base.cpp b/libi2pd/Base.cpp similarity index 100% rename from Base.cpp rename to libi2pd/Base.cpp diff --git a/Base.h b/libi2pd/Base.h similarity index 100% rename from Base.h rename to libi2pd/Base.h diff --git a/BloomFilter.cpp b/libi2pd/BloomFilter.cpp similarity index 100% rename from BloomFilter.cpp rename to libi2pd/BloomFilter.cpp diff --git a/BloomFilter.h b/libi2pd/BloomFilter.h similarity index 100% rename from BloomFilter.h rename to libi2pd/BloomFilter.h diff --git a/Config.cpp b/libi2pd/Config.cpp similarity index 89% rename from Config.cpp rename to libi2pd/Config.cpp index c2d35340..309c0e9c 100644 --- a/Config.cpp +++ b/libi2pd/Config.cpp @@ -48,21 +48,23 @@ namespace config { ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") ("ipv4", value()->zero_tokens()->default_value(true), "Enable communication through ipv4") ("ipv6", value()->zero_tokens()->default_value(false), "Enable communication through ipv6") - ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") + ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("daemon", value()->zero_tokens()->default_value(false), "Router will go to background after start") ("service", value()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'") ("notransit", value()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup") ("floodfill", value()->zero_tokens()->default_value(false), "Router will be floodfill") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") + ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100") ("ntcp", value()->zero_tokens()->default_value(true), "Enable NTCP transport") ("ssu", value()->zero_tokens()->default_value(true), "Enable SSU transport") + ("ntcpproxy", value()->default_value(""), "proxy url for ntcp transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; - + options_description limits("Limits options"); limits.add_options() ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") @@ -86,12 +88,12 @@ namespace config { ("httpproxy.address", value()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.port", value()->default_value(4444), "HTTP Proxy listen port") ("httpproxy.keys", value()->default_value(""), "File to persist HTTP Proxy keys") - ("httpproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") - ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") + ("httpproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") ("httpproxy.outbound.length", value()->default_value("3"), "HTTP proxy outbound tunnel length") - ("httpproxy.inbound.quantity", value()->default_value("5"), "HTTP proxy inbound tunnels quantity") + ("httpproxy.inbound.quantity", value()->default_value("5"), "HTTP proxy inbound tunnels quantity") ("httpproxy.outbound.quantity", value()->default_value("5"), "HTTP proxy outbound tunnels quantity") - ("httpproxy.latency.min", value()->default_value("0"), "HTTP proxy min latency for tunnels") + ("httpproxy.latency.min", value()->default_value("0"), "HTTP proxy min latency for tunnels") ("httpproxy.latency.max", value()->default_value("0"), "HTTP proxy max latency for tunnels") ("httpproxy.outproxy", value()->default_value(""), "HTTP proxy upstream out proxy url") ("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper") @@ -103,20 +105,20 @@ namespace config { ("socksproxy.address", value()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.port", value()->default_value(4447), "SOCKS Proxy listen port") ("socksproxy.keys", value()->default_value(""), "File to persist SOCKS Proxy keys") - ("socksproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") - ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") + ("socksproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") ("socksproxy.outbound.length", value()->default_value("3"), "SOCKS proxy outbound tunnel length") - ("socksproxy.inbound.quantity", value()->default_value("5"), "SOCKS proxy inbound tunnels quantity") + ("socksproxy.inbound.quantity", value()->default_value("5"), "SOCKS proxy inbound tunnels quantity") ("socksproxy.outbound.quantity", value()->default_value("5"), "SOCKS proxy outbound tunnels quantity") - ("socksproxy.latency.min", value()->default_value("0"), "SOCKS proxy min latency for tunnels") - ("socksproxy.latency.max", value()->default_value("0"), "SOCKS proxy max latency for tunnels") + ("socksproxy.latency.min", value()->default_value("0"), "SOCKS proxy min latency for tunnels") + ("socksproxy.latency.max", value()->default_value("0"), "SOCKS proxy max latency for tunnels") ("socksproxy.outproxy", value()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy") ("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") ; options_description sam("SAM bridge options"); sam.add_options() - ("sam.enabled", value()->default_value(false), "Enable or disable SAM Application bridge") + ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") ("sam.port", value()->default_value(7656), "SAM listen port") ; @@ -147,26 +149,26 @@ namespace config { bool upnp_default = false; #if (defined(USE_UPNP) && (defined(WIN32_APP) || defined(ANDROID))) - upnp_default = true; // enable UPNP for windows GUI and android by default + upnp_default = true; // enable UPNP for windows GUI and android by default #endif options_description upnp("UPnP options"); upnp.add_options() ("upnp.enabled", value()->default_value(upnp_default), "Enable or disable UPnP: automatic port forwarding") - ("upnp.name", value()->default_value("I2Pd"), "Name i2pd appears in UPnP forwardings list") + ("upnp.name", value()->default_value("I2Pd"), "Name i2pd appears in UPnP forwardings list") ; options_description precomputation("Precomputation options"); - precomputation.add_options() - ("precomputation.elgamal", -#if defined(__x86_64__) - value()->default_value(false), + precomputation.add_options() + ("precomputation.elgamal", +#if defined(__x86_64__) + value()->default_value(false), #else - value()->default_value(true), -#endif + value()->default_value(true), +#endif "Enable or disable elgamal precomputation table") ; - - options_description reseed("Reseed options"); + + options_description reseed("Reseed options"); reseed.add_options() ("reseed.verify", value()->default_value(false), "Verify .su3 signature") ("reseed.threshold", value()->default_value(25), "Minimum number of known routers before requesting reseed") @@ -186,17 +188,17 @@ namespace config { "https://reseed.atomike.ninja/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," - "https://itoopie.atomike.ninja/," - "https://randomrng.ddns.net/" + "https://itoopie.atomike.ninja/" +// "https://randomrng.ddns.net/" // dead ), "Reseed URLs, separated by comma") - ; + ; options_description addressbook("AddressBook options"); addressbook.add_options() ("addressbook.defaulturl", value()->default_value( "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt" ), "AddressBook subscription URL for initial setup") - ("addressbook.subscriptions", value()->default_value(""), + ("addressbook.subscriptions", value()->default_value(""), "AddressBook subscriptions URLs, separated by comma"); options_description trust("Trust options"); @@ -205,7 +207,7 @@ namespace config { ("trust.family", value()->default_value(""), "Router Familiy to trust for first hops") ("trust.routers", value()->default_value(""), "Only Connect to these routers") ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?"); - + options_description websocket("Websocket Options"); websocket.add_options() ("websockets.enabled", value()->default_value(false), "enable websocket server") @@ -214,50 +216,50 @@ namespace config { options_description exploratory("Exploratory Options"); exploratory.add_options() - ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") + ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") ("exploratory.outbound.length", value()->default_value(2), "Exploratory outbound tunnel length") - ("exploratory.inbound.quantity", value()->default_value(3), "Exploratory inbound tunnels quantity") - ("exploratory.outbound.quantity", value()->default_value(3), "Exploratory outbound tunnels quantity"); + ("exploratory.inbound.quantity", value()->default_value(3), "Exploratory inbound tunnels quantity") + ("exploratory.outbound.quantity", value()->default_value(3), "Exploratory outbound tunnels quantity"); m_OptionsDesc .add(general) - .add(limits) + .add(limits) .add(httpserver) .add(httpproxy) .add(socksproxy) .add(sam) .add(bob) - .add(i2cp) + .add(i2cp) .add(i2pcontrol) .add(upnp) .add(precomputation) - .add(reseed) - .add(addressbook) + .add(reseed) + .add(addressbook) .add(trust) .add(websocket) .add(exploratory) ; } - void ParseCmdline(int argc, char* argv[], bool ignoreUnknown) + void ParseCmdline(int argc, char* argv[], bool ignoreUnknown) { - try + try { auto style = boost::program_options::command_line_style::unix_style | boost::program_options::command_line_style::allow_long_disguise; style &= ~ boost::program_options::command_line_style::allow_guessing; if (ignoreUnknown) - store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options); - else + store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options); + else store(parse_command_line(argc, argv, m_OptionsDesc, style), m_Options); - } - catch (boost::program_options::error& e) + } + catch (boost::program_options::error& e) { std::cerr << "args: " << e.what() << std::endl; exit(EXIT_FAILURE); } - if (!ignoreUnknown && (m_Options.count("help") || m_Options.count("h"))) + if (!ignoreUnknown && (m_Options.count("help") || m_Options.count("h"))) { std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl; std::cout << m_OptionsDesc; @@ -270,17 +272,17 @@ namespace config { std::ifstream config(path, std::ios::in); - if (!config.is_open()) + if (!config.is_open()) { std::cerr << "missing/unreadable config file: " << path << std::endl; exit(EXIT_FAILURE); } - try + try { store(boost::program_options::parse_config_file(config, m_OptionsDesc), m_Options); - } - catch (boost::program_options::error& e) + } + catch (boost::program_options::error& e) { std::cerr << e.what() << std::endl; exit(EXIT_FAILURE); diff --git a/Config.h b/libi2pd/Config.h similarity index 100% rename from Config.h rename to libi2pd/Config.h diff --git a/Crypto.cpp b/libi2pd/Crypto.cpp similarity index 100% rename from Crypto.cpp rename to libi2pd/Crypto.cpp diff --git a/Crypto.h b/libi2pd/Crypto.h similarity index 100% rename from Crypto.h rename to libi2pd/Crypto.h diff --git a/Datagram.cpp b/libi2pd/Datagram.cpp similarity index 100% rename from Datagram.cpp rename to libi2pd/Datagram.cpp diff --git a/Datagram.h b/libi2pd/Datagram.h similarity index 100% rename from Datagram.h rename to libi2pd/Datagram.h diff --git a/Destination.cpp b/libi2pd/Destination.cpp similarity index 99% rename from Destination.cpp rename to libi2pd/Destination.cpp index dd3edcf6..31447e79 100644 --- a/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -4,7 +4,7 @@ #include "Log.h" #include "FS.h" #include "Timestamp.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Destination.h" #include "util.h" diff --git a/Destination.h b/libi2pd/Destination.h similarity index 99% rename from Destination.h rename to libi2pd/Destination.h index 12acf56a..4b22e043 100644 --- a/Destination.h +++ b/libi2pd/Destination.h @@ -17,7 +17,7 @@ #include "Crypto.h" #include "LeaseSet.h" #include "Garlic.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Streaming.h" #include "Datagram.h" diff --git a/Event.cpp b/libi2pd/Event.cpp similarity index 100% rename from Event.cpp rename to libi2pd/Event.cpp diff --git a/Event.h b/libi2pd/Event.h similarity index 100% rename from Event.h rename to libi2pd/Event.h diff --git a/FS.cpp b/libi2pd/FS.cpp similarity index 100% rename from FS.cpp rename to libi2pd/FS.cpp diff --git a/FS.h b/libi2pd/FS.h similarity index 100% rename from FS.h rename to libi2pd/FS.h diff --git a/Family.cpp b/libi2pd/Family.cpp similarity index 100% rename from Family.cpp rename to libi2pd/Family.cpp diff --git a/Family.h b/libi2pd/Family.h similarity index 100% rename from Family.h rename to libi2pd/Family.h diff --git a/Garlic.cpp b/libi2pd/Garlic.cpp similarity index 100% rename from Garlic.cpp rename to libi2pd/Garlic.cpp diff --git a/Garlic.h b/libi2pd/Garlic.h similarity index 100% rename from Garlic.h rename to libi2pd/Garlic.h diff --git a/Gost.cpp b/libi2pd/Gost.cpp similarity index 99% rename from Gost.cpp rename to libi2pd/Gost.cpp index 688035eb..351dac10 100644 --- a/Gost.cpp +++ b/libi2pd/Gost.cpp @@ -323,7 +323,7 @@ namespace crypto for (int i = 63; i >= 0; i--) { uint16_t sum = buf[i] + other.buf[i] + carry; - ret.buf[i] = sum & 0xFF; + ret.buf[i] = sum; carry = sum >> 8; } return ret; @@ -333,9 +333,10 @@ namespace crypto { for (int i = 63; i >= 0; i--) { + if (!c) return; c += buf[i]; buf[i] = c; - c >>= 8; + c >>= 8; } } diff --git a/Gost.h b/libi2pd/Gost.h similarity index 100% rename from Gost.h rename to libi2pd/Gost.h diff --git a/Gzip.cpp b/libi2pd/Gzip.cpp similarity index 100% rename from Gzip.cpp rename to libi2pd/Gzip.cpp diff --git a/Gzip.h b/libi2pd/Gzip.h similarity index 100% rename from Gzip.h rename to libi2pd/Gzip.h diff --git a/HTTP.cpp b/libi2pd/HTTP.cpp similarity index 100% rename from HTTP.cpp rename to libi2pd/HTTP.cpp diff --git a/HTTP.h b/libi2pd/HTTP.h similarity index 100% rename from HTTP.h rename to libi2pd/HTTP.h diff --git a/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp similarity index 99% rename from I2NPProtocol.cpp rename to libi2pd/I2NPProtocol.cpp index 4e4ca7c3..9f7738f3 100644 --- a/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -6,7 +6,7 @@ #include "I2PEndian.h" #include "Timestamp.h" #include "RouterContext.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Tunnel.h" #include "Transports.h" #include "Garlic.h" @@ -332,7 +332,8 @@ namespace i2p // replace record to reply if (i2p::context.AcceptsTunnels () && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && - !i2p::transport::transports.IsBandwidthExceeded ()) + !i2p::transport::transports.IsBandwidthExceeded () && + !i2p::transport::transports.IsTransitBandwidthExceeded ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), diff --git a/I2NPProtocol.h b/libi2pd/I2NPProtocol.h similarity index 100% rename from I2NPProtocol.h rename to libi2pd/I2NPProtocol.h diff --git a/I2PEndian.cpp b/libi2pd/I2PEndian.cpp similarity index 100% rename from I2PEndian.cpp rename to libi2pd/I2PEndian.cpp diff --git a/I2PEndian.h b/libi2pd/I2PEndian.h similarity index 100% rename from I2PEndian.h rename to libi2pd/I2PEndian.h diff --git a/Identity.cpp b/libi2pd/Identity.cpp similarity index 100% rename from Identity.cpp rename to libi2pd/Identity.cpp diff --git a/Identity.h b/libi2pd/Identity.h similarity index 100% rename from Identity.h rename to libi2pd/Identity.h diff --git a/LeaseSet.cpp b/libi2pd/LeaseSet.cpp similarity index 99% rename from LeaseSet.cpp rename to libi2pd/LeaseSet.cpp index bddb517e..8b8a17c0 100644 --- a/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -3,7 +3,7 @@ #include "Crypto.h" #include "Log.h" #include "Timestamp.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Tunnel.h" #include "LeaseSet.h" diff --git a/LeaseSet.h b/libi2pd/LeaseSet.h similarity index 100% rename from LeaseSet.h rename to libi2pd/LeaseSet.h diff --git a/LittleBigEndian.h b/libi2pd/LittleBigEndian.h similarity index 100% rename from LittleBigEndian.h rename to libi2pd/LittleBigEndian.h diff --git a/Log.cpp b/libi2pd/Log.cpp similarity index 100% rename from Log.cpp rename to libi2pd/Log.cpp diff --git a/Log.h b/libi2pd/Log.h similarity index 100% rename from Log.h rename to libi2pd/Log.h diff --git a/NTCPSession.cpp b/libi2pd/NTCPSession.cpp similarity index 67% rename from NTCPSession.cpp rename to libi2pd/NTCPSession.cpp index a2aec85c..a6329f04 100644 --- a/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -10,8 +10,10 @@ #include "I2NPProtocol.h" #include "RouterContext.h" #include "Transports.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "NTCPSession.h" +#include "HTTP.h" +#include "util.h" #ifdef WITH_EVENTS #include "Event.h" #endif @@ -22,15 +24,15 @@ namespace i2p { namespace transport { - NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): - TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), - m_Server (server), m_Socket (m_Server.GetService ()), + NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): + TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), + m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false) - { + { m_Establisher = new Establisher; } - + NTCPSession::~NTCPSession () { delete m_Establisher; @@ -40,14 +42,14 @@ namespace transport { uint8_t sharedKey[256]; m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation - + i2p::crypto::AESKey aesKey; if (sharedKey[0] & 0x80) { aesKey[0] = 0; memcpy (aesKey + 1, sharedKey, 31); - } - else if (sharedKey[0]) + } + else if (sharedKey[0]) memcpy (aesKey, sharedKey, 32); else { @@ -60,24 +62,24 @@ namespace transport { LogPrint (eLogWarning, "NTCP: First 32 bytes of shared key is all zeros, ignored"); return; - } + } } memcpy (aesKey, nonZero, 32); } m_Decryption.SetKey (aesKey); m_Encryption.SetKey (aesKey); - } + } void NTCPSession::Done () { - m_Server.GetService ().post (std::bind (&NTCPSession::Terminate, shared_from_this ())); - } - + m_Server.GetService ().post (std::bind (&NTCPSession::Terminate, shared_from_this ())); + } + void NTCPSession::Terminate () { if (!m_IsTerminated) - { + { m_IsTerminated = true; m_IsEstablished = false; m_Socket.close (); @@ -86,8 +88,8 @@ namespace transport m_SendQueue.clear (); m_NextMessage = nullptr; LogPrint (eLogDebug, "NTCP: session terminated"); - } - } + } + } void NTCPSession::Connected () { @@ -95,14 +97,14 @@ namespace transport delete m_Establisher; m_Establisher = nullptr; - - m_DHKeysPair = nullptr; + + m_DHKeysPair = nullptr; SetTerminationTimeout (NTCP_TERMINATION_TIMEOUT); - SendTimeSyncMessage (); + SendTimeSyncMessage (); transports.PeerConnected (shared_from_this ()); - } - + } + void NTCPSession::ClientLogin () { if (!m_DHKeysPair) @@ -114,61 +116,61 @@ namespace transport const uint8_t * ident = m_RemoteIdentity->GetIdentHash (); for (int i = 0; i < 32; i++) m_Establisher->phase1.HXxorHI[i] ^= ident[i]; - + boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } + std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } void NTCPSession::ServerLogin () { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); // receive Phase1 - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (), + boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - + } + void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogInfo, "NTCP: couldn't send Phase 1 message: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase2Received, shared_from_this (), + { + boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandlePhase2Received, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - } + } + } void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) { (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogInfo, "NTCP: phase 1 read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { + { // verify ident uint8_t digest[32]; SHA256(m_Establisher->phase1.pubKey, 256, digest); const uint8_t * ident = i2p::context.GetIdentHash (); for (int i = 0; i < 32; i++) - { + { if ((m_Establisher->phase1.HXxorHI[i] ^ ident[i]) != digest[i]) { LogPrint (eLogError, "NTCP: phase 1 error: ident mismatch"); Terminate (); return; - } - } + } + } #if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 7) // due the bug in gcc 4.7. std::shared_future.get() is not const if (!m_DHKeysPair) @@ -183,15 +185,15 @@ namespace transport if (!s->m_DHKeysPair) s->m_DHKeysPair = transports.GetNextDHKeysPair (); s->CreateAESKey (s->m_Establisher->phase1.pubKey); - }).share (); + }).share (); m_Server.GetService ().post ([s, keyCreated]() - { - keyCreated.get (); - s->SendPhase2 (); - }); -#endif - } - } + { + keyCreated.get (); + s->SendPhase2 (); + }); +#endif + } + } void NTCPSession::SendPhase2 () { @@ -200,42 +202,42 @@ namespace transport uint8_t xy[512]; memcpy (xy, m_Establisher->phase1.pubKey, 256); memcpy (xy + 256, y, 256); - SHA256(xy, 512, m_Establisher->phase2.encrypted.hxy); + SHA256(xy, 512, m_Establisher->phase2.encrypted.hxy); uint32_t tsB = htobe32 (i2p::util::GetSecondsSinceEpoch ()); memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4); RAND_bytes (m_Establisher->phase2.encrypted.filler, 12); m_Encryption.SetIV (y + 240); m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - + m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase2Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsB)); + std::bind(&NTCPSession::HandlePhase2Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsB)); + + } - } - void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) { (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Couldn't send Phase 2 message: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Received, shared_from_this (), + { + boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandlePhase3Received, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsB)); - } - } - + } + } + void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) { (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Phase 2 read error: ", ecode.message (), ". Wrong ident assumed"); if (ecode != boost::asio::error::operation_aborted) { @@ -247,7 +249,7 @@ namespace transport } } else - { + { #if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 7) // due the bug in gcc 4.7. std::shared_future.get() is not const CreateAESKey (m_Establisher->phase2.pubKey); @@ -258,22 +260,22 @@ namespace transport auto keyCreated = std::async (std::launch::async, [s] () { s->CreateAESKey (s->m_Establisher->phase2.pubKey); - }).share (); // TODO: use move capture in C++ 14 instead shared_future + }).share (); // TODO: use move capture in C++ 14 instead shared_future // let other operations execute while a key gets created m_Server.GetService ().post ([s, keyCreated]() - { + { keyCreated.get (); // we might wait if no more pending operations s->HandlePhase2 (); - }); + }); #endif - } - } + } + } void NTCPSession::HandlePhase2 () { m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - + m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); // verify uint8_t xy[512]; @@ -281,31 +283,31 @@ namespace transport memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); uint8_t digest[32]; SHA256 (xy, 512, digest); - if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) + if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) { LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); transports.ReuseDHKeysPair (m_DHKeysPair); m_DHKeysPair = nullptr; Terminate (); return ; - } + } SendPhase3 (); - } - + } + void NTCPSession::SendPhase3 () { auto& keys = i2p::context.GetPrivateKeys (); - uint8_t * buf = m_ReceiveBuffer; + uint8_t * buf = m_ReceiveBuffer; htobe16buf (buf, keys.GetPublic ()->GetFullLen ()); buf += 2; buf += i2p::context.GetIdentity ()->ToBuffer (buf, NTCP_BUFFER_SIZE); uint32_t tsA = htobe32 (i2p::util::GetSecondsSinceEpoch ()); htobuf32(buf,tsA); - buf += 4; + buf += 4; size_t signatureLen = keys.GetPublic ()->GetSignatureLen (); size_t len = (buf - m_ReceiveBuffer) + signatureLen; size_t paddingSize = len & 0x0F; // %16 - if (paddingSize > 0) + if (paddingSize > 0) { paddingSize = 16 - paddingSize; // fill padding with random data @@ -318,46 +320,46 @@ namespace transport s.Insert (m_Establisher->phase1.pubKey, 256); // x s.Insert (m_Establisher->phase2.pubKey, 256); // y s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA + s.Insert (tsA); // tsA s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB s.Sign (keys, buf); - m_Encryption.Encrypt(m_ReceiveBuffer, len, m_ReceiveBuffer); + m_Encryption.Encrypt(m_ReceiveBuffer, len, m_ReceiveBuffer); boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, len), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA)); - } - + std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA)); + } + void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) { - (void) bytes_transferred; + (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Couldn't send Phase 3 message: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { - // wait for phase4 + { + // wait for phase4 auto signatureLen = m_RemoteIdentity->GetSignatureLen (); size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Received, shared_from_this (), + if (paddingSize > 0) signatureLen += (16 - paddingSize); + boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandlePhase4Received, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA)); - } - } + } + } void NTCPSession::HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) - { + { if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Phase 3 read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { + { m_Decryption.Decrypt (m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); uint8_t * buf = m_ReceiveBuffer; uint16_t size = bufbe16toh (buf); @@ -366,30 +368,30 @@ namespace transport { LogPrint (eLogInfo, "NTCP: session already exists"); Terminate (); - } + } auto existing = i2p::data::netdb.FindRouter (identity->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : identity); - + size_t expectedSize = size + 2/*size*/ + 4/*timestamp*/ + m_RemoteIdentity->GetSignatureLen (); size_t paddingLen = expectedSize & 0x0F; - if (paddingLen) paddingLen = (16 - paddingLen); + if (paddingLen) paddingLen = (16 - paddingLen); if (expectedSize > NTCP_DEFAULT_PHASE3_SIZE) { // we need more bytes for Phase3 - expectedSize += paddingLen; - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, expectedSize - NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3ExtraReceived, shared_from_this (), + expectedSize += paddingLen; + boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, expectedSize - NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandlePhase3ExtraReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsB, paddingLen)); } else HandlePhase3 (tsB, paddingLen); - } + } } void NTCPSession::HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen) { if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Phase 3 extra read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); @@ -398,25 +400,25 @@ namespace transport { m_Decryption.Decrypt (m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, bytes_transferred, m_ReceiveBuffer+ NTCP_DEFAULT_PHASE3_SIZE); HandlePhase3 (tsB, paddingLen); - } - } + } + } void NTCPSession::HandlePhase3 (uint32_t tsB, size_t paddingLen) { uint8_t * buf = m_ReceiveBuffer + m_RemoteIdentity->GetFullLen () + 2 /*size*/; - uint32_t tsA = buf32toh(buf); + uint32_t tsA = buf32toh(buf); buf += 4; - buf += paddingLen; + buf += paddingLen; // check timestamp auto ts = i2p::util::GetSecondsSinceEpoch (); uint32_t tsA1 = be32toh (tsA); if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW) { - LogPrint (eLogError, "NTCP: Phase3 time difference ", ts - tsA1, " exceeds clock skew"); + LogPrint (eLogError, "NTCP: Phase3 time difference ", ts - tsA1, " exceeds clock skew"); Terminate (); return; - } + } // check signature SignedData s; @@ -424,13 +426,13 @@ namespace transport s.Insert (m_Establisher->phase2.pubKey, 256); // y s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident s.Insert (tsA); // tsA - s.Insert (tsB); // tsB + s.Insert (tsB); // tsB if (!s.Verify (m_RemoteIdentity, buf)) - { + { LogPrint (eLogError, "NTCP: signature verification failed"); Terminate (); return; - } + } SendPhase4 (tsA, tsB); } @@ -444,27 +446,27 @@ namespace transport s.Insert (tsA); // tsA s.Insert (tsB); // tsB auto& keys = i2p::context.GetPrivateKeys (); - auto signatureLen = keys.GetPublic ()->GetSignatureLen (); + auto signatureLen = keys.GetPublic ()->GetSignatureLen (); s.Sign (keys, m_ReceiveBuffer); size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); + if (paddingSize > 0) signatureLen += (16 - paddingSize); m_Encryption.Encrypt (m_ReceiveBuffer, signatureLen, m_ReceiveBuffer); boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } + std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { (void) bytes_transferred; if (ecode) - { + { LogPrint (eLogWarning, "NTCP: Couldn't send Phase 4 message: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else - { + { LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); m_Server.AddNTCPSession (shared_from_this ()); @@ -472,23 +474,23 @@ namespace transport m_ReceiveBufferOffset = 0; m_NextMessage = nullptr; Receive (); - } - } - + } + } + void NTCPSession::HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) { if (ecode) - { + { LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock"); if (ecode != boost::asio::error::operation_aborted) { - // this router doesn't like us + // this router doesn't like us i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); Terminate (); - } + } } else - { + { m_Decryption.Decrypt(m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); // check timestamp @@ -496,11 +498,11 @@ namespace transport auto ts = i2p::util::GetSecondsSinceEpoch (); if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW) { - LogPrint (eLogError, "NTCP: Phase4 time difference ", ts - tsB, " exceeds clock skew"); + LogPrint (eLogError, "NTCP: Phase4 time difference ", ts - tsB, " exceeds clock skew"); Terminate (); return; - } - + } + // verify signature SignedData s; s.Insert (m_Establisher->phase1.pubKey, 256); // x @@ -510,14 +512,14 @@ namespace transport s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB if (!s.Verify (m_RemoteIdentity, m_ReceiveBuffer)) - { + { LogPrint (eLogError, "NTCP: Phase 4 process error: signature verification failed"); Terminate (); return; - } + } LogPrint (eLogDebug, "NTCP: session to ", m_Socket.remote_endpoint (), " connected"); Connected (); - + m_ReceiveBufferOffset = 0; m_NextMessage = nullptr; Receive (); @@ -526,14 +528,14 @@ namespace transport void NTCPSession::Receive () { - m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, NTCP_BUFFER_SIZE - m_ReceiveBufferOffset), - std::bind(&NTCPSession::HandleReceived, shared_from_this (), + m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, NTCP_BUFFER_SIZE - m_ReceiveBufferOffset), + std::bind(&NTCPSession::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - + } + void NTCPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode) + if (ecode) { if (ecode != boost::asio::error::operation_aborted) LogPrint (eLogDebug, "NTCP: Read error: ", ecode.message ()); @@ -547,7 +549,7 @@ namespace transport m_ReceiveBufferOffset += bytes_transferred; if (m_ReceiveBufferOffset >= 16) - { + { // process received data uint8_t * nextBlock = m_ReceiveBuffer; while (m_ReceiveBufferOffset >= 16) @@ -555,14 +557,14 @@ namespace transport if (!DecryptNextBlock (nextBlock)) // 16 bytes { Terminate (); - return; - } + return; + } nextBlock += 16; m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) - memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); - } + } + if (m_ReceiveBufferOffset > 0) + memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); + } // read and process more is available boost::system::error_code ec; @@ -586,11 +588,11 @@ namespace transport delete[] buf; Terminate (); return; - } - m_ReceiveBufferOffset += moreBytes; + } + m_ReceiveBufferOffset += moreBytes; m_NumReceivedBytes += moreBytes; i2p::transport::transports.UpdateReceivedBytes (moreBytes); - // process more data + // process more data uint8_t * nextBlock = moreBuf; while (m_ReceiveBufferOffset >= 16) { @@ -598,26 +600,26 @@ namespace transport { delete[] buf; Terminate (); - return; - } + return; + } nextBlock += 16; m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) + } + if (m_ReceiveBufferOffset > 0) memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); // nextBlock points to memory inside buf delete[] buf; - } - m_Handler.Flush (); - + } + m_Handler.Flush (); + m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); Receive (); - } - } + } + } bool NTCPSession::DecryptNextBlock (const uint8_t * encrypted) // 16 bytes { if (!m_NextMessage) // new message, header expected - { + { // decrypt header and extract length uint8_t buf[16]; m_Decryption.Decrypt (encrypted, buf); @@ -633,26 +635,26 @@ namespace transport m_NextMessage = (dataSize + 16U + 15U) <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage (); m_NextMessage->Align (16); m_NextMessage->offset += 2; // size field - m_NextMessage->len = m_NextMessage->offset + dataSize; + m_NextMessage->len = m_NextMessage->offset + dataSize; memcpy (m_NextMessage->GetBuffer () - 2, buf, 16); m_NextMessageOffset = 16; - } + } else - { + { // timestamp int diff = (int)bufbe32toh (buf + 2) - (int)i2p::util::GetSecondsSinceEpoch (); LogPrint (eLogInfo, "NTCP: Timestamp. Time difference ", diff, " seconds"); return true; - } - } + } + } else // message continues - { + { m_Decryption.Decrypt (encrypted, m_NextMessage->GetBuffer () - 2 + m_NextMessageOffset); m_NextMessageOffset += 16; - } - + } + if (m_NextMessageOffset >= m_NextMessage->GetLength () + 2 + 4) // +checksum - { + { // we have a complete I2NP message uint8_t checksum[4]; htobe32buf (checksum, adler32 (adler32 (0, Z_NULL, 0), m_NextMessage->GetBuffer () - 2, m_NextMessageOffset - 4)); @@ -667,19 +669,19 @@ namespace transport } else LogPrint (eLogInfo, "NTCP: message expired"); - } + } else LogPrint (eLogWarning, "NTCP: Incorrect adler checksum of message, dropped"); m_NextMessage = nullptr; } - return true; - } + return true; + } void NTCPSession::Send (std::shared_ptr msg) { m_IsSending = true; - boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector >{ msg })); + boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (), + std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector >{ msg })); } boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (std::shared_ptr msg) @@ -688,14 +690,14 @@ namespace transport int len; if (msg) - { + { // regular I2NP if (msg->offset < 2) LogPrint (eLogError, "NTCP: Malformed I2NP message"); // TODO: - sendBuffer = msg->GetBuffer () - 2; + sendBuffer = msg->GetBuffer () - 2; len = msg->GetLength (); htobe16buf (sendBuffer, len); - } + } else { // prepare timestamp @@ -703,7 +705,7 @@ namespace transport len = 4; htobuf16(sendBuffer, 0); htobe32buf (sendBuffer + 2, i2p::util::GetSecondsSinceEpoch ()); - } + } int rem = (len + 6) & 0x0F; // %16 int padding = 0; if (rem > 0) { @@ -714,9 +716,9 @@ namespace transport htobe32buf (sendBuffer + len + 2 + padding, adler32 (adler32 (0, Z_NULL, 0), sendBuffer, len + 2+ padding)); int l = len + padding + 6; - m_Encryption.Encrypt(sendBuffer, l, sendBuffer); + m_Encryption.Encrypt(sendBuffer, l, sendBuffer); return boost::asio::buffer ((const uint8_t *)sendBuffer, l); - } + } void NTCPSession::Send (const std::vector >& msgs) @@ -725,23 +727,23 @@ namespace transport std::vector bufs; for (const auto& it: msgs) bufs.push_back (CreateMsgBuffer (it)); - boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); + boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), + std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); } - + void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs) { (void) msgs; m_IsSending = false; if (ecode) - { + { LogPrint (eLogWarning, "NTCP: Couldn't send msgs: ", ecode.message ()); // we shouldn't call Terminate () here, because HandleReceive takes care // TODO: 'delete this' statement in Terminate () must be eliminated later // Terminate (); } else - { + { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); m_NumSentBytes += bytes_transferred; i2p::transport::transports.UpdateSentBytes (bytes_transferred); @@ -749,28 +751,28 @@ namespace transport { Send (m_SendQueue); m_SendQueue.clear (); - } - } - } + } + } + } + - void NTCPSession::SendTimeSyncMessage () { Send (nullptr); - } + } void NTCPSession::SendI2NPMessages (const std::vector >& msgs) { - m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); - } + m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); + } void NTCPSession::PostI2NPMessages (std::vector > msgs) { if (m_IsTerminated) return; if (m_IsSending) { - if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE) + if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE) { for (const auto& it: msgs) m_SendQueue.push_back (it); @@ -779,131 +781,152 @@ namespace transport { LogPrint (eLogWarning, "NTCP: outgoing messages queue size exceeds ", NTCP_MAX_OUTGOING_QUEUE_SIZE); Terminate (); - } - } - else + } + } + else Send (msgs); - } + } //----------------------------------------- NTCPServer::NTCPServer (): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), - m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr) + m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), + m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr), + m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr) { } - + NTCPServer::~NTCPServer () { Stop (); - } + } void NTCPServer::Start () { if (!m_IsRunning) - { + { m_IsRunning = true; m_Thread = new std::thread (std::bind (&NTCPServer::Run, this)); - // create acceptors - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) + // we are using a proxy, don't create any acceptors + if(UsingProxy()) { - if (!address) continue; - if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP) + // TODO: resolve proxy until it is resolved + boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); + boost::system::error_code e; + auto itr = m_Resolver.resolve(q, e); + if(e) { - if (address->host.is_v4()) + LogPrint(eLogError, "NTCP: Failed to resolve proxy ", e.message()); + } + else + { + m_ProxyEndpoint = new boost::asio::ip::tcp::endpoint(*itr); + } + } + else + { + // create acceptors + auto& addresses = context.GetRouterInfo ().GetAddresses (); + for (const auto& address: addresses) + { + if (!address) continue; + if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { - try + if (address->host.is_v4()) { - m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); - } catch ( std::exception & ex ) { - /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to ip4 port ",address->port, ex.what()); - continue; + try + { + m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); + } catch ( std::exception & ex ) { + /** fail to bind ip4 */ + LogPrint(eLogError, "NTCP: Failed to bind to ip4 port ",address->port, ex.what()); + continue; + } + + LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address->port); + auto conn = std::make_shared(*this); + m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, conn, std::placeholders::_1)); } - - LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address->port); - auto conn = std::make_shared(*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, - conn, std::placeholders::_1)); - } - else if (address->host.is_v6() && context.SupportsV6 ()) - { - m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service); - try + else if (address->host.is_v6() && context.SupportsV6 ()) { - m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6()); - m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true)); - - m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); - m_NTCPV6Acceptor->listen (); - - LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address->port); - auto conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, - this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); - continue; + m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service); + try + { + m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6()); + m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true)); + m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); + m_NTCPV6Acceptor->listen (); + + LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address->port); + auto conn = std::make_shared (*this); + m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); + } catch ( std::exception & ex ) { + LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); + continue; + } } - } + } } } - ScheduleTermination (); - } + ScheduleTermination (); + } } - + void NTCPServer::Stop () - { + { { // we have to copy it because Terminate changes m_NTCPSessions - auto ntcpSessions = m_NTCPSessions; + auto ntcpSessions = m_NTCPSessions; for (auto& it: ntcpSessions) it.second->Terminate (); for (auto& it: m_PendingIncomingSessions) it->Terminate (); - } + } m_NTCPSessions.clear (); if (m_IsRunning) - { + { m_IsRunning = false; - m_TerminationTimer.cancel (); - if (m_NTCPAcceptor) - { - delete m_NTCPAcceptor; + m_TerminationTimer.cancel (); + if (m_NTCPAcceptor) + { + delete m_NTCPAcceptor; m_NTCPAcceptor = nullptr; } - if (m_NTCPV6Acceptor) + if (m_NTCPV6Acceptor) { - delete m_NTCPV6Acceptor; + delete m_NTCPV6Acceptor; m_NTCPV6Acceptor = nullptr; } m_Service.stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = nullptr; - } - } - } + } + if(m_ProxyEndpoint) + { + delete m_ProxyEndpoint; + m_ProxyEndpoint = nullptr; + } + } + } + - - void NTCPServer::Run () - { + void NTCPServer::Run () + { while (m_IsRunning) { try - { + { m_Service.run (); } catch (std::exception& ex) { LogPrint (eLogError, "NTCP: runtime exception: ", ex.what ()); - } - } - } + } + } + } bool NTCPServer::AddNTCPSession (std::shared_ptr session) { @@ -918,13 +941,13 @@ namespace transport } m_NTCPSessions.insert (std::pair >(ident, session)); return true; - } + } void NTCPServer::RemoveNTCPSession (std::shared_ptr session) { if (session && session->GetRemoteIdentity ()) m_NTCPSessions.erase (session->GetRemoteIdentity ()->GetIdentHash ()); - } + } std::shared_ptr NTCPServer::FindNTCPSession (const i2p::data::IdentHash& ident) { @@ -932,14 +955,14 @@ namespace transport if (it != m_NTCPSessions.end ()) return it->second; return nullptr; - } - + } + void NTCPServer::HandleAccept (std::shared_ptr conn, const boost::system::error_code& error) - { + { if (!error) { boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); + auto ep = conn->GetSocket ().remote_endpoint(ec); if (!ec) { LogPrint (eLogDebug, "NTCP: Connected from ", ep); @@ -947,35 +970,35 @@ namespace transport { conn->ServerLogin (); m_PendingIncomingSessions.push_back (conn); - } + } } else LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); } - + if (error != boost::asio::error::operation_aborted) { - conn = std::make_shared (*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, + conn = std::make_shared (*this); + m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, conn, std::placeholders::_1)); - } + } } void NTCPServer::HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error) - { + { if (!error) { boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); + auto ep = conn->GetSocket ().remote_endpoint(ec); if (!ec) { LogPrint (eLogDebug, "NTCP: Connected from ", ep); if (conn) - { + { conn->ServerLogin (); m_PendingIncomingSessions.push_back (conn); - } + } } else LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); @@ -983,40 +1006,65 @@ namespace transport if (error != boost::asio::error::operation_aborted) { - conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, + conn = std::make_shared (*this); + m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - } + } + } - void NTCPServer::Connect (const boost::asio::ip::address& address, int port, std::shared_ptr conn) + void NTCPServer::Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn) { LogPrint (eLogDebug, "NTCP: Connecting to ", address ,":", port); - m_Service.post([=]() - { + m_Service.post([=]() { if (this->AddNTCPSession (conn)) { + auto timer = std::make_shared(m_Service); - timer->expires_from_now (boost::posix_time::seconds(NTCP_CONNECT_TIMEOUT)); - timer->async_wait ([conn](const boost::system::error_code& ecode) + timer->expires_from_now (boost::posix_time::seconds(NTCP_CONNECT_TIMEOUT)); + timer->async_wait ([conn](const boost::system::error_code& ecode) { + if (ecode != boost::asio::error::operation_aborted) { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), - std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn, timer)); - } - }); + LogPrint (eLogInfo, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn, timer)); + } + }); + } + + void NTCPServer::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(m_ProxyEndpoint == nullptr) + { + return; + } + m_Service.post([=]() { + if (this->AddNTCPSession (conn)) + { + + auto timer = std::make_shared(m_Service); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCPServer::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); } void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer) { - timer->cancel (); + timer->cancel (); if (ecode) - { + { LogPrint (eLogInfo, "NTCP: Connect error ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); @@ -1028,8 +1076,193 @@ namespace transport if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6 context.UpdateNTCPV6Address (conn->GetSocket ().local_endpoint ().address ()); conn->ClientLogin (); - } - } + } + } + + void NTCPServer::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) + { + m_ProxyType = proxytype; + m_ProxyAddress = addr; + m_ProxyPort = port; + } + + void NTCPServer::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + if(ecode) + { + LogPrint(eLogWarning, "NTCP: failed to connect to proxy ", ecode.message()); + timer->cancel(); + conn->Terminate(); + return; + } + if(m_ProxyType == eSocksProxy) + { + // TODO: support username/password auth etc + uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { + (void) transferred; + if(ec) + { + LogPrint(eLogWarning, "NTCP: socks5 write error ", ec.message()); + } + }); + uint8_t readbuff[2]; + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), [=](const boost::system::error_code & ec, std::size_t transferred) { + if(ec) + { + LogPrint(eLogError, "NTCP: socks5 read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + return; + } + else if(transferred == 2) + { + if(readbuff[1] == 0x00) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if (readbuff[1] == 0xff) + { + LogPrint(eLogError, "NTCP: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + } + LogPrint(eLogError, "NTCP: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); + } + else if(m_ProxyType == eHTTPProxy) + { + i2p::http::HTTPReq req; + req.method = "CONNECT"; + req.version ="HTTP/1.1"; + if(addrtype == eIP6Address) + req.uri = "[" + host + "]:" + std::to_string(port); + else + req.uri = host + ":" + std::to_string(port); + + boost::asio::streambuf writebuff; + std::ostream out(&writebuff); + out << req.to_string(); + + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP: http proxy write error ", ec.message()); + }); + + boost::asio::streambuf * readbuff = new boost::asio::streambuf; + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", [=] (const boost::system::error_code & ec, std::size_t transferred) { + if(ec) + { + LogPrint(eLogError, "NTCP: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + } + else + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + { + LogPrint(eLogError, "NTCP: http proxy rejected request ", res.code); + } + } + else + LogPrint(eLogError, "NTCP: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); + } + else + LogPrint(eLogError, "NTCP: unknown proxy type, invalid state"); + } + + void NTCPServer::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + + // build request + size_t sz = 0; + uint8_t buff[256]; + uint8_t readbuff[256]; + buff[0] = 0x05; + buff[1] = 0x01; + buff[2] = 0x00; + + if(addrtype == eIP4Address) + { + buff[3] = 0x01; + auto addr = boost::asio::ip::address::from_string(host).to_v4(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff+4, addrbytes.data(), addrsize); + } + else if (addrtype == eIP6Address) + { + buff[3] = 0x04; + auto addr = boost::asio::ip::address::from_string(host).to_v6(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff+4, addrbytes.data(), addrsize); + } + else if (addrtype == eHostname) + { + buff[3] = 0x03; + size_t addrsize = host.size(); + sz = addrsize + 1 + 4; + if (2 + sz > sizeof(buff)) + { + // too big + return; + } + buff[4] = (uint8_t) addrsize; + memcpy(buff+4, host.c_str(), addrsize); + } + htobe16buf(buff+sz, port); + sz += 2; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { + if(ec) + { + LogPrint(eLogError, "NTCP: failed to write handshake to socks proxy ", ec.message()); + return; + } + }); + + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, sz), [=](const boost::system::error_code & e, std::size_t transferred) { + if(e) + { + LogPrint(eLogError, "NTCP: socks proxy read error ", e.message()); + } + else if(transferred == sz) + { + if( readbuff[1] == 0x00) + { + timer->cancel(); + conn->ClientLogin(); + return; + } + } + if(!e) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + timer->cancel(); + conn->Terminate(); + }); + } void NTCPServer::ScheduleTermination () { @@ -1041,19 +1274,18 @@ namespace transport void NTCPServer::HandleTerminationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { auto ts = i2p::util::GetSecondsSinceEpoch (); // established for (auto& it: m_NTCPSessions) - if (it.second->IsTerminationTimeoutExpired (ts)) + if (it.second->IsTerminationTimeoutExpired (ts)) { auto session = it.second; // Termniate modifies m_NTCPSession, so we postpone it - m_Service.post ([session] - { + m_Service.post ([session] { LogPrint (eLogDebug, "NTCP: No activity for ", session->GetTerminationTimeout (), " seconds"); session->Terminate (); - }); + }); } // pending for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) @@ -1062,15 +1294,15 @@ namespace transport it = m_PendingIncomingSessions.erase (it); // established or terminated else if ((*it)->IsTerminationTimeoutExpired (ts)) { - (*it)->Terminate (); + (*it)->Terminate (); it = m_PendingIncomingSessions.erase (it); // expired - } + } else it++; } - - ScheduleTermination (); - } - } -} -} + + ScheduleTermination (); + } + } +} +} diff --git a/NTCPSession.h b/libi2pd/NTCPSession.h similarity index 75% rename from NTCPSession.h rename to libi2pd/NTCPSession.h index 9de75d02..a45f06f7 100644 --- a/NTCPSession.h +++ b/libi2pd/NTCPSession.h @@ -21,8 +21,8 @@ namespace transport { uint8_t pubKey[256]; uint8_t HXxorHI[32]; - }; - + }; + struct NTCPPhase2 { uint8_t pubKey[256]; @@ -31,17 +31,17 @@ namespace transport uint8_t hxy[32]; uint8_t timestamp[4]; uint8_t filler[12]; - } encrypted; - }; + } encrypted; + }; - const size_t NTCP_MAX_MESSAGE_SIZE = 16384; + const size_t NTCP_MAX_MESSAGE_SIZE = 16384; const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds const int NTCP_ESTABLISH_TIMEOUT = 10; // 10 seconds const int NTCP_TERMINATION_TIMEOUT = 120; // 2 minutes - const int NTCP_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds - const size_t NTCP_DEFAULT_PHASE3_SIZE = 2/*size*/ + i2p::data::DEFAULT_IDENTITY_SIZE/*387*/ + 4/*ts*/ + 15/*padding*/ + 40/*signature*/; // 448 - const int NTCP_CLOCK_SKEW = 60; // in seconds + const int NTCP_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds + const size_t NTCP_DEFAULT_PHASE3_SIZE = 2/*size*/ + i2p::data::DEFAULT_IDENTITY_SIZE/*387*/ + 4/*ts*/ + 15/*padding*/ + 40/*signature*/; // 448 + const int NTCP_CLOCK_SKEW = 60; // in seconds const int NTCP_MAX_OUTGOING_QUEUE_SIZE = 200; // how many messages we can queue up class NTCPServer; @@ -55,13 +55,13 @@ namespace transport void Done (); boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; - bool IsEstablished () const { return m_IsEstablished; }; + bool IsEstablished () const { return m_IsEstablished; }; bool IsTerminated () const { return m_IsTerminated; }; - + void ClientLogin (); void ServerLogin (); void SendI2NPMessages (const std::vector >& msgs); - + private: void PostI2NPMessages (std::vector > msgs); @@ -70,7 +70,7 @@ namespace transport void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; } void CreateAESKey (uint8_t * pubKey); - + // client void SendPhase3 (); void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); @@ -88,35 +88,35 @@ namespace transport void HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen); void HandlePhase3 (uint32_t tsB, size_t paddingLen); void HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - + // common void Receive (); void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - bool DecryptNextBlock (const uint8_t * encrypted); - + bool DecryptNextBlock (const uint8_t * encrypted); + void Send (std::shared_ptr msg); boost::asio::const_buffers_1 CreateMsgBuffer (std::shared_ptr msg); void Send (const std::vector >& msgs); void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs); - + private: NTCPServer& m_Server; boost::asio::ip::tcp::socket m_Socket; bool m_IsEstablished, m_IsTerminated; - + i2p::crypto::CBCDecryption m_Decryption; i2p::crypto::CBCEncryption m_Encryption; struct Establisher - { + { NTCPPhase1 phase1; NTCPPhase2 phase2; - } * m_Establisher; - + } * m_Establisher; + i2p::crypto::AESAlignedBuffer m_ReceiveBuffer; i2p::crypto::AESAlignedBuffer<16> m_TimeSyncBuffer; - int m_ReceiveBufferOffset; + int m_ReceiveBufferOffset; std::shared_ptr m_NextMessage; size_t m_NextMessageOffset; @@ -124,13 +124,28 @@ namespace transport bool m_IsSending; std::vector > m_SendQueue; - }; + }; // TODO: move to NTCP.h/.cpp class NTCPServer { public: + enum RemoteAddressType + { + eIP4Address, + eIP6Address, + eHostname + }; + + enum ProxyType + { + eNoProxy, + eSocksProxy, + eHTTPProxy + }; + + NTCPServer (); ~NTCPServer (); @@ -140,12 +155,17 @@ namespace transport bool AddNTCPSession (std::shared_ptr session); void RemoveNTCPSession (std::shared_ptr session); std::shared_ptr FindNTCPSession (const i2p::data::IdentHash& ident); - void Connect (const boost::asio::ip::address& address, int port, std::shared_ptr conn); + void ConnectWithProxy (const std::string& addr, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn); + void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn); + + bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; }; + bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; }; + bool NetworkIsReady() const { return IsBoundV4() || IsBoundV6() || UsingProxy(); }; + bool UsingProxy() const { return m_ProxyType != eNoProxy; }; - bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; }; - bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; }; - - boost::asio::io_service& GetService () { return m_Service; }; + void UseProxy(ProxyType proxy, const std::string & address, uint16_t port); + + boost::asio::io_service& GetService () { return m_Service; }; private: @@ -155,14 +175,17 @@ namespace transport void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); + void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); + void AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); + // timer void ScheduleTermination (); void HandleTerminationTimer (const boost::system::error_code& ecode); - - private: + + private: bool m_IsRunning; - std::thread * m_Thread; + std::thread * m_Thread; boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; boost::asio::deadline_timer m_TerminationTimer; @@ -170,12 +193,17 @@ namespace transport std::map > m_NTCPSessions; // access from m_Thread only std::list > m_PendingIncomingSessions; + ProxyType m_ProxyType; + std::string m_ProxyAddress; + uint16_t m_ProxyPort; + boost::asio::ip::tcp::resolver m_Resolver; + boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; public: // for HTTP/I2PControl const decltype(m_NTCPSessions)& GetNTCPSessions () const { return m_NTCPSessions; }; - }; -} -} + }; +} +} #endif diff --git a/NetDb.cpp b/libi2pd/NetDb.cpp similarity index 99% rename from NetDb.cpp rename to libi2pd/NetDb.cpp index b4ad6399..7b6a2c1a 100644 --- a/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -13,7 +13,7 @@ #include "Transports.h" #include "RouterContext.h" #include "Garlic.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Config.h" using namespace i2p::transport; diff --git a/NetDb.h b/libi2pd/NetDb.hpp similarity index 98% rename from NetDb.h rename to libi2pd/NetDb.hpp index 0a05c143..a5cec84f 100644 --- a/NetDb.h +++ b/libi2pd/NetDb.hpp @@ -1,6 +1,6 @@ #ifndef NETDB_H__ #define NETDB_H__ - +// this file is called NetDb.hpp to resolve conflict with libc's netdb.h on case insensitive fs #include #include #include diff --git a/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp similarity index 99% rename from NetDbRequests.cpp rename to libi2pd/NetDbRequests.cpp index 866bc6d9..2fe2c229 100644 --- a/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -1,7 +1,7 @@ #include "Log.h" #include "I2NPProtocol.h" #include "Transports.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "NetDbRequests.h" namespace i2p diff --git a/NetDbRequests.h b/libi2pd/NetDbRequests.h similarity index 100% rename from NetDbRequests.h rename to libi2pd/NetDbRequests.h diff --git a/Profiling.cpp b/libi2pd/Profiling.cpp similarity index 100% rename from Profiling.cpp rename to libi2pd/Profiling.cpp diff --git a/Profiling.h b/libi2pd/Profiling.h similarity index 100% rename from Profiling.h rename to libi2pd/Profiling.h diff --git a/Queue.h b/libi2pd/Queue.h similarity index 100% rename from Queue.h rename to libi2pd/Queue.h diff --git a/Reseed.cpp b/libi2pd/Reseed.cpp similarity index 99% rename from Reseed.cpp rename to libi2pd/Reseed.cpp index 1766e1f6..f35425da 100644 --- a/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -14,7 +14,7 @@ #include "FS.h" #include "Log.h" #include "Identity.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "HTTP.h" #include "util.h" #include "Config.h" diff --git a/Reseed.h b/libi2pd/Reseed.h similarity index 100% rename from Reseed.h rename to libi2pd/Reseed.h diff --git a/RouterContext.cpp b/libi2pd/RouterContext.cpp similarity index 97% rename from RouterContext.cpp rename to libi2pd/RouterContext.cpp index b558e050..7be25b04 100644 --- a/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -3,7 +3,7 @@ #include "Crypto.h" #include "Timestamp.h" #include "I2NPProtocol.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "FS.h" #include "util.h" #include "version.h" @@ -17,8 +17,8 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_StartupTime (0), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone), - m_NetID (I2PD_NET_ID) + m_StartupTime (0), m_ShareRatio (100), m_Status (eRouterStatusOK), + m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -246,6 +246,13 @@ namespace i2p else { SetBandwidth('K'); } } + void RouterContext::SetShareRatio (int percents) + { + if (percents < 0) percents = 0; + if (percents > 100) percents = 100; + m_ShareRatio = percents; + } + bool RouterContext::IsUnreachable () const { return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; diff --git a/RouterContext.h b/libi2pd/RouterContext.h similarity index 95% rename from RouterContext.h rename to libi2pd/RouterContext.h index 7ce310ee..b3146b56 100644 --- a/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -54,6 +54,7 @@ namespace i2p uint32_t GetStartupTime () const { return m_StartupTime; }; uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; + uint64_t GetTransitBandwidthLimit () const { return (m_BandwidthLimit*m_ShareRatio)/100LL; }; RouterStatus GetStatus () const { return m_Status; }; void SetStatus (RouterStatus status); RouterError GetError () const { return m_Error; }; @@ -74,6 +75,7 @@ namespace i2p std::string GetFamily () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ + void SetShareRatio (int percents); // 0 - 100 bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; @@ -116,7 +118,8 @@ namespace i2p uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; uint64_t m_StartupTime; // in seconds since epoch - uint32_t m_BandwidthLimit; // allowed bandwidth + uint64_t m_BandwidthLimit; // allowed bandwidth + int m_ShareRatio; RouterStatus m_Status; RouterError m_Error; int m_NetID; diff --git a/RouterInfo.cpp b/libi2pd/RouterInfo.cpp similarity index 97% rename from RouterInfo.cpp rename to libi2pd/RouterInfo.cpp index 205262e5..be2a5904 100644 --- a/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -12,7 +12,7 @@ #include "Base.h" #include "Timestamp.h" #include "Log.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "RouterContext.h" #include "RouterInfo.h" @@ -264,6 +264,8 @@ namespace data introducer.iTag = boost::lexical_cast(value); else if (!strcmp (key, "ikey")) Base64ToByteStream (value, strlen (value), introducer.iKey, 32); + else if (!strcmp (key, "iexp")) + introducer.iExp = boost::lexical_cast(value); } if (!s) return; } @@ -478,6 +480,18 @@ namespace data properties << ';'; i++; } + i = 0; + for (const auto& introducer: address.ssu->introducers) + { + if (introducer.iExp) // expiration is specified + { + WriteString ("iexp" + boost::lexical_cast(i), properties); + properties << '='; + WriteString (boost::lexical_cast(introducer.iExp), properties); + properties << ';'; + } + i++; + } } // write intro key WriteString ("key", properties); diff --git a/RouterInfo.h b/libi2pd/RouterInfo.h similarity index 99% rename from RouterInfo.h rename to libi2pd/RouterInfo.h index 7300e579..f23fb152 100644 --- a/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -73,10 +73,12 @@ namespace data typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey struct Introducer { + Introducer (): iExp (0) {}; boost::asio::ip::address iHost; int iPort; IntroKey iKey; uint32_t iTag; + uint32_t iExp; }; struct SSUExt diff --git a/SSU.cpp b/libi2pd/SSU.cpp similarity index 99% rename from SSU.cpp rename to libi2pd/SSU.cpp index 93eedb23..1edeb3bd 100644 --- a/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -3,7 +3,7 @@ #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "SSU.h" namespace i2p diff --git a/SSU.h b/libi2pd/SSU.h similarity index 100% rename from SSU.h rename to libi2pd/SSU.h diff --git a/SSUData.cpp b/libi2pd/SSUData.cpp similarity index 99% rename from SSUData.cpp rename to libi2pd/SSUData.cpp index 78f93270..67394d98 100644 --- a/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -2,7 +2,7 @@ #include #include "Log.h" #include "Timestamp.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "SSU.h" #include "SSUData.h" #ifdef WITH_EVENTS diff --git a/SSUData.h b/libi2pd/SSUData.h similarity index 100% rename from SSUData.h rename to libi2pd/SSUData.h diff --git a/SSUSession.cpp b/libi2pd/SSUSession.cpp similarity index 99% rename from SSUSession.cpp rename to libi2pd/SSUSession.cpp index 49757772..b7493814 100644 --- a/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -4,7 +4,7 @@ #include "Timestamp.h" #include "RouterContext.h" #include "Transports.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "SSU.h" #include "SSUSession.h" diff --git a/SSUSession.h b/libi2pd/SSUSession.h similarity index 100% rename from SSUSession.h rename to libi2pd/SSUSession.h diff --git a/Signature.cpp b/libi2pd/Signature.cpp similarity index 100% rename from Signature.cpp rename to libi2pd/Signature.cpp diff --git a/Signature.h b/libi2pd/Signature.h similarity index 100% rename from Signature.h rename to libi2pd/Signature.h diff --git a/Streaming.cpp b/libi2pd/Streaming.cpp similarity index 100% rename from Streaming.cpp rename to libi2pd/Streaming.cpp diff --git a/Streaming.h b/libi2pd/Streaming.h similarity index 100% rename from Streaming.h rename to libi2pd/Streaming.h diff --git a/Tag.h b/libi2pd/Tag.h similarity index 100% rename from Tag.h rename to libi2pd/Tag.h diff --git a/Timestamp.cpp b/libi2pd/Timestamp.cpp similarity index 100% rename from Timestamp.cpp rename to libi2pd/Timestamp.cpp diff --git a/Timestamp.h b/libi2pd/Timestamp.h similarity index 100% rename from Timestamp.h rename to libi2pd/Timestamp.h diff --git a/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp similarity index 97% rename from TransitTunnel.cpp rename to libi2pd/TransitTunnel.cpp index dfe01a05..bcba4d60 100644 --- a/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -22,6 +22,7 @@ namespace tunnel void TransitTunnel::EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) { m_Encryption.Encrypt (in->GetPayload () + 4, out->GetPayload () + 4); + i2p::transport::transports.UpdateTotalTransitTransmittedBytes (TUNNEL_DATA_MSG_SIZE); } TransitTunnelParticipant::~TransitTunnelParticipant () diff --git a/TransitTunnel.h b/libi2pd/TransitTunnel.h similarity index 100% rename from TransitTunnel.h rename to libi2pd/TransitTunnel.h diff --git a/TransportSession.h b/libi2pd/TransportSession.h similarity index 100% rename from TransportSession.h rename to libi2pd/TransportSession.h diff --git a/Transports.cpp b/libi2pd/Transports.cpp similarity index 83% rename from Transports.cpp rename to libi2pd/Transports.cpp index b0a19379..21007408 100644 --- a/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -2,9 +2,10 @@ #include "Crypto.h" #include "RouterContext.h" #include "I2NPProtocol.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Transports.h" #include "Config.h" +#include "HTTP.h" #ifdef WITH_EVENTS #include "Event.h" #include "util.h" @@ -19,7 +20,7 @@ namespace transport DHKeysPairSupplier::DHKeysPairSupplier (int size): m_QueueSize (size), m_IsRunning (false), m_Thread (nullptr) { - } + } DHKeysPairSupplier::~DHKeysPairSupplier () { @@ -35,13 +36,13 @@ namespace transport void DHKeysPairSupplier::Stop () { m_IsRunning = false; - m_Acquired.notify_one (); + m_Acquired.notify_one (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = 0; - } + } } void DHKeysPairSupplier::Run () @@ -50,7 +51,7 @@ namespace transport { int num, total = 0; while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 20) - { + { CreateDHKeysPairs (num); total += num; } @@ -63,9 +64,9 @@ namespace transport { std::unique_lock l(m_AcquiredMutex); m_Acquired.wait (l); // wait for element gets aquired - } + } } - } + } void DHKeysPairSupplier::CreateDHKeysPairs (int num) { @@ -91,8 +92,8 @@ namespace transport m_Queue.pop (); m_Acquired.notify_one (); return pair; - } - } + } + } // queue is empty, create new auto pair = std::make_shared (); pair->GenerateKeys (); @@ -106,19 +107,21 @@ namespace transport m_Queue.push (pair); } - Transports transports; - - Transports::Transports (): + Transports transports; + + Transports::Transports (): m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys - m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0), - m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) - { + m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), + m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), + m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), + m_LastTransitBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) + { } - - Transports::~Transports () - { + + Transports::~Transports () + { Stop (); if (m_Service) { @@ -126,8 +129,8 @@ namespace transport delete m_PeerTestTimer; m_PeerTestTimer = nullptr; delete m_Work; m_Work = nullptr; delete m_Service; m_Service = nullptr; - } - } + } + } void Transports::Start (bool enableNTCP, bool enableSSU) { @@ -142,6 +145,39 @@ namespace transport m_DHKeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); + std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); + i2p::http::URL proxyurl; + if(ntcpproxy.size() && enableNTCP) + { + if(proxyurl.parse(ntcpproxy)) + { + if(proxyurl.schema == "socks" || proxyurl.schema == "http") + { + m_NTCPServer = new NTCPServer(); + + NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy; + + if (proxyurl.schema == "http") + proxytype = NTCPServer::eHTTPProxy; + + m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCPServer->Start(); + if(!m_NTCPServer->NetworkIsReady()) + { + LogPrint(eLogError, "Transports: NTCP failed to start with proxy"); + m_NTCPServer->Stop(); + delete m_NTCPServer; + m_NTCPServer = nullptr; + } + } + else + LogPrint(eLogError, "Transports: unsupported NTCP proxy URL ", ntcpproxy); + } + else + LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy); + return; + } + // create acceptors auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address : addresses) @@ -158,8 +194,8 @@ namespace transport delete m_NTCPServer; m_NTCPServer = nullptr; } - } - + } + if (address->transportStyle == RouterInfo::eTransportSSU) { if (m_SSUServer == nullptr && enableSSU) @@ -182,16 +218,16 @@ namespace transport else LogPrint (eLogError, "Transports: SSU server already exists"); } - } + } m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); } - + void Transports::Stop () - { - if (m_PeerCleanupTimer) m_PeerCleanupTimer->cancel (); + { + if (m_PeerCleanupTimer) m_PeerCleanupTimer->cancel (); if (m_PeerTestTimer) m_PeerTestTimer->cancel (); m_Peers.clear (); if (m_SSUServer) @@ -199,40 +235,40 @@ namespace transport m_SSUServer->Stop (); delete m_SSUServer; m_SSUServer = nullptr; - } + } if (m_NTCPServer) { m_NTCPServer->Stop (); delete m_NTCPServer; m_NTCPServer = nullptr; - } + } m_DHKeysPairSupplier.Stop (); m_IsRunning = false; if (m_Service) m_Service->stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = nullptr; - } - } + } + } - void Transports::Run () - { + void Transports::Run () + { while (m_IsRunning && m_Service) { try - { + { m_Service->run (); } catch (std::exception& ex) { LogPrint (eLogError, "Transports: runtime exception: ", ex.what ()); - } - } + } + } } - + void Transports::UpdateBandwidth () { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); @@ -241,13 +277,15 @@ namespace transport auto delta = ts - m_LastBandwidthUpdateTime; if (delta > 0) { - m_InBandwidth = (m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes)*1000/delta; // per second - m_OutBandwidth = (m_TotalSentBytes - m_LastOutBandwidthUpdateBytes)*1000/delta; // per second - } + m_InBandwidth = (m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes)*1000/delta; // per second + m_OutBandwidth = (m_TotalSentBytes - m_LastOutBandwidthUpdateBytes)*1000/delta; // per second + m_TransitBandwidth = (m_TotalTransitTransmittedBytes - m_LastTransitBandwidthUpdateBytes)*1000/delta; + } } m_LastBandwidthUpdateTime = ts; - m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes; - m_LastOutBandwidthUpdateBytes = m_TotalSentBytes; + m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes; + m_LastOutBandwidthUpdateBytes = m_TotalSentBytes; + m_LastTransitBandwidthUpdateBytes = m_TotalTransitTransmittedBytes; } bool Transports::IsBandwidthExceeded () const @@ -257,10 +295,16 @@ namespace transport return bw > limit; } + bool Transports::IsTransitBandwidthExceeded () const + { + auto limit = i2p::context.GetTransitBandwidthLimit() * 1024; // convert to bytes + return m_TransitBandwidth > limit; + } + void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { - SendMessages (ident, std::vector > {msg }); - } + SendMessages (ident, std::vector > {msg }); + } void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) { @@ -268,12 +312,12 @@ namespace transport QueueIntEvent("transport.send", ident.ToBase64(), msgs.size()); #endif m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs)); - } + } void Transports::PostMessages (i2p::data::IdentHash ident, std::vector > msgs) { if (ident == i2p::context.GetRouterInfo ().GetIdentHash ()) - { + { // we send it to ourself for (auto& it: msgs) m_LoopbackHandler.PutNextMessage (it); @@ -284,12 +328,12 @@ namespace transport auto it = m_Peers.find (ident); if (it == m_Peers.end ()) { - bool connected = false; + bool connected = false; try { auto r = netdb.FindRouter (ident); { - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, i2p::util::GetSecondsSinceEpoch (), {} })).first; } @@ -300,29 +344,29 @@ namespace transport LogPrint (eLogError, "Transports: PostMessages exception:", ex.what ()); } if (!connected) return; - } + } if (!it->second.sessions.empty ()) it->second.sessions.front ()->SendI2NPMessages (msgs); else - { + { if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES) - { + { for (auto& it1: msgs) it->second.delayedMessages.push_back (it1); } else { LogPrint (eLogWarning, "Transports: delayed messages queue size exceeds ", MAX_NUM_DELAYED_MESSAGES); - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (it); - } - } - } - + } + } + } + bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer) { if (peer.router) // we have RI already - { + { if (!peer.numAttempts) // NTCP { peer.numAttempts++; @@ -333,14 +377,25 @@ namespace transport if (!address->host.is_unspecified ()) // we have address now #else boost::system::error_code ecode; - address->host.to_string (ecode); + address->host.to_string (ecode); if (!ecode) #endif { if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ()) - { + { auto s = std::make_shared (*m_NTCPServer, peer.router); - m_NTCPServer->Connect (address->host, address->port, s); + if(m_NTCPServer->UsingProxy()) + { + NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address; + std::string addr = address->host.to_string(); + + if(address->host.is_v6()) + remote = NTCPServer::eIP6Address; + + m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s); + } + else + m_NTCPServer->Connect (address->host, address->port, s); return true; } } @@ -348,12 +403,20 @@ namespace transport { if (address->addressString.length () > 0) // trying to resolve { - LogPrint (eLogDebug, "Transports: Resolving NTCP ", address->addressString); - NTCPResolve (address->addressString, ident); + if(m_NTCPServer->UsingProxy()) + { + auto s = std::make_shared (*m_NTCPServer, peer.router); + m_NTCPServer->ConnectWithProxy(address->addressString, address->port, NTCPServer::eHostname, s); + } + else + { + LogPrint (eLogDebug, "Transports: Resolving NTCP ", address->addressString); + NTCPResolve (address->addressString, ident); + } return true; } } - } + } else LogPrint (eLogDebug, "Transports: NTCP address is not present for ", i2p::data::GetIdentHashAbbreviation (ident), ", trying SSU"); } @@ -384,56 +447,56 @@ namespace transport } } } - } + } LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); peer.Done (); - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (ident); return false; - } + } else // otherwise request RI { LogPrint (eLogInfo, "Transports: RouterInfo for ", ident.ToBase64 (), " not found, requested"); i2p::data::netdb.RequestDestination (ident, std::bind ( &Transports::RequestComplete, this, std::placeholders::_1, ident)); - } + } return true; - } - + } + void Transports::RequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident) { m_Service->post (std::bind (&Transports::HandleRequestComplete, this, r, ident)); - } - + } + void Transports::HandleRequestComplete (std::shared_ptr r, i2p::data::IdentHash ident) { auto it = m_Peers.find (ident); if (it != m_Peers.end ()) - { + { if (r) { LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, Trying to connect"); it->second.router = r; ConnectToPeer (ident, it->second); - } + } else { LogPrint (eLogWarning, "Transports: RouterInfo not found, Failed to send messages"); - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (it); - } - } - } + } + } + } void Transports::NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident) { auto resolver = std::make_shared(*m_Service); - resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), - std::bind (&Transports::HandleNTCPResolve, this, + resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), + std::bind (&Transports::HandleNTCPResolve, this, std::placeholders::_1, std::placeholders::_2, ident, resolver)); } - void Transports::HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + void Transports::HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, i2p::data::IdentHash ident, std::shared_ptr resolver) { auto it1 = m_Peers.find (ident); @@ -443,7 +506,7 @@ namespace transport if (!ecode && peer.router) { while (it != boost::asio::ip::tcp::resolver::iterator()) - { + { auto address = (*it).endpoint ().address (); LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address); if (address.is_v4 () || context.SupportsV6 ()) @@ -456,14 +519,14 @@ namespace transport return; } break; - } + } else LogPrint (eLogInfo, "Transports: NTCP ", address, " is not supported"); it++; - } + } } LogPrint (eLogError, "Transports: Unable to resolve NTCP address: ", ecode.message ()); - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (it1); } } @@ -471,12 +534,12 @@ namespace transport void Transports::SSUResolve (const std::string& addr, const i2p::data::IdentHash& ident) { auto resolver = std::make_shared(*m_Service); - resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), - std::bind (&Transports::HandleSSUResolve, this, + resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), + std::bind (&Transports::HandleSSUResolve, this, std::placeholders::_1, std::placeholders::_2, ident, resolver)); } - void Transports::HandleSSUResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + void Transports::HandleSSUResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, i2p::data::IdentHash ident, std::shared_ptr resolver) { auto it1 = m_Peers.find (ident); @@ -486,7 +549,7 @@ namespace transport if (!ecode && peer.router) { while (it != boost::asio::ip::tcp::resolver::iterator()) - { + { auto address = (*it).endpoint ().address (); LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address); if (address.is_v4 () || context.SupportsV6 ()) @@ -502,10 +565,10 @@ namespace transport else LogPrint (eLogInfo, "Transports: SSU ", address, " is not supported"); it++; - } + } } LogPrint (eLogError, "Transports: Unable to resolve SSU address: ", ecode.message ()); - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (it1); } } @@ -513,14 +576,14 @@ namespace transport void Transports::CloseSession (std::shared_ptr router) { if (!router) return; - m_Service->post (std::bind (&Transports::PostCloseSession, this, router)); - } + m_Service->post (std::bind (&Transports::PostCloseSession, this, router)); + } void Transports::PostCloseSession (std::shared_ptr router) { auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (router) : nullptr; if (ssuSession) // try SSU first - { + { m_SSUServer->DeleteSession (ssuSession); LogPrint (eLogDebug, "Transports: SSU session closed"); } @@ -530,8 +593,8 @@ namespace transport ntcpSession->Terminate (); LogPrint(eLogDebug, "Transports: NTCP session closed"); } - } - + } + void Transports::DetectExternalIP () { if (RoutesRestricted()) @@ -550,7 +613,7 @@ namespace transport { auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 if (router) - m_SSUServer->CreateSession (router, true, isv4); // peer test + m_SSUServer->CreateSession (router, true, isv4); // peer test else { // if not peer test capable routers found pick any @@ -558,7 +621,7 @@ namespace transport if (router && router->IsSSU ()) m_SSUServer->CreateSession (router); // no peer test } - } + } } else LogPrint (eLogError, "Transports: Can't detect external IP. SSU is not available"); @@ -568,26 +631,26 @@ namespace transport { if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; if (m_SSUServer) - { + { bool statusChanged = false; for (int i = 0; i < 5; i++) { auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 only if (router) - { + { if (!statusChanged) - { + { statusChanged = true; i2p::context.SetStatus (eRouterStatusTesting); // first time only - } - m_SSUServer->CreateSession (router, true, true); // peer test v4 - } + } + m_SSUServer->CreateSession (router, true, true); // peer test v4 + } } if (!statusChanged) - LogPrint (eLogWarning, "Can't find routers for peer test"); + LogPrint (eLogWarning, "Can't find routers for peer test"); } - } - + } + std::shared_ptr Transports::GetNextDHKeysPair () { return m_DHKeysPairSupplier.Acquire (); @@ -601,8 +664,8 @@ namespace transport void Transports::PeerConnected (std::shared_ptr session) { m_Service->post([session, this]() - { - auto remoteIdentity = session->GetRemoteIdentity (); + { + auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); auto it = m_Peers.find (ident); @@ -619,7 +682,7 @@ namespace transport if (firstMsg && firstMsg->GetTypeID () == eI2NPDatabaseStore && i2p::data::IdentHash(firstMsg->GetPayload () + DATABASE_STORE_KEY_OFFSET) == i2p::context.GetIdentHash ()) sendDatabaseStore = false; // we have it in the list already - } + } if (sendDatabaseStore) session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); else @@ -640,17 +703,17 @@ namespace transport EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "true"}}); #endif session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); } }); } - + void Transports::PeerDisconnected (std::shared_ptr session) { m_Service->post([session, this]() { - auto remoteIdentity = session->GetRemoteIdentity (); + auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); #ifdef WITH_EVENTS @@ -661,26 +724,26 @@ namespace transport { it->second.sessions.remove (session); if (it->second.sessions.empty ()) // TODO: why? - { + { if (it->second.delayedMessages.size () > 0) ConnectToPeer (ident, it->second); else { - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); m_Peers.erase (it); } } } - }); - } + }); + } bool Transports::IsConnected (const i2p::data::IdentHash& ident) const - { - std::unique_lock l(m_PeersMutex); + { + std::unique_lock l(m_PeersMutex); auto it = m_Peers.find (ident); return it != m_Peers.end (); - } - + } + void Transports::HandlePeerCleanupTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) @@ -697,7 +760,7 @@ namespace transport profile->TunnelNonReplied(); profile->Save(it->first); } - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } else @@ -708,7 +771,7 @@ namespace transport DetectExternalIP (); m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); - } + } } void Transports::HandlePeerTestTimer (const boost::system::error_code& ecode) @@ -718,15 +781,15 @@ namespace transport PeerTest (); m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); - } - } - + } + } + std::shared_ptr Transports::GetRandomPeer () const { if (m_Peers.empty ()) return nullptr; - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); auto it = m_Peers.begin (); - std::advance (it, rand () % m_Peers.size ()); + std::advance (it, rand () % m_Peers.size ()); return it != m_Peers.end () ? it->second.router : nullptr; } void Transports::RestrictRoutesToFamilies(std::set families) @@ -744,7 +807,7 @@ namespace transport for (const auto & ri : routers ) m_TrustedRouters.push_back(ri); } - + bool Transports::RoutesRestricted() const { std::unique_lock famlock(m_FamilyMutex); std::unique_lock routerslock(m_TrustedRoutersMutex); @@ -804,4 +867,3 @@ namespace transport } } } - diff --git a/Transports.h b/libi2pd/Transports.h similarity index 87% rename from Transports.h rename to libi2pd/Transports.h index a68838e2..0a7a9310 100644 --- a/Transports.h +++ b/libi2pd/Transports.h @@ -45,7 +45,7 @@ namespace transport std::queue > m_Queue; bool m_IsRunning; - std::thread * m_Thread; + std::thread * m_Thread; std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; @@ -62,12 +62,12 @@ namespace transport { for (auto& it: sessions) it->Done (); - } - }; - + } + }; + const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds const int PEER_TEST_INTERVAL = 71; // in minutes - const int MAX_NUM_DELAYED_MESSAGES = 50; + const int MAX_NUM_DELAYED_MESSAGES = 50; class Transports { public: @@ -80,12 +80,12 @@ namespace transport bool IsBoundNTCP() const { return m_NTCPServer != nullptr; } bool IsBoundSSU() const { return m_SSUServer != nullptr; } - + bool IsOnline() const { return m_IsOnline; }; void SetOnline (bool online) { m_IsOnline = online; }; boost::asio::io_service& GetService () { return *m_Service; }; - std::shared_ptr GetNextDHKeysPair (); + std::shared_ptr GetNextDHKeysPair (); void ReuseDHKeysPair (std::shared_ptr pair); void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); @@ -95,30 +95,34 @@ namespace transport void PeerConnected (std::shared_ptr session); void PeerDisconnected (std::shared_ptr session); bool IsConnected (const i2p::data::IdentHash& ident) const; - + void UpdateSentBytes (uint64_t numBytes) { m_TotalSentBytes += numBytes; }; void UpdateReceivedBytes (uint64_t numBytes) { m_TotalReceivedBytes += numBytes; }; uint64_t GetTotalSentBytes () const { return m_TotalSentBytes; }; - uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; }; + uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; }; + uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; } + void UpdateTotalTransitTransmittedBytes (uint32_t add) { m_TotalTransitTransmittedBytes += add; }; uint32_t GetInBandwidth () const { return m_InBandwidth; }; uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; + uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; }; bool IsBandwidthExceeded () const; + bool IsTransitBandwidthExceeded () const; size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer () const; /** get a trusted first hop for restricted routes */ std::shared_ptr GetRestrictedPeer() const; /** do we want to use restricted routes? */ - bool RoutesRestricted() const; + bool RoutesRestricted() const; /** restrict routes to use only these router families for first hops */ void RestrictRoutesToFamilies(std::set families); /** restrict routes to use only these routers for first hops */ void RestrictRoutesToRouters(std::set routers); bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; - + void PeerTest (); - + private: void Run (); @@ -127,9 +131,9 @@ namespace transport void PostMessages (i2p::data::IdentHash ident, std::vector > msgs); void PostCloseSession (std::shared_ptr router); bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer); - void HandlePeerCleanupTimer (const boost::system::error_code& ecode); + void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerTestTimer (const boost::system::error_code& ecode); - + 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, i2p::data::IdentHash ident, std::shared_ptr resolver); @@ -139,11 +143,11 @@ namespace transport void UpdateBandwidth (); void DetectExternalIP (); - + private: bool m_IsOnline, m_IsRunning; - std::thread * m_Thread; + std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer; @@ -152,13 +156,13 @@ namespace transport SSUServer * m_SSUServer; mutable std::mutex m_PeersMutex; std::map m_Peers; - + DHKeysPairSupplier m_DHKeysPairSupplier; - std::atomic m_TotalSentBytes, m_TotalReceivedBytes; - uint32_t m_InBandwidth, m_OutBandwidth; // bytes per second - uint64_t m_LastInBandwidthUpdateBytes, m_LastOutBandwidthUpdateBytes; - uint64_t m_LastBandwidthUpdateTime; + std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; + uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; // bytes per second + uint64_t m_LastInBandwidthUpdateBytes, m_LastOutBandwidthUpdateBytes, m_LastTransitBandwidthUpdateBytes; + uint64_t m_LastBandwidthUpdateTime; /** which router families to trust for first hops */ std::vector m_TrustedFamilies; @@ -168,18 +172,18 @@ namespace transport std::vector m_TrustedRouters; mutable std::mutex m_TrustedRoutersMutex; - i2p::I2NPMessagesHandler m_LoopbackHandler; - + i2p::I2NPMessagesHandler m_LoopbackHandler; + public: // for HTTP only const NTCPServer * GetNTCPServer () const { return m_NTCPServer; }; const SSUServer * GetSSUServer () const { return m_SSUServer; }; const decltype(m_Peers)& GetPeers () const { return m_Peers; }; - }; + }; extern Transports transports; -} +} } #endif diff --git a/Tunnel.cpp b/libi2pd/Tunnel.cpp similarity index 99% rename from Tunnel.cpp rename to libi2pd/Tunnel.cpp index 798d7198..6ae1e119 100644 --- a/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -9,7 +9,7 @@ #include "Timestamp.h" #include "I2NPProtocol.h" #include "Transports.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Config.h" #include "Tunnel.h" #include "TunnelPool.h" diff --git a/Tunnel.h b/libi2pd/Tunnel.h similarity index 100% rename from Tunnel.h rename to libi2pd/Tunnel.h diff --git a/TunnelBase.h b/libi2pd/TunnelBase.h similarity index 100% rename from TunnelBase.h rename to libi2pd/TunnelBase.h diff --git a/TunnelConfig.h b/libi2pd/TunnelConfig.h similarity index 100% rename from TunnelConfig.h rename to libi2pd/TunnelConfig.h diff --git a/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp similarity index 99% rename from TunnelEndpoint.cpp rename to libi2pd/TunnelEndpoint.cpp index dde7d0a6..aec53e66 100644 --- a/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -2,7 +2,7 @@ #include #include "Crypto.h" #include "Log.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "I2NPProtocol.h" #include "Transports.h" #include "RouterContext.h" diff --git a/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h similarity index 100% rename from TunnelEndpoint.h rename to libi2pd/TunnelEndpoint.h diff --git a/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp similarity index 100% rename from TunnelGateway.cpp rename to libi2pd/TunnelGateway.cpp diff --git a/TunnelGateway.h b/libi2pd/TunnelGateway.h similarity index 100% rename from TunnelGateway.h rename to libi2pd/TunnelGateway.h diff --git a/TunnelPool.cpp b/libi2pd/TunnelPool.cpp similarity index 99% rename from TunnelPool.cpp rename to libi2pd/TunnelPool.cpp index a59b796e..a3592708 100644 --- a/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -2,7 +2,7 @@ #include "I2PEndian.h" #include "Crypto.h" #include "Tunnel.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Timestamp.h" #include "Garlic.h" #include "Transports.h" diff --git a/TunnelPool.h b/libi2pd/TunnelPool.h similarity index 100% rename from TunnelPool.h rename to libi2pd/TunnelPool.h diff --git a/api.cpp b/libi2pd/api.cpp similarity index 99% rename from api.cpp rename to libi2pd/api.cpp index ffc2de6e..022280f8 100644 --- a/api.cpp +++ b/libi2pd/api.cpp @@ -2,7 +2,7 @@ #include #include "Config.h" #include "Log.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "Transports.h" #include "Tunnel.h" #include "RouterContext.h" diff --git a/api.h b/libi2pd/api.h similarity index 100% rename from api.h rename to libi2pd/api.h diff --git a/util.cpp b/libi2pd/util.cpp similarity index 100% rename from util.cpp rename to libi2pd/util.cpp diff --git a/util.h b/libi2pd/util.h similarity index 100% rename from util.h rename to libi2pd/util.h diff --git a/version.h b/libi2pd/version.h similarity index 91% rename from version.h rename to libi2pd/version.h index 178f8e05..8c3a5c7f 100644 --- a/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 13 +#define I2PD_VERSION_MINOR 14 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #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_MINOR 9 -#define I2P_VERSION_MICRO 29 +#define I2P_VERSION_MICRO 30 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/AddressBook.cpp b/libi2pd_client/AddressBook.cpp similarity index 93% rename from AddressBook.cpp rename to libi2pd_client/AddressBook.cpp index c41dec50..d5620758 100644 --- a/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -13,7 +13,7 @@ #include "FS.h" #include "Log.h" #include "HTTP.h" -#include "NetDb.h" +#include "NetDb.hpp" #include "ClientContext.h" #include "AddressBook.h" #include "Config.h" @@ -50,11 +50,11 @@ namespace client }; bool AddressBookFilesystemStorage::Init() - { + { storage.SetPlace(i2p::fs::GetDataDir()); // init storage if (storage.Init(i2p::data::GetBase32SubstitutionTable(), 32)) - { + { // init ETags etagsPath = i2p::fs::StorageRootPath (storage, "etags"); if (!i2p::fs::Exists (etagsPath)) @@ -63,7 +63,7 @@ namespace client indexPath = i2p::fs::StorageRootPath (storage, "addresses.csv"); localPath = i2p::fs::StorageRootPath (storage, "local.csv"); return true; - } + } return false; } @@ -103,7 +103,7 @@ namespace client address->ToBuffer (buf, len); f.write ((char *)buf, len); delete[] buf; - } + } void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident) { @@ -112,12 +112,12 @@ namespace client int AddressBookFilesystemStorage::LoadFromFile (const std::string& filename, std::map& addresses) { - int num = 0; + int num = 0; std::ifstream f (filename, std::ifstream::in); // in text mode if (!f) return -1; addresses.clear (); - while (!f.eof ()) + while (!f.eof ()) { std::string s; getline(f, s); @@ -133,19 +133,19 @@ namespace client ident.FromBase32 (addr); addresses[name] = ident; num++; - } + } } return num; } int AddressBookFilesystemStorage::Load (std::map& addresses) { - int num = LoadFromFile (indexPath, addresses); + int num = LoadFromFile (indexPath, addresses); if (num < 0) { LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath); return 0; - } + } LogPrint(eLogInfo, "Addressbook: using index file ", indexPath); LogPrint (eLogInfo, "Addressbook: ", num, " addresses loaded from storage"); @@ -154,9 +154,9 @@ namespace client int AddressBookFilesystemStorage::LoadLocal (std::map& addresses) { - int num = LoadFromFile (localPath, addresses); + int num = LoadFromFile (localPath, addresses); if (num < 0) return 0; - LogPrint (eLogInfo, "Addressbook: ", num, " local addresses loaded"); + LogPrint (eLogInfo, "Addressbook: ", num, " local addresses loaded"); return num; } @@ -180,18 +180,18 @@ namespace client num++; } LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); - return num; - } + return num; + } void AddressBookFilesystemStorage::SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) { std::string fname = etagsPath + i2p::fs::dirSep + subscription.ToBase32 () + ".txt"; std::ofstream f (fname, std::ofstream::out | std::ofstream::trunc); if (f) - { - f << etag << std::endl; + { + f << etag << std::endl; f<< lastModified << std::endl; - } + } } bool AddressBookFilesystemStorage::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) @@ -200,7 +200,7 @@ namespace client std::ifstream f (fname, std::ofstream::in); if (!f || f.eof ()) return false; std::getline (f, etag); - if (f.eof ()) return false; + if (f.eof ()) return false; std::getline (f, lastModified); return true; } @@ -212,7 +212,7 @@ namespace client } AddressBook::~AddressBook () - { + { Stop (); } @@ -229,17 +229,17 @@ namespace client void AddressBook::StartResolvers () { LoadLocal (); - } - + } + void AddressBook::Stop () { StopLookups (); StopSubscriptions (); if (m_SubscriptionsUpdateTimer) - { - delete m_SubscriptionsUpdateTimer; + { + delete m_SubscriptionsUpdateTimer; m_SubscriptionsUpdateTimer = nullptr; - } + } if (m_IsDownloading) { LogPrint (eLogInfo, "Addressbook: subscriptions is downloading, abort"); @@ -249,9 +249,9 @@ namespace client { LogPrint (eLogInfo, "Addressbook: subscriptions download complete"); break; - } + } std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds - } + } LogPrint (eLogError, "Addressbook: subscription download timeout"); m_IsDownloading = false; } @@ -261,10 +261,10 @@ namespace client delete m_Storage; m_Storage = nullptr; } - m_DefaultSubscription = nullptr; - m_Subscriptions.clear (); - } - + m_DefaultSubscription = nullptr; + m_Subscriptions.clear (); + } + bool AddressBook::GetIdentHash (const std::string& address, i2p::data::IdentHash& ident) { auto pos = address.find(".b32.i2p"); @@ -274,23 +274,23 @@ namespace client return true; } else - { + { pos = address.find (".i2p"); if (pos != std::string::npos) { - auto identHash = FindAddress (address); + auto identHash = FindAddress (address); if (identHash) { ident = *identHash; return true; } else - { + { LookupAddress (address); // TODO: return false; - } + } } - } + } // if not .b32 we assume full base64 address i2p::data::IdentityEx dest; if (!dest.FromBase64 (address)) @@ -298,13 +298,13 @@ namespace client ident = dest.GetIdentHash (); return true; } - + const i2p::data::IdentHash * AddressBook::FindAddress (const std::string& address) { auto it = m_Addresses.find (address); if (it != m_Addresses.end ()) return &it->second; - return nullptr; + return nullptr; } void AddressBook::InsertAddress (const std::string& address, const std::string& base64) @@ -326,7 +326,7 @@ namespace client i2p::data::IdentHash ident; if (!GetIdentHash (address, ident)) return nullptr; return m_Storage->GetAddress (ident); - } + } void AddressBook::LoadHosts () { @@ -335,10 +335,10 @@ namespace client m_IsLoaded = true; return; } - + // then try hosts.txt std::ifstream f (i2p::fs::DataDirPath("hosts.txt"), std::ifstream::in); // in text mode - if (f.is_open ()) + if (f.is_open ()) { LoadHostsFromStream (f, false); m_IsLoaded = true; @@ -355,8 +355,8 @@ namespace client { getline(f, s); - if (!s.length()) - continue; // skip empty line + if (!s.length() || s[0] == '#') + continue; // skip empty or comment line size_t pos = s.find('='); @@ -365,6 +365,10 @@ namespace client std::string name = s.substr(0, pos++); std::string addr = s.substr(pos); + size_t pos = s.find('#'); + if (pos != std::string::npos) + addr = addr.substr(pos); // remove comments + auto ident = std::make_shared (); if (!ident->FromBase64(addr)) { LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name); @@ -378,19 +382,19 @@ namespace client m_Storage->AddAddress (ident); if (is_update) LogPrint(eLogInfo, "Addressbook: added new host: ", name); - } + } else incomplete = f.eof (); } LogPrint (eLogInfo, "Addressbook: ", numAddresses, " addresses processed"); if (numAddresses > 0) - { + { if (!incomplete) m_IsLoaded = true; m_Storage->Save (m_Addresses); - } + } return !incomplete; - } - + } + void AddressBook::LoadSubscriptions () { if (!m_Subscriptions.size ()) @@ -440,11 +444,11 @@ namespace client if (it1 != m_Addresses.end ()) { auto dest = context.FindLocalDestination (it1->second); - if (dest) + if (dest) { // address is ours std::shared_ptr resolver; - auto it2 = m_Resolvers.find (it1->second); + auto it2 = m_Resolvers.find (it1->second); if (it2 != m_Resolvers.end ()) resolver = it2->second; // resolver exists else @@ -463,9 +467,9 @@ namespace client bool AddressBook::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) { if (m_Storage) - return m_Storage->GetEtag (subscription, etag, lastModified); + return m_Storage->GetEtag (subscription, etag, lastModified); else - return false; + return false; } void AddressBook::DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) @@ -473,14 +477,14 @@ namespace client m_IsDownloading = false; int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT; if (success) - { + { if (m_DefaultSubscription) m_DefaultSubscription = nullptr; if (m_IsLoaded) - nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT; + nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT; else m_IsLoaded = true; if (m_Storage) m_Storage->SaveEtag (subscription, etag, lastModified); - } + } if (m_SubscriptionsUpdateTimer) { m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(nextUpdateTimeout)); @@ -493,7 +497,7 @@ namespace client { LoadSubscriptions (); if (m_IsLoaded && m_Subscriptions.empty ()) return; - + auto dest = i2p::client::context.GetSharedLocalDestination (); if (dest) { @@ -525,23 +529,23 @@ namespace client { if (!m_IsLoaded) { - // download it from default subscription + // download it from default subscription LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription."); std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL); if (!m_DefaultSubscription) m_DefaultSubscription = std::make_shared(*this, defaultSubURL); - m_IsDownloading = true; + m_IsDownloading = true; std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_DefaultSubscription)); load_hosts.detach(); // TODO: use join - } + } else if (!m_Subscriptions.empty ()) - { + { // pick random subscription - auto ind = rand () % m_Subscriptions.size(); - m_IsDownloading = true; + auto ind = rand () % m_Subscriptions.size(); + m_IsDownloading = true; std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_Subscriptions[ind])); load_hosts.detach(); // TODO: use join - } + } } else { @@ -564,9 +568,9 @@ namespace client datagram->SetReceiver (std::bind (&AddressBook::HandleLookupResponse, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), ADDRESS_RESPONSE_DATAGRAM_PORT); - } + } } - + void AddressBook::StopLookups () { auto dest = i2p::client::context.GetSharedLocalDestination (); @@ -574,7 +578,7 @@ namespace client { auto datagram = dest->GetDatagramDestination (); if (datagram) datagram->ResetReceiver (ADDRESS_RESPONSE_DATAGRAM_PORT); - } + } } void AddressBook::LookupAddress (const std::string& address) @@ -587,8 +591,8 @@ namespace client { LogPrint (eLogError, "Addressbook: Can't find domain for ", address); return; - } - + } + auto dest = i2p::client::context.GetSharedLocalDestination (); if (dest) { @@ -599,8 +603,8 @@ namespace client RAND_bytes ((uint8_t *)&nonce, 4); { std::unique_lock l(m_LookupsMutex); - m_Lookups[nonce] = address; - } + m_Lookups[nonce] = address; + } LogPrint (eLogDebug, "Addressbook: Lookup of ", address, " to ", ident->ToBase32 (), " nonce=", nonce); size_t len = address.length () + 9; uint8_t * buf = new uint8_t[len]; @@ -610,10 +614,10 @@ namespace client memcpy (buf + 9, address.c_str (), address.length ()); datagram->SendDatagramTo (buf, len, *ident, ADDRESS_RESPONSE_DATAGRAM_PORT, ADDRESS_RESOLVER_DATAGRAM_PORT); delete[] buf; - } - } - } - + } + } + } + void AddressBook::HandleLookupResponse (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { if (len < 44) @@ -628,22 +632,22 @@ namespace client std::unique_lock l(m_LookupsMutex); auto it = m_Lookups.find (nonce); if (it != m_Lookups.end ()) - { + { address = it->second; m_Lookups.erase (it); - } - } + } + } if (address.length () > 0) { // TODO: verify from i2p::data::IdentHash hash(buf + 8); - if (!hash.IsZero ()) + if (!hash.IsZero ()) m_Addresses[address] = hash; else LogPrint (eLogInfo, "AddressBook: Lookup response: ", address, " not found"); - } + } } - + AddressBookSubscription::AddressBookSubscription (AddressBook& book, const std::string& link): m_Book (book), m_Link (link) { @@ -658,7 +662,7 @@ namespace client bool AddressBookSubscription::MakeRequest () { i2p::http::URL url; - // must be run in separate thread + // must be run in separate thread LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link); if (!url.parse(m_Link)) { LogPrint(eLogError, "Addressbook: failed to parse url: ", m_Link); @@ -723,7 +727,7 @@ namespace client uint8_t recv_buf[4096]; bool end = false; int numAttempts = 5; - while (!end) + while (!end) { stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096), [&](const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -737,47 +741,47 @@ namespace client 30); // wait for 30 seconds std::unique_lock l(newDataReceivedMutex); if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) - { + { LogPrint (eLogError, "Addressbook: subscriptions request timeout expired"); numAttempts++; if (numAttempts > 5) end = true; - } + } } // process remaining buffer - while (size_t len = stream->ReadSome (recv_buf, sizeof(recv_buf))) + while (size_t len = stream->ReadSome (recv_buf, sizeof(recv_buf))) response.append ((char *)recv_buf, len); /* parse response */ i2p::http::HTTPRes res; int res_head_len = res.parse(response); - if (res_head_len < 0) + if (res_head_len < 0) { LogPrint(eLogError, "Addressbook: can't parse http response from ", dest_host); return false; } - if (res_head_len == 0) + if (res_head_len == 0) { LogPrint(eLogError, "Addressbook: incomplete http response from ", dest_host, ", interrupted by timeout"); return false; } /* assert: res_head_len > 0 */ response.erase(0, res_head_len); - if (res.code == 304) + if (res.code == 304) { LogPrint (eLogInfo, "Addressbook: no updates from ", dest_host, ", code 304"); return false; } - if (res.code != 200) + if (res.code != 200) { LogPrint (eLogWarning, "Adressbook: can't get updates from ", dest_host, ", response code ", res.code); return false; } int len = res.content_length(); - if (response.empty()) + if (response.empty()) { LogPrint(eLogError, "Addressbook: empty response from ", dest_host, ", expected ", len, " bytes"); return false; } - if (!res.is_gzipped () && len > 0 && len != (int) response.length()) + if (!res.is_gzipped () && len > 0 && len != (int) response.length()) { LogPrint(eLogError, "Addressbook: response size mismatch, expected: ", len, ", got: ", response.length(), "bytes"); return false; @@ -787,18 +791,18 @@ namespace client if (it != res.headers.end()) m_Etag = it->second; it = res.headers.find("If-Modified-Since"); if (it != res.headers.end()) m_LastModified = it->second; - if (res.is_chunked()) + if (res.is_chunked()) { std::stringstream in(response), out; i2p::http::MergeChunkedResponse (in, out); response = out.str(); - } - else if (res.is_gzipped()) + } + else if (res.is_gzipped()) { std::stringstream out; i2p::data::GzipInflator inflator; inflator.Inflate ((const uint8_t *) response.data(), response.length(), out); - if (out.fail()) + if (out.fail()) { LogPrint(eLogError, "Addressbook: can't gunzip http response"); return false; @@ -819,8 +823,8 @@ namespace client auto datagram = m_LocalDestination->GetDatagramDestination (); if (!datagram) datagram = m_LocalDestination->CreateDatagramDestination (); - datagram->SetReceiver (std::bind (&AddressResolver::HandleRequest, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), + datagram->SetReceiver (std::bind (&AddressResolver::HandleRequest, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), ADDRESS_RESOLVER_DATAGRAM_PORT); } } @@ -832,9 +836,9 @@ namespace client auto datagram = m_LocalDestination->GetDatagramDestination (); if (datagram) datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT); - } - } - + } + } + void AddressResolver::HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { if (len < 9 || len < buf[8] + 9U) @@ -846,26 +850,25 @@ namespace client uint8_t l = buf[8]; char address[255]; memcpy (address, buf + 9, l); - address[l] = 0; + address[l] = 0; LogPrint (eLogDebug, "Addressbook: Address request ", address); // send response uint8_t response[44]; memset (response, 0, 4); // reserved - memcpy (response + 4, buf + 4, 4); // nonce + memcpy (response + 4, buf + 4, 4); // nonce auto it = m_LocalAddresses.find (address); // address lookup - if (it != m_LocalAddresses.end ()) - memcpy (response + 8, it->second, 32); // ident + if (it != m_LocalAddresses.end ()) + memcpy (response + 8, it->second, 32); // ident else - memset (response + 8, 0, 32); // not found + memset (response + 8, 0, 32); // not found memset (response + 40, 0, 4); // set expiration time to zero m_LocalDestination->GetDatagramDestination ()->SendDatagramTo (response, 44, from.GetIdentHash(), toPort, fromPort); } void AddressResolver::AddAddress (const std::string& name, const i2p::data::IdentHash& ident) { - m_LocalAddresses[name] = ident; + m_LocalAddresses[name] = ident; } } } - diff --git a/AddressBook.h b/libi2pd_client/AddressBook.h similarity index 100% rename from AddressBook.h rename to libi2pd_client/AddressBook.h diff --git a/BOB.cpp b/libi2pd_client/BOB.cpp similarity index 100% rename from BOB.cpp rename to libi2pd_client/BOB.cpp diff --git a/BOB.h b/libi2pd_client/BOB.h similarity index 100% rename from BOB.h rename to libi2pd_client/BOB.h diff --git a/ClientContext.cpp b/libi2pd_client/ClientContext.cpp similarity index 100% rename from ClientContext.cpp rename to libi2pd_client/ClientContext.cpp diff --git a/ClientContext.h b/libi2pd_client/ClientContext.h similarity index 100% rename from ClientContext.h rename to libi2pd_client/ClientContext.h diff --git a/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp similarity index 99% rename from HTTPProxy.cpp rename to libi2pd_client/HTTPProxy.cpp index 55bd60fe..7fb64ad1 100644 --- a/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -309,7 +309,7 @@ namespace proxy { GenericProxyError("Outproxy failure", "bad outproxy settings"); } else { LogPrint (eLogWarning, "HTTPProxy: outproxy failure for ", dest_host, ": no outprxy enabled"); - std::string message = "Host" + dest_host + "not inside I2P network, but outproxy is not enabled"; + std::string message = "Host " + dest_host + " not inside I2P network, but outproxy is not enabled"; GenericProxyError("Outproxy failure", message.c_str()); } return true; diff --git a/HTTPProxy.h b/libi2pd_client/HTTPProxy.h similarity index 100% rename from HTTPProxy.h rename to libi2pd_client/HTTPProxy.h diff --git a/I2CP.cpp b/libi2pd_client/I2CP.cpp similarity index 100% rename from I2CP.cpp rename to libi2pd_client/I2CP.cpp diff --git a/I2CP.h b/libi2pd_client/I2CP.h similarity index 100% rename from I2CP.h rename to libi2pd_client/I2CP.h diff --git a/I2PService.cpp b/libi2pd_client/I2PService.cpp similarity index 100% rename from I2PService.cpp rename to libi2pd_client/I2PService.cpp diff --git a/I2PService.h b/libi2pd_client/I2PService.h similarity index 100% rename from I2PService.h rename to libi2pd_client/I2PService.h diff --git a/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp similarity index 100% rename from I2PTunnel.cpp rename to libi2pd_client/I2PTunnel.cpp diff --git a/I2PTunnel.h b/libi2pd_client/I2PTunnel.h similarity index 100% rename from I2PTunnel.h rename to libi2pd_client/I2PTunnel.h diff --git a/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp similarity index 100% rename from MatchedDestination.cpp rename to libi2pd_client/MatchedDestination.cpp diff --git a/MatchedDestination.h b/libi2pd_client/MatchedDestination.h similarity index 100% rename from MatchedDestination.h rename to libi2pd_client/MatchedDestination.h diff --git a/SAM.cpp b/libi2pd_client/SAM.cpp similarity index 100% rename from SAM.cpp rename to libi2pd_client/SAM.cpp diff --git a/SAM.h b/libi2pd_client/SAM.h similarity index 100% rename from SAM.h rename to libi2pd_client/SAM.h diff --git a/SOCKS.cpp b/libi2pd_client/SOCKS.cpp similarity index 100% rename from SOCKS.cpp rename to libi2pd_client/SOCKS.cpp diff --git a/SOCKS.h b/libi2pd_client/SOCKS.h similarity index 100% rename from SOCKS.h rename to libi2pd_client/SOCKS.h diff --git a/WebSocks.cpp b/libi2pd_client/WebSocks.cpp similarity index 100% rename from WebSocks.cpp rename to libi2pd_client/WebSocks.cpp diff --git a/WebSocks.h b/libi2pd_client/WebSocks.h similarity index 100% rename from WebSocks.h rename to libi2pd_client/WebSocks.h diff --git a/Websocket.cpp b/libi2pd_client/Websocket.cpp similarity index 97% rename from Websocket.cpp rename to libi2pd_client/Websocket.cpp index a1a58c5f..3d456655 100644 --- a/Websocket.cpp +++ b/libi2pd_client/Websocket.cpp @@ -1,3 +1,4 @@ +#ifdef WITH_EVENTS #include "Websocket.h" #include "Log.h" @@ -21,7 +22,7 @@ namespace i2p typedef websocketpp::server ServerImpl; typedef websocketpp::connection_hdl ServerConn; - + class WebsocketServerImpl : public EventListener { private: @@ -38,20 +39,20 @@ namespace i2p m_server.set_open_handler(std::bind(&WebsocketServerImpl::ConnOpened, this, std::placeholders::_1)); m_server.set_close_handler(std::bind(&WebsocketServerImpl::ConnClosed, this, std::placeholders::_1)); m_server.set_message_handler(std::bind(&WebsocketServerImpl::OnConnMessage, this, std::placeholders::_1, std::placeholders::_2)); - + m_server.listen(boost::asio::ip::address::from_string(addr), port); } ~WebsocketServerImpl() { } - + void Start() { m_run = true; m_server.start_accept(); m_ws_thread = new std::thread([&] () { while(m_run) { - try { + try { m_server.run(); } catch (std::exception & e ) { LogPrint(eLogError, "Websocket server: ", e.what()); @@ -60,7 +61,7 @@ namespace i2p }); m_ev_thread = new std::thread([&] () { while(m_run) { - try { + try { m_Service.run(); break; } catch (std::exception & e ) { @@ -81,7 +82,7 @@ namespace i2p delete m_ev_thread; } m_ev_thread = nullptr; - + if(m_ws_thread) { m_ws_thread->join(); delete m_ws_thread; @@ -94,7 +95,7 @@ namespace i2p std::lock_guard lock(m_connsMutex); m_conns.insert(c); } - + void ConnClosed(ServerConn c) { std::lock_guard lock(m_connsMutex); @@ -122,20 +123,20 @@ namespace i2p LogPrint(eLogDebug, "Websocket schedule tick"); boost::posix_time::seconds dlt(1); m_WebsocketTicker.expires_from_now(dlt); - m_WebsocketTicker.async_wait(std::bind(&WebsocketServerImpl::HandleTick, this, std::placeholders::_1)); + m_WebsocketTicker.async_wait(std::bind(&WebsocketServerImpl::HandleTick, this, std::placeholders::_1)); } - + /** @brief called from m_ev_thread */ void HandlePumpEvent(const EventType & ev, const uint64_t & val) { EventType e; for (const auto & i : ev) e[i.first] = i.second; - + e["number"] = std::to_string(val); HandleEvent(e); } - + /** @brief called from m_ws_thread */ void HandleEvent(const EventType & ev) { @@ -154,7 +155,7 @@ namespace i2p con->send(s); } } - + private: typedef std::set > ConnList; bool m_run; @@ -174,7 +175,7 @@ namespace i2p delete m_impl; } - + void WebsocketServer::Start() { m_impl->Start(); @@ -184,10 +185,11 @@ namespace i2p { m_impl->Stop(); } - + EventListener * WebsocketServer::ToListener() { return m_impl; } } } +#endif diff --git a/Websocket.h b/libi2pd_client/Websocket.h similarity index 100% rename from Websocket.h rename to libi2pd_client/Websocket.h diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore index 35d7caf4..3bbbf71a 100644 --- a/qt/i2pd_qt/.gitignore +++ b/qt/i2pd_qt/.gitignore @@ -1 +1,7 @@ i2pd_qt.pro.user* +moc_* +ui_* +qrc_* +i2pd_qt +Makefile +*.stash diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp index 5cd43858..585bd56c 100644 --- a/qt/i2pd_qt/DaemonQT.cpp +++ b/qt/i2pd_qt/DaemonQT.cpp @@ -1,5 +1,5 @@ #include "DaemonQT.h" -#include "../../Daemon.h" +#include "Daemon.h" #include "mainwindow.h" #include #include diff --git a/qt/i2pd_qt/android/AndroidManifest.xml b/qt/i2pd_qt/android/AndroidManifest.xml index dd5927b7..e6eb171f 100644 --- a/qt/i2pd_qt/android/AndroidManifest.xml +++ b/qt/i2pd_qt/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index a55a01da..229d3f2e 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -24,35 +24,45 @@ IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs # 2) Check API 11 # Finally, click Install. -SOURCES += DaemonQT.cpp mainwindow.cpp \ - ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ - ../../AddressBook.cpp ../../api.cpp ../../Base.cpp ../../BOB.cpp ../../ClientContext.cpp \ - ../../Crypto.cpp ../../Datagram.cpp ../../Destination.cpp ../../Family.cpp ../../FS.cpp \ - ../../Garlic.cpp ../../HTTP.cpp ../../HTTPProxy.cpp ../../I2CP.cpp ../../I2NPProtocol.cpp \ - ../../I2PEndian.cpp ../../I2PService.cpp ../../I2PTunnel.cpp ../../Identity.cpp \ - ../../LeaseSet.cpp ../../Log.cpp ../../NetDb.cpp ../../NetDbRequests.cpp \ - ../../NTCPSession.cpp ../../Profiling.cpp ../../Reseed.cpp ../../RouterContext.cpp \ - ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ - ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ - ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ - ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \ - ../../Event.cpp ../../BloomFiler.cpp ../../Gost.cpp ../../MatchedDestination.cpp \ - ../../i2pd.cpp - -HEADERS += DaemonQT.h mainwindow.h \ - ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ - ../../AddressBook.h ../../api.h ../../Base.h ../../BOB.h ../../ClientContext.h \ - ../../Crypto.h ../../Datagram.h ../../Destination.h ../../Family.h ../../FS.h \ - ../../Garlic.h ../../HTTP.h ../../HTTPProxy.h ../../I2CP.h ../../I2NPProtocol.h \ - ../../I2PEndian.h ../../I2PService.h ../../I2PTunnel.h ../../Identity.h ../../LeaseSet.h \ - ../../LittleBigEndian.h ../../Log.h ../../NetDb.h ../../NetDbRequests.h ../../NTCPSession.h \ - ../../Profiling.h ../../Queue.h ../../Reseed.h ../../RouterContext.h ../../RouterInfo.h \ - ../../SAM.h ../../Signature.h ../../SOCKS.h ../../SSU.h ../../SSUData.h ../../SSUSession.h \ - ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ - ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ - ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ - ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \ - ../../BloomFiler.h ../../Event.h ../../Gost.h ../../MatchedDestination.h +SOURCES += DaemonQT.cpp mainwindow.cpp +# ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ +# ../../AddressBook.cpp ../../api.cpp ../../Base.cpp ../../BOB.cpp ../../ClientContext.cpp \ +# ../../Crypto.cpp ../../Datagram.cpp ../../Destination.cpp ../../Family.cpp ../../FS.cpp \ +# ../../Garlic.cpp ../../HTTP.cpp ../../HTTPProxy.cpp ../../I2CP.cpp ../../I2NPProtocol.cpp \ +# ../../I2PEndian.cpp ../../I2PService.cpp ../../I2PTunnel.cpp ../../Identity.cpp \ +# ../../LeaseSet.cpp ../../Log.cpp ../../NetDb.cpp ../../NetDbRequests.cpp \ +# ../../NTCPSession.cpp ../../Profiling.cpp ../../Reseed.cpp ../../RouterContext.cpp \ +# ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ +# ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ +# ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ +# ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \ +# ../../Event.cpp ../../BloomFiler.cpp ../../Gost.cpp ../../MatchedDestination.cpp \ +# ../../i2pd.cpp + +SOURCES += $$files(../../libi2pd/*.cpp) +SOURCES += $$files(../../libi2pd_client/*.cpp) +SOURCES += $$files(../../daemon/*.cpp) + +SOURCES -= ../../daemon/UnixDaemon.cpp + +HEADERS += DaemonQT.h mainwindow.h +# ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ +# ../../AddressBook.h ../../api.h ../../Base.h ../../BOB.h ../../ClientContext.h \ +# ../../Crypto.h ../../Datagram.h ../../Destination.h ../../Family.h ../../FS.h \ +# ../../Garlic.h ../../HTTP.h ../../HTTPProxy.h ../../I2CP.h ../../I2NPProtocol.h \ +# ../../I2PEndian.h ../../I2PService.h ../../I2PTunnel.h ../../Identity.h ../../LeaseSet.h \ +# ../../LittleBigEndian.h ../../Log.h ../../NetDb.h ../../NetDbRequests.h ../../NTCPSession.h \ +# ../../Profiling.h ../../Queue.h ../../Reseed.h ../../RouterContext.h ../../RouterInfo.h \ +# ../../SAM.h ../../Signature.h ../../SOCKS.h ../../SSU.h ../../SSUData.h ../../SSUSession.h \ +# ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ +# ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ +# ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ +# ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \ +# ../../BloomFiler.h ../../Event.h ../../Gost.h ../../MatchedDestination.h + +INCLUDEPATH += ../../libi2pd +INCLUDEPATH += ../../libi2pd_client +INCLUDEPATH += ../../daemon FORMS += mainwindow.ui diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 1b8af253..4b749473 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -2,7 +2,7 @@ //#include "ui_mainwindow.h" #include #include -#include "../../RouterContext.h" +#include "RouterContext.h" #ifndef ANDROID #include #endif diff --git a/stdafx.cpp b/stdafx.cpp deleted file mode 100644 index fd4f341c..00000000 --- a/stdafx.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "stdafx.h" diff --git a/stdafx.h b/stdafx.h deleted file mode 100644 index 42490354..00000000 --- a/stdafx.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef STDAFX_H__ -#define STDAFX_H__ - -#include -#include -#include -#include -#include - -#include // TODO: replace with cstring and std:: through out -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/tests/Makefile b/tests/Makefile index d1284602..f769ad35 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,19 +1,19 @@ -CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 +CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread TESTS = test-gost test-gost-sig test-base-64 all: $(TESTS) run -test-http-%: ../HTTP.cpp test-http-%.cpp +test-http-%: ../libi2pd/HTTP.cpp test-http-%.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -test-base-%: ../Base.cpp test-base-%.cpp +test-base-%: ../libi2pd/Base.cpp test-base-%.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -test-gost: ../Gost.cpp ../I2PEndian.cpp test-gost.cpp +test-gost: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp test-gost.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -test-gost-sig: ../Gost.cpp ../I2PEndian.cpp ../Signature.cpp ../Crypto.cpp ../Log.cpp test-gost-sig.cpp +test-gost-sig: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Signature.cpp ../libi2pd/Crypto.cpp ../libi2pd/Log.cpp test-gost-sig.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system run: $(TESTS) diff --git a/tests/test-base-64.cpp b/tests/test-base-64.cpp index d8d0ce2f..0ab46c06 100644 --- a/tests/test-base-64.cpp +++ b/tests/test-base-64.cpp @@ -1,7 +1,7 @@ #include #include -#include "../Base.h" +#include "Base.h" using namespace i2p::data; diff --git a/tests/test-gost-sig.cpp b/tests/test-gost-sig.cpp index 63f7b27e..55cc2d1b 100644 --- a/tests/test-gost-sig.cpp +++ b/tests/test-gost-sig.cpp @@ -2,8 +2,8 @@ #include #include -#include "../Gost.h" -#include "../Signature.h" +#include "Gost.h" +#include "Signature.h" const uint8_t example2[72] = { @@ -30,6 +30,3 @@ int main () i2p::crypto::GOSTR3410_256_Verifier verifier1 (i2p::crypto::eGOSTR3410CryptoProA, pub); assert (verifier1.Verify (example2, 72, signature)); } - - - diff --git a/tests/test-gost.cpp b/tests/test-gost.cpp index b0ab1d51..658e87d4 100644 --- a/tests/test-gost.cpp +++ b/tests/test-gost.cpp @@ -2,7 +2,7 @@ #include #include -#include "../Gost.h" +#include "Gost.h" const uint8_t example1[63] = { @@ -51,19 +51,16 @@ const uint8_t example2_hash_256[32] = int main () { - uint8_t digest[64]; - i2p::crypto::GOSTR3411_2012_512 (example1, 63, digest); + uint8_t digest[64]; + i2p::crypto::GOSTR3411_2012_512 (example1, 63, digest); assert(memcmp (digest, example1_hash_512, 64) == 0); - i2p::crypto::GOSTR3411_2012_256 (example1, 63, digest); + i2p::crypto::GOSTR3411_2012_256 (example1, 63, digest); assert(memcmp (digest, example1_hash_256, 32) == 0); - i2p::crypto::GOSTR3411_2012_512 (example2, 72, digest); + i2p::crypto::GOSTR3411_2012_512 (example2, 72, digest); assert(memcmp (digest, example2_hash_512, 64) == 0); - i2p::crypto::GOSTR3411_2012_256 (example2, 72, digest); + i2p::crypto::GOSTR3411_2012_256 (example2, 72, digest); assert(memcmp (digest, example2_hash_256, 32) == 0); } - - -