mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
1 Commits
webconsole
...
moduled
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ab5ac66b6 |
9
.github/workflows/docker.yml
vendored
9
.github/workflows/docker.yml
vendored
@@ -1,11 +1,6 @@
|
|||||||
name: Build containers
|
name: Build containers
|
||||||
|
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- openssl
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@@ -63,8 +58,6 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
purplei2p/i2pd:latest
|
purplei2p/i2pd:latest
|
||||||
purplei2p/i2pd:latest-release
|
|
||||||
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
ghcr.io/purplei2p/i2pd:latest
|
ghcr.io/purplei2p/i2pd:latest
|
||||||
ghcr.io/purplei2p/i2pd:latest-release
|
|
||||||
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }}
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,15 +8,12 @@ netDb
|
|||||||
/libi2pd.a
|
/libi2pd.a
|
||||||
/libi2pdclient.a
|
/libi2pdclient.a
|
||||||
/libi2pdlang.a
|
/libi2pdlang.a
|
||||||
/libi2pdwebconsole.a
|
|
||||||
/libi2pd.so
|
/libi2pd.so
|
||||||
/libi2pdclient.so
|
/libi2pdclient.so
|
||||||
/libi2pdlang.so
|
/libi2pdlang.so
|
||||||
/libi2pdwebconsole.so
|
|
||||||
/libi2pd.dll
|
/libi2pd.dll
|
||||||
/libi2pdclient.dll
|
/libi2pdclient.dll
|
||||||
/libi2pdlang.dll
|
/libi2pdlang.dll
|
||||||
/libi2pdwebconsole.dll
|
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
34
ChangeLog
34
ChangeLog
@@ -1,40 +1,6 @@
|
|||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
## [2.42.1] - 2022-05-24
|
|
||||||
### Fixed
|
|
||||||
- Incorrect jump link in HTTP Proxy
|
|
||||||
|
|
||||||
## [2.42.0] - 2022-05-22
|
|
||||||
### Added
|
|
||||||
- Preliminary SSU2 implementation
|
|
||||||
- Tunnel length variance
|
|
||||||
- Localization to French
|
|
||||||
- Daily cleanup of obsolete peer profiles
|
|
||||||
- Ordered jump services list in HTTP proxy
|
|
||||||
- Win32 service
|
|
||||||
- Show port for local non-published SSU addresses in web console
|
|
||||||
### Changed
|
|
||||||
- Maximum RouterInfo length increased to 3K
|
|
||||||
- Skip unknown addresses in RouterInfo
|
|
||||||
- Don't pick own router for peer test
|
|
||||||
- Reseeds list
|
|
||||||
- Internal numeric id for families
|
|
||||||
- Use ipv6 preference only when netinet headers not used
|
|
||||||
- Close stream if delete requested
|
|
||||||
- Remove version from title in web console
|
|
||||||
- Drop MESHNET build option
|
|
||||||
- Set data path before initialization
|
|
||||||
- Don't show registration block in web console if token is not provided
|
|
||||||
### Fixed
|
|
||||||
- Encrypted LeaseSet for EdDSA signature
|
|
||||||
- Clients tunnels are not built if clock is not synced on start
|
|
||||||
- Incorrect processing of i2cp.dontPublishLeaseSet param
|
|
||||||
- UDP tunnels reload
|
|
||||||
- Build for LibreSSL 3.5.2
|
|
||||||
- Race condition in short tunnel build message
|
|
||||||
- Race condition in local RouterInfo buffer allocation
|
|
||||||
|
|
||||||
## [2.41.0] - 2022-02-20
|
## [2.41.0] - 2022-02-20
|
||||||
### Added
|
### Added
|
||||||
- Clock syncronization through SSU
|
- Clock syncronization through SSU
|
||||||
|
|||||||
83
Makefile
83
Makefile
@@ -4,7 +4,7 @@ SYS := $(shell $(CXX) -dumpmachine)
|
|||||||
|
|
||||||
ifneq (, $(findstring darwin, $(SYS)))
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
SHARED_SUFFIX = dylib
|
SHARED_SUFFIX = dylib
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
SHARED_SUFFIX = dll
|
SHARED_SUFFIX = dll
|
||||||
else
|
else
|
||||||
SHARED_SUFFIX = so
|
SHARED_SUFFIX = so
|
||||||
@@ -12,22 +12,19 @@ endif
|
|||||||
|
|
||||||
SHLIB := libi2pd.$(SHARED_SUFFIX)
|
SHLIB := libi2pd.$(SHARED_SUFFIX)
|
||||||
ARLIB := libi2pd.a
|
ARLIB := libi2pd.a
|
||||||
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
|
|
||||||
ARLIB_CLIENT := libi2pdclient.a
|
|
||||||
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
|
SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX)
|
||||||
ARLIB_LANG := libi2pdlang.a
|
ARLIB_LANG := libi2pdlang.a
|
||||||
SHLIB_WEBCONSOLE := libi2pdwebconsole.$(SHARED_SUFFIX)
|
SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX)
|
||||||
ARLIB_WEBCONSOLE := libi2pdwebconsole.a
|
ARLIB_CLIENT := libi2pdclient.a
|
||||||
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
|
SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX)
|
||||||
ARLIB_WRAP := libi2pdwrapper.a
|
ARLIB_WRAP := libi2pdwrapper.a
|
||||||
I2PD := i2pd
|
I2PD := i2pd
|
||||||
|
|
||||||
LIB_SRC_DIR := libi2pd
|
LIB_SRC_DIR := libi2pd
|
||||||
LIB_CLIENT_SRC_DIR := libi2pd_client
|
LIB_CLIENT_SRC_DIR := libi2pd_client
|
||||||
WEBCONSOLE_SRC_DIR := libi2pd_webconsole
|
WRAP_SRC_DIR := libi2pd_wrapper
|
||||||
LANG_SRC_DIR := i18n
|
LANG_SRC_DIR := i18n
|
||||||
DAEMON_SRC_DIR := daemon
|
DAEMON_SRC_DIR := daemon
|
||||||
WRAP_SRC_DIR := libi2pd_wrapper
|
|
||||||
|
|
||||||
# import source files lists
|
# import source files lists
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
@@ -43,6 +40,12 @@ USE_GIT_VERSION := $(or $(USE_GIT_VERSION),no)
|
|||||||
# for MacOS only, waiting for "1", not "yes"
|
# for MacOS only, waiting for "1", not "yes"
|
||||||
HOMEBREW := $(or $(HOMEBREW),0)
|
HOMEBREW := $(or $(HOMEBREW),0)
|
||||||
|
|
||||||
|
# Client protocols
|
||||||
|
USE_I2PC := $(or $(USE_I2PC),yes)
|
||||||
|
USE_I2CP := $(or $(USE_I2CP),yes)
|
||||||
|
USE_SAM := $(or $(USE_SAM),yes)
|
||||||
|
USE_BOB := $(or $(USE_BOB),yes)
|
||||||
|
|
||||||
ifeq ($(DEBUG),yes)
|
ifeq ($(DEBUG),yes)
|
||||||
CXX_DEBUG = -g
|
CXX_DEBUG = -g
|
||||||
else
|
else
|
||||||
@@ -50,21 +53,34 @@ else
|
|||||||
LD_DEBUG = -s
|
LD_DEBUG = -s
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(USE_I2PC),yes)
|
||||||
|
NEEDED_CXXFLAGS += -DWITH_I2PC
|
||||||
|
endif
|
||||||
|
ifeq ($(USE_I2CP),yes)
|
||||||
|
NEEDED_CXXFLAGS += -DWITH_I2CP
|
||||||
|
endif
|
||||||
|
ifeq ($(USE_SAM),yes)
|
||||||
|
NEEDED_CXXFLAGS += -DWITH_SAM
|
||||||
|
endif
|
||||||
|
ifeq ($(USE_BOB),yes)
|
||||||
|
NEEDED_CXXFLAGS += -DWITH_BOB
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (, $(findstring darwin, $(SYS)))
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
ifeq ($(HOMEBREW),1)
|
ifeq ($(HOMEBREW),1)
|
||||||
include Makefile.homebrew
|
include Makefile.homebrew
|
||||||
else
|
else
|
||||||
include Makefile.osx
|
include Makefile.osx
|
||||||
endif
|
endif
|
||||||
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.linux
|
include Makefile.linux
|
||||||
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonUnix.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.bsd
|
include Makefile.bsd
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
|
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Not supported platform)
|
$(error Not supported platform)
|
||||||
@@ -75,34 +91,31 @@ ifeq ($(USE_GIT_VERSION),yes)
|
|||||||
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
|
NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) -I$(WEBCONSOLE_SRC_DIR) -DOPENSSL_SUPPRESS_DEPRECATED
|
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
|
||||||
|
|
||||||
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
||||||
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
||||||
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
||||||
WEBCONSOLE_OBJS += $(patsubst %.cpp,obj/%.o,$(WEBCONSOLE_SRC))
|
|
||||||
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
||||||
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
|
WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC))
|
||||||
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(WEBCONSOLE_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
|
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d)
|
||||||
|
|
||||||
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
|
## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary
|
||||||
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(ARLIB_WEBCONSOLE) $(I2PD)
|
all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD)
|
||||||
|
|
||||||
mk_obj_dir:
|
mk_obj_dir:
|
||||||
@mkdir -p obj/$(LIB_SRC_DIR)
|
@mkdir -p obj/$(LIB_SRC_DIR)
|
||||||
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
||||||
@mkdir -p obj/$(LANG_SRC_DIR)
|
@mkdir -p obj/$(LANG_SRC_DIR)
|
||||||
@mkdir -p obj/$(WEBCONSOLE_SRC_DIR)
|
|
||||||
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
||||||
@mkdir -p obj/$(WRAP_SRC_DIR)
|
@mkdir -p obj/$(WRAP_SRC_DIR)
|
||||||
@mkdir -p obj/Win32
|
@mkdir -p obj/Win32
|
||||||
|
|
||||||
api: $(SHLIB) $(ARLIB)
|
api: $(SHLIB) $(ARLIB)
|
||||||
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
client: $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
lang: $(SHLIB_LANG) $(ARLIB_LANG)
|
lang: $(SHLIB_LANG) $(ARLIB_LANG)
|
||||||
webconsole: $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE)
|
api_client: api client lang
|
||||||
api_client: api client lang webconsole
|
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||||
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
@@ -117,7 +130,7 @@ obj/%.o: %.cpp | mk_obj_dir
|
|||||||
# '-' is 'ignore if missing' on first run
|
# '-' is 'ignore if missing' on first run
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB_WEBCONSOLE) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
||||||
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
|
$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG)
|
||||||
@@ -130,17 +143,12 @@ ifneq ($(USE_STATIC),yes)
|
|||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(SHLIB_LANG): $(LANG_OBJS)
|
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(SHLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
$(SHLIB_LANG): $(LANG_OBJS)
|
||||||
ifneq ($(USE_STATIC),yes)
|
|
||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(SHLIB_WRAP): $(WRAP_LIB_OBJS)
|
|
||||||
ifneq ($(USE_STATIC),yes)
|
ifneq ($(USE_STATIC),yes)
|
||||||
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
$(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
|
||||||
endif
|
endif
|
||||||
@@ -151,21 +159,18 @@ $(ARLIB): $(LIB_OBJS)
|
|||||||
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
$(ARLIB_LANG): $(LANG_OBJS)
|
|
||||||
$(AR) -r $@ $^
|
|
||||||
|
|
||||||
$(ARLIB_WEBCONSOLE): $(WEBCONSOLE_OBJS)
|
|
||||||
$(AR) -r $@ $^
|
|
||||||
|
|
||||||
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
|
$(ARLIB_WRAP): $(WRAP_LIB_OBJS)
|
||||||
$(AR) -r $@ $^
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
|
$(ARLIB_LANG): $(LANG_OBJS)
|
||||||
|
$(AR) -r $@ $^
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -r obj
|
$(RM) -r obj
|
||||||
$(RM) -r docs/generated
|
$(RM) -r docs/generated
|
||||||
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WEBCONSOLE) $(ARLIB_WEBCONSOLE) $(SHLIB_WRAP) $(ARLIB_WRAP)
|
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||||
|
|
||||||
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) $(SHLIB_WEBCONSOLE)
|
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
||||||
strip $^
|
strip $^
|
||||||
|
|
||||||
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
||||||
|
|||||||
@@ -3,11 +3,19 @@ USE_WIN32_APP := yes
|
|||||||
|
|
||||||
WINDRES = windres
|
WINDRES = windres
|
||||||
|
|
||||||
CXXFLAGS := $(CXX_DEBUG) -fPIC -msse
|
CXXFLAGS := $(CXX_DEBUG) -DWIN32_LEAN_AND_MEAN -fPIC -msse
|
||||||
INCFLAGS = -IWin32
|
INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32
|
||||||
LDFLAGS := ${LD_DEBUG} -static
|
LDFLAGS := ${LD_DEBUG} -static
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN
|
# detect proper flag for c++11 support by compilers
|
||||||
|
CXXVER := $(shell $(CXX) -dumpversion)
|
||||||
|
ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6
|
||||||
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
|
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7
|
||||||
|
NEEDED_CXXFLAGS += -std=c++17
|
||||||
|
else # not supported
|
||||||
|
$(error Compiler too old)
|
||||||
|
endif
|
||||||
|
|
||||||
# Boost libraries suffix
|
# Boost libraries suffix
|
||||||
BOOST_SUFFIX = -mt
|
BOOST_SUFFIX = -mt
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
@@ -15,6 +13,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
#include "Win32Service.h"
|
#include "Win32Service.h"
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -39,9 +38,6 @@ namespace util
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
i2p::win32::SetIsGraceful (std::bind (&DaemonWin32::SetIsGraceful, this, std::placeholders::_1));
|
|
||||||
i2p::win32::GetIsGraceful (std::bind (&DaemonWin32::GetIsGraceful, this));
|
|
||||||
|
|
||||||
if (!Daemon_Singleton::init(argc, argv))
|
if (!Daemon_Singleton::init(argc, argv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -49,8 +45,6 @@ namespace util
|
|||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Daemon: running as service");
|
LogPrint(eLogDebug, "Daemon: running as service");
|
||||||
I2PService service((PSTR)SERVICE_NAME);
|
I2PService service((PSTR)SERVICE_NAME);
|
||||||
service.SetDaemonStart (std::bind (&DaemonWin32::start, this));
|
|
||||||
service.SetDaemonStop (std::bind (&DaemonWin32::stop, this));
|
|
||||||
if (!I2PService::Run(service))
|
if (!I2PService::Run(service))
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
#include "Daemon.h"
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
#include "Win32NetState.h"
|
#include "Win32NetState.h"
|
||||||
|
|
||||||
@@ -55,15 +55,13 @@ namespace win32
|
|||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||||
if(!i2p::context.AcceptsTunnels())
|
if(!i2p::context.AcceptsTunnels())
|
||||||
if(m_getIsGraceful)
|
InsertMenu (hPopup, -1,
|
||||||
if(m_getIsGraceful())
|
i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING,
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING | MF_GRAYED, ID_ACCEPT_TRANSIT, "Accept &transit");
|
ID_ACCEPT_TRANSIT, "Accept &transit");
|
||||||
else
|
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ACCEPT_TRANSIT, "Accept &transit");
|
|
||||||
else
|
else
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config");
|
||||||
if (!m_getIsGraceful)
|
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||||
else
|
else
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
|
||||||
@@ -272,7 +270,7 @@ namespace win32
|
|||||||
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
||||||
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
|
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
|
||||||
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
||||||
if (m_setIsGraceful) m_setIsGraceful(true);
|
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ID_STOP_GRACEFUL_SHUTDOWN:
|
case ID_STOP_GRACEFUL_SHUTDOWN:
|
||||||
@@ -281,7 +279,7 @@ namespace win32
|
|||||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
||||||
g_GracefulShutdownEndtime = 0;
|
g_GracefulShutdownEndtime = 0;
|
||||||
if (m_setIsGraceful) m_setIsGraceful(false);
|
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ID_RELOAD:
|
case ID_RELOAD:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -22,15 +22,6 @@ namespace win32
|
|||||||
int RunWin32App ();
|
int RunWin32App ();
|
||||||
bool GracefulShutdown ();
|
bool GracefulShutdown ();
|
||||||
bool StopGracefulShutdown ();
|
bool StopGracefulShutdown ();
|
||||||
|
|
||||||
inline typedef std::function<void (bool)> DaemonSetIsGraceful;
|
|
||||||
inline DaemonSetIsGraceful m_setIsGraceful;
|
|
||||||
inline void SetIsGraceful (const DaemonSetIsGraceful& f) { m_setIsGraceful = f; };
|
|
||||||
|
|
||||||
inline typedef std::function<bool ()> DaemonGetIsGraceful;
|
|
||||||
inline DaemonGetIsGraceful m_getIsGraceful;
|
|
||||||
inline void GetIsGraceful (const DaemonGetIsGraceful& f) { m_getIsGraceful = f; };
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WIN32APP_H__
|
#endif // WIN32APP_H__
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "Daemon.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
I2PService *I2PService::s_service = NULL;
|
I2PService *I2PService::s_service = NULL;
|
||||||
@@ -131,13 +132,7 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
|
|||||||
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
|
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
|
LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
|
||||||
if(m_daemonStart)
|
Daemon.start();
|
||||||
m_daemonStart();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint(eLogError, "Win32Service: failed to start: Unable to call callback");
|
|
||||||
SetServiceStatus(SERVICE_STOPPED);
|
|
||||||
}
|
|
||||||
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
|
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,11 +171,7 @@ void I2PService::OnStop()
|
|||||||
{
|
{
|
||||||
// Log a service stop message to the Application log.
|
// Log a service stop message to the Application log.
|
||||||
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
|
LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
|
||||||
if(m_daemonStop)
|
Daemon.stop();
|
||||||
m_daemonStop();
|
|
||||||
else
|
|
||||||
LogPrint(eLogError, "Win32Service: failed to stop: Unable to call callback");
|
|
||||||
|
|
||||||
m_fStopping = TRUE;
|
m_fStopping = TRUE;
|
||||||
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,10 +6,9 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WIN32SERVICE_H__
|
#ifndef WIN_32_SERVICE_H__
|
||||||
#define WIN32SERVICE_H__
|
#define WIN_32_SERVICE_H__
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@@ -30,13 +29,6 @@ class I2PService
|
|||||||
static BOOL Run(I2PService &service);
|
static BOOL Run(I2PService &service);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
typedef std::function<bool ()> DaemonStart;
|
|
||||||
void SetDaemonStart (const DaemonStart& f) { m_daemonStart = f; };
|
|
||||||
|
|
||||||
typedef std::function<bool ()> DaemonStop;
|
|
||||||
void SetDaemonStop (const DaemonStop& f) { m_daemonStop = f; };
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||||
@@ -66,11 +58,6 @@ class I2PService
|
|||||||
HANDLE m_hStoppedEvent;
|
HANDLE m_hStoppedEvent;
|
||||||
|
|
||||||
std::thread* _worker;
|
std::thread* _worker;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DaemonStart m_daemonStart;
|
|
||||||
DaemonStop m_daemonStop;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIN32SERVICE_H__
|
#endif // WIN_32_SERVICE_H__
|
||||||
|
|||||||
@@ -33,13 +33,11 @@ target_architecture(ARCHITECTURE)
|
|||||||
|
|
||||||
set(LIBI2PD_SRC_DIR ../libi2pd)
|
set(LIBI2PD_SRC_DIR ../libi2pd)
|
||||||
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
||||||
set(WEBCONSOLE_SRC_DIR ../libi2pd_webconsole)
|
|
||||||
set(LANG_SRC_DIR ../i18n)
|
set(LANG_SRC_DIR ../i18n)
|
||||||
set(DAEMON_SRC_DIR ../daemon)
|
set(DAEMON_SRC_DIR ../daemon)
|
||||||
|
|
||||||
include_directories(${LIBI2PD_SRC_DIR})
|
include_directories(${LIBI2PD_SRC_DIR})
|
||||||
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
||||||
include_directories(${WEBCONSOLE_SRC_DIR})
|
|
||||||
include_directories(${LANG_SRC_DIR})
|
include_directories(${LANG_SRC_DIR})
|
||||||
include_directories(${DAEMON_SRC_DIR})
|
include_directories(${DAEMON_SRC_DIR})
|
||||||
|
|
||||||
@@ -70,18 +68,6 @@ if(WITH_LIBRARY)
|
|||||||
COMPONENT Libraries)
|
COMPONENT Libraries)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
FILE(GLOB WEBCONSOLE_SRC ${WEBCONSOLE_SRC_DIR}/*.cpp)
|
|
||||||
add_library(libi2pdwebconsole ${WEBCONSOLE_SRC})
|
|
||||||
set_target_properties(libi2pdwebconsole PROPERTIES PREFIX "")
|
|
||||||
|
|
||||||
if(WITH_LIBRARY)
|
|
||||||
install(TARGETS libi2pdwebconsole
|
|
||||||
EXPORT libi2pdwebconsole
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
COMPONENT Libraries)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
||||||
add_library(libi2pdlang ${LANG_SRC})
|
add_library(libi2pdlang ${LANG_SRC})
|
||||||
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
||||||
@@ -96,6 +82,7 @@ endif()
|
|||||||
|
|
||||||
set(DAEMON_SRC
|
set(DAEMON_SRC
|
||||||
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
||||||
|
"${DAEMON_SRC_DIR}/HTTPServer.cpp"
|
||||||
"${DAEMON_SRC_DIR}/I2PControl.cpp"
|
"${DAEMON_SRC_DIR}/I2PControl.cpp"
|
||||||
"${DAEMON_SRC_DIR}/i2pd.cpp"
|
"${DAEMON_SRC_DIR}/i2pd.cpp"
|
||||||
"${DAEMON_SRC_DIR}/UPnP.cpp"
|
"${DAEMON_SRC_DIR}/UPnP.cpp"
|
||||||
@@ -148,7 +135,7 @@ endif()
|
|||||||
|
|
||||||
# compiler flags customization(by system)
|
# compiler flags customization(by system)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/DaemonUnix.cpp")
|
list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
||||||
if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
|
if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
|
||||||
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
||||||
add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1")
|
add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1")
|
||||||
@@ -178,8 +165,20 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
# libraries
|
# libraries
|
||||||
|
# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826
|
||||||
|
# use imported Threads::Threads instead
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
if(IOS)
|
||||||
|
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
||||||
|
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
||||||
|
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
||||||
|
set(CMAKE_USE_PTHREADS_INIT 1)
|
||||||
|
else()
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
endif()
|
||||||
|
if(THREADS_HAVE_PTHREAD_ARG) # compile time flag
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_STATIC)
|
if(WITH_STATIC)
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
@@ -198,7 +197,7 @@ else()
|
|||||||
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(libi2pdwebconsole libi2pdclient libi2pd libi2pdlang)
|
target_link_libraries(libi2pdclient libi2pd libi2pdlang)
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||||
@@ -211,7 +210,7 @@ if(NOT DEFINED OPENSSL_INCLUDE_DIR)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
|
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
|
||||||
add_definitions(-DOPENSSL_SUPPRESS_DEPRECATED)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_UPNP)
|
if(WITH_UPNP)
|
||||||
@@ -279,7 +278,7 @@ if(WITH_BINARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
||||||
target_link_libraries("${PROJECT_NAME}" libi2pdwebconsole libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
||||||
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
|
|||||||
@@ -52,28 +52,22 @@ REM converting configuration files to DOS format (make usable in Windows Notepad
|
|||||||
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
|
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/* contrib/webconsole/style.css" >> build\build.log 2>&1
|
||||||
|
|
||||||
REM Prepare binary signing command if signing key and password provided
|
REM Prepare binary signing command if signing key and password provided
|
||||||
if defined SIGN (
|
if defined SIGNKEY (
|
||||||
echo Signing enabled
|
|
||||||
|
|
||||||
for %%X in (signtool.exe) do (set xSIGNTOOL=%%~$PATH:X)
|
|
||||||
if not defined xSIGNTOOL (
|
|
||||||
if not defined SIGNTOOL (
|
|
||||||
echo Error: Can't find signtool. Please provide path to binary using SIGNTOOL variable.
|
|
||||||
exit /b 1
|
|
||||||
) else (
|
|
||||||
set "xSIGNTOOL=%SIGNTOOL%"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if defined SIGNKEY (
|
|
||||||
set "xSIGNKEYOPTS=/f ^"%SIGNKEY%^""
|
|
||||||
)
|
|
||||||
|
|
||||||
if defined SIGNPASS (
|
if defined SIGNPASS (
|
||||||
set "xSIGNPASSOPTS=/p ^"%SIGNPASS%^""
|
echo Signing options found
|
||||||
)
|
|
||||||
|
|
||||||
set "xSIGNOPTS=sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 %xSIGNKEYOPTS% %xSIGNPASSOPTS%"
|
for %%X in (signtool.exe) do (set xSIGNTOOL=%%~$PATH:X)
|
||||||
|
if not defined xSIGNTOOL (
|
||||||
|
if not defined SIGNTOOL (
|
||||||
|
echo Error: Can't find signtool. Please provide path to binary using SIGNTOOL variable.
|
||||||
|
exit /b 1
|
||||||
|
) else (
|
||||||
|
set "xSIGNTOOL=%SIGNTOOL%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
set "xSIGNOPTS=sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f ^"%SIGNKEY%^" /p ^"%SIGNPASS%^""
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
REM starting building
|
REM starting building
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ port = 7070
|
|||||||
# user = i2pd
|
# user = i2pd
|
||||||
# pass = changeme
|
# pass = changeme
|
||||||
## Select webconsole language
|
## Select webconsole language
|
||||||
## Currently supported english (default), afrikaans, armenian, french, german,
|
## Currently supported english (default), afrikaans, armenian, german, russian,
|
||||||
## russian, turkmen, ukrainian and uzbek languages
|
## turkmen, ukrainian and uzbek languages
|
||||||
# lang = english
|
# lang = english
|
||||||
|
|
||||||
[httpproxy]
|
[httpproxy]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
||||||
|
|
||||||
Name: i2pd-git
|
Name: i2pd-git
|
||||||
Version: 2.42.1
|
Version: 2.41.0
|
||||||
Release: git%{git_hash}%{?dist}
|
Release: git%{git_hash}%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd
|
Conflicts: i2pd
|
||||||
@@ -164,12 +164,6 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
|
|
||||||
- update to 2.42.1
|
|
||||||
|
|
||||||
* Sun May 22 2022 orignal <orignal@i2pmail.org> - 2.42.0
|
|
||||||
- update to 2.42.0
|
|
||||||
|
|
||||||
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
||||||
- update to 2.41.0
|
- update to 2.41.0
|
||||||
- fixed build on Fedora Copr over openssl trunk code
|
- fixed build on Fedora Copr over openssl trunk code
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.42.1
|
Version: 2.41.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd-git
|
Conflicts: i2pd-git
|
||||||
@@ -161,12 +161,6 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue May 24 2022 r4sas <r4sas@i2pmail.org> - 2.42.1
|
|
||||||
- update to 2.42.1
|
|
||||||
|
|
||||||
* Sun May 22 2022 orignal <orignal@i2pmail.org> - 2.42.0
|
|
||||||
- update to 2.42.0
|
|
||||||
|
|
||||||
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
* Sun Feb 20 2022 r4sas <r4sas@i2pmail.org> - 2.41.0
|
||||||
- update to 2.41.0
|
- update to 2.41.0
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "Destination.h"
|
#include "Destination.h"
|
||||||
#include "HTTPServer.h"
|
#include "HTTPServer.h"
|
||||||
|
#ifdef WITH_I2PC
|
||||||
#include "I2PControl.h"
|
#include "I2PControl.h"
|
||||||
|
#endif
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "UPnP.h"
|
#include "UPnP.h"
|
||||||
@@ -45,7 +47,9 @@ namespace util
|
|||||||
~Daemon_Singleton_Private() {};
|
~Daemon_Singleton_Private() {};
|
||||||
|
|
||||||
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
||||||
|
#ifdef WITH_I2PC
|
||||||
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
||||||
|
#endif
|
||||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||||
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
||||||
};
|
};
|
||||||
@@ -58,7 +62,9 @@ namespace util
|
|||||||
bool Daemon_Singleton::IsService () const
|
bool Daemon_Singleton::IsService () const
|
||||||
{
|
{
|
||||||
bool service = false;
|
bool service = false;
|
||||||
|
#ifndef _WIN32
|
||||||
i2p::config::GetOption("service", service);
|
i2p::config::GetOption("service", service);
|
||||||
|
#endif
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +83,7 @@ namespace util
|
|||||||
i2p::config::Init();
|
i2p::config::Init();
|
||||||
i2p::config::ParseCmdline(argc, argv);
|
i2p::config::ParseCmdline(argc, argv);
|
||||||
|
|
||||||
std::string config; i2p::config::GetOption("conf", config);
|
std::string config; i2p::config::GetOption("conf", config);
|
||||||
std::string datadir;
|
std::string datadir;
|
||||||
if(DaemonDataDir != "") {
|
if(DaemonDataDir != "") {
|
||||||
datadir = DaemonDataDir;
|
datadir = DaemonDataDir;
|
||||||
@@ -109,9 +115,9 @@ namespace util
|
|||||||
|
|
||||||
certsdir = i2p::fs::GetCertsDir();
|
certsdir = i2p::fs::GetCertsDir();
|
||||||
|
|
||||||
std::string logs = ""; i2p::config::GetOption("log", logs);
|
std::string logs = ""; i2p::config::GetOption("log", logs);
|
||||||
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
||||||
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
||||||
bool logclftime; i2p::config::GetOption("logclftime", logclftime);
|
bool logclftime; i2p::config::GetOption("logclftime", logclftime);
|
||||||
|
|
||||||
/* setup logging */
|
/* setup logging */
|
||||||
@@ -252,17 +258,17 @@ namespace util
|
|||||||
}
|
}
|
||||||
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
if (ssu2)
|
if (ssu2)
|
||||||
{
|
{
|
||||||
bool published; i2p::config::GetOption("ssu2.published", published);
|
bool published; i2p::config::GetOption("ssu2.published", published);
|
||||||
if (published)
|
if (published)
|
||||||
{
|
{
|
||||||
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
|
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
|
||||||
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
|
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
|
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
|
||||||
}
|
}
|
||||||
|
|
||||||
bool transit; i2p::config::GetOption("notransit", transit);
|
bool transit; i2p::config::GetOption("notransit", transit);
|
||||||
i2p::context.SetAcceptsTunnels (!transit);
|
i2p::context.SetAcceptsTunnels (!transit);
|
||||||
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
||||||
@@ -423,10 +429,6 @@ namespace util
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
||||||
d.httpServer->SetDaemonStop (std::bind (Daemon_Singleton::stop, this));
|
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
|
||||||
d.httpServer->SetDaemonGracefulTimer (std::bind (gracefulShutdownInterval, this));
|
|
||||||
#endif
|
|
||||||
d.httpServer->Start();
|
d.httpServer->Start();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
@@ -443,6 +445,7 @@ namespace util
|
|||||||
LogPrint(eLogInfo, "Daemon: Starting Client");
|
LogPrint(eLogInfo, "Daemon: Starting Client");
|
||||||
i2p::client::context.Start ();
|
i2p::client::context.Start ();
|
||||||
|
|
||||||
|
#ifdef WITH_I2PC
|
||||||
// I2P Control Protocol
|
// I2P Control Protocol
|
||||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
if (i2pcontrol) {
|
if (i2pcontrol) {
|
||||||
@@ -460,6 +463,7 @@ namespace util
|
|||||||
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
|
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,12 +496,14 @@ namespace util
|
|||||||
d.httpServer->Stop();
|
d.httpServer->Stop();
|
||||||
d.httpServer = nullptr;
|
d.httpServer = nullptr;
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_I2PC
|
||||||
if (d.m_I2PControlService)
|
if (d.m_I2PControlService)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Daemon: Stopping I2PControl");
|
LogPrint(eLogInfo, "Daemon: Stopping I2PControl");
|
||||||
d.m_I2PControlService->Stop ();
|
d.m_I2PControlService->Stop ();
|
||||||
d.m_I2PControlService = nullptr;
|
d.m_I2PControlService = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
i2p::crypto::TerminateCrypto ();
|
i2p::crypto::TerminateCrypto ();
|
||||||
i2p::log::Logger().Stop();
|
i2p::log::Logger().Stop();
|
||||||
|
|
||||||
|
|||||||
@@ -75,17 +75,14 @@ namespace util
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init (int argc, char* argv[]);
|
bool init(int argc, char* argv[]);
|
||||||
bool start ();
|
bool start();
|
||||||
bool stop ();
|
bool stop();
|
||||||
void run ();
|
void run ();
|
||||||
|
|
||||||
void SetIsGraceful (bool state) { m_isGraceful = state; };
|
bool isGraceful;
|
||||||
const bool GetIsGraceful () { return m_isGraceful; };
|
|
||||||
|
|
||||||
private:
|
DaemonWin32 ():isGraceful(false) {}
|
||||||
|
|
||||||
bool m_isGraceful;
|
|
||||||
};
|
};
|
||||||
#elif (defined(ANDROID) && !defined(ANDROID_BINARY))
|
#elif (defined(ANDROID) && !defined(ANDROID_BINARY))
|
||||||
#define Daemon i2p::util::DaemonAndroid::Instance()
|
#define Daemon i2p::util::DaemonAndroid::Instance()
|
||||||
@@ -112,8 +109,8 @@ namespace util
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start ();
|
bool start();
|
||||||
bool stop ();
|
bool stop();
|
||||||
void run ();
|
void run ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -27,16 +27,14 @@
|
|||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
#include "HTTPServer.h"
|
#include "HTTPServer.h"
|
||||||
|
#include "Daemon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ECIESX25519AEADRatchetSession.h"
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
#include "I18N.h"
|
#include "I18N.h"
|
||||||
|
|
||||||
//#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
//#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
// Inja template engine
|
|
||||||
#include "inja/inja.hpp"
|
|
||||||
|
|
||||||
// For image, style and info
|
// For image, style and info
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@@ -60,7 +58,7 @@ namespace http {
|
|||||||
static void GetStyles (std::stringstream& s)
|
static void GetStyles (std::stringstream& s)
|
||||||
{
|
{
|
||||||
if (externalCSS.length() != 0)
|
if (externalCSS.length() != 0)
|
||||||
s << externalCSS;
|
s << "<style>\r\n" << externalCSS << "</style>\r\n";
|
||||||
else
|
else
|
||||||
s << internalCSS;
|
s << internalCSS;
|
||||||
}
|
}
|
||||||
@@ -70,9 +68,13 @@ namespace http {
|
|||||||
const char HTTP_PAGE_TRANSPORTS[] = "transports";
|
const char HTTP_PAGE_TRANSPORTS[] = "transports";
|
||||||
const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations";
|
const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations";
|
||||||
const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination";
|
const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination";
|
||||||
|
#ifdef WITH_I2CP
|
||||||
const char HTTP_PAGE_I2CP_LOCAL_DESTINATION[] = "i2cp_local_destination";
|
const char HTTP_PAGE_I2CP_LOCAL_DESTINATION[] = "i2cp_local_destination";
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SAM
|
||||||
const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions";
|
const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions";
|
||||||
const char HTTP_PAGE_SAM_SESSION[] = "sam_session";
|
const char HTTP_PAGE_SAM_SESSION[] = "sam_session";
|
||||||
|
#endif
|
||||||
const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels";
|
const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels";
|
||||||
const char HTTP_PAGE_COMMANDS[] = "commands";
|
const char HTTP_PAGE_COMMANDS[] = "commands";
|
||||||
const char HTTP_PAGE_LEASESETS[] = "leasesets";
|
const char HTTP_PAGE_LEASESETS[] = "leasesets";
|
||||||
@@ -89,7 +91,9 @@ namespace http {
|
|||||||
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
|
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
|
||||||
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
|
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
|
||||||
const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css";
|
const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css";
|
||||||
|
#ifdef WITH_SAM
|
||||||
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
||||||
|
#endif
|
||||||
const char HTTP_PARAM_ADDRESS[] = "address";
|
const char HTTP_PARAM_ADDRESS[] = "address";
|
||||||
|
|
||||||
static std::string ConvertTime (uint64_t time)
|
static std::string ConvertTime (uint64_t time)
|
||||||
@@ -184,11 +188,9 @@ namespace http {
|
|||||||
" <meta charset=\"UTF-8\">\r\n"
|
" <meta charset=\"UTF-8\">\r\n"
|
||||||
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
|
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
|
||||||
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
||||||
" <title>Purple I2P Webconsole</title>\r\n"
|
" <title>Purple I2P Webconsole</title>\r\n";
|
||||||
" <style>";
|
|
||||||
GetStyles(s);
|
GetStyles(s);
|
||||||
s <<
|
s <<
|
||||||
"\r\n</style>\r\n"
|
|
||||||
"</head>\r\n"
|
"</head>\r\n"
|
||||||
"<body>\r\n"
|
"<body>\r\n"
|
||||||
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
|
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
|
||||||
@@ -206,8 +208,10 @@ namespace http {
|
|||||||
s <<
|
s <<
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
|
||||||
|
#ifdef WITH_SAM
|
||||||
if (i2p::client::context.GetSAMBridge ())
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
|
||||||
|
#endif
|
||||||
s <<
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=\"content\">";
|
"<div class=\"content\">";
|
||||||
@@ -272,22 +276,23 @@ namespace http {
|
|||||||
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
|
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rewrite timer access
|
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (auto remains = m_DaemonGracefulTimer) {
|
if (auto remains = Daemon.gracefulShutdownInterval) {
|
||||||
s << "<b>" << tr("Stopping in") << ":</b> ";
|
s << "<b>" << tr("Stopping in") << ":</b> ";
|
||||||
ShowUptime(s, remains);
|
ShowUptime(s, remains);
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
/*#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::win32::g_GracefulShutdownEndtime != 0) {
|
if (i2p::win32::g_GracefulShutdownEndtime != 0) {
|
||||||
uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
||||||
s << "<b>" << tr("Stopping in") << ":</b> ";
|
s << "<b>" << tr("Stopping in") << ":</b> ";
|
||||||
ShowUptime(s, remains);
|
ShowUptime(s, remains);
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}*/
|
}
|
||||||
#endif
|
#endif
|
||||||
|
auto family = i2p::context.GetFamily ();
|
||||||
|
if (family.length () > 0)
|
||||||
|
s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n";
|
||||||
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
||||||
s << "<b>" << tr("Received") << ":</b> ";
|
s << "<b>" << tr("Received") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
||||||
@@ -327,9 +332,9 @@ namespace http {
|
|||||||
default:
|
default:
|
||||||
s << tr("Unknown");
|
s << tr("Unknown");
|
||||||
}
|
}
|
||||||
if (address->IsV6 ())
|
if (address->IsV6 ())
|
||||||
{
|
{
|
||||||
if (address->IsV4 ()) s << "v4";
|
if (address->IsV4 ()) s << "v4";
|
||||||
s << "v6";
|
s << "v6";
|
||||||
}
|
}
|
||||||
s << "</td>\r\n";
|
s << "</td>\r\n";
|
||||||
@@ -364,17 +369,25 @@ namespace http {
|
|||||||
if (outputFormat==OutputFormatEnum::forWebConsole) {
|
if (outputFormat==OutputFormatEnum::forWebConsole) {
|
||||||
bool httpproxy = i2p::client::context.GetHttpProxy () ? true : false;
|
bool httpproxy = i2p::client::context.GetHttpProxy () ? true : false;
|
||||||
bool socksproxy = i2p::client::context.GetSocksProxy () ? true : false;
|
bool socksproxy = i2p::client::context.GetSocksProxy () ? true : false;
|
||||||
bool bob = i2p::client::context.GetBOBCommandChannel () ? true : false;
|
|
||||||
bool sam = i2p::client::context.GetSAMBridge () ? true : false;
|
|
||||||
bool i2cp = i2p::client::context.GetI2CPServer () ? true : false;
|
|
||||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
|
||||||
s << "<table class=\"services\"><caption>" << tr("Services") << "</caption><tbody>\r\n";
|
s << "<table class=\"services\"><caption>" << tr("Services") << "</caption><tbody>\r\n";
|
||||||
s << "<tr><td>" << "HTTP " << tr("Proxy") << "</td><td class='" << (httpproxy ? "enabled" : "disabled") << "'>" << (httpproxy ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "HTTP " << tr("Proxy") << "</td><td class='" << (httpproxy ? "enabled" : "disabled") << "'>" << (httpproxy ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
s << "<tr><td>" << "SOCKS " << tr("Proxy") << "</td><td class='" << (socksproxy ? "enabled" : "disabled") << "'>" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "SOCKS " << tr("Proxy") << "</td><td class='" << (socksproxy ? "enabled" : "disabled") << "'>" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
|
#ifdef WITH_BOB
|
||||||
|
bool bob = i2p::client::context.GetBOBCommandChannel () ? true : false;
|
||||||
s << "<tr><td>" << "BOB" << "</td><td class='" << (bob ? "enabled" : "disabled") << "'>" << (bob ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "BOB" << "</td><td class='" << (bob ? "enabled" : "disabled") << "'>" << (bob ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SAM
|
||||||
|
bool sam = i2p::client::context.GetSAMBridge () ? true : false;
|
||||||
s << "<tr><td>" << "SAM" << "</td><td class='" << (sam ? "enabled" : "disabled") << "'>" << (sam ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "SAM" << "</td><td class='" << (sam ? "enabled" : "disabled") << "'>" << (sam ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
|
bool i2cp = i2p::client::context.GetI2CPServer () ? true : false;
|
||||||
s << "<tr><td>" << "I2CP" << "</td><td class='" << (i2cp ? "enabled" : "disabled") << "'>" << (i2cp ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "I2CP" << "</td><td class='" << (i2cp ? "enabled" : "disabled") << "'>" << (i2cp ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2PC
|
||||||
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
s << "<tr><td>" << "I2PControl" << "</td><td class='" << (i2pcontrol ? "enabled" : "disabled") << "'>" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
s << "<tr><td>" << "I2PControl" << "</td><td class='" << (i2pcontrol ? "enabled" : "disabled") << "'>" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "</td></tr>\r\n";
|
||||||
|
#endif
|
||||||
s << "</tbody></table>\r\n";
|
s << "</tbody></table>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,6 +404,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
||||||
{
|
{
|
||||||
@@ -408,6 +422,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
|
static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr<const i2p::client::LeaseSetDestination> dest, uint32_t token)
|
||||||
@@ -422,7 +437,7 @@ namespace http {
|
|||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ())
|
if (dest->IsPublic() && token)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
auto base32 = dest->GetIdentHash ().ToBase32 ();
|
auto base32 = dest->GetIdentHash ().ToBase32 ();
|
||||||
@@ -575,6 +590,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
||||||
{
|
{
|
||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
@@ -590,6 +606,7 @@ namespace http {
|
|||||||
else
|
else
|
||||||
ShowError(s, tr("I2CP is not enabled"));
|
ShowError(s, tr("I2CP is not enabled"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ShowLeasesSets(std::stringstream& s)
|
void ShowLeasesSets(std::stringstream& s)
|
||||||
{
|
{
|
||||||
@@ -713,12 +730,11 @@ namespace http {
|
|||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
||||||
/*#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a><br><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a><br><br>\r\n";
|
||||||
@@ -883,6 +899,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
void ShowSAMSessions (std::stringstream& s)
|
void ShowSAMSessions (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
@@ -945,6 +962,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ShowI2PTunnels (std::stringstream& s)
|
void ShowI2PTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
@@ -1023,8 +1041,8 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket, HTTPServer& server):
|
HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
|
||||||
m_Socket (socket), m_Server (server), m_BufferLen (0), expected_host(hostname)
|
m_Socket (socket), m_BufferLen (0), expected_host(hostname)
|
||||||
{
|
{
|
||||||
/* cache options */
|
/* cache options */
|
||||||
i2p::config::GetOption("http.auth", needAuth);
|
i2p::config::GetOption("http.auth", needAuth);
|
||||||
@@ -1198,12 +1216,16 @@ namespace http {
|
|||||||
uint32_t token = CreateToken ();
|
uint32_t token = CreateToken ();
|
||||||
ShowLocalDestination (s, params["b32"], token);
|
ShowLocalDestination (s, params["b32"], token);
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_I2CP
|
||||||
else if (page == HTTP_PAGE_I2CP_LOCAL_DESTINATION)
|
else if (page == HTTP_PAGE_I2CP_LOCAL_DESTINATION)
|
||||||
ShowI2CPLocalDestination (s, params["i2cp_id"]);
|
ShowI2CPLocalDestination (s, params["i2cp_id"]);
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SAM
|
||||||
else if (page == HTTP_PAGE_SAM_SESSIONS)
|
else if (page == HTTP_PAGE_SAM_SESSIONS)
|
||||||
ShowSAMSessions (s);
|
ShowSAMSessions (s);
|
||||||
else if (page == HTTP_PAGE_SAM_SESSION)
|
else if (page == HTTP_PAGE_SAM_SESSION)
|
||||||
ShowSAMSession (s, params["sam_id"]);
|
ShowSAMSession (s, params["sam_id"]);
|
||||||
|
#endif
|
||||||
else if (page == HTTP_PAGE_I2P_TUNNELS)
|
else if (page == HTTP_PAGE_I2P_TUNNELS)
|
||||||
ShowI2PTunnels (s);
|
ShowI2PTunnels (s);
|
||||||
else if (page == HTTP_PAGE_LEASESETS)
|
else if (page == HTTP_PAGE_LEASESETS)
|
||||||
@@ -1245,33 +1267,28 @@ namespace http {
|
|||||||
else if (cmd == HTTP_COMMAND_SHUTDOWN_START)
|
else if (cmd == HTTP_COMMAND_SHUTDOWN_START)
|
||||||
{
|
{
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
// TODO: rewrite timer access
|
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (m_DaemonGracefulTimer) m_DaemonGracefulTimer = 10 * 60;
|
Daemon.gracefulShutdownInterval = 10*60;
|
||||||
/*#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
i2p::win32::GracefulShutdown ();
|
i2p::win32::GracefulShutdown ();
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL)
|
else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL)
|
||||||
{
|
{
|
||||||
i2p::context.SetAcceptsTunnels (true);
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
// TODO: rewrite timer access
|
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (m_DaemonGracefulTimer) m_DaemonGracefulTimer = 0;
|
Daemon.gracefulShutdownInterval = 0;
|
||||||
/*#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
i2p::win32::StopGracefulShutdown ();
|
i2p::win32::StopGracefulShutdown ();
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW)
|
else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW)
|
||||||
{
|
{
|
||||||
// TODO: rewrite stop command access
|
#ifndef WIN32_APP
|
||||||
//#ifndef WIN32_APP
|
Daemon.running = false;
|
||||||
m_Server.GetDaemonStop();
|
#else
|
||||||
//#else
|
i2p::win32::StopWin32App ();
|
||||||
// i2p::win32::StopWin32App ();
|
#endif
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
else if (cmd == HTTP_COMMAND_LOGLEVEL)
|
else if (cmd == HTTP_COMMAND_LOGLEVEL)
|
||||||
{
|
{
|
||||||
@@ -1505,7 +1522,7 @@ namespace http {
|
|||||||
|
|
||||||
void HTTPServer::CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket)
|
void HTTPServer::CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket)
|
||||||
{
|
{
|
||||||
auto conn = std::make_shared<HTTPConnection> (m_Hostname, newSocket, *this);
|
auto conn = std::make_shared<HTTPConnection> (m_Hostname, newSocket);
|
||||||
conn->Receive ();
|
conn->Receive ();
|
||||||
}
|
}
|
||||||
} // http
|
} // http
|
||||||
@@ -25,13 +25,11 @@ namespace http
|
|||||||
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
|
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
|
||||||
const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds
|
const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds
|
||||||
|
|
||||||
class HTTPServer;
|
|
||||||
|
|
||||||
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
|
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HTTPConnection (std::string serverhost, std::shared_ptr<boost::asio::ip::tcp::socket> socket, HTTPServer& server);
|
HTTPConnection (std::string serverhost, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
void Receive ();
|
void Receive ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -50,7 +48,6 @@ namespace http
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
HTTPServer& m_Server;
|
|
||||||
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
|
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
std::string m_SendBuffer;
|
std::string m_SendBuffer;
|
||||||
@@ -72,13 +69,6 @@ namespace http
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
typedef std::function<void ()> DaemonStop;
|
|
||||||
void SetDaemonStop (const DaemonStop& f) { m_DaemonStop = f; };
|
|
||||||
DaemonStop GetDaemonStop () { return m_DaemonStop; };
|
|
||||||
|
|
||||||
void SetDaemonGracefulTimer (const int& f) { m_DaemonGracefulTimer = f; };
|
|
||||||
int GetDaemonGracefulTimer () { return m_DaemonGracefulTimer; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
@@ -95,11 +85,6 @@ namespace http
|
|||||||
boost::asio::io_service::work m_Work;
|
boost::asio::io_service::work m_Work;
|
||||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||||
std::string m_Hostname;
|
std::string m_Hostname;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DaemonStop m_DaemonStop;
|
|
||||||
int m_DaemonGracefulTimer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
||||||
@@ -110,11 +95,15 @@ namespace http
|
|||||||
void ShowTunnels (std::stringstream& s);
|
void ShowTunnels (std::stringstream& s);
|
||||||
void ShowTransitTunnels (std::stringstream& s);
|
void ShowTransitTunnels (std::stringstream& s);
|
||||||
void ShowTransports (std::stringstream& s);
|
void ShowTransports (std::stringstream& s);
|
||||||
void ShowSAMSessions (std::stringstream& s);
|
|
||||||
void ShowI2PTunnels (std::stringstream& s);
|
void ShowI2PTunnels (std::stringstream& s);
|
||||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||||
|
#ifdef WITH_SAM
|
||||||
|
void ShowSAMSessions (std::stringstream& s);
|
||||||
void ShowSAMSession (std::stringstream& s, const std::string& id);
|
void ShowSAMSession (std::stringstream& s, const std::string& id);
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
|
void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
|
||||||
|
#endif
|
||||||
} // http
|
} // http
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ namespace http
|
|||||||
|
|
||||||
// bundled style sheet
|
// bundled style sheet
|
||||||
const std::string internalCSS =
|
const std::string internalCSS =
|
||||||
|
"<style>\r\n"
|
||||||
":root { --main-bg-color: #fafafa; --main-text-color: #103456; --main-link-color: #894c84; --main-link-hover-color: #fafafa; }\r\n"
|
":root { --main-bg-color: #fafafa; --main-text-color: #103456; --main-link-color: #894c84; --main-link-hover-color: #fafafa; }\r\n"
|
||||||
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n"
|
"@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n"
|
||||||
"body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n"
|
"body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n"
|
||||||
@@ -84,127 +85,12 @@ namespace http
|
|||||||
" border-radius: 5px; font-size: 12px; }\r\n"
|
" border-radius: 5px; font-size: 12px; }\r\n"
|
||||||
" button[type=submit] { padding: 5px 15px; background: transparent; border: 2px solid var(--main-link-color); cursor: pointer;\r\n"
|
" button[type=submit] { padding: 5px 15px; background: transparent; border: 2px solid var(--main-link-color); cursor: pointer;\r\n"
|
||||||
" border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
" border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
||||||
"}\r\n";
|
"}\r\n"
|
||||||
|
"</style>\r\n";
|
||||||
|
|
||||||
// for external style sheet
|
// for external style sheet
|
||||||
std::string externalCSS;
|
std::string externalCSS;
|
||||||
|
|
||||||
const std::string pageBase =
|
|
||||||
"<!DOCTYPE html> \
|
|
||||||
<html lang=\"{{ langCode }}\"> \
|
|
||||||
<head> \
|
|
||||||
{% block head %} \
|
|
||||||
<meta charset=\"UTF-8\"> \
|
|
||||||
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> \
|
|
||||||
<link rel=\"shortcut icon\" href=\"{% getFavicon() %}\"> \
|
|
||||||
<title>{% block title %}{% endblock %} - Purple I2P Webconsole</title> \
|
|
||||||
<style>{% getStyles() %}</style> \
|
|
||||||
{% endblock %} \
|
|
||||||
</head> \
|
|
||||||
<body> \
|
|
||||||
<div class=\"header\">{% tr(\"<b>i2pd</b> webconsole\") %}</div> \
|
|
||||||
<div class=\"wrapper\"> \
|
|
||||||
<div class=\"menu\"> \
|
|
||||||
<a href=\"{{ webroot }}\">{% tr(\"Main page\") %}</a><br><br> \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_COMMANDS\") %}\">{% tr(\"Router commands\") %}</a><br> \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_LOCAL_DESTINATIONS\") %}\">{% tr(\"Local Destinations\") %}</a><br> \
|
|
||||||
{% if isFloodfill %} \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_LEASESETS\") %}\">{% tr(\"LeaseSets\") %}</a><br> \
|
|
||||||
{% endif %} \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_TUNNELS\") %}\">{% tr(\"Tunnels\") %}</a><br> \
|
|
||||||
{% if (acceptingTunnels || transitTunnels) %} \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_TRANSIT_TUNNELS\") %}\">{% tr(\"Transit Tunnels\") %}</a><br> \
|
|
||||||
{% endif %} \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_TRANSPORTS\") %}\">{% tr(\"Transports\") %}</a><br> \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_I2P_TUNNELS\") %}\">{% tr(\"I2P tunnels\") %}</a><br> \
|
|
||||||
{% if samEnabled %} \
|
|
||||||
<a href=\"{{ webroot }}?page={% getCommand(\"HTTP_PAGE_SAM_SESSIONS\") %}\">{% tr(\"SAM sessions\") %}</a><br> \
|
|
||||||
{% endif %} \
|
|
||||||
</div> \
|
|
||||||
<div class=\"content\">{% block content %}{% endblock %}</div> \
|
|
||||||
</div> \
|
|
||||||
</body> \
|
|
||||||
</html>";
|
|
||||||
|
|
||||||
const std::string pageMain =
|
|
||||||
"{% extends \"base.html\" %} \
|
|
||||||
{% block title %}Main{% endblock %} \
|
|
||||||
{% block content %} \
|
|
||||||
<b>{% tr(\"Uptime\") %}:</b> {% getUptime() %}<br> \
|
|
||||||
<b>{% tr(\"Network status\") %}:</b> {% getNetworkStatus(false) %}<br> \
|
|
||||||
{% if supportsV6 %} \
|
|
||||||
<b>{% tr(\"Network status v6\") %}:</b> {% getNetworkStatus(true) %}<br> \
|
|
||||||
{% endif %} \
|
|
||||||
{% if gracefulShutdown %} \
|
|
||||||
<b>{% tr(\"Stopping in\") %}:</b> {% getShutdownTimer() %}<br> \
|
|
||||||
{% endif %} \
|
|
||||||
<b>{% tr(\"Tunnel creation success rate\") %}:</b> {% getSuccessRate() %}%<br> \
|
|
||||||
<b>{% tr(\"Received\") %}:</b> {% getInBytes() %} ({% getInBW() %} {% tr(/* tr: Kibibit/s */ \"KiB/s\") %})<br> \
|
|
||||||
<b>{% tr(\"Sent\") %}:</b> {% getOutBytes() %} ({% getOutBW() %} {% tr(/* tr: Kibibit/s */ \"KiB/s\") %})<br> \
|
|
||||||
<b>{% tr(\"Transit\") %}:</b> {% getTransitBytes() %} ({% getTransitBW() %} {% tr(/* tr: Kibibit/s */ \"KiB/s\") %})<br> \
|
|
||||||
<b>{% tr(\"Data path\") %}:</b> {% getDataPath() %}<br> \
|
|
||||||
{% if notQt || withHiddenContent %} \
|
|
||||||
<div class=\"slide\"> \
|
|
||||||
<label for=\"slide-info\">{% tr(\"Hidden content. Press on text to see.\") %}</label> \
|
|
||||||
<input type=\"checkbox\" id=\"slide-info\" /> \
|
|
||||||
<div class=\"slidecontent\"> \
|
|
||||||
<b>{% tr(\"Router Ident\") %}:</b> {% getRI() %}<br> \
|
|
||||||
{% if lenght(family) %} \
|
|
||||||
<b>{% tr(\"Family\") %}:</b> {{ family }}<br> \
|
|
||||||
{% endif %} \
|
|
||||||
<b>{% tr(\"Router Caps\") %}:</b> {% getCaps() %}<br> \
|
|
||||||
<b>{% tr(\"Version\") %}:</b> {{ version }}<br> \
|
|
||||||
<b>{% tr(\"Our external address\") %}:</b><br> \
|
|
||||||
<table class=\"extaddr\"> \
|
|
||||||
<tbody> \
|
|
||||||
{% for type, address in addresses %} \
|
|
||||||
<tr><td>{{ type }}</td><td>{{ address }}</td></tr> \
|
|
||||||
{% endfor %} \
|
|
||||||
</tbody> \
|
|
||||||
</table> \
|
|
||||||
</div> \
|
|
||||||
</div> \
|
|
||||||
{% else %} \
|
|
||||||
<br> \
|
|
||||||
{% endif %} \
|
|
||||||
<b>{% tr(\"Routers\") %}:</b> {% getNumRouter() %} \
|
|
||||||
<b>{% tr(\"Floodfills\") %}:</b> {% getNumFloodfills() %} \
|
|
||||||
<b>{% tr(\"LeaseSets\") %}:</b> {% getNumLeaseSets() %}<br> \
|
|
||||||
<b>{% tr(\"Client Tunnels\") %}:</b> {% getClientTunnelsCount() %} \
|
|
||||||
<b>{% tr(\"Transit Tunnels\") %}:</b> {% getTransitTunnelsCount() %}<br> \
|
|
||||||
<br> \
|
|
||||||
{% if notQt == false %} \
|
|
||||||
<table class=\"services\"> \
|
|
||||||
<caption>{% tr(\"Services\") %}</caption> \
|
|
||||||
<tbody> \
|
|
||||||
<tr> \
|
|
||||||
<td>HTTP {% tr(\"Proxy\") %}</td> \
|
|
||||||
<td class=\"{% if httpproxy %}enabled{% else %}disabled{% endif %}\">{% if httpproxy %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
<tr> \
|
|
||||||
<td>SOCKS {% tr(\"Proxy\") %}</td> \
|
|
||||||
<td class=\"{% if socksproxy %}enabled{% else %}disabled{% endif %}\">{% if socksproxy %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
<tr> \
|
|
||||||
<td>BOB</td> \
|
|
||||||
<td class=\"{% if bob %}enabled{% else %}disabled{% endif %}\">{% if bob %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
<tr> \
|
|
||||||
<td>SAM</td> \
|
|
||||||
<td class=\"{% if sam %}enabled{% else %}disabled{% endif %}\">{% if sam %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
<tr> \
|
|
||||||
<td>I2CP</td> \
|
|
||||||
<td class=\"{% if i2cp %}enabled{% else %}disabled{% endif %}\">{% if i2cp %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
<tr> \
|
|
||||||
<td>I2PControl</td> \
|
|
||||||
<td class=\"{% if i2pcontrol %}enabled{% else %}disabled{% endif %}\">{% if i2pcontrol %}{% tr(\"Enabled\") %}{% else %}{% tr(\"Disabled\") %}{% endif %}</td> \
|
|
||||||
</tr> \
|
|
||||||
</tbody> \
|
|
||||||
</table> \
|
|
||||||
{% endblock %}";
|
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_I2PC
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
@@ -66,28 +68,28 @@ namespace client
|
|||||||
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||||
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||||
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||||
|
|
||||||
// RouterInfo
|
// RouterInfo
|
||||||
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
||||||
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
||||||
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||||
|
|
||||||
@@ -103,10 +105,16 @@ namespace client
|
|||||||
// ClientServicesInfo
|
// ClientServicesInfo
|
||||||
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
#ifdef WITH_SAM
|
||||||
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
#endif
|
||||||
|
#ifdef WITH_BOB
|
||||||
|
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
|
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
I2PControlService::~I2PControlService ()
|
I2PControlService::~I2PControlService ()
|
||||||
@@ -167,7 +175,7 @@ namespace client
|
|||||||
Accept ();
|
Accept ();
|
||||||
|
|
||||||
if (ecode) {
|
if (ecode) {
|
||||||
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
|
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
|
||||||
@@ -289,12 +297,12 @@ namespace client
|
|||||||
{
|
{
|
||||||
ss << "\"" << name << "\":";
|
ss << "\"" << name << "\":";
|
||||||
if (value.length () > 0)
|
if (value.length () > 0)
|
||||||
{
|
{
|
||||||
if (quotes)
|
if (quotes)
|
||||||
ss << "\"" << value << "\"";
|
ss << "\"" << value << "\"";
|
||||||
else
|
else
|
||||||
ss << value;
|
ss << value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ss << "null";
|
ss << "null";
|
||||||
}
|
}
|
||||||
@@ -345,8 +353,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
|
|
||||||
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
int api = params.get<int> ("API");
|
int api = params.get<int> ("API");
|
||||||
@@ -371,8 +378,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
|
|
||||||
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto& it: params)
|
for (auto& it: params)
|
||||||
@@ -478,7 +484,7 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -532,7 +538,7 @@ namespace client
|
|||||||
i2p::data::netdb.Reseed ();
|
i2p::data::netdb.Reseed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// network setting
|
// network setting
|
||||||
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
@@ -612,8 +618,7 @@ namespace client
|
|||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientServicesInfo
|
// ClientServicesInfo
|
||||||
|
|
||||||
void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
@@ -719,6 +724,7 @@ namespace client
|
|||||||
InsertParam (results, "SOCKS", pt);
|
InsertParam (results, "SOCKS", pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
void I2PControlService::SAMInfoHandler (std::ostringstream& results)
|
void I2PControlService::SAMInfoHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
@@ -754,7 +760,9 @@ namespace client
|
|||||||
|
|
||||||
InsertParam (results, "SAM", pt);
|
InsertParam (results, "SAM", pt);
|
||||||
}
|
}
|
||||||
|
#endif // WITH_SAM
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
void I2PControlService::BOBInfoHandler (std::ostringstream& results)
|
void I2PControlService::BOBInfoHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
@@ -769,7 +777,9 @@ namespace client
|
|||||||
|
|
||||||
InsertParam (results, "BOB", pt);
|
InsertParam (results, "BOB", pt);
|
||||||
}
|
}
|
||||||
|
#endif // WITH_BOB
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
void I2PControlService::I2CPInfoHandler (std::ostringstream& results)
|
void I2PControlService::I2CPInfoHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
@@ -784,5 +794,7 @@ namespace client
|
|||||||
|
|
||||||
InsertParam (results, "I2CP", pt);
|
InsertParam (results, "I2CP", pt);
|
||||||
}
|
}
|
||||||
|
#endif // WITH_I2CP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // WITH_I2PC
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_I2PC
|
||||||
|
|
||||||
#ifndef I2P_CONTROL_H__
|
#ifndef I2P_CONTROL_H__
|
||||||
#define I2P_CONTROL_H__
|
#define I2P_CONTROL_H__
|
||||||
|
|
||||||
@@ -114,9 +116,15 @@ namespace client
|
|||||||
void I2PTunnelInfoHandler (std::ostringstream& results);
|
void I2PTunnelInfoHandler (std::ostringstream& results);
|
||||||
void HTTPProxyInfoHandler (std::ostringstream& results);
|
void HTTPProxyInfoHandler (std::ostringstream& results);
|
||||||
void SOCKSInfoHandler (std::ostringstream& results);
|
void SOCKSInfoHandler (std::ostringstream& results);
|
||||||
|
#ifdef WITH_SAM
|
||||||
void SAMInfoHandler (std::ostringstream& results);
|
void SAMInfoHandler (std::ostringstream& results);
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_BOB
|
||||||
void BOBInfoHandler (std::ostringstream& results);
|
void BOBInfoHandler (std::ostringstream& results);
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
void I2CPInfoHandler (std::ostringstream& results);
|
void I2CPInfoHandler (std::ostringstream& results);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -141,3 +149,4 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif // WITH_I2PC
|
||||||
@@ -93,7 +93,7 @@ namespace transport
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
isError = err != UPNPDISCOVER_SUCCESS;
|
isError = err != UPNPDISCOVER_SUCCESS;
|
||||||
#else // MINIUPNPC_API_VERSION >= 8
|
#else // MINIUPNPC_API_VERSION >= 8
|
||||||
err = 0;
|
err = 0;
|
||||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
||||||
isError = m_Devlist == NULL;
|
isError = m_Devlist == NULL;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace transport
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void Discover ();
|
void Discover ();
|
||||||
int CheckMapping (const char* port, const char* type);
|
int CheckMapping (const char* port, const char* type);
|
||||||
void PortMapping ();
|
void PortMapping ();
|
||||||
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
void CloseMapping ();
|
void CloseMapping ();
|
||||||
@@ -80,7 +80,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // USE_UPNP
|
#else // USE_UPNP
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace transport {
|
namespace transport {
|
||||||
/* class stub */
|
/* class stub */
|
||||||
|
|||||||
13
debian/changelog
vendored
13
debian/changelog
vendored
@@ -1,16 +1,3 @@
|
|||||||
i2pd (2.42.1-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* updated to version 2.42.1/0.9.54
|
|
||||||
* remove -O3 optimization flag
|
|
||||||
|
|
||||||
-- r4sas <r4sas@i2pmail.org> Tue, 24 May 2022 12:00:00 +0000
|
|
||||||
|
|
||||||
i2pd (2.42.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* updated to version 2.42.0/0.9.54
|
|
||||||
|
|
||||||
-- orignal <orignal@i2pmail.org> Sun, 22 May 2022 16:00:00 +0000
|
|
||||||
|
|
||||||
i2pd (2.41.0-1) unstable; urgency=medium
|
i2pd (2.41.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* updated to version 2.41.0/0.9.53
|
* updated to version 2.41.0/0.9.53
|
||||||
|
|||||||
7
debian/rules
vendored
7
debian/rules
vendored
@@ -1,12 +1,17 @@
|
|||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
#export DH_VERBOSE=1
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
|
||||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
|
||||||
include /usr/share/dpkg/architecture.mk
|
include /usr/share/dpkg/architecture.mk
|
||||||
|
|
||||||
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic
|
export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic -O3
|
||||||
|
|
||||||
export DEB_LDFLAGS_MAINT_APPEND =
|
export DEB_LDFLAGS_MAINT_APPEND =
|
||||||
|
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@ --parallel
|
dh $@ --parallel
|
||||||
|
|
||||||
|
|||||||
23
filelist.mk
23
filelist.mk
@@ -1,7 +1,26 @@
|
|||||||
|
#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 Gost.cpp
|
||||||
|
|
||||||
LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.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
|
||||||
|
|
||||||
LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.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
|
||||||
|
|
||||||
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
|
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
|
||||||
WEBCONSOLE_SRC = $(wildcard $(WEBCONSOLE_SRC_DIR)/*.cpp)
|
|
||||||
|
|
||||||
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
|
WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp)
|
||||||
DAEMON_SRC = $(DAEMON_SRC_DIR)/Daemon.cpp $(DAEMON_SRC_DIR)/I2PControl.cpp $(DAEMON_SRC_DIR)/i2pd.cpp $(DAEMON_SRC_DIR)/UPnP.cpp
|
|
||||||
|
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
|
||||||
|
|||||||
102
i18n/French.cpp
102
i18n/French.cpp
@@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022, The PurpleI2P Project
|
|
||||||
*
|
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
*
|
|
||||||
* See full license text in LICENSE file at top of project tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include "I18N.h"
|
|
||||||
|
|
||||||
// French localization file
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace i18n
|
|
||||||
{
|
|
||||||
namespace french // language namespace
|
|
||||||
{
|
|
||||||
// language name in lowercase
|
|
||||||
static std::string language = "french";
|
|
||||||
|
|
||||||
// See for language plural forms here:
|
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
|
||||||
static int plural (int n) {
|
|
||||||
return n != 1 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::map<std::string, std::string> strings
|
|
||||||
{
|
|
||||||
{"KiB", "Kio"},
|
|
||||||
{"MiB", "Mio"},
|
|
||||||
{"GiB", "Gio"},
|
|
||||||
{"building", "En construction"},
|
|
||||||
{"failed", "echoué"},
|
|
||||||
{"expiring", "expiré"},
|
|
||||||
{"established", "établi"},
|
|
||||||
{"unknown", "inconnu"},
|
|
||||||
{"exploratory", "exploratoire"},
|
|
||||||
{"<b>i2pd</b> webconsole", "Console web <b>i2pd</b>"},
|
|
||||||
{"Main page", "Page principale"},
|
|
||||||
{"Router commands", "Commandes du routeur"},
|
|
||||||
{"Local Destinations", "Destinations locales"},
|
|
||||||
{"Tunnels", "Tunnels"},
|
|
||||||
{"Transit Tunnels", "Tunnels transitoires"},
|
|
||||||
{"I2P tunnels", "Tunnels I2P"},
|
|
||||||
{"SAM sessions", "Sessions SAM"},
|
|
||||||
{"ERROR", "ERREUR"},
|
|
||||||
{"OK", "OK"},
|
|
||||||
{"Firewalled", "Derrière un pare-feu"},
|
|
||||||
{"Error", "Erreur"},
|
|
||||||
{"Offline", "Hors ligne"},
|
|
||||||
{"Uptime", "Temps de fonctionnement"},
|
|
||||||
{"Network status", "État du réseau"},
|
|
||||||
{"Network status v6", "État du réseau v6"},
|
|
||||||
{"Stopping in", "Arrêt dans"},
|
|
||||||
{"Family", "Famille"},
|
|
||||||
{"Tunnel creation success rate", "Taux de succès de création de tunnels"},
|
|
||||||
{"Received", "Reçu"},
|
|
||||||
{"KiB/s", "kio/s"},
|
|
||||||
{"Sent", "Envoyé"},
|
|
||||||
{"Transit", "Transit"},
|
|
||||||
{"Hidden content. Press on text to see.", "Contenu caché. Cliquez sur le texte pour regarder."},
|
|
||||||
{"Router Ident", "Identifiant du routeur"},
|
|
||||||
{"Router Family", "Famille du routeur"},
|
|
||||||
{"Version", "Version"},
|
|
||||||
{"Our external address", "Notre adresse externe"},
|
|
||||||
{"Client Tunnels", "Tunnels clients"},
|
|
||||||
{"Services", "Services"},
|
|
||||||
{"Enabled", "Activé"},
|
|
||||||
{"Disabled", "Désactivé"},
|
|
||||||
{"Encrypted B33 address", "Adresse B33 chiffrée"},
|
|
||||||
{"Domain", "Domaine"},
|
|
||||||
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Note:</b> La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."},
|
|
||||||
{"Address", "Adresse"},
|
|
||||||
{"ms", "ms"},
|
|
||||||
{"Outbound tunnels", "Tunnels sortants"},
|
|
||||||
{"Destination", "Destination"},
|
|
||||||
{"Local Destination", "Destination locale"},
|
|
||||||
{"", ""},
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::map<std::string, std::vector<std::string>> plurals
|
|
||||||
{
|
|
||||||
{"days", {"jour", "jours"}},
|
|
||||||
{"hours", {"heure", "heures"}},
|
|
||||||
{"minutes", {"minute", "minutes"}},
|
|
||||||
{"seconds", {"seconde", "secondes"}},
|
|
||||||
{"", {"", ""}},
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
|
||||||
{
|
|
||||||
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // language
|
|
||||||
} // i18n
|
|
||||||
} // i2p
|
|
||||||
@@ -74,7 +74,6 @@ namespace i18n
|
|||||||
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace armenian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace french { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
|
||||||
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace german { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace russian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
@@ -89,7 +88,6 @@ namespace i18n
|
|||||||
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
|
{ "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} },
|
||||||
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
|
{ "armenian", {"հայերէն", "hy", i2p::i18n::armenian::GetLocale} },
|
||||||
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
|
{ "english", {"English", "en", i2p::i18n::english::GetLocale} },
|
||||||
{ "french", {"Français", "fr", i2p::i18n::french::GetLocale} },
|
|
||||||
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
|
{ "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} },
|
||||||
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
|
{ "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} },
|
||||||
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
|
{ "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} },
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ namespace data {
|
|||||||
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
||||||
*/
|
*/
|
||||||
size_t Base64EncodingBufferSize(const size_t input_size);
|
size_t Base64EncodingBufferSize(const size_t input_size);
|
||||||
|
|
||||||
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace data
|
|||||||
static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args)
|
static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args)
|
||||||
// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
|
// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
|
||||||
{
|
{
|
||||||
size_t publicKeyLength = 0;
|
size_t publicKeyLength = 0;
|
||||||
EC_GROUP * group = nullptr;
|
EC_GROUP * group = nullptr;
|
||||||
switch (sigType)
|
switch (sigType)
|
||||||
{
|
{
|
||||||
@@ -147,8 +147,8 @@ namespace data
|
|||||||
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
|
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
|
||||||
m_SigType = identity->GetSigningKeyType ();
|
m_SigType = identity->GetSigningKeyType ();
|
||||||
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||||
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
|
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
|
||||||
else
|
else
|
||||||
m_BlindedSigType = m_SigType;
|
m_BlindedSigType = m_SigType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ namespace data
|
|||||||
|
|
||||||
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
|
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
|
||||||
size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
|
size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
|
||||||
SigningKeyType GetSigType () const { return m_SigType; };
|
SigningKeyType GetSigType () const { return m_SigType; };
|
||||||
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
|
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
|
||||||
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
|
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
|
||||||
|
|
||||||
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ namespace config {
|
|||||||
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
||||||
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
||||||
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
||||||
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored")
|
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)")
|
||||||
("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
|
("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
|
||||||
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")
|
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpserver("HTTP Server options");
|
options_description httpserver("HTTP Server options");
|
||||||
@@ -230,7 +230,6 @@ namespace config {
|
|||||||
|
|
||||||
options_description addressbook("AddressBook options");
|
options_description addressbook("AddressBook options");
|
||||||
addressbook.add_options()
|
addressbook.add_options()
|
||||||
("addressbook.enabled", value<bool>()->default_value(true), "Enable address book lookups and subscritions (default: enabled)")
|
|
||||||
("addressbook.defaulturl", value<std::string>()->default_value(
|
("addressbook.defaulturl", value<std::string>()->default_value(
|
||||||
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
|
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
|
||||||
), "AddressBook subscription URL for initial setup")
|
), "AddressBook subscription URL for initial setup")
|
||||||
@@ -273,12 +272,12 @@ namespace config {
|
|||||||
;
|
;
|
||||||
|
|
||||||
options_description ssu2("SSU2 Options");
|
options_description ssu2("SSU2 Options");
|
||||||
ssu2.add_options()
|
ntcp2.add_options()
|
||||||
("ssu2.enabled", value<bool>()->default_value(false), "Enable SSU2 (default: disabled)")
|
("ssu2.enabled", value<bool>()->default_value(false), "Enable SSU2 (default: disabled)")
|
||||||
("ssu2.published", value<bool>()->default_value(false), "Publish SSU2 (default: disabled)")
|
("ssu2.published", value<bool>()->default_value(false), "Publish SSU2 (default: disabled)")
|
||||||
("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
|
("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description nettime("Time sync options");
|
options_description nettime("Time sync options");
|
||||||
nettime.add_options()
|
nettime.add_options()
|
||||||
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ namespace config {
|
|||||||
extern boost::program_options::variables_map m_Options;
|
extern boost::program_options::variables_map m_Options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize list of acceptable parameters
|
* @brief Initialize list of acceptable parameters
|
||||||
*
|
*
|
||||||
* Should be called before any Parse* functions.
|
* Should be called before any Parse* functions.
|
||||||
*/
|
*/
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parse cmdline parameters, and show help if requested
|
* @brief Parse cmdline parameters, and show help if requested
|
||||||
* @param argc Cmdline arguments count, should be passed from main().
|
* @param argc Cmdline arguments count, should be passed from main().
|
||||||
* @param argv Cmdline parameters array, should be passed from main()
|
* @param argv Cmdline parameters array, should be passed from main()
|
||||||
*
|
*
|
||||||
* If --help is given in parameters, shows its list with description
|
* If --help is given in parameters, shows its list with description
|
||||||
* and terminates the program with exitcode 0.
|
* and terminates the program with exitcode 0.
|
||||||
@@ -52,8 +52,8 @@ namespace config {
|
|||||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load and parse given config file
|
* @brief Load and parse given config file
|
||||||
* @param path Path to config file
|
* @param path Path to config file
|
||||||
*
|
*
|
||||||
* If error occurred when opening file path is points to,
|
* If error occurred when opening file path is points to,
|
||||||
* we show the error message and terminate program.
|
* we show the error message and terminate program.
|
||||||
@@ -67,14 +67,14 @@ namespace config {
|
|||||||
void ParseConfig(const std::string& path);
|
void ParseConfig(const std::string& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to combine options from cmdline, config and default values
|
* @brief Used to combine options from cmdline, config and default values
|
||||||
*/
|
*/
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accessor to parameters by name
|
* @brief Accessor to parameters by name
|
||||||
* @param name Name of the requested parameter
|
* @param name Name of the requested parameter
|
||||||
* @param value Variable where to store option
|
* @param value Variable where to store option
|
||||||
* @return this function returns false if parameter not found
|
* @return this function returns false if parameter not found
|
||||||
*
|
*
|
||||||
* Example: uint16_t port; GetOption("sam.port", port);
|
* Example: uint16_t port; GetOption("sam.port", port);
|
||||||
@@ -98,9 +98,9 @@ namespace config {
|
|||||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set value of given parameter
|
* @brief Set value of given parameter
|
||||||
* @param name Name of settable parameter
|
* @param name Name of settable parameter
|
||||||
* @param value New parameter value
|
* @param value New parameter value
|
||||||
* @return true if value set up successful, false otherwise
|
* @return true if value set up successful, false otherwise
|
||||||
*
|
*
|
||||||
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
||||||
@@ -116,8 +116,8 @@ namespace config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check is value explicitly given or default
|
* @brief Check is value explicitly given or default
|
||||||
* @param name Name of checked parameter
|
* @param name Name of checked parameter
|
||||||
* @return true if value set to default, false otherwise
|
* @return true if value set to default, false otherwise
|
||||||
*/
|
*/
|
||||||
bool IsDefault(const char *name);
|
bool IsDefault(const char *name);
|
||||||
|
|||||||
@@ -1313,8 +1313,8 @@ namespace crypto
|
|||||||
for (const auto& it: bufs)
|
for (const auto& it: bufs)
|
||||||
SHA256_Update (&ctx, it.first, it.second);
|
SHA256_Update (&ctx, it.first, it.second);
|
||||||
SHA256_Final (m_H, &ctx);
|
SHA256_Final (m_H, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
|
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
|
||||||
{
|
{
|
||||||
HKDF (m_CK, sharedSecret, 32, "", m_CK);
|
HKDF (m_CK, sharedSecret, 32, "", m_CK);
|
||||||
@@ -1330,7 +1330,7 @@ namespace crypto
|
|||||||
SHA256_Init (&ctx);
|
SHA256_Init (&ctx);
|
||||||
SHA256_Update (&ctx, hh, 32);
|
SHA256_Update (&ctx, hh, 32);
|
||||||
SHA256_Update (&ctx, pub, 32);
|
SHA256_Update (&ctx, pub, 32);
|
||||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
@@ -1368,12 +1368,12 @@ namespace crypto
|
|||||||
}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
|
}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
|
||||||
static const uint8_t hh[32] =
|
static const uint8_t hh[32] =
|
||||||
{
|
{
|
||||||
0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
|
0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
|
||||||
0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
|
0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
|
||||||
}; // SHA256 (protocolNameHash)
|
}; // SHA256 (protocolNameHash)
|
||||||
InitNoiseState (state, protocolNameHash, hh, pub);
|
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||||
{
|
{
|
||||||
static const uint8_t protocolNameHash[32] =
|
static const uint8_t protocolNameHash[32] =
|
||||||
|
|||||||
@@ -29,25 +29,23 @@
|
|||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
|
||||||
// recognize openssl version and features
|
// recognize openssl version and features
|
||||||
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050200fL)) // LibreSSL 3.5.2 and above
|
#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
||||||
# define LEGACY_OPENSSL 0
|
# define LEGACY_OPENSSL 1
|
||||||
#elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
# define X509_getm_notBefore X509_get_notBefore
|
||||||
# define LEGACY_OPENSSL 1
|
# define X509_getm_notAfter X509_get_notAfter
|
||||||
# define X509_getm_notBefore X509_get_notBefore
|
|
||||||
# define X509_getm_notAfter X509_get_notAfter
|
|
||||||
#else
|
#else
|
||||||
# define LEGACY_OPENSSL 0
|
# define LEGACY_OPENSSL 0
|
||||||
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
# define OPENSSL_HKDF 1
|
# define OPENSSL_HKDF 1
|
||||||
# define OPENSSL_EDDSA 1
|
# define OPENSSL_EDDSA 1
|
||||||
# define OPENSSL_X25519 1
|
# define OPENSSL_X25519 1
|
||||||
# if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash
|
# if (OPENSSL_VERSION_NUMBER < 0x030000000) // 3.0.0, regression in SipHash
|
||||||
# define OPENSSL_SIPHASH 1
|
# define OPENSSL_SIPHASH 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
||||||
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@@ -385,7 +383,7 @@ inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
|||||||
if (dh->p) BN_free (dh->p);
|
if (dh->p) BN_free (dh->p);
|
||||||
if (dh->q) BN_free (dh->q);
|
if (dh->q) BN_free (dh->q);
|
||||||
if (dh->g) BN_free (dh->g);
|
if (dh->g) BN_free (dh->g);
|
||||||
dh->p = p; dh->q = q; dh->g = g; return 1;
|
dh->p = p; dh->q = q; dh->g = g; return 1;
|
||||||
}
|
}
|
||||||
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ namespace datagram
|
|||||||
|
|
||||||
auto path = m_RoutingSession->GetSharedRoutingPath();
|
auto path = m_RoutingSession->GetSharedRoutingPath();
|
||||||
if (path && m_RoutingSession->IsRatchets () &&
|
if (path && m_RoutingSession->IsRatchets () &&
|
||||||
m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
|
m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
|
||||||
{
|
{
|
||||||
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
||||||
path = nullptr;
|
path = nullptr;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
@@ -35,7 +36,7 @@ namespace client
|
|||||||
int outLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
|
int outLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
|
||||||
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
||||||
int inVar = DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE;
|
int inVar = DEFAULT_INBOUND_TUNNELS_LENGTH_VARIANCE;
|
||||||
int outVar = DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE;
|
int outVar = DEFAULT_OUTBOUND_TUNNELS_LENGTH_VARIANCE;
|
||||||
int numTags = DEFAULT_TAGS_TO_SEND;
|
int numTags = DEFAULT_TAGS_TO_SEND;
|
||||||
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
|
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
|
||||||
try
|
try
|
||||||
@@ -93,7 +94,9 @@ namespace client
|
|||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
{
|
{
|
||||||
// oveeride isPublic
|
// oveeride isPublic
|
||||||
m_IsPublic = (it->second != "true");
|
bool dontpublish = false;
|
||||||
|
i2p::config::GetOption (it->second, dontpublish);
|
||||||
|
m_IsPublic = !dontpublish;
|
||||||
}
|
}
|
||||||
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
@@ -350,8 +353,8 @@ namespace client
|
|||||||
{
|
{
|
||||||
s->AddECIESx25519Key (data.k, data.t);
|
s->AddECIESx25519Key (data.k, data.t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
|
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
|
||||||
@@ -417,7 +420,7 @@ namespace client
|
|||||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||||
auto it = m_RemoteLeaseSets.find (key);
|
auto it = m_RemoteLeaseSets.find (key);
|
||||||
if (it != m_RemoteLeaseSets.end () &&
|
if (it != m_RemoteLeaseSets.end () &&
|
||||||
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
|
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
|
||||||
{
|
{
|
||||||
leaseSet = it->second;
|
leaseSet = it->second;
|
||||||
if (leaseSet->IsNewer (buf + offset, len - offset))
|
if (leaseSet->IsNewer (buf + offset, len - offset))
|
||||||
@@ -587,7 +590,7 @@ namespace client
|
|||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
||||||
m_ExcludedFloodfills.clear ();
|
m_ExcludedFloodfills.clear ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
||||||
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
if (!outbound || !inbound)
|
if (!outbound || !inbound)
|
||||||
@@ -599,22 +602,22 @@ namespace client
|
|||||||
{
|
{
|
||||||
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
|
||||||
if (outbound)
|
if (outbound)
|
||||||
{
|
{
|
||||||
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
|
||||||
if (!inbound)
|
if (!inbound)
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
||||||
if (!floodfill || !outbound || !inbound)
|
if (!floodfill || !outbound || !inbound)
|
||||||
{
|
{
|
||||||
m_ExcludedFloodfills.clear ();
|
m_ExcludedFloodfills.clear ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
||||||
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
||||||
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
|
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
|
||||||
@@ -951,7 +954,7 @@ namespace client
|
|||||||
for (auto& it: encryptionKeyTypes)
|
for (auto& it: encryptionKeyTypes)
|
||||||
{
|
{
|
||||||
auto encryptionKey = new EncryptionKey (it);
|
auto encryptionKey = new EncryptionKey (it);
|
||||||
if (IsPublic ())
|
if (isPublic)
|
||||||
PersistTemporaryKeys (encryptionKey, isSingleKey);
|
PersistTemporaryKeys (encryptionKey, isSingleKey);
|
||||||
else
|
else
|
||||||
encryptionKey->GenerateKeys ();
|
encryptionKey->GenerateKeys ();
|
||||||
@@ -966,7 +969,7 @@ namespace client
|
|||||||
m_StandardEncryptionKey.reset (encryptionKey);
|
m_StandardEncryptionKey.reset (encryptionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPublic ())
|
if (isPublic)
|
||||||
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -979,7 +982,7 @@ namespace client
|
|||||||
m_StreamingAckDelay = std::stoi(it->second);
|
m_StreamingAckDelay = std::stoi(it->second);
|
||||||
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
m_IsStreamingAnswerPings = (it->second == "true");
|
i2p::config::GetOption (it->second, m_IsStreamingAnswerPings);
|
||||||
|
|
||||||
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -319,5 +319,4 @@ namespace client
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ namespace garlic
|
|||||||
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
||||||
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
||||||
SessionState m_State = eSessionStateNew;
|
SessionState m_State = eSessionStateNew;
|
||||||
uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds)
|
uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds)
|
||||||
m_LastSentTimestamp = 0; // in milliseconds
|
m_LastSentTimestamp = 0; // in milliseconds
|
||||||
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
|
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
|
||||||
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
||||||
@@ -229,7 +229,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// single session for all incoming messages
|
// single session for all incoming messages
|
||||||
class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession
|
class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace crypto
|
|||||||
BN_add (l, l, tmp);
|
BN_add (l, l, tmp);
|
||||||
BN_sub_word (two_252_2, 2); // 2^252 - 2
|
BN_sub_word (two_252_2, 2); // 2^252 - 2
|
||||||
|
|
||||||
// -121665*inv(121666)
|
// -121665*inv(121666)
|
||||||
d = BN_new ();
|
d = BN_new ();
|
||||||
BN_set_word (tmp, 121666);
|
BN_set_word (tmp, 121666);
|
||||||
BN_mod_inverse (tmp, tmp, q, ctx);
|
BN_mod_inverse (tmp, tmp, q, ctx);
|
||||||
@@ -61,7 +61,7 @@ namespace crypto
|
|||||||
BN_mod (By, By, q, ctx); // % q
|
BN_mod (By, By, q, ctx); // % q
|
||||||
|
|
||||||
// precalculate Bi256 table
|
// precalculate Bi256 table
|
||||||
Bi256Carry = { Bx, By }; // B
|
Bi256Carry = { Bx, By }; // B
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
Bi256[i][0] = Bi256Carry; // first point
|
Bi256[i][0] = Bi256Carry; // first point
|
||||||
@@ -215,7 +215,7 @@ namespace crypto
|
|||||||
if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
|
if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
|
||||||
if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
|
if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
|
||||||
BN_mul (t3, t1, t2, ctx);
|
BN_mul (t3, t1, t2, ctx);
|
||||||
BN_mul (t3, t3, d, ctx); // C = d*t1*t2
|
BN_mul (t3, t3, d, ctx); // C = d*t1*t2
|
||||||
|
|
||||||
if (p1.z)
|
if (p1.z)
|
||||||
{
|
{
|
||||||
@@ -264,9 +264,9 @@ namespace crypto
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BN_mul (t2, p.x, p.y, ctx); // t = x*y
|
BN_mul (t2, p.x, p.y, ctx); // t = x*y
|
||||||
BN_sqr (t2, t2, ctx); // t2 = t^2
|
BN_sqr (t2, t2, ctx); // t2 = t^2
|
||||||
}
|
}
|
||||||
BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
|
BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
|
||||||
if (p.z)
|
if (p.z)
|
||||||
BN_sqr (z2, p.z, ctx); // z2 = D = z^2
|
BN_sqr (z2, p.z, ctx); // z2 = D = z^2
|
||||||
else
|
else
|
||||||
@@ -349,7 +349,7 @@ namespace crypto
|
|||||||
BN_mod_inverse (y, p.z, q, ctx);
|
BN_mod_inverse (y, p.z, q, ctx);
|
||||||
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
|
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
|
||||||
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
|
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
|
||||||
return EDDSAPoint{x, y};
|
return EDDSAPoint{x, y};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
|
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
|
||||||
@@ -506,13 +506,13 @@ namespace crypto
|
|||||||
std::swap (z2, z3);
|
std::swap (z2, z3);
|
||||||
}
|
}
|
||||||
BN_mod_inverse (z2, z2, q, ctx);
|
BN_mod_inverse (z2, z2, q, ctx);
|
||||||
BIGNUM * res = BN_new (); // not from ctx
|
BIGNUM * res = BN_new (); // not from ctx
|
||||||
BN_mod_mul(res, x2, z2, q, ctx);
|
BN_mod_mul(res, x2, z2, q, ctx);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
BIGNUM * p1 = DecodeBN<32> (p);
|
BIGNUM * p1 = DecodeBN<32> (p);
|
||||||
uint8_t k[32];
|
uint8_t k[32];
|
||||||
@@ -524,7 +524,7 @@ namespace crypto
|
|||||||
BN_free (p1); BN_free (n); BN_free (q1);
|
BN_free (p1); BN_free (n); BN_free (q1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
|
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
|
||||||
uint8_t k[32];
|
uint8_t k[32];
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ namespace crypto
|
|||||||
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
||||||
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
#if !OPENSSL_X25519
|
#if !OPENSSL_X25519
|
||||||
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
||||||
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
#endif
|
#endif
|
||||||
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ namespace crypto
|
|||||||
// assume a < p, so don't check for a % p = 0, but a = 0 only
|
// assume a < p, so don't check for a % p = 0, but a = 0 only
|
||||||
if (BN_is_zero(a)) return 0;
|
if (BN_is_zero(a)) return 0;
|
||||||
BIGNUM * r = BN_CTX_get (ctx);
|
BIGNUM * r = BN_CTX_get (ctx);
|
||||||
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
||||||
if (BN_is_word(r, 1))
|
if (BN_is_word(r, 1))
|
||||||
return 1;
|
return 1;
|
||||||
else if (BN_is_zero(r))
|
else if (BN_is_zero(r))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -60,38 +60,10 @@ namespace fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
||||||
// with 'datadir' option
|
|
||||||
if (cmdline_param != "") {
|
if (cmdline_param != "") {
|
||||||
dataDir = cmdline_param;
|
dataDir = cmdline_param;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MAC_OSX) && !defined(ANDROID)
|
|
||||||
// with 'service' option
|
|
||||||
if (isService) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
wchar_t commonAppData[MAX_PATH];
|
|
||||||
if(SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, commonAppData) != S_OK)
|
|
||||||
{
|
|
||||||
#ifdef WIN32_APP
|
|
||||||
MessageBox(NULL, TEXT("Unable to get common AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "Error: Unable to get common AppData path!");
|
|
||||||
#endif
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dataDir = boost::filesystem::wpath(commonAppData).string() + "\\" + appName;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
dataDir = "/var/lib/" + appName;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// detect directory as usual
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t localAppData[MAX_PATH];
|
wchar_t localAppData[MAX_PATH];
|
||||||
|
|
||||||
@@ -145,10 +117,12 @@ namespace fs {
|
|||||||
dataDir = std::string (ext) + "/" + appName;
|
dataDir = std::string (ext) + "/" + appName;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif // ANDROID
|
#endif
|
||||||
// use /home/user/.i2pd or /tmp/i2pd
|
// otherwise use /data/files
|
||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
if (home != NULL && strlen(home) > 0) {
|
if (isService) {
|
||||||
|
dataDir = "/var/lib/" + appName;
|
||||||
|
} else if (home != NULL && strlen(home) > 0) {
|
||||||
dataDir = std::string(home) + "/." + appName;
|
dataDir = std::string(home) + "/." + appName;
|
||||||
} else {
|
} else {
|
||||||
dataDir = "/tmp/" + appName;
|
dataDir = "/tmp/" + appName;
|
||||||
|
|||||||
12
libi2pd/FS.h
12
libi2pd/FS.h
@@ -83,8 +83,8 @@ namespace fs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set datadir either from cmdline option or using autodetection
|
* @brief Set datadir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||||
* @param isService Value of cmdline parameter --service
|
* @param isService Value of cmdline parameter --service
|
||||||
*
|
*
|
||||||
* Examples of autodetected paths:
|
* Examples of autodetected paths:
|
||||||
*
|
*
|
||||||
@@ -93,11 +93,11 @@ namespace fs {
|
|||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||||
*/
|
*/
|
||||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set certsdir either from cmdline option or using autodetection
|
* @brief Set certsdir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
|
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
|
||||||
*
|
*
|
||||||
* Examples of autodetected paths:
|
* Examples of autodetected paths:
|
||||||
*
|
*
|
||||||
@@ -106,7 +106,7 @@ namespace fs {
|
|||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
|
||||||
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
|
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
|
||||||
*/
|
*/
|
||||||
void SetCertsDir(const std::string & cmdline_certsdir);
|
void SetCertsDir(const std::string & cmdline_certsdir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create subdirectories inside datadir
|
* @brief Create subdirectories inside datadir
|
||||||
@@ -115,7 +115,7 @@ namespace fs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get list of files in directory
|
* @brief Get list of files in directory
|
||||||
* @param path Path to directory
|
* @param path Path to directory
|
||||||
* @param files Vector to store found files
|
* @param files Vector to store found files
|
||||||
* @return true on success and false if directory not exists
|
* @return true on success and false if directory not exists
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -148,8 +148,8 @@ namespace data
|
|||||||
if (it != m_SigningKeys.end ())
|
if (it != m_SigningKeys.end ())
|
||||||
return it->second.second;
|
return it->second.second;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
|
||||||
{
|
{
|
||||||
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
||||||
|
|||||||
@@ -293,14 +293,14 @@ namespace garlic
|
|||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (isDestination)
|
if (isDestination)
|
||||||
{
|
{
|
||||||
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
|
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
|
||||||
size++;
|
size++;
|
||||||
memcpy (buf + size, m_Destination->GetIdentHash (), 32);
|
memcpy (buf + size, m_Destination->GetIdentHash (), 32);
|
||||||
size += 32;
|
size += 32;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf[size] = 0;// delivery instructions flag local
|
buf[size] = 0;// delivery instructions flag local
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,8 +487,8 @@ namespace garlic
|
|||||||
void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
|
void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
|
||||||
{
|
{
|
||||||
AddECIESx25519Key (key, tag);
|
AddECIESx25519Key (key, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
@@ -744,7 +744,7 @@ namespace garlic
|
|||||||
LogPrint (eLogError, "Garlic: Message is too short");
|
LogPrint (eLogError, "Garlic: Message is too short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf += GetI2NPMessageLength (buf, len - offset); // I2NP
|
buf += GetI2NPMessageLength (buf, len - offset); // I2NP
|
||||||
buf += 4; // CloveID
|
buf += 4; // CloveID
|
||||||
buf += 8; // Date
|
buf += 8; // Date
|
||||||
buf += 3; // Certificate
|
buf += 3; // Certificate
|
||||||
@@ -1024,7 +1024,7 @@ namespace garlic
|
|||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto it: files)
|
for (auto it: files)
|
||||||
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
i2p::fs::Remove (it);
|
i2p::fs::Remove (it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace crypto
|
|||||||
EC_POINT * C = EC_POINT_new (m_Group);
|
EC_POINT * C = EC_POINT_new (m_Group);
|
||||||
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
|
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
|
||||||
BIGNUM * x = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx);
|
||||||
GetXY (C, x, nullptr); // Cx
|
GetXY (C, x, nullptr); // Cx
|
||||||
BN_mod (x, x, q, ctx); // Cx % q
|
BN_mod (x, x, q, ctx); // Cx % q
|
||||||
bool ret = !BN_cmp (x, r); // Cx = r ?
|
bool ret = !BN_cmp (x, r); // Cx = r ?
|
||||||
EC_POINT_free (C);
|
EC_POINT_free (C);
|
||||||
@@ -111,8 +111,8 @@ namespace crypto
|
|||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
|
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
|
||||||
EC_POINT * Q = nullptr;
|
EC_POINT * Q = nullptr;
|
||||||
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
|
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
|
||||||
{
|
{
|
||||||
EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
|
EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
|
||||||
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
|
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ namespace http
|
|||||||
method = tokens[0];
|
method = tokens[0];
|
||||||
uri = tokens[1];
|
uri = tokens[1];
|
||||||
version = tokens[2];
|
version = tokens[2];
|
||||||
expect = HEADER_LINE;
|
expect = HEADER_LINE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -363,7 +363,7 @@ namespace http
|
|||||||
return false; /* no header */
|
return false; /* no header */
|
||||||
if (it->second.find("gzip") != std::string::npos)
|
if (it->second.find("gzip") != std::string::npos)
|
||||||
return true; /* gotcha! */
|
return true; /* gotcha! */
|
||||||
if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos)
|
if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -409,7 +409,7 @@ namespace http
|
|||||||
/* all ok */
|
/* all ok */
|
||||||
version = tokens[0];
|
version = tokens[0];
|
||||||
status = tokens[2];
|
status = tokens[2];
|
||||||
expect = HEADER_LINE;
|
expect = HEADER_LINE;
|
||||||
} else {
|
} else {
|
||||||
std::string line = str.substr(pos, eol - pos);
|
std::string line = str.substr(pos, eol - pos);
|
||||||
auto p = parse_header_line(line);
|
auto p = parse_header_line(line);
|
||||||
@@ -460,7 +460,7 @@ namespace http
|
|||||||
case 304: ptr = "Not Modified"; break;
|
case 304: ptr = "Not Modified"; break;
|
||||||
case 307: ptr = "Temporary Redirect"; break;
|
case 307: ptr = "Temporary Redirect"; break;
|
||||||
/* client error */
|
/* client error */
|
||||||
case 400: ptr = "Bad Request"; break;
|
case 400: ptr = "Bad Request"; break;
|
||||||
case 401: ptr = "Unauthorized"; break;
|
case 401: ptr = "Unauthorized"; break;
|
||||||
case 403: ptr = "Forbidden"; break;
|
case 403: ptr = "Forbidden"; break;
|
||||||
case 404: ptr = "Not Found"; break;
|
case 404: ptr = "Not Found"; break;
|
||||||
@@ -471,7 +471,7 @@ namespace http
|
|||||||
case 502: ptr = "Bad Gateway"; break;
|
case 502: ptr = "Bad Gateway"; break;
|
||||||
case 503: ptr = "Not Implemented"; break;
|
case 503: ptr = "Not Implemented"; break;
|
||||||
case 504: ptr = "Gateway Timeout"; break;
|
case 504: ptr = "Gateway Timeout"; break;
|
||||||
default: ptr = "Unknown Status"; break;
|
default: ptr = "Unknown Status"; break;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace http
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Merge HTTP response content with Transfer-Encoding: chunked
|
* @brief Merge HTTP response content with Transfer-Encoding: chunked
|
||||||
* @param in Input stream
|
* @param in Input stream
|
||||||
* @param out Output stream
|
* @param out Output stream
|
||||||
* @return true on success, false otherwise
|
* @return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2021, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -171,7 +171,7 @@ namespace i2p
|
|||||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
||||||
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
||||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
||||||
const uint8_t * replyTag, bool replyECIES)
|
const uint8_t * replyTag, bool replyECIES)
|
||||||
{
|
{
|
||||||
int cnt = excludedFloodfills.size ();
|
int cnt = excludedFloodfills.size ();
|
||||||
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
|
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
|
||||||
@@ -244,7 +244,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
||||||
{
|
{
|
||||||
if (!router) // we send own RouterInfo
|
if (!router) // we send own RouterInfo
|
||||||
router = context.GetSharedRouterInfo ();
|
router = context.GetSharedRouterInfo ();
|
||||||
@@ -629,7 +629,7 @@ namespace i2p
|
|||||||
// we send it to reply tunnel
|
// we send it to reply tunnel
|
||||||
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
|
i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -802,8 +802,13 @@ namespace i2p
|
|||||||
break;
|
break;
|
||||||
case eI2NPGarlic:
|
case eI2NPGarlic:
|
||||||
{
|
{
|
||||||
if (msg->from && msg->from->GetTunnelPool ())
|
if (msg->from)
|
||||||
msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
|
{
|
||||||
|
if (msg->from->GetTunnelPool ())
|
||||||
|
msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
|
||||||
|
else
|
||||||
|
LogPrint (eLogInfo, "I2NP: Local destination for garlic doesn't exist anymore");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
i2p::context.ProcessGarlicMessage (msg);
|
i2p::context.ProcessGarlicMessage (msg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace tunnel
|
|||||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from;
|
std::shared_ptr<i2p::tunnel::InboundTunnel> from;
|
||||||
|
|
||||||
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
|
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
|
||||||
offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header
|
offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header
|
||||||
|
|
||||||
// header accessors
|
// header accessors
|
||||||
uint8_t * GetHeader () { return GetBuffer (); };
|
uint8_t * GetHeader () { return GetBuffer (); };
|
||||||
@@ -274,8 +274,8 @@ namespace tunnel
|
|||||||
uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
|
uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
|
||||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
||||||
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
||||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
|
||||||
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
|
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
|
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||||
{
|
{
|
||||||
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
|
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
|
||||||
RAND_bytes (m_StandardIdentity.signingKey, padding);
|
RAND_bytes (m_StandardIdentity.signingKey, padding);
|
||||||
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
|
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
|
||||||
break;
|
break;
|
||||||
@@ -788,7 +788,7 @@ namespace data
|
|||||||
keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
|
keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
|
||||||
htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
|
htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
|
||||||
htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type
|
htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type
|
||||||
GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key
|
GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key
|
||||||
Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
|
Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
|
||||||
// recreate signer
|
// recreate signer
|
||||||
keys.m_Signer = nullptr;
|
keys.m_Signer = nullptr;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ namespace data
|
|||||||
CryptoKeyType GetCryptoKeyType () const;
|
CryptoKeyType GetCryptoKeyType () const;
|
||||||
void DropVerifier () const; // to save memory
|
void DropVerifier () const; // to save memory
|
||||||
|
|
||||||
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
||||||
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
||||||
|
|
||||||
static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
|
static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
|
||||||
@@ -222,7 +222,7 @@ namespace data
|
|||||||
RoutingDestination () {};
|
RoutingDestination () {};
|
||||||
virtual ~RoutingDestination () {};
|
virtual ~RoutingDestination () {};
|
||||||
|
|
||||||
virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0;
|
virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0;
|
||||||
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
|
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
|
||||||
virtual bool IsDestination () const = 0; // for garlic
|
virtual bool IsDestination () const = 0; // for garlic
|
||||||
|
|
||||||
|
|||||||
@@ -582,7 +582,7 @@ namespace data
|
|||||||
// helper for ExtractClientAuthData
|
// helper for ExtractClientAuthData
|
||||||
static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie)
|
static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie)
|
||||||
{
|
{
|
||||||
// try to find clientCookie_i for clientID_i = okm[44:51]
|
// try to find clientCookie_i for clientID_i = okm[44:51]
|
||||||
for (int i = 0; i < numClients; i++)
|
for (int i = 0; i < numClients; i++)
|
||||||
{
|
{
|
||||||
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
|
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
|
||||||
@@ -606,7 +606,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
|
const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
|
||||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||||
if (offset > len)
|
if (offset > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data");
|
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data");
|
||||||
@@ -632,7 +632,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
|
const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
|
||||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||||
if (offset > len)
|
if (offset > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
|
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
|
||||||
@@ -737,7 +737,7 @@ namespace data
|
|||||||
htobe64buf (m_Buffer + offset, ts);
|
htobe64buf (m_Buffer + offset, ts);
|
||||||
offset += 8; // end date
|
offset += 8; // end date
|
||||||
}
|
}
|
||||||
// we don't sign it yet. must be signed later on
|
// we don't sign it yet. must be signed later on
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len):
|
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len):
|
||||||
@@ -995,7 +995,7 @@ namespace data
|
|||||||
ek.GenerateKeys (); // esk and epk
|
ek.GenerateKeys (); // esk and epk
|
||||||
memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
|
memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
|
||||||
htobe16buf (authData, authKeys->size ()); authData += 2; // num clients
|
htobe16buf (authData, authKeys->size ()); authData += 2; // num clients
|
||||||
uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp
|
uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp
|
||||||
memcpy (authInput + 64, subcredential, 36);
|
memcpy (authInput + 64, subcredential, 36);
|
||||||
for (auto& it: *authKeys)
|
for (auto& it: *authKeys)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ namespace data
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* validate lease set buffer signature and extract expiration timestamp
|
validate lease set buffer signature and extract expiration timestamp
|
||||||
* @returns true if the leaseset is well formed and signature is valid
|
@returns true if the leaseset is well formed and signature is valid
|
||||||
*/
|
*/
|
||||||
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
|
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace log {
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/**
|
/**
|
||||||
* @brief Maps our log levels to syslog one
|
* @brief Maps our log levels to syslog one
|
||||||
* @return syslog priority LOG_*, as defined in syslog.h
|
* @return syslog priority LOG_*, as defined in syslog.h
|
||||||
*/
|
*/
|
||||||
static inline int GetSyslogPrio (enum LogLevel l) {
|
static inline int GetSyslogPrio (enum LogLevel l) {
|
||||||
@@ -113,11 +113,11 @@ namespace log {
|
|||||||
|
|
||||||
std::string str_tolower(std::string s) {
|
std::string str_tolower(std::string s) {
|
||||||
std::transform(s.begin(), s.end(), s.begin(),
|
std::transform(s.begin(), s.end(), s.begin(),
|
||||||
// static_cast<int(*)(int)>(std::tolower) // wrong
|
// static_cast<int(*)(int)>(std::tolower) // wrong
|
||||||
// [](int c){ return std::tolower(c); } // wrong
|
// [](int c){ return std::tolower(c); } // wrong
|
||||||
// [](char c){ return std::tolower(c); } // wrong
|
// [](char c){ return std::tolower(c); } // wrong
|
||||||
[](unsigned char c){ return std::tolower(c); } // correct
|
[](unsigned char c){ return std::tolower(c); } // correct
|
||||||
);
|
);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ namespace log {
|
|||||||
break;
|
break;
|
||||||
case eLogStdout:
|
case eLogStdout:
|
||||||
default:
|
default:
|
||||||
std::cout << TimeAsString(msg->timestamp)
|
std::cout << TimeAsString(msg->timestamp)
|
||||||
<< "@" << short_tid
|
<< "@" << short_tid
|
||||||
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
|
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
|
||||||
<< " - " << msg->text << std::endl;
|
<< " - " << msg->text << std::endl;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace log {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum LogType m_Destination;
|
enum LogType m_Destination;
|
||||||
enum LogLevel m_MinLevel;
|
enum LogLevel m_MinLevel;
|
||||||
std::shared_ptr<std::ostream> m_LogStream;
|
std::shared_ptr<std::ostream> m_LogStream;
|
||||||
std::string m_Logfile;
|
std::string m_Logfile;
|
||||||
@@ -75,7 +75,7 @@ namespace log {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Makes formatted string from unix timestamp
|
* @brief Makes formatted string from unix timestamp
|
||||||
* @param ts Second since epoch
|
* @param ts Second since epoch
|
||||||
*
|
*
|
||||||
* This function internally caches the result for last provided value
|
* This function internally caches the result for last provided value
|
||||||
*/
|
*/
|
||||||
@@ -86,52 +86,52 @@ namespace log {
|
|||||||
Log ();
|
Log ();
|
||||||
~Log ();
|
~Log ();
|
||||||
|
|
||||||
LogType GetLogType () { return m_Destination; };
|
LogType GetLogType () { return m_Destination; };
|
||||||
LogLevel GetLogLevel () { return m_MinLevel; };
|
LogLevel GetLogLevel () { return m_MinLevel; };
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets minimal allowed level for log messages
|
* @brief Sets minimal allowed level for log messages
|
||||||
* @param level String with wanted minimal msg level
|
* @param level String with wanted minimal msg level
|
||||||
*/
|
*/
|
||||||
void SetLogLevel (const std::string& level);
|
void SetLogLevel (const std::string& level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to logfile
|
* @brief Sets log destination to logfile
|
||||||
* @param path Path to logfile
|
* @param path Path to logfile
|
||||||
*/
|
*/
|
||||||
void SendTo (const std::string &path);
|
void SendTo (const std::string &path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to given output stream
|
* @brief Sets log destination to given output stream
|
||||||
* @param os Output stream
|
* @param os Output stream
|
||||||
*/
|
*/
|
||||||
void SendTo (std::shared_ptr<std::ostream> os);
|
void SendTo (std::shared_ptr<std::ostream> os);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets format for timestamps in log
|
* @brief Sets format for timestamps in log
|
||||||
* @param format String with timestamp format
|
* @param format String with timestamp format
|
||||||
*/
|
*/
|
||||||
void SetTimeFormat (std::string format) { m_TimeFormat = format; };
|
void SetTimeFormat (std::string format) { m_TimeFormat = format; };
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/**
|
/**
|
||||||
* @brief Sets log destination to syslog
|
* @brief Sets log destination to syslog
|
||||||
* @param name Wanted program name
|
* @param name Wanted program name
|
||||||
* @param facility Wanted log category
|
* @param facility Wanted log category
|
||||||
*/
|
*/
|
||||||
void SendTo (const char *name, int facility);
|
void SendTo (const char *name, int facility);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Format log message and write to output stream/syslog
|
* @brief Format log message and write to output stream/syslog
|
||||||
* @param msg Pointer to processed message
|
* @param msg Pointer to processed message
|
||||||
*/
|
*/
|
||||||
void Append(std::shared_ptr<i2p::log::LogMsg> &);
|
void Append(std::shared_ptr<i2p::log::LogMsg> &);
|
||||||
|
|
||||||
/** @brief Reopen log file */
|
/** @brief Reopen log file */
|
||||||
void Reopen();
|
void Reopen();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,8 +144,8 @@ namespace log {
|
|||||||
*/
|
*/
|
||||||
struct LogMsg {
|
struct LogMsg {
|
||||||
std::time_t timestamp;
|
std::time_t timestamp;
|
||||||
std::string text; /**< message text as single string */
|
std::string text; /**< message text as single string */
|
||||||
LogLevel level; /**< message level */
|
LogLevel level; /**< message level */
|
||||||
std::thread::id tid; /**< id of thread that generated message */
|
std::thread::id tid; /**< id of thread that generated message */
|
||||||
|
|
||||||
LogMsg (LogLevel lvl, std::time_t ts, std::string&& txt): timestamp(ts), text(std::move(txt)), level(lvl) {}
|
LogMsg (LogLevel lvl, std::time_t ts, std::string&& txt): timestamp(ts), text(std::move(txt)), level(lvl) {}
|
||||||
@@ -153,7 +153,7 @@ namespace log {
|
|||||||
|
|
||||||
Log & Logger();
|
Log & Logger();
|
||||||
|
|
||||||
typedef std::function<void (const std::string&)> ThrowFunction;
|
typedef std::function<void (const std::string&)> ThrowFunction;
|
||||||
ThrowFunction GetThrowFunction ();
|
ThrowFunction GetThrowFunction ();
|
||||||
void SetThrowFunction (ThrowFunction f);
|
void SetThrowFunction (ThrowFunction f);
|
||||||
} // log
|
} // log
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
MixHash (sessionRequest + 32, 32); // encrypted payload
|
MixHash (sessionRequest + 32, 32); // encrypted payload
|
||||||
|
|
||||||
int paddingLength = sessionRequestLen - 64;
|
int paddingLength = sessionRequestLen - 64;
|
||||||
if (paddingLength > 0)
|
if (paddingLength > 0)
|
||||||
MixHash (sessionRequest + 64, paddingLength);
|
MixHash (sessionRequest + 64, paddingLength);
|
||||||
MixHash (epub, 32);
|
MixHash (epub, 32);
|
||||||
@@ -130,7 +130,7 @@ namespace transport
|
|||||||
// m3p2Len
|
// m3p2Len
|
||||||
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
|
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
|
||||||
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
|
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
|
||||||
htobe16buf (options + 4, m3p2Len);
|
htobe16buf (options + 4, m3p2Len);
|
||||||
// fill m3p2 payload (RouterInfo block)
|
// fill m3p2 payload (RouterInfo block)
|
||||||
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
|
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
|
||||||
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
||||||
@@ -231,11 +231,11 @@ namespace transport
|
|||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
uint32_t tsA = bufbe32toh (options + 8);
|
uint32_t tsA = bufbe32toh (options + 8);
|
||||||
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
|
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
|
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
|
||||||
clockSkew = true;
|
clockSkew = true;
|
||||||
// we send SessionCreate to let Alice know our time and then close session
|
// we send SessionCreate to let Alice know our time and then close session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -320,7 +320,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
|
|
||||||
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
|
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
|
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
|
||||||
TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
|
TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
|
||||||
m_Server (server), m_Socket (m_Server.GetService ()),
|
m_Server (server), m_Socket (m_Server.GetService ()),
|
||||||
m_IsEstablished (false), m_IsTerminated (false),
|
m_IsEstablished (false), m_IsTerminated (false),
|
||||||
@@ -418,7 +418,7 @@ namespace transport
|
|||||||
void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
|
void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
|
||||||
{
|
{
|
||||||
if (m_NextReceivedBuffer && !m_IsReceiving &&
|
if (m_NextReceivedBuffer && !m_IsReceiving &&
|
||||||
ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
|
ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
|
||||||
{
|
{
|
||||||
delete[] m_NextReceivedBuffer;
|
delete[] m_NextReceivedBuffer;
|
||||||
m_NextReceivedBuffer = nullptr;
|
m_NextReceivedBuffer = nullptr;
|
||||||
@@ -484,9 +484,9 @@ namespace transport
|
|||||||
if (clockSkew)
|
if (clockSkew)
|
||||||
{
|
{
|
||||||
// we don't care about padding, send SessionCreated and close session
|
// we don't care about padding, send SessionCreated and close session
|
||||||
SendSessionCreated ();
|
SendSessionCreated ();
|
||||||
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
||||||
}
|
}
|
||||||
else if (paddingLen > 0)
|
else if (paddingLen > 0)
|
||||||
{
|
{
|
||||||
if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
|
if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
|
||||||
@@ -496,7 +496,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
|
LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,7 +549,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
|
LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,11 +1126,11 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (!m_SendKey ||
|
if (!m_SendKey ||
|
||||||
#if OPENSSL_SIPHASH
|
#if OPENSSL_SIPHASH
|
||||||
!m_SendMDCtx
|
!m_SendMDCtx
|
||||||
#else
|
#else
|
||||||
!m_SendSipKey
|
!m_SendSipKey
|
||||||
#endif
|
#endif
|
||||||
) return;
|
) return;
|
||||||
m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
|
m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
|
||||||
// termination block
|
// termination block
|
||||||
m_NextSendBuffer[2] = eNTCP2BlkTermination;
|
m_NextSendBuffer[2] = eNTCP2BlkTermination;
|
||||||
@@ -1164,7 +1164,7 @@ namespace transport
|
|||||||
else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
|
else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
|
LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
|
||||||
GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
|
GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1177,7 +1177,7 @@ namespace transport
|
|||||||
|
|
||||||
NTCP2Server::NTCP2Server ():
|
NTCP2Server::NTCP2Server ():
|
||||||
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
|
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
|
||||||
m_ProxyType(eNoProxy), m_Resolver(GetService ())
|
m_ProxyType(eNoProxy), m_Resolver(GetService ())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,10 +107,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
i2p::util::SetThreadName("NetDB");
|
i2p::util::SetThreadName("NetDB");
|
||||||
|
|
||||||
uint64_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
||||||
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
|
|
||||||
int16_t profilesCleanupVariance = 0;
|
|
||||||
|
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -158,7 +155,6 @@ namespace data
|
|||||||
m_Requests.ManageRequests ();
|
m_Requests.ManageRequests ();
|
||||||
lastManageRequest = ts;
|
lastManageRequest = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
|
if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
|
||||||
{
|
{
|
||||||
if (lastSave)
|
if (lastSave)
|
||||||
@@ -168,20 +164,12 @@ namespace data
|
|||||||
}
|
}
|
||||||
lastSave = ts;
|
lastSave = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
i2p::context.CleanupDestination ();
|
i2p::context.CleanupDestination ();
|
||||||
lastDestinationCleanup = ts;
|
lastDestinationCleanup = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance))
|
|
||||||
{
|
|
||||||
DeleteObsoleteProfiles ();
|
|
||||||
lastProfilesCleanup = ts;
|
|
||||||
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// publish
|
// publish
|
||||||
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
||||||
{
|
{
|
||||||
@@ -207,7 +195,6 @@ namespace data
|
|||||||
lastPublish = ts;
|
lastPublish = ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts - lastExploratory >= 30) // exploratory every 30 seconds
|
if (ts - lastExploratory >= 30) // exploratory every 30 seconds
|
||||||
{
|
{
|
||||||
auto numRouters = m_RouterInfos.size ();
|
auto numRouters = m_RouterInfos.size ();
|
||||||
@@ -489,7 +476,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
auto r = std::make_shared<RouterInfo>(path);
|
auto r = std::make_shared<RouterInfo>(path);
|
||||||
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses () &&
|
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses () &&
|
||||||
ts < r->GetTimestamp () + 24*60*60*NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT*1000LL)
|
ts < r->GetTimestamp () + 24*60*60*NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT*1000LL)
|
||||||
{
|
{
|
||||||
r->DeleteBuffer ();
|
r->DeleteBuffer ();
|
||||||
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
||||||
@@ -620,7 +607,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
// make router reachable back if too few routers or floodfills
|
// make router reachable back if too few routers or floodfills
|
||||||
if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS ||
|
if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS ||
|
||||||
(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
|
(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
|
||||||
it.second->SetUnreachable (false);
|
it.second->SetUnreachable (false);
|
||||||
// find & mark expired routers
|
// find & mark expired routers
|
||||||
if (!it.second->IsReachable () && it.second->IsSSU (false))
|
if (!it.second->IsReachable () && it.second->IsSSU (false))
|
||||||
@@ -643,7 +630,7 @@ namespace data
|
|||||||
} // m_RouterInfos iteration
|
} // m_RouterInfos iteration
|
||||||
|
|
||||||
m_RouterInfoBuffersPool.CleanUpMt ();
|
m_RouterInfoBuffersPool.CleanUpMt ();
|
||||||
|
|
||||||
if (updatedCount > 0)
|
if (updatedCount > 0)
|
||||||
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
||||||
if (deletedCount > 0)
|
if (deletedCount > 0)
|
||||||
@@ -672,7 +659,7 @@ namespace data
|
|||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct)
|
void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct)
|
||||||
@@ -688,7 +675,7 @@ namespace data
|
|||||||
if (floodfill)
|
if (floodfill)
|
||||||
{
|
{
|
||||||
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
|
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
|
||||||
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
||||||
direct = false; // floodfill can't be reached directly
|
direct = false; // floodfill can't be reached directly
|
||||||
if (direct)
|
if (direct)
|
||||||
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
|
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
|
||||||
@@ -971,7 +958,7 @@ namespace data
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
||||||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
||||||
{
|
{
|
||||||
auto router = FindRouter (ident);
|
auto router = FindRouter (ident);
|
||||||
if (router)
|
if (router)
|
||||||
@@ -1136,7 +1123,7 @@ namespace data
|
|||||||
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
||||||
m_PublishReplyToken = replyToken;
|
m_PublishReplyToken = replyToken;
|
||||||
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
||||||
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
||||||
// send directly
|
// send directly
|
||||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
||||||
else
|
else
|
||||||
@@ -1203,16 +1190,6 @@ namespace data
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const
|
|
||||||
{
|
|
||||||
return GetRandomRouter (
|
|
||||||
[v4, &excluded](std::shared_ptr<const RouterInfo> router)->bool
|
|
||||||
{
|
|
||||||
return !router->IsHidden () && router->IsECIES () &&
|
|
||||||
router->IsSSU2PeerTesting (v4) && !excluded.count (router->GetIdentHash ());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSUV6Router () const
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSUV6Router () const
|
||||||
{
|
{
|
||||||
return GetRandomRouter (
|
return GetRandomRouter (
|
||||||
@@ -1387,7 +1364,7 @@ namespace data
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const
|
||||||
{
|
{
|
||||||
return GetRandomRouter(
|
return GetRandomRouter(
|
||||||
[fam](std::shared_ptr<const RouterInfo> router)->bool
|
[fam](std::shared_ptr<const RouterInfo> router)->bool
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ namespace data
|
|||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||||
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
|
||||||
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
|
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
|
||||||
std::shared_ptr<const RouterInfo> GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||||
@@ -124,7 +123,7 @@ namespace data
|
|||||||
|
|
||||||
void ClearRouterInfos () { m_RouterInfos.clear (); };
|
void ClearRouterInfos () { m_RouterInfos.clear (); };
|
||||||
std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
|
std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
|
||||||
|
|
||||||
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace data
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
|
void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
|
||||||
std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
|
std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
|
||||||
void ManageRequests ();
|
void ManageRequests ();
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
/**
|
|
||||||
* This code is licensed under the MCGSI Public License
|
|
||||||
* Copyright 2018 Jeff Becker
|
|
||||||
*
|
|
||||||
*Kovri go write your own code
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Poly1305.h"
|
#include "Poly1305.h"
|
||||||
|
/**
|
||||||
|
This code is licensed under the MCGSI Public License
|
||||||
|
Copyright 2018 Jeff Becker
|
||||||
|
|
||||||
|
Kovri go write your own code
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
namespace i2p
|
namespace i2p
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
* Kovri go write your own code
|
* Kovri go write your own code
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBI2PD_POLY1305_H
|
#ifndef LIBI2PD_POLY1305_H
|
||||||
#define LIBI2PD_POLY1305_H
|
#define LIBI2PD_POLY1305_H
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -29,8 +29,6 @@ namespace data
|
|||||||
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
||||||
|
|
||||||
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
|
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
|
||||||
const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day)
|
|
||||||
const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours)
|
|
||||||
|
|
||||||
class RouterProfile
|
class RouterProfile
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace util
|
|||||||
|
|
||||||
void Put (Element e)
|
void Put (Element e)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
m_Queue.push (std::move(e));
|
m_Queue.push (std::move(e));
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
if (!vec.empty ())
|
if (!vec.empty ())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
for (const auto& it: vec)
|
for (const auto& it: vec)
|
||||||
m_Queue.push (std::move(it));
|
m_Queue.push (std::move(it));
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
|
|||||||
@@ -187,31 +187,31 @@ namespace data
|
|||||||
}
|
}
|
||||||
s.seekg (1, std::ios::cur); // su3 file format version
|
s.seekg (1, std::ios::cur); // su3 file format version
|
||||||
SigningKeyType signatureType;
|
SigningKeyType signatureType;
|
||||||
s.read ((char *)&signatureType, 2); // signature type
|
s.read ((char *)&signatureType, 2); // signature type
|
||||||
signatureType = be16toh (signatureType);
|
signatureType = be16toh (signatureType);
|
||||||
uint16_t signatureLength;
|
uint16_t signatureLength;
|
||||||
s.read ((char *)&signatureLength, 2); // signature length
|
s.read ((char *)&signatureLength, 2); // signature length
|
||||||
signatureLength = be16toh (signatureLength);
|
signatureLength = be16toh (signatureLength);
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t versionLength;
|
uint8_t versionLength;
|
||||||
s.read ((char *)&versionLength, 1); // version length
|
s.read ((char *)&versionLength, 1); // version length
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t signerIDLength;
|
uint8_t signerIDLength;
|
||||||
s.read ((char *)&signerIDLength, 1); // signer ID length
|
s.read ((char *)&signerIDLength, 1); // signer ID length
|
||||||
uint64_t contentLength;
|
uint64_t contentLength;
|
||||||
s.read ((char *)&contentLength, 8); // content length
|
s.read ((char *)&contentLength, 8); // content length
|
||||||
contentLength = be64toh (contentLength);
|
contentLength = be64toh (contentLength);
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t fileType;
|
uint8_t fileType;
|
||||||
s.read ((char *)&fileType, 1); // file type
|
s.read ((char *)&fileType, 1); // file type
|
||||||
if (fileType != 0x00) // zip file
|
if (fileType != 0x00) // zip file
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
|
LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s.seekg (1, std::ios::cur); // unused
|
s.seekg (1, std::ios::cur); // unused
|
||||||
uint8_t contentType;
|
uint8_t contentType;
|
||||||
s.read ((char *)&contentType, 1); // content type
|
s.read ((char *)&contentType, 1); // content type
|
||||||
if (contentType != 0x03) // reseed data
|
if (contentType != 0x03) // reseed data
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
|
LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
|
||||||
@@ -688,7 +688,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
boost::asio::ip::tcp::endpoint ep = *it;
|
boost::asio::ip::tcp::endpoint ep = *it;
|
||||||
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
||||||
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
||||||
{
|
{
|
||||||
s.lowest_layer().connect (ep, ecode);
|
s.lowest_layer().connect (ep, ecode);
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ namespace i2p
|
|||||||
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
||||||
if (port == 9150) port = 9151; // Tor browser
|
if (port == 9150) port = 9151; // Tor browser
|
||||||
}
|
}
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
||||||
bool nat; i2p::config::GetOption("nat", nat);
|
bool nat; i2p::config::GetOption("nat", nat);
|
||||||
|
|
||||||
if ((ntcp2 || ygg) && !m_NTCP2Keys)
|
if ((ntcp2 || ygg) && !m_NTCP2Keys)
|
||||||
NewNTCP2Keys ();
|
NewNTCP2Keys ();
|
||||||
@@ -123,11 +123,11 @@ namespace i2p
|
|||||||
if (ssu2Published)
|
if (ssu2Published)
|
||||||
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
|
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
|
||||||
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ipv6)
|
if (ipv6)
|
||||||
{
|
{
|
||||||
@@ -168,12 +168,12 @@ namespace i2p
|
|||||||
if (ssu2Published)
|
if (ssu2Published)
|
||||||
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port);
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ipv4) // no other ssu2 addresses yet
|
if (!ipv4) // no other ssu2 addresses yet
|
||||||
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
|
||||||
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
|
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ygg)
|
if (ygg)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ namespace i2p
|
|||||||
std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
|
std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
|
||||||
fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
|
fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::SetStatus (RouterStatus status)
|
void RouterContext::SetStatus (RouterStatus status)
|
||||||
{
|
{
|
||||||
if (status != m_Status)
|
if (status != m_Status)
|
||||||
@@ -313,7 +313,7 @@ namespace i2p
|
|||||||
if (updated)
|
if (updated)
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::UpdateNTCP2Address (bool enable)
|
void RouterContext::UpdateNTCP2Address (bool enable)
|
||||||
{
|
{
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
@@ -360,8 +360,8 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
if (updated)
|
if (updated)
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::UpdateSSU2Address (bool enable)
|
void RouterContext::UpdateSSU2Address (bool enable)
|
||||||
{
|
{
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
@@ -392,14 +392,14 @@ namespace i2p
|
|||||||
if (updated)
|
if (updated)
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (auto& address : m_RouterInfo.GetAddresses ())
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
{
|
{
|
||||||
if (address->host != host && address->IsCompatible (host) &&
|
if (address->host != host && address->IsCompatible (host) &&
|
||||||
!i2p::util::net::IsYggdrasilAddress (address->host))
|
!i2p::util::net::IsYggdrasilAddress (address->host))
|
||||||
{
|
{
|
||||||
address->host = host;
|
address->host = host;
|
||||||
if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
|
||||||
@@ -643,12 +643,12 @@ namespace i2p
|
|||||||
break;
|
break;
|
||||||
case i2p::data::RouterInfo::eTransportNTCP:
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
foundNTCP2 = true;
|
foundNTCP2 = true;
|
||||||
break;
|
break;
|
||||||
case i2p::data::RouterInfo::eTransportSSU2:
|
case i2p::data::RouterInfo::eTransportSSU2:
|
||||||
foundSSU2 = true;
|
foundSSU2 = true;
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
port = addr->port;
|
port = addr->port;
|
||||||
}
|
}
|
||||||
@@ -690,17 +690,17 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
if (ssu2)
|
if (ssu2)
|
||||||
{
|
{
|
||||||
bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
|
bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
|
||||||
if (ssu2Published)
|
if (ssu2Published)
|
||||||
{
|
{
|
||||||
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
||||||
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port);
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_RouterInfo.EnableV6 ();
|
m_RouterInfo.EnableV6 ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -731,12 +731,12 @@ namespace i2p
|
|||||||
break;
|
break;
|
||||||
case i2p::data::RouterInfo::eTransportNTCP:
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
foundNTCP2 = true;
|
foundNTCP2 = true;
|
||||||
break;
|
break;
|
||||||
case i2p::data::RouterInfo::eTransportSSU2:
|
case i2p::data::RouterInfo::eTransportSSU2:
|
||||||
foundSSU2 = true;
|
foundSSU2 = true;
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addr->port) port = addr->port;
|
if (addr->port) port = addr->port;
|
||||||
}
|
}
|
||||||
@@ -776,11 +776,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
|
||||||
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port);
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_RouterInfo.EnableV4 ();
|
m_RouterInfo.EnableV4 ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -883,7 +883,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
|
std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
|
||||||
if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
|
if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
|
||||||
m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
||||||
{
|
{
|
||||||
// update keys
|
// update keys
|
||||||
LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
|
LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
|
||||||
@@ -935,7 +935,7 @@ namespace i2p
|
|||||||
UpdateNTCP2Address (true); // enable NTCP2
|
UpdateNTCP2Address (true); // enable NTCP2
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UpdateNTCP2Address (false); // disable NTCP2
|
UpdateNTCP2Address (false); // disable NTCP2
|
||||||
|
|
||||||
// read SSU2
|
// read SSU2
|
||||||
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
|
||||||
@@ -960,7 +960,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
UpdateSSU2Address (false); // disable SSU2
|
UpdateSSU2Address (false); // disable SSU2
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,5 +1103,5 @@ namespace i2p
|
|||||||
delete x;
|
delete x;
|
||||||
}
|
}
|
||||||
return *m_SSU2StaticKeys;
|
return *m_SSU2StaticKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace garlic
|
|||||||
uint8_t staticPrivateKey[32];
|
uint8_t staticPrivateKey[32];
|
||||||
uint8_t intro[32];
|
uint8_t intro[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RouterContext ();
|
RouterContext ();
|
||||||
@@ -86,7 +86,7 @@ namespace garlic
|
|||||||
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
||||||
[](i2p::garlic::GarlicDestination *) {});
|
[](i2p::garlic::GarlicDestination *) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
||||||
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
|
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
|
||||||
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
||||||
@@ -96,7 +96,7 @@ namespace garlic
|
|||||||
const uint8_t * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
|
const uint8_t * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
|
||||||
const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
|
const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
|
||||||
i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
|
i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
|
||||||
|
|
||||||
uint32_t GetUptime () const; // in seconds
|
uint32_t GetUptime () const; // in seconds
|
||||||
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
||||||
uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };
|
uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };
|
||||||
|
|||||||
@@ -33,16 +33,16 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (len > size ()) len = size ();
|
if (len > size ()) len = size ();
|
||||||
memcpy (data (), buf, len);
|
memcpy (data (), buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (): m_Buffer (nullptr)
|
RouterInfo::RouterInfo (): m_Buffer (nullptr)
|
||||||
{
|
{
|
||||||
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (const std::string& fullPath):
|
RouterInfo::RouterInfo (const std::string& fullPath):
|
||||||
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
|
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
|
||||||
m_SupportedTransports (0),m_ReachableTransports (0),
|
m_SupportedTransports (0),m_ReachableTransports (0),
|
||||||
m_Caps (0), m_Version (0)
|
m_Caps (0), m_Version (0)
|
||||||
{
|
{
|
||||||
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
||||||
@@ -51,8 +51,8 @@ namespace data
|
|||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
|
RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
|
||||||
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
|
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
|
||||||
m_SupportedTransports (0), m_ReachableTransports (0),
|
m_SupportedTransports (0), m_ReachableTransports (0),
|
||||||
m_Caps (0), m_Version (0)
|
m_Caps (0), m_Version (0)
|
||||||
{
|
{
|
||||||
if (len <= MAX_RI_BUFFER_SIZE)
|
if (len <= MAX_RI_BUFFER_SIZE)
|
||||||
@@ -68,12 +68,12 @@ namespace data
|
|||||||
m_Buffer = nullptr;
|
m_Buffer = nullptr;
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (const uint8_t * buf, size_t len):
|
RouterInfo::RouterInfo (const uint8_t * buf, size_t len):
|
||||||
RouterInfo (std::make_shared<Buffer> (buf, len), len)
|
RouterInfo (std::make_shared<Buffer> (buf, len), len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::~RouterInfo ()
|
RouterInfo::~RouterInfo ()
|
||||||
{
|
{
|
||||||
@@ -160,7 +160,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen);
|
m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen);
|
||||||
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
||||||
if (identityLen >= m_BufferLen)
|
if (identityLen >= m_BufferLen)
|
||||||
@@ -241,7 +241,7 @@ namespace data
|
|||||||
// skip unknown address
|
// skip unknown address
|
||||||
s.seekg (size, std::ios_base::cur);
|
s.seekg (size, std::ios_base::cur);
|
||||||
if (s) continue; else return;
|
if (s) continue; else return;
|
||||||
}
|
}
|
||||||
while (r < size)
|
while (r < size)
|
||||||
{
|
{
|
||||||
char key[255], value[255];
|
char key[255], value[255];
|
||||||
@@ -288,7 +288,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
else if (address->IsSSU2 ())
|
else if (address->IsSSU2 ())
|
||||||
Base64ToByteStream (value, strlen (value), address->i, 32);
|
Base64ToByteStream (value, strlen (value), address->i, 32);
|
||||||
else
|
else
|
||||||
Base64ToByteStream (value, strlen (value), iV2, 32);
|
Base64ToByteStream (value, strlen (value), iV2, 32);
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "v"))
|
else if (!strcmp (key, "v"))
|
||||||
@@ -297,7 +297,7 @@ namespace data
|
|||||||
isV2 = true;
|
isV2 = true;
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v");
|
LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v");
|
||||||
}
|
}
|
||||||
else if (key[0] == 'i')
|
else if (key[0] == 'i')
|
||||||
{
|
{
|
||||||
// introducers
|
// introducers
|
||||||
@@ -344,7 +344,7 @@ namespace data
|
|||||||
if (isHost)
|
if (isHost)
|
||||||
{
|
{
|
||||||
if (address->host.is_v6 ())
|
if (address->host.is_v6 ())
|
||||||
supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
|
supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
|
||||||
else
|
else
|
||||||
supportedTransports |= eNTCP2V4;
|
supportedTransports |= eNTCP2V4;
|
||||||
m_ReachableTransports |= supportedTransports;
|
m_ReachableTransports |= supportedTransports;
|
||||||
@@ -366,7 +366,7 @@ namespace data
|
|||||||
if (isIntroKey)
|
if (isIntroKey)
|
||||||
{
|
{
|
||||||
if (isHost)
|
if (isHost)
|
||||||
supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
|
supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
|
||||||
else if (address->caps & AddressCaps::eV6)
|
else if (address->caps & AddressCaps::eV6)
|
||||||
{
|
{
|
||||||
supportedTransports |= eSSUV6;
|
supportedTransports |= eSSUV6;
|
||||||
@@ -383,7 +383,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT;
|
if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT;
|
||||||
if (ts <= it.iExp && it.iPort > 0 &&
|
if (ts <= it.iExp && it.iPort > 0 &&
|
||||||
((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
|
((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
|
||||||
numValid++;
|
numValid++;
|
||||||
else
|
else
|
||||||
it.iPort = 0;
|
it.iPort = 0;
|
||||||
@@ -408,12 +408,12 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4;
|
if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4;
|
||||||
if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6;
|
if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (supportedTransports)
|
if (supportedTransports)
|
||||||
{
|
{
|
||||||
if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates
|
if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates
|
||||||
{
|
{
|
||||||
addresses->push_back(address);
|
addresses->push_back(address);
|
||||||
if (address->transportStyle == eTransportSSU && isV2)
|
if (address->transportStyle == eTransportSSU && isV2)
|
||||||
{
|
{
|
||||||
@@ -427,10 +427,10 @@ namespace data
|
|||||||
ssu2addr->ssu.reset (new SSUExt ()); ssu2addr->ssu->mtu = address->ssu->mtu;
|
ssu2addr->ssu.reset (new SSUExt ()); ssu2addr->ssu->mtu = address->ssu->mtu;
|
||||||
for (const auto& introducer: address->ssu->introducers)
|
for (const auto& introducer: address->ssu->introducers)
|
||||||
if (!introducer.iPort) // SSU2
|
if (!introducer.iPort) // SSU2
|
||||||
ssu2addr->ssu->introducers.push_back (introducer);
|
ssu2addr->ssu->introducers.push_back (introducer);
|
||||||
addresses->push_back(ssu2addr);
|
addresses->push_back(ssu2addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_SupportedTransports |= supportedTransports;
|
m_SupportedTransports |= supportedTransports;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,10 +483,10 @@ namespace data
|
|||||||
{
|
{
|
||||||
isNetId = true;
|
isNetId = true;
|
||||||
if (atoi (value) != i2p::context.GetNetID ())
|
if (atoi (value) != i2p::context.GetNetID ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
|
LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// family
|
// family
|
||||||
else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY))
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY))
|
||||||
@@ -498,7 +498,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value))
|
if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value))
|
||||||
m_FamilyID = netdb.GetFamilies ().GetFamilyID (family);
|
m_FamilyID = netdb.GetFamilies ().GetFamilyID (family);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed");
|
LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ namespace data
|
|||||||
if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4;
|
if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4;
|
||||||
if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6;
|
if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6;
|
||||||
m_Addresses->push_back(std::move(addr));
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
|
void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
|
||||||
const boost::asio::ip::address& host, int port)
|
const boost::asio::ip::address& host, int port)
|
||||||
@@ -706,24 +706,24 @@ namespace data
|
|||||||
memcpy (addr->s, staticKey, 32);
|
memcpy (addr->s, staticKey, 32);
|
||||||
memcpy (addr->i, introKey, 32);
|
memcpy (addr->i, introKey, 32);
|
||||||
if (addr->IsV4 ())
|
if (addr->IsV4 ())
|
||||||
{
|
{
|
||||||
m_SupportedTransports |= eSSU2V4;
|
m_SupportedTransports |= eSSU2V4;
|
||||||
m_ReachableTransports |= eSSU2V4;
|
m_ReachableTransports |= eSSU2V4;
|
||||||
}
|
}
|
||||||
if (addr->IsV6 ())
|
if (addr->IsV6 ())
|
||||||
{
|
{
|
||||||
m_SupportedTransports |= eSSU2V6;
|
m_SupportedTransports |= eSSU2V6;
|
||||||
m_ReachableTransports |= eSSU2V6;
|
m_ReachableTransports |= eSSU2V6;
|
||||||
}
|
}
|
||||||
m_Addresses->push_back(std::move(addr));
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::AddIntroducer (const Introducer& introducer)
|
bool RouterInfo::AddIntroducer (const Introducer& introducer)
|
||||||
{
|
{
|
||||||
for (auto& addr : *m_Addresses)
|
for (auto& addr : *m_Addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == eTransportSSU &&
|
if (addr->transportStyle == eTransportSSU &&
|
||||||
((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
|
((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
|
||||||
{
|
{
|
||||||
for (auto& intro: addr->ssu->introducers)
|
for (auto& intro: addr->ssu->introducers)
|
||||||
if (intro.iTag == introducer.iTag) return false; // already presented
|
if (intro.iTag == introducer.iTag) return false; // already presented
|
||||||
@@ -740,7 +740,7 @@ namespace data
|
|||||||
for (auto& addr: *m_Addresses)
|
for (auto& addr: *m_Addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == eTransportSSU &&
|
if (addr->transportStyle == eTransportSSU &&
|
||||||
((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
|
((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
|
||||||
{
|
{
|
||||||
for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
|
for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
|
||||||
if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
|
if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
|
||||||
@@ -894,8 +894,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
return (address->transportStyle == eTransportSSU2) && address->IsV4();
|
return (address->transportStyle == eTransportSSU2) && address->IsV4();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSU2V6Address () const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSU2V6Address () const
|
||||||
{
|
{
|
||||||
return GetAddress (
|
return GetAddress (
|
||||||
@@ -903,8 +903,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
return (address->transportStyle == eTransportSSU2) && address->IsV6();
|
return (address->transportStyle == eTransportSSU2) && address->IsV6();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
|
||||||
{
|
{
|
||||||
@@ -939,7 +939,7 @@ namespace data
|
|||||||
return address->IsSSU2 () && !memcmp (address->s, key, 32) && address->IsV6 () == isV6;
|
return address->IsSSU2 () && !memcmp (address->s, key, 32) && address->IsV6 () == isV6;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V4Address () const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V4Address () const
|
||||||
{
|
{
|
||||||
return GetAddress (
|
return GetAddress (
|
||||||
@@ -1000,17 +1000,6 @@ namespace data
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsSSU2PeerTesting (bool v4) const
|
|
||||||
{
|
|
||||||
if (!(m_SupportedTransports & (v4 ? eSSU2V4 : eSSU2V6))) return false;
|
|
||||||
return (bool)GetAddress (
|
|
||||||
[v4](std::shared_ptr<const RouterInfo::Address> address)->bool
|
|
||||||
{
|
|
||||||
return (address->IsSSU2 ()) && address->IsPeerTesting () &&
|
|
||||||
((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())) && address->IsReachableSSU ();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RouterInfo::IsIntroducer (bool v4) const
|
bool RouterInfo::IsIntroducer (bool v4) const
|
||||||
{
|
{
|
||||||
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
||||||
@@ -1068,17 +1057,17 @@ namespace data
|
|||||||
if (len > m_Buffer->size ()) len = m_Buffer->size ();
|
if (len > m_Buffer->size ()) len = m_Buffer->size ();
|
||||||
memcpy (m_Buffer->data (), buf, len);
|
memcpy (m_Buffer->data (), buf, len);
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterInfo::Buffer> RouterInfo::NewBuffer () const
|
std::shared_ptr<RouterInfo::Buffer> RouterInfo::NewBuffer () const
|
||||||
{
|
{
|
||||||
return netdb.NewRouterInfoBuffer ();
|
return netdb.NewRouterInfoBuffer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::RefreshTimestamp ()
|
void RouterInfo::RefreshTimestamp ()
|
||||||
{
|
{
|
||||||
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
||||||
{
|
{
|
||||||
@@ -1099,13 +1088,13 @@ namespace data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", len + signatureLen);
|
LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", len + signatureLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::UpdateCaps (uint8_t caps)
|
void LocalRouterInfo::UpdateCaps (uint8_t caps)
|
||||||
{
|
{
|
||||||
SetCaps (caps);
|
SetCaps (caps);
|
||||||
UpdateCapsProperty ();
|
UpdateCapsProperty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::UpdateCapsProperty ()
|
void LocalRouterInfo::UpdateCapsProperty ()
|
||||||
{
|
{
|
||||||
@@ -1164,7 +1153,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
WriteString ("NTCP2", s);
|
WriteString ("NTCP2", s);
|
||||||
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
|
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
|
||||||
isPublished = true;
|
isPublished = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteString ("caps", properties);
|
WriteString ("caps", properties);
|
||||||
@@ -1223,12 +1212,12 @@ namespace data
|
|||||||
// caps
|
// caps
|
||||||
std::string caps;
|
std::string caps;
|
||||||
if (address.published)
|
if (address.published)
|
||||||
{
|
{
|
||||||
isPublished = true;
|
isPublished = true;
|
||||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
||||||
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
||||||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||||
@@ -1239,8 +1228,8 @@ namespace data
|
|||||||
properties << '=';
|
properties << '=';
|
||||||
WriteString (caps, properties);
|
WriteString (caps, properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WriteString ("", s);
|
WriteString ("", s);
|
||||||
|
|
||||||
@@ -1276,7 +1265,7 @@ namespace data
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (address.transportStyle == eTransportSSU)
|
if (address.transportStyle == eTransportSSU)
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -1286,13 +1275,13 @@ namespace data
|
|||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
if (address.IsSSU2 ())
|
if (address.IsSSU2 ())
|
||||||
WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
|
||||||
else
|
else
|
||||||
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
char value[64];
|
char value[64];
|
||||||
@@ -1313,7 +1302,7 @@ namespace data
|
|||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -1337,7 +1326,7 @@ namespace data
|
|||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
|
if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
|
||||||
{
|
{
|
||||||
// write mtu
|
// write mtu
|
||||||
if (address.ssu && address.ssu->mtu)
|
if (address.ssu && address.ssu->mtu)
|
||||||
{
|
{
|
||||||
@@ -1384,7 +1373,7 @@ namespace data
|
|||||||
uint16_t size = htobe16 (properties.str ().size ());
|
uint16_t size = htobe16 (properties.str ().size ());
|
||||||
s.write ((char *)&size, sizeof (size));
|
s.write ((char *)&size, sizeof (size));
|
||||||
s.write (properties.str ().c_str (), properties.str ().size ());
|
s.write (properties.str ().c_str (), properties.str ().size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::SetProperty (const std::string& key, const std::string& value)
|
void LocalRouterInfo::SetProperty (const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
@@ -1402,18 +1391,18 @@ namespace data
|
|||||||
if (it != m_Properties.end ())
|
if (it != m_Properties.end ())
|
||||||
return it->second;
|
return it->second;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const
|
void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const
|
||||||
{
|
{
|
||||||
uint8_t len = str.size ();
|
uint8_t len = str.size ();
|
||||||
s.write ((char *)&len, 1);
|
s.write ((char *)&len, 1);
|
||||||
s.write (str.c_str (), len);
|
s.write (str.c_str (), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterInfo::Buffer> LocalRouterInfo::NewBuffer () const
|
std::shared_ptr<RouterInfo::Buffer> LocalRouterInfo::NewBuffer () const
|
||||||
{
|
{
|
||||||
return std::make_shared<Buffer> ();
|
return std::make_shared<Buffer> ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace data
|
|||||||
const uint8_t COST_SSU_DIRECT = 9;
|
const uint8_t COST_SSU_DIRECT = 9;
|
||||||
const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
|
const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
|
||||||
const uint8_t COST_SSU2_NON_PUBLISHED = 15;
|
const uint8_t COST_SSU2_NON_PUBLISHED = 15;
|
||||||
|
|
||||||
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
|
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
|
||||||
class RouterInfo: public RoutingDestination
|
class RouterInfo: public RoutingDestination
|
||||||
{
|
{
|
||||||
@@ -146,11 +146,11 @@ namespace data
|
|||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
|
bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
|
||||||
bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
|
bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
|
||||||
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
|
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
|
||||||
bool IsReachableSSU () const { return (bool)ssu && (published || UsesIntroducer ()); };
|
bool IsReachableSSU () const { return (bool)ssu && (published || UsesIntroducer ()); };
|
||||||
bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };
|
bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };
|
||||||
|
|
||||||
bool IsIntroducer () const { return caps & eSSUIntroducer; };
|
bool IsIntroducer () const { return caps & eSSUIntroducer; };
|
||||||
bool IsPeerTesting () const { return caps & eSSUTesting; };
|
bool IsPeerTesting () const { return caps & eSSUTesting; };
|
||||||
@@ -166,7 +166,7 @@ namespace data
|
|||||||
Buffer () = default;
|
Buffer () = default;
|
||||||
Buffer (const uint8_t * buf, size_t len);
|
Buffer (const uint8_t * buf, size_t len);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<std::shared_ptr<Address> > Addresses;
|
typedef std::vector<std::shared_ptr<Address> > Addresses;
|
||||||
|
|
||||||
RouterInfo (const std::string& fullPath);
|
RouterInfo (const std::string& fullPath);
|
||||||
@@ -181,7 +181,7 @@ namespace data
|
|||||||
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
||||||
uint64_t GetTimestamp () const { return m_Timestamp; };
|
uint64_t GetTimestamp () const { return m_Timestamp; };
|
||||||
int GetVersion () const { return m_Version; };
|
int GetVersion () const { return m_Version; };
|
||||||
virtual void SetProperty (const std::string& key, const std::string& value) {};
|
virtual void SetProperty (const std::string& key, const std::string& value) {};
|
||||||
virtual void ClearProperties () {};
|
virtual void ClearProperties () {};
|
||||||
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
|
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
|
||||||
std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
|
std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
|
||||||
@@ -232,7 +232,6 @@ namespace data
|
|||||||
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
||||||
bool IsEligibleFloodfill () const;
|
bool IsEligibleFloodfill () const;
|
||||||
bool IsPeerTesting (bool v4) const;
|
bool IsPeerTesting (bool v4) const;
|
||||||
bool IsSSU2PeerTesting (bool v4) const;
|
|
||||||
bool IsIntroducer (bool v4) const;
|
bool IsIntroducer (bool v4) const;
|
||||||
|
|
||||||
uint8_t GetCaps () const { return m_Caps; };
|
uint8_t GetCaps () const { return m_Caps; };
|
||||||
@@ -273,7 +272,7 @@ namespace data
|
|||||||
void SetBufferLen (size_t len) { m_BufferLen = len; };
|
void SetBufferLen (size_t len) { m_BufferLen = len; };
|
||||||
void RefreshTimestamp ();
|
void RefreshTimestamp ();
|
||||||
const Addresses& GetAddresses () const { return *m_Addresses; };
|
const Addresses& GetAddresses () const { return *m_Addresses; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool LoadFile (const std::string& fullPath);
|
bool LoadFile (const std::string& fullPath);
|
||||||
@@ -286,7 +285,7 @@ namespace data
|
|||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<const Address> GetAddress (Filter filter) const;
|
std::shared_ptr<const Address> GetAddress (Filter filter) const;
|
||||||
virtual std::shared_ptr<Buffer> NewBuffer () const;
|
virtual std::shared_ptr<Buffer> NewBuffer () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
FamilyID m_FamilyID;
|
FamilyID m_FamilyID;
|
||||||
@@ -310,22 +309,22 @@ namespace data
|
|||||||
void CreateBuffer (const PrivateKeys& privateKeys);
|
void CreateBuffer (const PrivateKeys& privateKeys);
|
||||||
void UpdateCaps (uint8_t caps);
|
void UpdateCaps (uint8_t caps);
|
||||||
|
|
||||||
void SetProperty (const std::string& key, const std::string& value) override;
|
void SetProperty (const std::string& key, const std::string& value) override;
|
||||||
void DeleteProperty (const std::string& key);
|
void DeleteProperty (const std::string& key);
|
||||||
std::string GetProperty (const std::string& key) const;
|
std::string GetProperty (const std::string& key) const;
|
||||||
void ClearProperties () override { m_Properties.clear (); };
|
void ClearProperties () override { m_Properties.clear (); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void WriteToStream (std::ostream& s) const;
|
void WriteToStream (std::ostream& s) const;
|
||||||
void UpdateCapsProperty ();
|
void UpdateCapsProperty ();
|
||||||
void WriteString (const std::string& str, std::ostream& s) const;
|
void WriteString (const std::string& str, std::ostream& s) const;
|
||||||
std::shared_ptr<Buffer> NewBuffer () const override;
|
std::shared_ptr<Buffer> NewBuffer () const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string, std::string> m_Properties;
|
std::map<std::string, std::string> m_Properties;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,14 +273,14 @@ namespace transport
|
|||||||
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
|
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
|
||||||
{
|
{
|
||||||
if (!ecode
|
if (!ecode
|
||||||
|| ecode == boost::asio::error::connection_refused
|
|| ecode == boost::asio::error::connection_refused
|
||||||
|| ecode == boost::asio::error::connection_reset
|
|| ecode == boost::asio::error::connection_reset
|
||||||
|| ecode == boost::asio::error::network_unreachable
|
|| ecode == boost::asio::error::network_unreachable
|
||||||
|| ecode == boost::asio::error::host_unreachable
|
|| ecode == boost::asio::error::host_unreachable
|
||||||
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
||||||
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
||||||
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
||||||
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
// just try continue reading when received ICMP response otherwise socket can crash,
|
// just try continue reading when received ICMP response otherwise socket can crash,
|
||||||
@@ -332,14 +332,14 @@ namespace transport
|
|||||||
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
|
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
|
||||||
{
|
{
|
||||||
if (!ecode
|
if (!ecode
|
||||||
|| ecode == boost::asio::error::connection_refused
|
|| ecode == boost::asio::error::connection_refused
|
||||||
|| ecode == boost::asio::error::connection_reset
|
|| ecode == boost::asio::error::connection_reset
|
||||||
|| ecode == boost::asio::error::network_unreachable
|
|| ecode == boost::asio::error::network_unreachable
|
||||||
|| ecode == boost::asio::error::host_unreachable
|
|| ecode == boost::asio::error::host_unreachable
|
||||||
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
||||||
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
||||||
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
||||||
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
// just try continue reading when received ICMP response otherwise socket can crash,
|
// just try continue reading when received ICMP response otherwise socket can crash,
|
||||||
@@ -582,7 +582,7 @@ namespace transport
|
|||||||
"] through introducer ", introducer->iHost, ":", introducer->iPort);
|
"] through introducer ", introducer->iHost, ":", introducer->iPort);
|
||||||
session->WaitForIntroduction ();
|
session->WaitForIntroduction ();
|
||||||
if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) ||
|
if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) ||
|
||||||
(address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
|
(address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
|
||||||
{
|
{
|
||||||
uint8_t buf[1];
|
uint8_t buf[1];
|
||||||
Send (buf, 0, remoteEndpoint); // send HolePunch
|
Send (buf, 0, remoteEndpoint); // send HolePunch
|
||||||
@@ -676,7 +676,7 @@ namespace transport
|
|||||||
for (const auto& s : sessions)
|
for (const auto& s : sessions)
|
||||||
{
|
{
|
||||||
if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished &&
|
if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished &&
|
||||||
ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION)
|
ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION)
|
||||||
ret.push_back (s.second);
|
ret.push_back (s.second);
|
||||||
else if (s.second->GetRemoteIdentity ())
|
else if (s.second->GetRemoteIdentity ())
|
||||||
excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ());
|
excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ());
|
||||||
|
|||||||
1697
libi2pd/SSU2.cpp
1697
libi2pd/SSU2.cpp
File diff suppressed because it is too large
Load Diff
260
libi2pd/SSU2.h
260
libi2pd/SSU2.h
@@ -9,26 +9,237 @@
|
|||||||
#ifndef SSU2_H__
|
#ifndef SSU2_H__
|
||||||
#define SSU2_H__
|
#define SSU2_H__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "util.h"
|
#include <boost/asio.hpp>
|
||||||
#include "SSU2Session.h"
|
#include "Crypto.h"
|
||||||
|
#include "RouterInfo.h"
|
||||||
|
#include "TransportSession.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace transport
|
namespace transport
|
||||||
{
|
{
|
||||||
|
const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||||
|
const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
||||||
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
||||||
|
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in seconds
|
||||||
|
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
|
||||||
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
|
const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
|
const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
|
||||||
|
const size_t SSU2_MTU = 1488;
|
||||||
class SSU2Server: private i2p::util::RunnableServiceWithWork
|
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
|
||||||
|
const int SSU2_RESEND_INTERVAL = 3; // in seconds
|
||||||
|
const int SSU2_MAX_NUM_RESENDS = 5;
|
||||||
|
const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds
|
||||||
|
const size_t SSU2_MAX_WINDOW_SIZE = 128; // in packets
|
||||||
|
|
||||||
|
enum SSU2MessageType
|
||||||
{
|
{
|
||||||
struct Packet
|
eSSU2SessionRequest = 0,
|
||||||
|
eSSU2SessionCreated = 1,
|
||||||
|
eSSU2SessionConfirmed = 2,
|
||||||
|
eSSU2Data = 6,
|
||||||
|
eSSU2Retry = 9,
|
||||||
|
eSSU2TokenRequest = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSU2BlockType
|
||||||
|
{
|
||||||
|
eSSU2BlkDateTime = 0,
|
||||||
|
eSSU2BlkOptions, // 1
|
||||||
|
eSSU2BlkRouterInfo, // 2
|
||||||
|
eSSU2BlkI2NPMessage, // 3
|
||||||
|
eSSU2BlkFirstFragment, // 4
|
||||||
|
eSSU2BlkFollowOnFragment, // 5
|
||||||
|
eSSU2BlkTermination, // 6
|
||||||
|
eSSU2BlkRelayRequest, // 7
|
||||||
|
eSSU2BlkRelayResponse, // 8
|
||||||
|
eSSU2BlkRelayIntro, // 9
|
||||||
|
eSSU2BlkPeerTest, // 10
|
||||||
|
eSSU2BlkNextNonce, // 11
|
||||||
|
eSSU2BlkAck, // 12
|
||||||
|
eSSU2BlkAddress, // 13
|
||||||
|
eSSU2BlkIntroKey, // 14
|
||||||
|
eSSU2BlkRelayTagRequest, // 15
|
||||||
|
eSSU2BlkRelayTag, // 16
|
||||||
|
eSSU2BlkNewToken, // 17
|
||||||
|
eSSU2BlkPathChallenge, // 18
|
||||||
|
eSSU2BlkPathResponse, // 19
|
||||||
|
eSSU2BlkFirstPacketNumber, // 20
|
||||||
|
eSSU2BlkPadding = 254
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSU2SessionState
|
||||||
|
{
|
||||||
|
eSSU2SessionStateUnknown,
|
||||||
|
eSSU2SessionStateIntroduced,
|
||||||
|
eSSU2SessionStateEstablished,
|
||||||
|
eSSU2SessionStateTerminated,
|
||||||
|
eSSU2SessionStateFailed
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SSU2IncompleteMessage
|
||||||
|
{
|
||||||
|
struct Fragment
|
||||||
{
|
{
|
||||||
uint8_t buf[SSU2_MTU];
|
uint8_t buf[SSU2_MTU];
|
||||||
size_t len;
|
size_t len;
|
||||||
boost::asio::ip::udp::endpoint from;
|
bool isLast;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<I2NPMessage> msg;
|
||||||
|
int nextFragmentNum;
|
||||||
|
uint32_t lastFragmentInsertTime; // in seconds
|
||||||
|
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RouterInfo flags
|
||||||
|
const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
|
||||||
|
const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02;
|
||||||
|
|
||||||
|
class SSU2Server;
|
||||||
|
class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
|
||||||
|
{
|
||||||
|
union Header
|
||||||
|
{
|
||||||
|
uint64_t ll[2];
|
||||||
|
uint8_t buf[16];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint64_t connID;
|
||||||
|
uint32_t packetNum;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t flags[3];
|
||||||
|
} h;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SentPacket
|
||||||
|
{
|
||||||
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
|
size_t payloadSize = 0;
|
||||||
|
uint32_t nextResendTime; // in seconds
|
||||||
|
int numResends = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SessionConfirmedFragment
|
||||||
|
{
|
||||||
|
Header header;
|
||||||
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
|
size_t payloadSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::function<void ()> OnEstablished;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr,
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> addr = nullptr);
|
||||||
|
~SSU2Session ();
|
||||||
|
|
||||||
|
void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
|
||||||
|
const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
|
||||||
|
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
|
||||||
|
|
||||||
|
void Connect ();
|
||||||
|
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
|
||||||
|
void Terminate ();
|
||||||
|
void TerminateByTimeout ();
|
||||||
|
void CleanUp (uint64_t ts);
|
||||||
|
void FlushData ();
|
||||||
|
void Done () override;
|
||||||
|
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) override;
|
||||||
|
void Resend (uint64_t ts);
|
||||||
|
bool IsEstablished () const { return m_State == eSSU2SessionStateEstablished; };
|
||||||
|
uint64_t GetConnID () const { return m_SourceConnID; };
|
||||||
|
SSU2SessionState GetState () const { return m_State; };
|
||||||
|
void SetState (SSU2SessionState state) { m_State = state; };
|
||||||
|
|
||||||
|
bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
|
||||||
|
bool ProcessSessionCreated (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
||||||
|
bool ProcessRetry (uint8_t * buf, size_t len);
|
||||||
|
void ProcessData (uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void Established ();
|
||||||
|
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
|
||||||
|
bool SendQueue ();
|
||||||
|
void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
|
void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len);
|
||||||
|
void ProcessTokenRequest (Header& header, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
void SendSessionRequest (uint64_t token = 0);
|
||||||
|
void SendSessionCreated (const uint8_t * X);
|
||||||
|
void SendSessionConfirmed (const uint8_t * Y);
|
||||||
|
void KDFDataPhase (uint8_t * keydata_ab, uint8_t * keydata_ba);
|
||||||
|
void SendTokenRequest ();
|
||||||
|
void SendRetry ();
|
||||||
|
uint32_t SendData (const uint8_t * buf, size_t len); // returns packet num
|
||||||
|
void SendQuickAck ();
|
||||||
|
void SendTermination ();
|
||||||
|
|
||||||
|
void HandlePayload (const uint8_t * buf, size_t len);
|
||||||
|
void HandleAck (const uint8_t * buf, size_t len);
|
||||||
|
void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum);
|
||||||
|
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
|
||||||
|
size_t CreateEndpoint (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo> ExtractRouterInfo (const uint8_t * buf, size_t size);
|
||||||
|
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
||||||
|
bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate
|
||||||
|
void HandleFirstFragment (const uint8_t * buf, size_t len);
|
||||||
|
void HandleFollowOnFragment (const uint8_t * buf, size_t len);
|
||||||
|
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
||||||
|
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
||||||
|
void HandleRelayIntro (const uint8_t * buf, size_t len);
|
||||||
|
void HandleRelayResponse (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
|
||||||
|
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
||||||
|
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
|
||||||
|
size_t CreateI2NPBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage>&& msg);
|
||||||
|
size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
|
||||||
|
size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
|
||||||
|
size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
|
||||||
|
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SSU2Server& m_Server;
|
||||||
|
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
||||||
|
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_NoiseState;
|
||||||
|
std::unique_ptr<SessionConfirmedFragment> m_SessionConfirmedFragment1; // for Bob if applicable
|
||||||
|
std::shared_ptr<const i2p::data::RouterInfo::Address> m_Address;
|
||||||
|
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||||
|
uint64_t m_DestConnID, m_SourceConnID;
|
||||||
|
SSU2SessionState m_State;
|
||||||
|
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
||||||
|
uint32_t m_SendPacketNum, m_ReceivePacketNum;
|
||||||
|
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
||||||
|
std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
|
||||||
|
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
|
||||||
|
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
|
||||||
|
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||||
|
i2p::I2NPMessagesHandler m_Handler;
|
||||||
|
bool m_IsDataReceived;
|
||||||
|
size_t m_WindowSize;
|
||||||
|
uint32_t m_RelayTag; // between Bob and Charlie
|
||||||
|
OnEstablished m_OnEstablished; // callback from Established
|
||||||
|
};
|
||||||
|
|
||||||
|
class SSU2Server: private i2p::util::RunnableServiceWithWork
|
||||||
|
{
|
||||||
|
struct Packet
|
||||||
|
{
|
||||||
|
uint8_t buf[SSU2_MTU];
|
||||||
|
size_t len;
|
||||||
|
boost::asio::ip::udp::endpoint from;
|
||||||
|
};
|
||||||
|
|
||||||
class ReceiveService: public i2p::util::RunnableService
|
class ReceiveService: public i2p::util::RunnableService
|
||||||
{
|
{
|
||||||
@@ -38,8 +249,8 @@ namespace transport
|
|||||||
boost::asio::io_service& GetService () { return GetIOService (); };
|
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||||
void Start () { StartIOService (); };
|
void Start () { StartIOService (); };
|
||||||
void Stop () { StopIOService (); };
|
void Stop () { StopIOService (); };
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SSU2Server ();
|
SSU2Server ();
|
||||||
@@ -48,35 +259,34 @@ namespace transport
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
boost::asio::io_service& GetService () { return GetIOService (); };
|
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||||
|
|
||||||
void AddSession (std::shared_ptr<SSU2Session> session);
|
void AddSession (std::shared_ptr<SSU2Session> session);
|
||||||
void RemoveSession (uint64_t connID);
|
void RemoveSession (uint64_t connID);
|
||||||
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
|
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
|
||||||
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
|
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
|
||||||
std::shared_ptr<SSU2Session> FindSession (const i2p::data::IdentHash& ident) const;
|
|
||||||
|
|
||||||
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
|
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
|
||||||
void RemoveRelay (uint32_t tag);
|
void RemoveRelay (uint32_t tag);
|
||||||
std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag);
|
std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag);
|
||||||
|
|
||||||
void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
|
void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
|
||||||
const boost::asio::ip::udp::endpoint& to);
|
const boost::asio::ip::udp::endpoint& to);
|
||||||
void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
|
void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
|
||||||
const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to);
|
const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to);
|
||||||
|
void SendHolePunch (const boost::asio::ip::udp::endpoint& to);
|
||||||
|
|
||||||
bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
||||||
bool StartPeerTest (std::shared_ptr<const i2p::data::RouterInfo> router, bool v4);
|
|
||||||
|
|
||||||
void UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp);
|
void UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp);
|
||||||
uint64_t FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const;
|
uint64_t FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const;
|
||||||
uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
|
uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
|
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
|
||||||
void Receive (boost::asio::ip::udp::socket& socket);
|
void Receive (boost::asio::ip::udp::socket& socket);
|
||||||
void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred,
|
void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred,
|
||||||
Packet * packet, boost::asio::ip::udp::socket& socket);
|
Packet * packet, boost::asio::ip::udp::socket& socket);
|
||||||
void HandleReceivedPacket (Packet * packet);
|
void HandleReceivedPacket (Packet * packet);
|
||||||
void HandleReceivedPackets (std::vector<Packet *> packets);
|
void HandleReceivedPackets (std::vector<Packet *> packets);
|
||||||
@@ -90,16 +300,16 @@ namespace transport
|
|||||||
|
|
||||||
void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
|
void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ReceiveService m_ReceiveService;
|
ReceiveService m_ReceiveService;
|
||||||
boost::asio::ip::udp::socket m_SocketV4, m_SocketV6;
|
boost::asio::ip::udp::socket m_SocketV4, m_SocketV6;
|
||||||
std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
|
std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
|
||||||
std::map<i2p::data::IdentHash, std::shared_ptr<SSU2Session> > m_SessionsByRouterHash;
|
std::map<i2p::data::IdentHash, std::shared_ptr<SSU2Session> > m_SessionsByRouterHash;
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::pair<uint64_t, uint32_t> > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds)
|
std::map<boost::asio::ip::udp::endpoint, std::pair<uint64_t, uint32_t> > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds)
|
||||||
std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
|
std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
|
||||||
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
|
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
|
||||||
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
|
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
|
||||||
std::shared_ptr<SSU2Session> m_LastSession;
|
std::shared_ptr<SSU2Session> m_LastSession;
|
||||||
@@ -107,8 +317,8 @@ namespace transport
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
// for HTTP/I2PControl
|
// for HTTP/I2PControl
|
||||||
const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };
|
const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,273 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022, The PurpleI2P Project
|
|
||||||
*
|
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
*
|
|
||||||
* See full license text in LICENSE file at top of project tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SSU2_SESSION_H__
|
|
||||||
#define SSU2_SESSION_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
#include <list>
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#include "Crypto.h"
|
|
||||||
#include "RouterInfo.h"
|
|
||||||
#include "TransportSession.h"
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace transport
|
|
||||||
{
|
|
||||||
const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
|
|
||||||
const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
|
|
||||||
const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in seconds
|
|
||||||
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
|
|
||||||
const int SSU2_PEER_TEST_EXPIRATION_TIMEOUT = 60; // 60 seconds
|
|
||||||
const size_t SSU2_MTU = 1488;
|
|
||||||
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
|
|
||||||
const int SSU2_RESEND_INTERVAL = 3; // in seconds
|
|
||||||
const int SSU2_MAX_NUM_RESENDS = 5;
|
|
||||||
const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds
|
|
||||||
const size_t SSU2_MAX_WINDOW_SIZE = 128; // in packets
|
|
||||||
|
|
||||||
enum SSU2MessageType
|
|
||||||
{
|
|
||||||
eSSU2SessionRequest = 0,
|
|
||||||
eSSU2SessionCreated = 1,
|
|
||||||
eSSU2SessionConfirmed = 2,
|
|
||||||
eSSU2Data = 6,
|
|
||||||
eSSU2PeerTest = 7,
|
|
||||||
eSSU2Retry = 9,
|
|
||||||
eSSU2TokenRequest = 10,
|
|
||||||
eSSU2HolePunch = 11
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SSU2BlockType
|
|
||||||
{
|
|
||||||
eSSU2BlkDateTime = 0,
|
|
||||||
eSSU2BlkOptions, // 1
|
|
||||||
eSSU2BlkRouterInfo, // 2
|
|
||||||
eSSU2BlkI2NPMessage, // 3
|
|
||||||
eSSU2BlkFirstFragment, // 4
|
|
||||||
eSSU2BlkFollowOnFragment, // 5
|
|
||||||
eSSU2BlkTermination, // 6
|
|
||||||
eSSU2BlkRelayRequest, // 7
|
|
||||||
eSSU2BlkRelayResponse, // 8
|
|
||||||
eSSU2BlkRelayIntro, // 9
|
|
||||||
eSSU2BlkPeerTest, // 10
|
|
||||||
eSSU2BlkNextNonce, // 11
|
|
||||||
eSSU2BlkAck, // 12
|
|
||||||
eSSU2BlkAddress, // 13
|
|
||||||
eSSU2BlkIntroKey, // 14
|
|
||||||
eSSU2BlkRelayTagRequest, // 15
|
|
||||||
eSSU2BlkRelayTag, // 16
|
|
||||||
eSSU2BlkNewToken, // 17
|
|
||||||
eSSU2BlkPathChallenge, // 18
|
|
||||||
eSSU2BlkPathResponse, // 19
|
|
||||||
eSSU2BlkFirstPacketNumber, // 20
|
|
||||||
eSSU2BlkPadding = 254
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SSU2SessionState
|
|
||||||
{
|
|
||||||
eSSU2SessionStateUnknown,
|
|
||||||
eSSU2SessionStateIntroduced,
|
|
||||||
eSSU2SessionStatePeerTest,
|
|
||||||
eSSU2SessionStateEstablished,
|
|
||||||
eSSU2SessionStateTerminated,
|
|
||||||
eSSU2SessionStateFailed
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SSU2PeerTestCode
|
|
||||||
{
|
|
||||||
eSSU2PeerTestCodeAccept = 0,
|
|
||||||
eSSU2PeerTestCodeBobReasonUnspecified = 1,
|
|
||||||
eSSU2PeerTestCodeBobNoCharlieAvailable = 2,
|
|
||||||
eSSU2PeerTestCodeBobLimitExceeded = 3,
|
|
||||||
eSSU2PeerTestCodeBobSignatureFailure = 4,
|
|
||||||
eSSU2PeerTestCodeCharlieReasonUnspecified = 64,
|
|
||||||
eSSU2PeerTestCodeCharlieUnsupportedAddress = 65,
|
|
||||||
eSSU2PeerTestCodeCharlieLimitExceeded = 66,
|
|
||||||
eSSU2PeerTestCodeCharlieSignatureFailure = 67,
|
|
||||||
eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected = 68,
|
|
||||||
eSSU2PeerTestCodeCharlieAliceIsBanned = 69,
|
|
||||||
eSSU2PeerTestCodeCharlieAliceIsUnknown = 70,
|
|
||||||
eSSU2PeerTestCodeUnspecified = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SSU2IncompleteMessage
|
|
||||||
{
|
|
||||||
struct Fragment
|
|
||||||
{
|
|
||||||
uint8_t buf[SSU2_MTU];
|
|
||||||
size_t len;
|
|
||||||
bool isLast;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> msg;
|
|
||||||
int nextFragmentNum;
|
|
||||||
uint32_t lastFragmentInsertTime; // in seconds
|
|
||||||
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
|
|
||||||
};
|
|
||||||
|
|
||||||
// RouterInfo flags
|
|
||||||
const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
|
|
||||||
const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02;
|
|
||||||
|
|
||||||
class SSU2Server;
|
|
||||||
class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
|
|
||||||
{
|
|
||||||
union Header
|
|
||||||
{
|
|
||||||
uint64_t ll[2];
|
|
||||||
uint8_t buf[16];
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t connID;
|
|
||||||
uint32_t packetNum;
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t flags[3];
|
|
||||||
} h;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SentPacket
|
|
||||||
{
|
|
||||||
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
|
||||||
size_t payloadSize = 0;
|
|
||||||
uint32_t nextResendTime; // in seconds
|
|
||||||
int numResends = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SessionConfirmedFragment
|
|
||||||
{
|
|
||||||
Header header;
|
|
||||||
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
|
||||||
size_t payloadSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::function<void ()> OnEstablished;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr,
|
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> addr = nullptr);
|
|
||||||
~SSU2Session ();
|
|
||||||
|
|
||||||
void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
|
|
||||||
const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
|
|
||||||
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
|
|
||||||
|
|
||||||
void Connect ();
|
|
||||||
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
|
|
||||||
void SendPeerTest (); // Alice, Data message
|
|
||||||
void Terminate ();
|
|
||||||
void TerminateByTimeout ();
|
|
||||||
void CleanUp (uint64_t ts);
|
|
||||||
void FlushData ();
|
|
||||||
void Done () override;
|
|
||||||
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) override;
|
|
||||||
void Resend (uint64_t ts);
|
|
||||||
bool IsEstablished () const { return m_State == eSSU2SessionStateEstablished; };
|
|
||||||
uint64_t GetConnID () const { return m_SourceConnID; };
|
|
||||||
SSU2SessionState GetState () const { return m_State; };
|
|
||||||
void SetState (SSU2SessionState state) { m_State = state; };
|
|
||||||
|
|
||||||
bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
|
|
||||||
bool ProcessSessionCreated (uint8_t * buf, size_t len);
|
|
||||||
bool ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
|
||||||
bool ProcessRetry (uint8_t * buf, size_t len);
|
|
||||||
bool ProcessHolePunch (uint8_t * buf, size_t len);
|
|
||||||
bool ProcessPeerTest (uint8_t * buf, size_t len);
|
|
||||||
void ProcessData (uint8_t * buf, size_t len);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void Established ();
|
|
||||||
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
|
|
||||||
bool SendQueue ();
|
|
||||||
void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
|
|
||||||
|
|
||||||
void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len);
|
|
||||||
void ProcessTokenRequest (Header& header, uint8_t * buf, size_t len);
|
|
||||||
|
|
||||||
void SendSessionRequest (uint64_t token = 0);
|
|
||||||
void SendSessionCreated (const uint8_t * X);
|
|
||||||
void SendSessionConfirmed (const uint8_t * Y);
|
|
||||||
void KDFDataPhase (uint8_t * keydata_ab, uint8_t * keydata_ba);
|
|
||||||
void SendTokenRequest ();
|
|
||||||
void SendRetry ();
|
|
||||||
uint32_t SendData (const uint8_t * buf, size_t len); // returns packet num
|
|
||||||
void SendQuickAck ();
|
|
||||||
void SendTermination ();
|
|
||||||
void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey);
|
|
||||||
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey); // PeerTest message
|
|
||||||
|
|
||||||
void HandlePayload (const uint8_t * buf, size_t len);
|
|
||||||
void HandleAck (const uint8_t * buf, size_t len);
|
|
||||||
void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum);
|
|
||||||
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
|
|
||||||
size_t CreateEndpoint (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
|
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> FindLocalAddress () const;
|
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> ExtractRouterInfo (const uint8_t * buf, size_t size);
|
|
||||||
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
|
||||||
bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate
|
|
||||||
void HandleFirstFragment (const uint8_t * buf, size_t len);
|
|
||||||
void HandleFollowOnFragment (const uint8_t * buf, size_t len);
|
|
||||||
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
|
||||||
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
|
||||||
void HandleRelayIntro (const uint8_t * buf, size_t len);
|
|
||||||
void HandleRelayResponse (const uint8_t * buf, size_t len);
|
|
||||||
void HandlePeerTest (const uint8_t * buf, size_t len);
|
|
||||||
|
|
||||||
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
|
|
||||||
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
|
|
||||||
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
|
||||||
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
|
|
||||||
size_t CreateI2NPBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage>&& msg);
|
|
||||||
size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
|
|
||||||
size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
|
|
||||||
size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
|
|
||||||
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
|
|
||||||
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
|
|
||||||
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
SSU2Server& m_Server;
|
|
||||||
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
|
||||||
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_NoiseState;
|
|
||||||
std::unique_ptr<SessionConfirmedFragment> m_SessionConfirmedFragment1; // for Bob if applicable
|
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> m_Address;
|
|
||||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
|
||||||
uint64_t m_DestConnID, m_SourceConnID;
|
|
||||||
SSU2SessionState m_State;
|
|
||||||
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
|
||||||
uint32_t m_SendPacketNum, m_ReceivePacketNum;
|
|
||||||
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
|
||||||
std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
|
|
||||||
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
|
|
||||||
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
|
|
||||||
std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_PeerTests; // same as for relay sessions
|
|
||||||
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
|
||||||
i2p::I2NPMessagesHandler m_Handler;
|
|
||||||
bool m_IsDataReceived;
|
|
||||||
size_t m_WindowSize;
|
|
||||||
uint32_t m_RelayTag; // between Bob and Charlie
|
|
||||||
OnEstablished m_OnEstablished; // callback from Established
|
|
||||||
};
|
|
||||||
|
|
||||||
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)
|
|
||||||
{
|
|
||||||
uint64_t data = 0;
|
|
||||||
i2p::crypto::ChaCha20 ((uint8_t *)&data, 8, kh, nonce, (uint8_t *)&data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -171,7 +171,7 @@ namespace transport
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find message with msgID
|
// find message with msgID
|
||||||
auto it = m_IncompleteMessages.find (msgID);
|
auto it = m_IncompleteMessages.find (msgID);
|
||||||
if (it == m_IncompleteMessages.end ())
|
if (it == m_IncompleteMessages.end ())
|
||||||
{
|
{
|
||||||
@@ -318,7 +318,7 @@ namespace transport
|
|||||||
sentMessage->numResends = 0;
|
sentMessage->numResends = 0;
|
||||||
}
|
}
|
||||||
auto& fragments = sentMessage->fragments;
|
auto& fragments = sentMessage->fragments;
|
||||||
size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3)
|
size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3)
|
||||||
size_t len = msg->GetLength ();
|
size_t len = msg->GetLength ();
|
||||||
uint8_t * msgBuf = msg->GetSSUHeader ();
|
uint8_t * msgBuf = msg->GetSSUHeader ();
|
||||||
|
|
||||||
|
|||||||
@@ -296,8 +296,8 @@ namespace transport
|
|||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
|
LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
|
||||||
i2p::util::AdjustTimeOffset (-offset);
|
i2p::util::AdjustTimeOffset (-offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (std::abs (offset) > SSU_CLOCK_SKEW)
|
else if (std::abs (offset) > SSU_CLOCK_SKEW)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock");
|
LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock");
|
||||||
@@ -388,11 +388,11 @@ namespace transport
|
|||||||
// fill extended options, 3 bytes extended options don't change message size
|
// fill extended options, 3 bytes extended options don't change message size
|
||||||
bool isV4 = m_RemoteEndpoint.address ().is_v4 ();
|
bool isV4 = m_RemoteEndpoint.address ().is_v4 ();
|
||||||
if ((isV4 && i2p::context.GetStatus () == eRouterStatusOK) ||
|
if ((isV4 && i2p::context.GetStatus () == eRouterStatusOK) ||
|
||||||
(!isV4 && i2p::context.GetStatusV6 () == eRouterStatusOK)) // we don't need relays
|
(!isV4 && i2p::context.GetStatusV6 () == eRouterStatusOK)) // we don't need relays
|
||||||
{
|
{
|
||||||
// tell out peer to now assign relay tag
|
// tell out peer to now assign relay tag
|
||||||
flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED;
|
flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED;
|
||||||
*payload = 2; payload++; // 1 byte length
|
*payload = 2; payload++; // 1 byte length
|
||||||
uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
|
uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
|
||||||
htobe16buf (payload, flags);
|
htobe16buf (payload, flags);
|
||||||
payload += 2;
|
payload += 2;
|
||||||
@@ -1020,7 +1020,7 @@ namespace transport
|
|||||||
for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();)
|
for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();)
|
||||||
{
|
{
|
||||||
if (ts > it->second.second + SSU_CONNECT_TIMEOUT)
|
if (ts > it->second.second + SSU_CONNECT_TIMEOUT)
|
||||||
it = m_RelayRequests.erase (it);
|
it = m_RelayRequests.erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ namespace crypto
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t l = 64;
|
size_t l = 64;
|
||||||
uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232
|
uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232
|
||||||
EVP_DigestSign (m_MDCtx, sig, &l, buf, len);
|
EVP_DigestSign (m_MDCtx, sig, &l, buf, len);
|
||||||
memcpy (signature, sig, 64);
|
memcpy (signature, sig, 64);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1249,7 +1249,7 @@ namespace stream
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamingDestination::SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote)
|
void StreamingDestination::SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote)
|
||||||
{
|
{
|
||||||
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, 0);
|
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, 0);
|
||||||
s->SendPing ();
|
s->SendPing ();
|
||||||
@@ -1277,7 +1277,7 @@ namespace stream
|
|||||||
{
|
{
|
||||||
m_PacketsPool.CleanUp ();
|
m_PacketsPool.CleanUp ();
|
||||||
m_I2NPMsgsPool.CleanUp ();
|
m_I2NPMsgsPool.CleanUp ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
|
bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
|
||||||
@@ -1285,13 +1285,7 @@ namespace stream
|
|||||||
auto it = m_Streams.find (recvStreamID);
|
auto it = m_Streams.find (recvStreamID);
|
||||||
if (it == m_Streams.end ())
|
if (it == m_Streams.end ())
|
||||||
return false;
|
return false;
|
||||||
auto s = it->second;
|
DeleteStream (it->second);
|
||||||
m_Owner->GetService ().post ([this, s] ()
|
|
||||||
{
|
|
||||||
s->Close (); // try to send FIN
|
|
||||||
s->Terminate (false);
|
|
||||||
DeleteStream (s);
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,6 @@ namespace util
|
|||||||
void AdjustTimeOffset (int64_t offset)
|
void AdjustTimeOffset (int64_t offset)
|
||||||
{
|
{
|
||||||
g_TimeOffset += offset;
|
g_TimeOffset += offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace util
|
|||||||
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
|
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
|
||||||
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
|
void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
|
||||||
void AdjustTimeOffset (int64_t offset); // in seconds from current
|
void AdjustTimeOffset (int64_t offset); // in seconds from current
|
||||||
|
|
||||||
class NTPTimeSync
|
class NTPTimeSync
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
// create SSU2 server
|
// create SSU2 server
|
||||||
if (enableSSU2) m_SSU2Server = new SSU2Server ();
|
if (enableSSU2) m_SSU2Server = new SSU2Server ();
|
||||||
|
|
||||||
// bind to interfaces
|
// bind to interfaces
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
if (ipv4)
|
if (ipv4)
|
||||||
@@ -268,7 +268,6 @@ namespace transport
|
|||||||
|
|
||||||
// start servers
|
// start servers
|
||||||
if (m_NTCP2Server) m_NTCP2Server->Start ();
|
if (m_NTCP2Server) m_NTCP2Server->Start ();
|
||||||
if (m_SSU2Server) m_SSU2Server->Start ();
|
|
||||||
if (m_SSUServer)
|
if (m_SSUServer)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort);
|
LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort);
|
||||||
@@ -285,7 +284,8 @@ namespace transport
|
|||||||
}
|
}
|
||||||
if (m_SSUServer) DetectExternalIP ();
|
if (m_SSUServer) DetectExternalIP ();
|
||||||
}
|
}
|
||||||
|
if (m_SSU2Server) m_SSU2Server->Start ();
|
||||||
|
|
||||||
m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
|
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_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
|
||||||
|
|
||||||
@@ -307,14 +307,14 @@ namespace transport
|
|||||||
delete m_SSUServer;
|
delete m_SSUServer;
|
||||||
m_SSUServer = nullptr;
|
m_SSUServer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_SSU2Server)
|
if (m_SSU2Server)
|
||||||
{
|
{
|
||||||
m_SSU2Server->Stop ();
|
m_SSU2Server->Stop ();
|
||||||
delete m_SSU2Server;
|
delete m_SSU2Server;
|
||||||
m_SSU2Server = nullptr;
|
m_SSU2Server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_NTCP2Server)
|
if (m_NTCP2Server)
|
||||||
{
|
{
|
||||||
m_NTCP2Server->Stop ();
|
m_NTCP2Server->Stop ();
|
||||||
@@ -569,7 +569,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
peer.numAttempts += 2;
|
peer.numAttempts += 2;
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
||||||
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
||||||
peer.Done ();
|
peer.Done ();
|
||||||
@@ -654,16 +654,6 @@ namespace transport
|
|||||||
}
|
}
|
||||||
if (!statusChanged)
|
if (!statusChanged)
|
||||||
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv4");
|
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv4");
|
||||||
|
|
||||||
// SSU2
|
|
||||||
if (m_SSU2Server)
|
|
||||||
{
|
|
||||||
excluded.clear ();
|
|
||||||
excluded.insert (i2p::context.GetIdentHash ());
|
|
||||||
auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (true, excluded); // v4
|
|
||||||
if (router)
|
|
||||||
m_SSU2Server->StartPeerTest (router, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ipv6 && i2p::context.SupportsV6 ())
|
if (ipv6 && i2p::context.SupportsV6 ())
|
||||||
{
|
{
|
||||||
@@ -691,16 +681,6 @@ namespace transport
|
|||||||
}
|
}
|
||||||
if (!statusChanged)
|
if (!statusChanged)
|
||||||
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv6");
|
LogPrint (eLogWarning, "Transports: Can't find routers for peer test IPv6");
|
||||||
|
|
||||||
// SSU2
|
|
||||||
if (m_SSU2Server)
|
|
||||||
{
|
|
||||||
excluded.clear ();
|
|
||||||
excluded.insert (i2p::context.GetIdentHash ());
|
|
||||||
auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (false, excluded); // v6
|
|
||||||
if (router)
|
|
||||||
m_SSU2Server->StartPeerTest (router, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,18 +829,18 @@ namespace transport
|
|||||||
}
|
}
|
||||||
return i2p::data::netdb.FindRouter (ident);
|
return i2p::data::netdb.FindRouter (ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
|
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
||||||
m_TrustedFamilies.clear();
|
m_TrustedFamilies.clear();
|
||||||
for (auto fam : families)
|
for (auto fam : families)
|
||||||
{
|
{
|
||||||
boost::to_lower (fam);
|
boost::to_lower (fam);
|
||||||
auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam);
|
auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam);
|
||||||
if (id)
|
if (id)
|
||||||
m_TrustedFamilies.push_back (id);
|
m_TrustedFamilies.push_back (id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
|
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ namespace tunnel
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Config->IsShort () && m_Config->GetLastHop () &&
|
if (m_Config->IsShort () && m_Config->GetLastHop () &&
|
||||||
m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent)
|
m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent)
|
||||||
{
|
{
|
||||||
// add garlic key/tag for reply
|
// add garlic key/tag for reply
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
@@ -403,7 +403,7 @@ namespace tunnel
|
|||||||
return tunnel;
|
return tunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops,
|
std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops,
|
||||||
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance)
|
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance)
|
||||||
{
|
{
|
||||||
auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance);
|
auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance);
|
||||||
@@ -822,7 +822,7 @@ namespace tunnel
|
|||||||
|
|
||||||
template<class TTunnel>
|
template<class TTunnel>
|
||||||
std::shared_ptr<TTunnel> Tunnels::CreateTunnel (std::shared_ptr<TunnelConfig> config,
|
std::shared_ptr<TTunnel> Tunnels::CreateTunnel (std::shared_ptr<TunnelConfig> config,
|
||||||
std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel)
|
std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel)
|
||||||
{
|
{
|
||||||
auto newTunnel = std::make_shared<TTunnel> (config);
|
auto newTunnel = std::make_shared<TTunnel> (config);
|
||||||
newTunnel->SetTunnelPool (pool);
|
newTunnel->SetTunnelPool (pool);
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ namespace tunnel
|
|||||||
void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
||||||
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
|
||||||
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
|
||||||
std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops, int numOuboundHops,
|
std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops, int numOuboundHops,
|
||||||
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
||||||
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
|
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
|
||||||
void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
|
void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
|
||||||
@@ -226,7 +226,7 @@ namespace tunnel
|
|||||||
|
|
||||||
template<class TTunnel>
|
template<class TTunnel>
|
||||||
std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config,
|
std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config,
|
||||||
std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
|
std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
|
||||||
|
|
||||||
template<class TTunnel>
|
template<class TTunnel>
|
||||||
std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
|
std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ namespace tunnel
|
|||||||
memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2);
|
memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2);
|
||||||
clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES
|
clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES
|
||||||
htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ());
|
htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ());
|
||||||
htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes
|
htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes
|
||||||
htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
|
htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
|
||||||
memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET);
|
memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET);
|
||||||
// encrypt
|
// encrypt
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace tunnel
|
|||||||
|
|
||||||
TunnelConfig (const std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers,
|
TunnelConfig (const std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers,
|
||||||
uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort,
|
uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort,
|
||||||
i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound
|
i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound
|
||||||
m_IsShort (isShort), m_FarEndTransports (farEndTransports)
|
m_IsShort (isShort), m_FarEndTransports (farEndTransports)
|
||||||
{
|
{
|
||||||
CreatePeers (peers);
|
CreatePeers (peers);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
peers.push_back (r->GetRouterIdentity ());
|
peers.push_back (r->GetRouterIdentity ());
|
||||||
if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION ||
|
if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION ||
|
||||||
r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||||
isShort = false;
|
isShort = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,11 +40,11 @@ namespace tunnel
|
|||||||
std::reverse (peers.begin (), peers.end ());
|
std::reverse (peers.begin (), peers.end ());
|
||||||
}
|
}
|
||||||
|
|
||||||
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
||||||
int numOutboundTunnels, int inboundVariance, int outboundVariance):
|
int numOutboundTunnels, int inboundVariance, int outboundVariance):
|
||||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
|
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
|
||||||
m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance),
|
m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance),
|
||||||
m_IsActive (true), m_CustomPeerSelector(nullptr)
|
m_IsActive (true), m_CustomPeerSelector(nullptr)
|
||||||
{
|
{
|
||||||
if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
|
if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
|
||||||
@@ -54,11 +54,11 @@ namespace tunnel
|
|||||||
if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0)
|
if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0)
|
||||||
m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0;
|
m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0;
|
||||||
if (m_OutboundVariance < 0 && m_NumOutboundHops + m_OutboundVariance <= 0)
|
if (m_OutboundVariance < 0 && m_NumOutboundHops + m_OutboundVariance <= 0)
|
||||||
m_OutboundVariance = m_NumOutboundHops ? -m_NumOutboundHops + 1 : 0;
|
m_OutboundVariance = m_NumOutboundHops ? -m_NumOutboundHops + 1 : 0;
|
||||||
if (m_InboundVariance > 0 && m_NumInboundHops + m_InboundVariance > STANDARD_NUM_RECORDS)
|
if (m_InboundVariance > 0 && m_NumInboundHops + m_InboundVariance > STANDARD_NUM_RECORDS)
|
||||||
m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0;
|
m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0;
|
||||||
if (m_OutboundVariance > 0 && m_NumOutboundHops + m_OutboundVariance > STANDARD_NUM_RECORDS)
|
if (m_OutboundVariance > 0 && m_NumOutboundHops + m_OutboundVariance > STANDARD_NUM_RECORDS)
|
||||||
m_OutboundVariance = (m_NumOutboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumOutboundHops : 0;
|
m_OutboundVariance = (m_NumOutboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumOutboundHops : 0;
|
||||||
m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL;
|
m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ namespace tunnel
|
|||||||
if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ()))
|
if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ()))
|
||||||
{
|
{
|
||||||
if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() &&
|
if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() &&
|
||||||
!it->LatencyFitsRange(m_MinLatency, m_MaxLatency)))
|
!it->LatencyFitsRange(m_MinLatency, m_MaxLatency)))
|
||||||
{
|
{
|
||||||
i++; skipped = true;
|
i++; skipped = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -423,7 +423,7 @@ namespace tunnel
|
|||||||
LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
|
LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
|
||||||
int numHops = 0;
|
int numHops = 0;
|
||||||
if (test.first) numHops += test.first->GetNumHops ();
|
if (test.first) numHops += test.first->GetNumHops ();
|
||||||
if (test.second) numHops += test.second->GetNumHops ();
|
if (test.second) numHops += test.second->GetNumHops ();
|
||||||
// restore from test failed state if any
|
// restore from test failed state if any
|
||||||
if (test.first)
|
if (test.first)
|
||||||
{
|
{
|
||||||
@@ -431,7 +431,7 @@ namespace tunnel
|
|||||||
test.first->SetState (eTunnelStateEstablished);
|
test.first->SetState (eTunnelStateEstablished);
|
||||||
// update latency
|
// update latency
|
||||||
uint64_t latency = 0;
|
uint64_t latency = 0;
|
||||||
if (numHops) latency = dlt*test.first->GetNumHops ()/numHops;
|
if (numHops) latency = dlt*test.first->GetNumHops ()/numHops;
|
||||||
if (!latency) latency = dlt/2;
|
if (!latency) latency = dlt/2;
|
||||||
test.first->AddLatencySample(latency);
|
test.first->AddLatencySample(latency);
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ namespace tunnel
|
|||||||
test.second->SetState (eTunnelStateEstablished);
|
test.second->SetState (eTunnelStateEstablished);
|
||||||
// update latency
|
// update latency
|
||||||
uint64_t latency = 0;
|
uint64_t latency = 0;
|
||||||
if (numHops) latency = dlt*test.second->GetNumHops ()/numHops;
|
if (numHops) latency = dlt*test.second->GetNumHops ()/numHops;
|
||||||
if (!latency) latency = dlt/2;
|
if (!latency) latency = dlt/2;
|
||||||
test.second->AddLatencySample(latency);
|
test.second->AddLatencySample(latency);
|
||||||
}
|
}
|
||||||
@@ -511,7 +511,7 @@ namespace tunnel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4
|
if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4
|
||||||
(inbound && !hop->IsReachable ()))) // IBGW is not reachable
|
(inbound && !hop->IsReachable ()))) // IBGW is not reachable
|
||||||
{
|
{
|
||||||
auto hop1 = nextHop (prevHop, true);
|
auto hop1 = nextHop (prevHop, true);
|
||||||
if (hop1) hop = hop1;
|
if (hop1) hop = hop1;
|
||||||
@@ -530,25 +530,25 @@ namespace tunnel
|
|||||||
// calculate num hops
|
// calculate num hops
|
||||||
int numHops;
|
int numHops;
|
||||||
if (isInbound)
|
if (isInbound)
|
||||||
{
|
{
|
||||||
numHops = m_NumInboundHops;
|
numHops = m_NumInboundHops;
|
||||||
if (m_InboundVariance)
|
if (m_InboundVariance)
|
||||||
{
|
{
|
||||||
int offset = rand () % (std::abs (m_InboundVariance) + 1);
|
int offset = rand () % (std::abs (m_InboundVariance) + 1);
|
||||||
if (m_InboundVariance < 0) offset = -offset;
|
if (m_InboundVariance < 0) offset = -offset;
|
||||||
numHops += offset;
|
numHops += offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
numHops = m_NumOutboundHops;
|
numHops = m_NumOutboundHops;
|
||||||
if (m_OutboundVariance)
|
if (m_OutboundVariance)
|
||||||
{
|
{
|
||||||
int offset = rand () % (std::abs (m_OutboundVariance) + 1);
|
int offset = rand () % (std::abs (m_OutboundVariance) + 1);
|
||||||
if (m_OutboundVariance < 0) offset = -offset;
|
if (m_OutboundVariance < 0) offset = -offset;
|
||||||
numHops += offset;
|
numHops += offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// peers is empty
|
// peers is empty
|
||||||
if (numHops <= 0) return true;
|
if (numHops <= 0) return true;
|
||||||
// custom peer selector in use ?
|
// custom peer selector in use ?
|
||||||
@@ -715,7 +715,7 @@ namespace tunnel
|
|||||||
auto tunnel = tunnels.CreateInboundTunnel (
|
auto tunnel = tunnels.CreateInboundTunnel (
|
||||||
m_NumOutboundHops > 0 ? std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers (),
|
m_NumOutboundHops > 0 ? std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers (),
|
||||||
outboundTunnel->IsShortBuildMessage ()) : nullptr,
|
outboundTunnel->IsShortBuildMessage ()) : nullptr,
|
||||||
shared_from_this (), outboundTunnel);
|
shared_from_this (), outboundTunnel);
|
||||||
if (tunnel->IsEstablished ()) // zero hops
|
if (tunnel->IsEstablished ()) // zero hops
|
||||||
TunnelCreated (tunnel);
|
TunnelCreated (tunnel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
|
||||||
int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
int numOutboundTunnels, int inboundVariance, int outboundVariance);
|
||||||
~TunnelPool ();
|
~TunnelPool ();
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ namespace tunnel
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination;
|
std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination;
|
||||||
int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels,
|
int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels,
|
||||||
m_InboundVariance, m_OutboundVariance;
|
m_InboundVariance, m_OutboundVariance;
|
||||||
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
|
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
|
||||||
mutable std::mutex m_InboundTunnelsMutex;
|
mutable std::mutex m_InboundTunnelsMutex;
|
||||||
|
|||||||
@@ -32,6 +32,10 @@
|
|||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "IPHLPAPI.lib")
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
||||||
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
||||||
|
|
||||||
@@ -517,7 +521,7 @@ namespace net
|
|||||||
|
|
||||||
bool IsLocalAddress (const boost::asio::ip::address& addr)
|
bool IsLocalAddress (const boost::asio::ip::address& addr)
|
||||||
{
|
{
|
||||||
auto mtu = // TODO: implement better
|
auto mtu = // TODO: implement better
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
GetMTUWindows(addr, 0);
|
GetMTUWindows(addr, 0);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
||||||
|
|
||||||
#define I2PD_VERSION_MAJOR 2
|
#define I2PD_VERSION_MAJOR 2
|
||||||
#define I2PD_VERSION_MINOR 42
|
#define I2PD_VERSION_MINOR 41
|
||||||
#define I2PD_VERSION_MICRO 1
|
#define I2PD_VERSION_MICRO 0
|
||||||
#define I2PD_VERSION_PATCH 0
|
#define I2PD_VERSION_PATCH 0
|
||||||
#ifdef GITVER
|
#ifdef GITVER
|
||||||
#define I2PD_VERSION GITVER
|
#define I2PD_VERSION GITVER
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#define I2P_VERSION_MAJOR 0
|
#define I2P_VERSION_MAJOR 0
|
||||||
#define I2P_VERSION_MINOR 9
|
#define I2P_VERSION_MINOR 9
|
||||||
#define I2P_VERSION_MICRO 54
|
#define I2P_VERSION_MICRO 53
|
||||||
#define I2P_VERSION_PATCH 0
|
#define I2P_VERSION_PATCH 0
|
||||||
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -299,8 +299,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
|
AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
|
||||||
m_NumRetries (0), m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr),
|
m_NumRetries (0), m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
||||||
m_IsEnabled (true)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,16 +310,12 @@ namespace client
|
|||||||
|
|
||||||
void AddressBook::Start ()
|
void AddressBook::Start ()
|
||||||
{
|
{
|
||||||
i2p::config::GetOption("addressbook.enabled", m_IsEnabled);
|
if (!m_Storage)
|
||||||
if (m_IsEnabled)
|
m_Storage = new AddressBookFilesystemStorage;
|
||||||
{
|
m_Storage->Init();
|
||||||
if (!m_Storage)
|
LoadHosts (); /* try storage, then hosts.txt, then download */
|
||||||
m_Storage = new AddressBookFilesystemStorage;
|
StartSubscriptions ();
|
||||||
m_Storage->Init();
|
StartLookups ();
|
||||||
LoadHosts (); /* try storage, then hosts.txt, then download */
|
|
||||||
StartSubscriptions ();
|
|
||||||
StartLookups ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBook::StartResolvers ()
|
void AddressBook::StartResolvers ()
|
||||||
@@ -375,10 +370,9 @@ namespace client
|
|||||||
pos = address.find (".i2p");
|
pos = address.find (".i2p");
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
if (!m_IsEnabled) return nullptr;
|
|
||||||
auto addr = FindAddress (address);
|
auto addr = FindAddress (address);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
LookupAddress (address); // TODO:
|
LookupAddress (address); // TODO:
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -500,7 +494,7 @@ namespace client
|
|||||||
auto it = m_Addresses.find (name);
|
auto it = m_Addresses.find (name);
|
||||||
if (it != m_Addresses.end ()) // already exists ?
|
if (it != m_Addresses.end ()) // already exists ?
|
||||||
{
|
{
|
||||||
if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () && // address changed?
|
if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () && // address changed?
|
||||||
ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
|
ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
|
||||||
{
|
{
|
||||||
it->second->identHash = ident->GetIdentHash ();
|
it->second->identHash = ident->GetIdentHash ();
|
||||||
@@ -864,9 +858,9 @@ namespace client
|
|||||||
if (!m_LastModified.empty())
|
if (!m_LastModified.empty())
|
||||||
req.AddHeader("If-Modified-Since", m_LastModified);
|
req.AddHeader("If-Modified-Since", m_LastModified);
|
||||||
/* convert url to relative */
|
/* convert url to relative */
|
||||||
url.schema = "";
|
url.schema = "";
|
||||||
url.host = "";
|
url.host = "";
|
||||||
req.uri = url.to_string();
|
req.uri = url.to_string();
|
||||||
req.version = "HTTP/1.1";
|
req.version = "HTTP/1.1";
|
||||||
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
|
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
|
||||||
std::string request = req.to_string();
|
std::string request = req.to_string();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -116,7 +116,7 @@ namespace client
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex m_AddressBookMutex;
|
std::mutex m_AddressBookMutex;
|
||||||
std::map<std::string, std::shared_ptr<Address> > m_Addresses;
|
std::map<std::string, std::shared_ptr<Address> > m_Addresses;
|
||||||
std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
|
std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
|
||||||
std::mutex m_LookupsMutex;
|
std::mutex m_LookupsMutex;
|
||||||
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
||||||
@@ -126,7 +126,6 @@ namespace client
|
|||||||
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||||
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
||||||
bool m_IsEnabled;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressBookSubscription
|
class AddressBookSubscription
|
||||||
@@ -163,7 +162,7 @@ namespace client
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||||
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
|
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
@@ -704,7 +706,7 @@ namespace client
|
|||||||
msg += operand;
|
msg += operand;
|
||||||
*(const_cast<char *>(value)) = '=';
|
*(const_cast<char *>(value)) = '=';
|
||||||
msg += " set to ";
|
msg += " set to ";
|
||||||
msg += value + 1;
|
msg += value;
|
||||||
SendReplyOK (msg.c_str ());
|
SendReplyOK (msg.c_str ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -884,3 +886,4 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // WITH_BOB
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
|
|
||||||
#ifndef BOB_H__
|
#ifndef BOB_H__
|
||||||
#define BOB_H__
|
#define BOB_H__
|
||||||
|
|
||||||
@@ -277,5 +279,5 @@ namespace client
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif // WITH_BOB
|
||||||
|
|||||||
@@ -26,8 +26,16 @@ namespace client
|
|||||||
ClientContext context;
|
ClientContext context;
|
||||||
|
|
||||||
ClientContext::ClientContext (): m_SharedLocalDestination (nullptr),
|
ClientContext::ClientContext (): m_SharedLocalDestination (nullptr),
|
||||||
m_HttpProxy (nullptr), m_SocksProxy (nullptr), m_SamBridge (nullptr),
|
m_HttpProxy (nullptr), m_SocksProxy (nullptr)
|
||||||
m_BOBCommandChannel (nullptr), m_I2CPServer (nullptr)
|
#ifdef WITH_SAM
|
||||||
|
, m_SamBridge (nullptr)
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_BOB
|
||||||
|
, m_BOBCommandChannel (nullptr)
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
|
, m_I2CPServer (nullptr)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +43,15 @@ namespace client
|
|||||||
{
|
{
|
||||||
delete m_HttpProxy;
|
delete m_HttpProxy;
|
||||||
delete m_SocksProxy;
|
delete m_SocksProxy;
|
||||||
|
#ifdef WITH_SAM
|
||||||
delete m_SamBridge;
|
delete m_SamBridge;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_BOB
|
||||||
delete m_BOBCommandChannel;
|
delete m_BOBCommandChannel;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
delete m_I2CPServer;
|
delete m_I2CPServer;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientContext::Start ()
|
void ClientContext::Start ()
|
||||||
@@ -58,6 +72,7 @@ namespace client
|
|||||||
// I2P tunnels
|
// I2P tunnels
|
||||||
ReadTunnels ();
|
ReadTunnels ();
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
// SAM
|
// SAM
|
||||||
bool sam; i2p::config::GetOption("sam.enabled", sam);
|
bool sam; i2p::config::GetOption("sam.enabled", sam);
|
||||||
if (sam)
|
if (sam)
|
||||||
@@ -77,7 +92,9 @@ namespace client
|
|||||||
ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ());
|
ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
// BOB
|
// BOB
|
||||||
bool bob; i2p::config::GetOption("bob.enabled", bob);
|
bool bob; i2p::config::GetOption("bob.enabled", bob);
|
||||||
if (bob) {
|
if (bob) {
|
||||||
@@ -95,7 +112,9 @@ namespace client
|
|||||||
ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ());
|
ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
// I2CP
|
// I2CP
|
||||||
bool i2cp; i2p::config::GetOption("i2cp.enabled", i2cp);
|
bool i2cp; i2p::config::GetOption("i2cp.enabled", i2cp);
|
||||||
if (i2cp)
|
if (i2cp)
|
||||||
@@ -115,6 +134,7 @@ namespace client
|
|||||||
ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ());
|
ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m_AddressBook.StartResolvers ();
|
m_AddressBook.StartResolvers ();
|
||||||
|
|
||||||
@@ -158,6 +178,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
m_ServerTunnels.clear ();
|
m_ServerTunnels.clear ();
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
if (m_SamBridge)
|
if (m_SamBridge)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Clients: Stopping SAM bridge");
|
LogPrint(eLogInfo, "Clients: Stopping SAM bridge");
|
||||||
@@ -165,7 +186,9 @@ namespace client
|
|||||||
delete m_SamBridge;
|
delete m_SamBridge;
|
||||||
m_SamBridge = nullptr;
|
m_SamBridge = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
if (m_BOBCommandChannel)
|
if (m_BOBCommandChannel)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Clients: Stopping BOB command channel");
|
LogPrint(eLogInfo, "Clients: Stopping BOB command channel");
|
||||||
@@ -173,7 +196,9 @@ namespace client
|
|||||||
delete m_BOBCommandChannel;
|
delete m_BOBCommandChannel;
|
||||||
m_BOBCommandChannel = nullptr;
|
m_BOBCommandChannel = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
if (m_I2CPServer)
|
if (m_I2CPServer)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Clients: Stopping I2CP");
|
LogPrint(eLogInfo, "Clients: Stopping I2CP");
|
||||||
@@ -181,6 +206,7 @@ namespace client
|
|||||||
delete m_I2CPServer;
|
delete m_I2CPServer;
|
||||||
m_I2CPServer = nullptr;
|
m_I2CPServer = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Clients: Stopping AddressBook");
|
LogPrint(eLogInfo, "Clients: Stopping AddressBook");
|
||||||
m_AddressBook.Stop ();
|
m_AddressBook.Stop ();
|
||||||
@@ -608,29 +634,21 @@ namespace client
|
|||||||
if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
|
if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
|
||||||
// udp client
|
// udp client
|
||||||
// TODO: hostnames
|
// TODO: hostnames
|
||||||
boost::asio::ip::udp::endpoint end (boost::asio::ip::address::from_string(address), port);
|
boost::asio::ip::udp::endpoint end(boost::asio::ip::address::from_string(address), port);
|
||||||
if (!localDestination)
|
if (!localDestination)
|
||||||
localDestination = m_SharedLocalDestination;
|
localDestination = m_SharedLocalDestination;
|
||||||
|
|
||||||
bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true);
|
bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true);
|
||||||
auto clientTunnel = std::make_shared<I2PUDPClientTunnel> (name, dest, end, localDestination, destinationPort, gzip);
|
auto clientTunnel = std::make_shared<I2PUDPClientTunnel>(name, dest, end, localDestination, destinationPort, gzip);
|
||||||
|
|
||||||
auto ins = m_ClientForwards.insert (std::make_pair (end, clientTunnel));
|
auto ins = m_ClientForwards.insert(std::make_pair(end, clientTunnel));
|
||||||
if (ins.second)
|
if (ins.second)
|
||||||
{
|
{
|
||||||
clientTunnel->Start ();
|
clientTunnel->Start();
|
||||||
numClientTunnels++;
|
numClientTunnels++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: update
|
|
||||||
if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
|
|
||||||
{
|
|
||||||
LogPrint (eLogInfo, "Clients: I2P UDP client tunnel destination updated");
|
|
||||||
ins.first->second->Stop ();
|
|
||||||
ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
|
|
||||||
ins.first->second->Start ();
|
|
||||||
}
|
|
||||||
ins.first->second->isUpdated = true;
|
ins.first->second->isUpdated = true;
|
||||||
LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
|
LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
|
||||||
}
|
}
|
||||||
@@ -864,8 +882,6 @@ namespace client
|
|||||||
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
||||||
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
||||||
bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper);
|
bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper);
|
||||||
if (httpAddresshelper)
|
|
||||||
i2p::config::GetOption("addressbook.enabled", httpAddresshelper); // addresshelper is not supported without address book
|
|
||||||
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
||||||
LogPrint(eLogInfo, "Clients: Starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
LogPrint(eLogInfo, "Clients: Starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
||||||
if (httpProxyKeys.length () > 0)
|
if (httpProxyKeys.length () > 0)
|
||||||
@@ -900,7 +916,7 @@ namespace client
|
|||||||
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
|
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
|
||||||
if (socksproxy)
|
if (socksproxy)
|
||||||
{
|
{
|
||||||
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
||||||
// we still need httpProxyKeys to compare with sockProxyKeys
|
// we still need httpProxyKeys to compare with sockProxyKeys
|
||||||
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
|
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
|
||||||
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);
|
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);
|
||||||
@@ -986,11 +1002,11 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write correct UDP tunnels stop
|
/* // TODO: Write correct UDP tunnels stop
|
||||||
for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();)
|
for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();)
|
||||||
{
|
{
|
||||||
if(clean && !it->second->isUpdated) {
|
if(clean && !it->second->isUpdated) {
|
||||||
it->second->Stop ();
|
it->second = nullptr;
|
||||||
it = m_ClientForwards.erase(it);
|
it = m_ClientForwards.erase(it);
|
||||||
} else {
|
} else {
|
||||||
it->second->isUpdated = false;
|
it->second->isUpdated = false;
|
||||||
@@ -1001,13 +1017,13 @@ namespace client
|
|||||||
for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();)
|
for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();)
|
||||||
{
|
{
|
||||||
if(clean && !it->second->isUpdated) {
|
if(clean && !it->second->isUpdated) {
|
||||||
it->second->Stop ();
|
it->second = nullptr;
|
||||||
it = m_ServerForwards.erase(it);
|
it = m_ServerForwards.erase(it);
|
||||||
} else {
|
} else {
|
||||||
it->second->isUpdated = false;
|
it->second->isUpdated = false;
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -18,9 +18,19 @@
|
|||||||
#include "HTTPProxy.h"
|
#include "HTTPProxy.h"
|
||||||
#include "SOCKS.h"
|
#include "SOCKS.h"
|
||||||
#include "I2PTunnel.h"
|
#include "I2PTunnel.h"
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
#include "SAM.h"
|
#include "SAM.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_BOB
|
||||||
#include "BOB.h"
|
#include "BOB.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
#include "I2CP.h"
|
#include "I2CP.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "AddressBook.h"
|
#include "AddressBook.h"
|
||||||
#include "I18N_langs.h"
|
#include "I18N_langs.h"
|
||||||
|
|
||||||
@@ -76,31 +86,45 @@ namespace client
|
|||||||
void ReloadConfig ();
|
void ReloadConfig ();
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
|
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (bool isPublic = false, // transient
|
|
||||||
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (
|
||||||
|
bool isPublic = false, // transient
|
||||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||||
const std::map<std::string, std::string> * params = nullptr); // used by SAM only
|
const std::map<std::string, std::string> * params = nullptr); // used by SAM only
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||||
bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||||
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||||
const std::map<std::string, std::string> * params = nullptr);
|
const std::map<std::string, std::string> * params = nullptr);
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||||
const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||||
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
||||||
const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
||||||
|
|
||||||
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
||||||
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
||||||
|
|
||||||
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
||||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
||||||
|
|
||||||
AddressBook& GetAddressBook () { return m_AddressBook; };
|
AddressBook& GetAddressBook () { return m_AddressBook; };
|
||||||
|
#ifdef WITH_BOB
|
||||||
const BOBCommandChannel * GetBOBCommandChannel () const { return m_BOBCommandChannel; };
|
const BOBCommandChannel * GetBOBCommandChannel () const { return m_BOBCommandChannel; };
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SAM
|
||||||
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
|
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
const I2CPServer * GetI2CPServer () const { return m_I2CPServer; };
|
const I2CPServer * GetI2CPServer () const { return m_I2CPServer; };
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<std::shared_ptr<DatagramSessionInfo> > GetForwardInfosFor(const i2p::data::IdentHash & destination);
|
std::vector<std::shared_ptr<DatagramSessionInfo> > GetForwardInfosFor(const i2p::data::IdentHash & destination);
|
||||||
|
|
||||||
@@ -142,16 +166,22 @@ namespace client
|
|||||||
|
|
||||||
i2p::proxy::HTTPProxy * m_HttpProxy;
|
i2p::proxy::HTTPProxy * m_HttpProxy;
|
||||||
i2p::proxy::SOCKSProxy * m_SocksProxy;
|
i2p::proxy::SOCKSProxy * m_SocksProxy;
|
||||||
std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint -> tunnel
|
std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint->tunnel
|
||||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port> -> tunnel
|
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel
|
||||||
|
|
||||||
std::mutex m_ForwardsMutex;
|
std::mutex m_ForwardsMutex;
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
|
||||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel
|
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel
|
||||||
|
|
||||||
|
#ifdef WITH_SAM
|
||||||
SAMBridge * m_SamBridge;
|
SAMBridge * m_SamBridge;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_BOB
|
||||||
BOBCommandChannel * m_BOBCommandChannel;
|
BOBCommandChannel * m_BOBCommandChannel;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_I2CP
|
||||||
I2CPServer * m_I2CPServer;
|
I2CPServer * m_I2CPServer;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2021, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -32,13 +32,7 @@
|
|||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace proxy {
|
namespace proxy {
|
||||||
static const std::vector<std::string> jumporder = {
|
std::map<std::string, std::string> jumpservices = {
|
||||||
"reg.i2p",
|
|
||||||
"stats.i2p",
|
|
||||||
"identiguy.i2p",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::map<std::string, std::string> jumpservices = {
|
|
||||||
{ "reg.i2p", "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/jump/" },
|
{ "reg.i2p", "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/jump/" },
|
||||||
{ "identiguy.i2p", "http://3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva.b32.i2p/cgi-bin/query?hostname=" },
|
{ "identiguy.i2p", "http://3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva.b32.i2p/cgi-bin/query?hostname=" },
|
||||||
{ "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" },
|
{ "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" },
|
||||||
@@ -180,11 +174,8 @@ namespace proxy {
|
|||||||
<< "<p>" << tr("Remote host not found in router's addressbook") << "</p>\r\n"
|
<< "<p>" << tr("Remote host not found in router's addressbook") << "</p>\r\n"
|
||||||
<< "<p>" << tr("You may try to find this host on jump services below") << ":</p>\r\n"
|
<< "<p>" << tr("You may try to find this host on jump services below") << ":</p>\r\n"
|
||||||
<< "<ul>\r\n";
|
<< "<ul>\r\n";
|
||||||
for (const auto& jump : jumporder)
|
for (const auto& js : jumpservices) {
|
||||||
{
|
ss << " <li><a href=\"" << js.second << host << "\">" << js.first << "</a></li>\r\n";
|
||||||
auto js = jumpservices.find (jump);
|
|
||||||
if (js != jumpservices.end())
|
|
||||||
ss << " <li><a href=\"" << js->second << host << "\">" << js->first << "</a></li>\r\n";
|
|
||||||
}
|
}
|
||||||
ss << "</ul>\r\n";
|
ss << "</ul>\r\n";
|
||||||
std::string content = ss.str();
|
std::string content = ss.str();
|
||||||
@@ -246,14 +237,14 @@ namespace proxy {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* according to i2p ticket #1862:
|
* according to i2p ticket #1862:
|
||||||
* leave Referer if requested URL with same schema, host and port,
|
* leave Referrer if requested URL with same schema, host and port,
|
||||||
* otherwise, drop it.
|
* otherwise, drop it.
|
||||||
*/
|
*/
|
||||||
if(req.GetHeader("Referer") != "") {
|
if(req.GetHeader("Referrer") != "") {
|
||||||
i2p::http::URL reqURL; reqURL.parse(req.uri);
|
i2p::http::URL reqURL; reqURL.parse(req.uri);
|
||||||
i2p::http::URL refURL; refURL.parse(req.GetHeader("Referer"));
|
i2p::http::URL refURL; refURL.parse(req.GetHeader("Referrer"));
|
||||||
if(!boost::iequals(reqURL.schema, refURL.schema) || !boost::iequals(reqURL.host, refURL.host) || reqURL.port != refURL.port)
|
if(!boost::iequals(reqURL.schema, refURL.schema) || !boost::iequals(reqURL.host, refURL.host) || reqURL.port != refURL.port)
|
||||||
req.RemoveHeader("Referer");
|
req.RemoveHeader("Referrer");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add headers */
|
/* add headers */
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_I2CP
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
@@ -24,7 +26,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
|
|
||||||
I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr<I2CPSession> owner,
|
I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr<I2CPSession> owner,
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
|
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
|
||||||
LeaseSetDestination (service, isPublic, ¶ms),
|
LeaseSetDestination (service, isPublic, ¶ms),
|
||||||
m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()),
|
m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()),
|
||||||
m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service)
|
m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service)
|
||||||
@@ -453,8 +455,8 @@ namespace client
|
|||||||
{
|
{
|
||||||
auto len = m_SendQueue.Get (m_SendBuffer, I2CP_MAX_MESSAGE_LENGTH);
|
auto len = m_SendQueue.Get (m_SendBuffer, I2CP_MAX_MESSAGE_LENGTH);
|
||||||
boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len),
|
boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len),
|
||||||
boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent,
|
boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent,
|
||||||
shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_IsSending = false;
|
m_IsSending = false;
|
||||||
@@ -524,21 +526,31 @@ namespace client
|
|||||||
|
|
||||||
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len)
|
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
|
if (m_Destination || !m_Owner.InsertSession (shared_from_this ()))
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "I2CP: Session already exists");
|
||||||
|
SendSessionStatusMessage (eI2CPSessionStatusRefused); // refused
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RAND_bytes ((uint8_t *)&m_SessionID, 2);
|
RAND_bytes ((uint8_t *)&m_SessionID, 2);
|
||||||
auto identity = std::make_shared<i2p::data::IdentityEx>();
|
auto identity = std::make_shared<i2p::data::IdentityEx>();
|
||||||
size_t offset = identity->FromBuffer (buf, len);
|
size_t offset = identity->FromBuffer (buf, len);
|
||||||
|
|
||||||
if (!offset)
|
if (!offset)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2CP: Create session malformed identity");
|
LogPrint (eLogError, "I2CP: Create session malformed identity");
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Owner.FindSessionByIdentHash (identity->GetIdentHash ()))
|
if (m_Owner.FindSessionByIdentHash (identity->GetIdentHash ()))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ());
|
LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ());
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t optionsSize = bufbe16toh (buf + offset);
|
uint16_t optionsSize = bufbe16toh (buf + offset);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if (optionsSize > len - offset)
|
if (optionsSize > len - offset)
|
||||||
@@ -547,42 +559,27 @@ namespace client
|
|||||||
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string> params;
|
std::map<std::string, std::string> params;
|
||||||
ExtractMapping (buf + offset, optionsSize, params);
|
ExtractMapping (buf + offset, optionsSize, params);
|
||||||
offset += optionsSize; // options
|
offset += optionsSize; // options
|
||||||
if (params[I2CP_PARAM_MESSAGE_RELIABILITY] == "none") m_IsSendAccepted = false;
|
if (params[I2CP_PARAM_MESSAGE_RELIABILITY] == "none") m_IsSendAccepted = false;
|
||||||
|
|
||||||
offset += 8; // date
|
offset += 8; // date
|
||||||
if (identity->Verify (buf, offset, buf + offset)) // signature
|
if (!identity->Verify (buf, offset, buf + offset)) // signature
|
||||||
{
|
|
||||||
if (!m_Destination)
|
|
||||||
{
|
|
||||||
m_Destination = m_Owner.IsSingleThread () ?
|
|
||||||
std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params):
|
|
||||||
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params);
|
|
||||||
if (m_Owner.InsertSession (shared_from_this ()))
|
|
||||||
{
|
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
|
|
||||||
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
|
|
||||||
m_Destination->Start ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "I2CP: Session already exists");
|
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusRefused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "I2CP: Session already exists");
|
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusRefused); // refused
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2CP: Create session signature verification failed");
|
LogPrint (eLogError, "I2CP: Create session signature verification failed");
|
||||||
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Destination = m_Owner.IsSingleThread () ?
|
||||||
|
std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params):
|
||||||
|
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params);
|
||||||
|
|
||||||
|
SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
|
||||||
|
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
|
||||||
|
m_Destination->Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len)
|
void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len)
|
||||||
@@ -712,7 +709,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
if (offset + 4 > len) return;
|
if (offset + 4 > len) return;
|
||||||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type
|
uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type
|
||||||
uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length
|
uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length
|
||||||
if (offset + keyLen > len) return;
|
if (offset + keyLen > len) return;
|
||||||
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||||
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
|
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
|
||||||
@@ -1040,3 +1037,4 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // WITH_I2CP
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user