mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6e75e9c5a | ||
|
|
4901434209 | ||
|
|
13d174c09c | ||
|
|
5363c063d1 | ||
|
|
32d300248e | ||
|
|
3426906a4f | ||
|
|
3aaa942c94 | ||
|
|
95d8887ab0 | ||
|
|
6272e15b47 | ||
|
|
20b4f6b24d | ||
|
|
6ee279d83e | ||
|
|
b00ff43be7 | ||
|
|
dfbefee477 | ||
|
|
8c2de4973c | ||
|
|
e1527dc137 | ||
|
|
0957f6b143 | ||
|
|
7db2e9dc4a | ||
|
|
b1c701085b | ||
|
|
e8d6c803cd | ||
|
|
f4a2dda94e | ||
|
|
c4216379ed | ||
|
|
52195bf296 | ||
|
|
10fe75ed87 | ||
|
|
1c659d6ef6 | ||
|
|
3ac86db038 | ||
|
|
4a77a03033 | ||
|
|
3820b51960 | ||
|
|
e070ce4e34 | ||
|
|
0bb0adbf3e | ||
|
|
ddd25f0945 | ||
|
|
162bd592f8 | ||
|
|
85fa728d41 | ||
|
|
c7db9010ad | ||
|
|
be16545063 | ||
|
|
c730839989 | ||
|
|
4ee364640d | ||
|
|
56dd0db001 | ||
|
|
626ed720a6 | ||
|
|
b8fd9ba83f | ||
|
|
316a4457af | ||
|
|
347a2c2150 | ||
|
|
42d3770b14 | ||
|
|
39ca07bcc6 | ||
|
|
914566ece0 | ||
|
|
f537e7b2c6 | ||
|
|
06020b8f54 | ||
|
|
b486d1cd27 | ||
|
|
b3b38015c2 | ||
|
|
4c6988e3bc | ||
|
|
0bd4db4cc7 | ||
|
|
bc72800fef | ||
|
|
951f8972c7 | ||
|
|
38b694a055 | ||
|
|
44a9c3ca0c | ||
|
|
6bf823fb15 | ||
|
|
43a751ee0b | ||
|
|
207212557e | ||
|
|
fd1aeeac92 | ||
|
|
50ba52756f | ||
|
|
e630b8f8a8 | ||
|
|
cf5081d300 | ||
|
|
8864cbf80a | ||
|
|
81d7a832c0 | ||
|
|
d41fabbc9f | ||
|
|
46f62e1af9 | ||
|
|
b91efaa973 | ||
|
|
e3238ff75c | ||
|
|
9cc4e8d03a | ||
|
|
34c98e03c1 | ||
|
|
41e40bbc0d | ||
|
|
ca49944c85 | ||
|
|
d5e9fc7677 | ||
|
|
6db7c5733d | ||
|
|
418f86ecbd | ||
|
|
c68c5af856 | ||
|
|
950dffbe06 | ||
|
|
5d557003b6 | ||
|
|
3b8c3c1346 | ||
|
|
1853263f6c | ||
|
|
b0f6d81f57 | ||
|
|
9ba0329432 | ||
|
|
614101c4b8 | ||
|
|
50e4fb138a | ||
|
|
6dba0c6e0e | ||
|
|
0f2d2156e6 | ||
|
|
13b17c5a93 | ||
|
|
511499d950 | ||
|
|
6632b71273 | ||
|
|
60ef70cee4 | ||
|
|
b3ba0a7241 | ||
|
|
fc73dabc0b | ||
|
|
1121d45eb6 | ||
|
|
18b6353803 | ||
|
|
c0c0642bd1 | ||
|
|
3cf26a84dc | ||
|
|
44d6d4405e | ||
|
|
cafa027f0b | ||
|
|
276a78cb2e | ||
|
|
1008510750 | ||
|
|
42483b6f32 | ||
|
|
c21c1f5225 | ||
|
|
14ca3fc2f3 | ||
|
|
36afef3498 |
@@ -3,7 +3,7 @@ cache:
|
|||||||
apt: true
|
apt: true
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
#- osx
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
compiler:
|
compiler:
|
||||||
|
|||||||
27
ChangeLog
27
ChangeLog
@@ -1,6 +1,23 @@
|
|||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
|
## [2.18.0] - 2018-01-30
|
||||||
|
### Added
|
||||||
|
- Show tunnel nicknames for I2CP destination in WebUI
|
||||||
|
- Re-create HTTP and SOCKS proxy by tunnel reload
|
||||||
|
- Graceful shutdown as soon as no more transit tunnels
|
||||||
|
### Changed
|
||||||
|
- Regenerate shared local destination by tunnel reload
|
||||||
|
- Use transient local destination by default if not specified
|
||||||
|
- Return correct code if pid file can't be created
|
||||||
|
- Timing and number of attempts for adressbook requests
|
||||||
|
- Certificates list
|
||||||
|
### Fixed
|
||||||
|
- Malformed addressbook subsctiption request
|
||||||
|
- Build with boost 1.66
|
||||||
|
- Few race conditions for SAM
|
||||||
|
- Check LeaseSet's signature before update
|
||||||
|
|
||||||
## [2.17.0] - 2017-12-04
|
## [2.17.0] - 2017-12-04
|
||||||
### Added
|
### Added
|
||||||
- Reseed through HTTP and SOCKS proxy
|
- Reseed through HTTP and SOCKS proxy
|
||||||
@@ -37,7 +54,7 @@
|
|||||||
|
|
||||||
## [2.15.0] - 2017-08-17
|
## [2.15.0] - 2017-08-17
|
||||||
### Added
|
### Added
|
||||||
- QT GUI
|
- QT GUI
|
||||||
- Ability to add and remove I2P tunnels without restart
|
- Ability to add and remove I2P tunnels without restart
|
||||||
- Ability to disable SOCKS outproxy option
|
- Ability to disable SOCKS outproxy option
|
||||||
### Changed
|
### Changed
|
||||||
@@ -81,7 +98,7 @@
|
|||||||
- Some stats in a main window for Windows version
|
- Some stats in a main window for Windows version
|
||||||
### Changed
|
### Changed
|
||||||
- Reseed servers list
|
- Reseed servers list
|
||||||
- MTU of 1488 for ipv6
|
- MTU of 1488 for ipv6
|
||||||
- Android and Mac OS X versions use OpenSSL 1.1
|
- Android and Mac OS X versions use OpenSSL 1.1
|
||||||
- New logo for Android
|
- New logo for Android
|
||||||
### Fixed
|
### Fixed
|
||||||
@@ -111,7 +128,7 @@
|
|||||||
## [2.10.2] - 2016-12-04
|
## [2.10.2] - 2016-12-04
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fixes UPnP discovery bug, producing excessive CPU usage
|
- Fixes UPnP discovery bug, producing excessive CPU usage
|
||||||
- Fixes sudden SSU thread stop for Windows.
|
- Fixes sudden SSU thread stop for Windows.
|
||||||
|
|
||||||
## [2.10.1] - 2016-11-07
|
## [2.10.1] - 2016-11-07
|
||||||
### Fixed
|
### Fixed
|
||||||
@@ -162,12 +179,12 @@
|
|||||||
- Configurable limit of transit tunnels
|
- Configurable limit of transit tunnels
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Speed-up of assymetric crypto for non-x64 platforms
|
- Speed-up of asymmetric crypto for non-x64 platforms
|
||||||
- Refactoring of web-console
|
- Refactoring of web-console
|
||||||
|
|
||||||
## [2.6.0] - 2016-03-31
|
## [2.6.0] - 2016-03-31
|
||||||
### Added
|
### Added
|
||||||
- Gracefull shutdown on SIGINT
|
- Graceful shutdown on SIGINT
|
||||||
- Numeric bandwidth limits (was: by router class)
|
- Numeric bandwidth limits (was: by router class)
|
||||||
- Jumpservices in web-console
|
- Jumpservices in web-console
|
||||||
- Logging to syslog
|
- Logging to syslog
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ RUN mkdir /user && adduser -S -h /user i2pd && chown -R i2pd:nobody /user
|
|||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
||||||
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
|
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
|
||||||
#
|
#
|
||||||
|
|
||||||
# 1. install deps, clone and build.
|
# 1. install deps, clone and build.
|
||||||
# 2. strip binaries.
|
# 2. strip binaries.
|
||||||
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
||||||
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
|
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
|
||||||
&& mkdir -p /tmp/build \
|
&& mkdir -p /tmp/build \
|
||||||
&& cd /tmp/build && git clone -b ${GIT_BRANCH} https://github.com/PurpleI2P/i2pd.git \
|
&& cd /tmp/build && git clone -b ${GIT_BRANCH} https://github.com/PurpleI2P/i2pd.git \
|
||||||
|
|||||||
14
Makefile
14
Makefile
@@ -1,9 +1,9 @@
|
|||||||
UNAME := $(shell uname -s)
|
SYS := $(shell $(CXX) -dumpmachine)
|
||||||
SHLIB := libi2pd.so
|
SHLIB := libi2pd.so
|
||||||
ARLIB := libi2pd.a
|
ARLIB := libi2pd.a
|
||||||
SHLIB_CLIENT := libi2pdclient.so
|
SHLIB_CLIENT := libi2pdclient.so
|
||||||
ARLIB_CLIENT := libi2pdclient.a
|
ARLIB_CLIENT := libi2pdclient.a
|
||||||
I2PD := i2pd
|
I2PD := i2pd
|
||||||
GREP := grep
|
GREP := grep
|
||||||
DEPS := obj/make.dep
|
DEPS := obj/make.dep
|
||||||
|
|
||||||
@@ -23,22 +23,24 @@ ifeq ($(WEBSOCKETS),1)
|
|||||||
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(UNAME),Darwin)
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
ifeq ($(HOMEBREW),1)
|
ifeq ($(HOMEBREW),1)
|
||||||
include Makefile.homebrew
|
include Makefile.homebrew
|
||||||
else
|
else
|
||||||
include Makefile.osx
|
include Makefile.osx
|
||||||
endif
|
endif
|
||||||
else ifeq ($(shell echo $(UNAME) | $(GREP) -Ec '(Free|Open)BSD'),1)
|
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.bsd
|
include Makefile.bsd
|
||||||
else ifeq ($(UNAME),Linux)
|
else ifneq (, $(findstring linux, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.linux
|
include Makefile.linux
|
||||||
else
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
|
else # not supported
|
||||||
|
$(error Not supported platform)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_MESHNET),yes)
|
ifeq ($(USE_MESHNET),yes)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS = -O2
|
CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
||||||
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
## For example, when adding 'hardening flags' to the build
|
## For example, when adding 'hardening flags' to the build
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ BOOSTROOT = ${BREWROOT}/opt/boost
|
|||||||
SSLROOT = ${BREWROOT}/opt/libressl
|
SSLROOT = ${BREWROOT}/opt/libressl
|
||||||
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
||||||
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
||||||
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||||
|
|
||||||
ifndef TRAVIS
|
ifndef TRAVIS
|
||||||
CXX = clang++
|
CXX = clang++
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ INCFLAGS ?=
|
|||||||
# detect proper flag for c++11 support by compilers
|
# detect proper flag for c++11 support by compilers
|
||||||
CXXVER := $(shell $(CXX) -dumpversion)
|
CXXVER := $(shell $(CXX) -dumpversion)
|
||||||
ifeq ($(shell expr match $(CXX) 'clang'),5)
|
ifeq ($(shell expr match $(CXX) 'clang'),5)
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
|
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
|
else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
|
||||||
@@ -24,7 +24,7 @@ else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0
|
|||||||
else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 ubuntu
|
else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 ubuntu
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Compiler too old)
|
$(error Compiler too old)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -fPIC
|
NEEDED_CXXFLAGS += -fPIC
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS = -Os -Wall -std=c++11 -DMAC_OSX
|
CXXFLAGS = -Os -Wall -std=c++11 -DMAC_OSX
|
||||||
#CXXFLAGS = -g -O2 -Wall -std=c++11
|
#CXXFLAGS = -g -O2 -Wall -std=c++11
|
||||||
INCFLAGS = -I/usr/local/include
|
INCFLAGS = -I/usr/local/include
|
||||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
|
|||||||
47
README.md
47
README.md
@@ -3,27 +3,27 @@ i2pd
|
|||||||
|
|
||||||
[Русская версия](https://github.com/PurpleI2P/i2pd_docs_ru/blob/master/README.md)
|
[Русская версия](https://github.com/PurpleI2P/i2pd_docs_ru/blob/master/README.md)
|
||||||
|
|
||||||
i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.
|
i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.
|
||||||
|
|
||||||
I2P (Invisible Internet Protocol) is a universal anonymous network layer.
|
I2P (Invisible Internet Protocol) is a universal anonymous network layer.
|
||||||
All communications over I2P are anonymous and end-to-end encrypted, participants
|
All communications over I2P are anonymous and end-to-end encrypted, participants
|
||||||
don't reveal their real IP addresses.
|
don't reveal their real IP addresses.
|
||||||
|
|
||||||
I2P client is a software used for building and using anonymous I2P
|
I2P client is a software used for building and using anonymous I2P
|
||||||
networks. Such networks are commonly used for anonymous peer-to-peer
|
networks. Such networks are commonly used for anonymous peer-to-peer
|
||||||
applications (filesharing, cryptocurrencies) and anonymous client-server
|
applications (filesharing, cryptocurrencies) and anonymous client-server
|
||||||
applications (websites, instant messengers, chat-servers).
|
applications (websites, instant messengers, chat-servers).
|
||||||
|
|
||||||
I2P allows people from all around the world to communicate and share information
|
I2P allows people from all around the world to communicate and share information
|
||||||
without restrictions.
|
without restrictions.
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* Distributed anonymous networking framework
|
* Distributed anonymous networking framework
|
||||||
* End-to-end encrypted communications
|
* End-to-end encrypted communications
|
||||||
* Small footprint, simple dependencies, fast performance
|
* Small footprint, simple dependencies, fast performance
|
||||||
* Rich set of APIs for developers of secure applications
|
* Rich set of APIs for developers of secure applications
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
@@ -38,10 +38,10 @@ Resources
|
|||||||
Installing
|
Installing
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The easiest way to install i2pd is by using
|
The easiest way to install i2pd is by using
|
||||||
[precompiled binaries](https://github.com/PurpleI2P/i2pd/releases/latest).
|
[precompiled binaries](https://github.com/PurpleI2P/i2pd/releases/latest).
|
||||||
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
||||||
i2pd from source on your OS.
|
i2pd from source on your OS.
|
||||||
|
|
||||||
|
|
||||||
Build instructions:
|
Build instructions:
|
||||||
@@ -58,28 +58,27 @@ Build instructions:
|
|||||||
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
||||||
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* FreeBSD
|
* FreeBSD
|
||||||
* Android
|
* Android
|
||||||
* iOS
|
* iOS
|
||||||
|
|
||||||
Using i2pd
|
Using i2pd
|
||||||
----------
|
----------
|
||||||
|
|
||||||
See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and
|
See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and
|
||||||
[example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf).
|
[example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf).
|
||||||
|
|
||||||
Donations
|
Donations
|
||||||
---------
|
---------
|
||||||
|
|
||||||
BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY
|
BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
|
||||||
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
|
|
||||||
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
|
|
||||||
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
|
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
|
||||||
DOGE: DNXLQKziRPAsD9H3DFNjk4fLQrdaSX893Y
|
ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
|
||||||
ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z
|
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
|
||||||
|
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
|
||||||
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
|
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
This project is licensed under the BSD 3-clause license, which can be found in the file
|
This project is licensed under the BSD 3-clause license, which can be found in the file
|
||||||
LICENSE in the root of the project source code.
|
LICENSE in the root of the project source code.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define I2Pd_AppName "i2pd"
|
#define I2Pd_AppName "i2pd"
|
||||||
#define I2Pd_ver "2.17.0"
|
#define I2Pd_ver "2.18.0"
|
||||||
#define I2Pd_Publisher "PurpleI2P"
|
#define I2Pd_Publisher "PurpleI2P"
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.purplei2p.i2pd"
|
package="org.purplei2p.i2pd"
|
||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="2.17.0"
|
android:versionName="2.18.0"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/>
|
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<service android:enabled="true" android:name=".ForegroundService"/>
|
<service android:enabled="true" android:name=".ForegroundService"/>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
47
android/build.gradle
Normal file
47
android/build.gradle
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.1.2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 25
|
||||||
|
buildToolsVersion "25.0.2"
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "org.purplei2p.i2pd"
|
||||||
|
targetSdkVersion 25
|
||||||
|
minSdkVersion 14
|
||||||
|
versionCode 1
|
||||||
|
versionName "2.17.1"
|
||||||
|
}
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
java.srcDirs = ['src']
|
||||||
|
res.srcDirs = ['res']
|
||||||
|
jniLibs.srcDirs = ['libs']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signingConfigs {
|
||||||
|
orignal {
|
||||||
|
storeFile file("i2pdapk.jks")
|
||||||
|
storePassword "android"
|
||||||
|
keyAlias "i2pdapk"
|
||||||
|
keyPassword "android"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
signingConfig signingConfigs.orignal
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ NDK_TOOLCHAIN_VERSION := 4.9
|
|||||||
# APP_STL := stlport_shared --> does not seem to contain C++11 features
|
# APP_STL := stlport_shared --> does not seem to contain C++11 features
|
||||||
APP_STL := gnustl_shared
|
APP_STL := gnustl_shared
|
||||||
|
|
||||||
# Enable c++11 extentions in source code
|
# Enable c++11 extensions in source code
|
||||||
APP_CPPFLAGS += -std=c++11
|
APP_CPPFLAGS += -std=c++11
|
||||||
|
|
||||||
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
|
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<menu
|
<menu
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".I2PD">
|
tools:context=".I2PD">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_graceful_quit"
|
android:id="@+id/action_graceful_quit"
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ public class DaemonSingleton {
|
|||||||
public static DaemonSingleton getInstance() {
|
public static DaemonSingleton getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
||||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
||||||
|
|
||||||
public synchronized void stopAcceptingTunnels() {
|
public synchronized void stopAcceptingTunnels() {
|
||||||
if(isStartedOkay()){
|
if(isStartedOkay()){
|
||||||
state=State.gracefulShutdownInProgress;
|
state=State.gracefulShutdownInProgress;
|
||||||
@@ -25,19 +25,19 @@ public class DaemonSingleton {
|
|||||||
I2PD_JNI.stopAcceptingTunnels();
|
I2PD_JNI.stopAcceptingTunnels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNetworkStateChange(boolean isConnected) {
|
public void onNetworkStateChange(boolean isConnected) {
|
||||||
I2PD_JNI.onNetworkStateChanged(isConnected);
|
I2PD_JNI.onNetworkStateChanged(isConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean startedOkay;
|
private boolean startedOkay;
|
||||||
|
|
||||||
public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress};
|
public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress};
|
||||||
|
|
||||||
private State state = State.uninitialized;
|
private State state = State.uninitialized;
|
||||||
|
|
||||||
public State getState() { return state; }
|
public State getState() { return state; }
|
||||||
|
|
||||||
public synchronized void start() {
|
public synchronized void start() {
|
||||||
if(state != State.uninitialized)return;
|
if(state != State.uninitialized)return;
|
||||||
state = State.starting;
|
state = State.starting;
|
||||||
@@ -76,9 +76,9 @@ public class DaemonSingleton {
|
|||||||
fireStateUpdate();
|
fireStateUpdate();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, "i2pdDaemonStart").start();
|
}, "i2pdDaemonStart").start();
|
||||||
}
|
}
|
||||||
private Throwable lastThrowable;
|
private Throwable lastThrowable;
|
||||||
@@ -87,10 +87,10 @@ public class DaemonSingleton {
|
|||||||
private synchronized void fireStateUpdate() {
|
private synchronized void fireStateUpdate() {
|
||||||
Log.i(TAG, "daemon state change: "+state);
|
Log.i(TAG, "daemon state change: "+state);
|
||||||
for(StateUpdateListener listener : stateUpdateListeners) {
|
for(StateUpdateListener listener : stateUpdateListeners) {
|
||||||
try {
|
try {
|
||||||
listener.daemonStateUpdate();
|
listener.daemonStateUpdate();
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG, "exception in listener ignored", tr);
|
Log.e(TAG, "exception in listener ignored", tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ public class DaemonSingleton {
|
|||||||
public String getDaemonStartResult() {
|
public String getDaemonStartResult() {
|
||||||
return daemonStartResult;
|
return daemonStartResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Object startedOkayLock = new Object();
|
private final Object startedOkayLock = new Object();
|
||||||
|
|
||||||
public boolean isStartedOkay() {
|
public boolean isStartedOkay() {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class ForegroundService extends Service {
|
|||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
// Cancel the persistent notification.
|
// Cancel the persistent notification.
|
||||||
notificationManager.cancel(NOTIFICATION);
|
notificationManager.cancel(NOTIFICATION);
|
||||||
|
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
|
||||||
// Tell the user we stopped.
|
// Tell the user we stopped.
|
||||||
@@ -91,7 +91,7 @@ public class ForegroundService extends Service {
|
|||||||
//mNM.notify(NOTIFICATION, notification);
|
//mNM.notify(NOTIFICATION, notification);
|
||||||
startForeground(NOTIFICATION, notification);
|
startForeground(NOTIFICATION, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ public class I2PD extends Activity {
|
|||||||
private static final String TAG = "i2pd";
|
private static final String TAG = "i2pd";
|
||||||
|
|
||||||
private TextView textView;
|
private TextView textView;
|
||||||
|
|
||||||
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||||
|
|
||||||
private DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
private DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
||||||
new DaemonSingleton.StateUpdateListener() {
|
new DaemonSingleton.StateUpdateListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void daemonStateUpdate() {
|
public void daemonStateUpdate() {
|
||||||
runOnUiThread(new Runnable(){
|
runOnUiThread(new Runnable(){
|
||||||
@@ -53,7 +53,7 @@ public class I2PD extends Activity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -123,7 +123,7 @@ public class I2PD extends Activity {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private boolean mIsBound;
|
private boolean mIsBound;
|
||||||
|
|
||||||
private void doBindService() {
|
private void doBindService() {
|
||||||
@@ -147,7 +147,7 @@ public class I2PD extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
getMenuInflater().inflate(R.menu.options_main, menu);
|
getMenuInflater().inflate(R.menu.options_main, menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,9 +216,9 @@ public class I2PD extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
quit();
|
quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, 10*60*1000/*milliseconds*/);
|
}, 10*60*1000/*milliseconds*/);
|
||||||
}else{
|
}else{
|
||||||
quit();
|
quit();
|
||||||
@@ -227,7 +227,7 @@ public class I2PD extends Activity {
|
|||||||
Log.e(TAG,"",tr);
|
Log.e(TAG,"",tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},"gracQuitInit").start();
|
},"gracQuitInit").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ public class I2PD_JNI {
|
|||||||
public static native String startDaemon();
|
public static native String startDaemon();
|
||||||
//should only be called after startDaemon() success
|
//should only be called after startDaemon() success
|
||||||
public static native void stopDaemon();
|
public static native void stopDaemon();
|
||||||
|
|
||||||
public static native void stopAcceptingTunnels();
|
public static native void stopAcceptingTunnels();
|
||||||
|
|
||||||
public static native void onNetworkStateChanged(boolean isConnected);
|
public static native void onNetworkStateChanged(boolean isConnected);
|
||||||
|
|
||||||
public static void loadLibraries() {
|
public static void loadLibraries() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: 2.17.{build}
|
version: 2.18.{build}
|
||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
branches:
|
branches:
|
||||||
|
|||||||
3
build/.gitignore
vendored
3
build/.gitignore
vendored
@@ -8,6 +8,7 @@
|
|||||||
/CPackConfig.cmake
|
/CPackConfig.cmake
|
||||||
/CPackSourceConfig.cmake
|
/CPackSourceConfig.cmake
|
||||||
/install_manifest.txt
|
/install_manifest.txt
|
||||||
|
/arch.c
|
||||||
# windows build script
|
# windows build script
|
||||||
i2pd*.zip
|
i2pd*.zip
|
||||||
build*.log
|
build*.log
|
||||||
@@ -26,6 +26,10 @@ option(WITH_WEBSOCKETS "Build with websocket ui" OFF)
|
|||||||
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
||||||
set ( CMAKE_SOURCE_DIR ".." )
|
set ( CMAKE_SOURCE_DIR ".." )
|
||||||
|
|
||||||
|
# architecture
|
||||||
|
include(TargetArch)
|
||||||
|
target_architecture(ARCHITECTURE)
|
||||||
|
|
||||||
set(LIBI2PD_SRC_DIR ../libi2pd)
|
set(LIBI2PD_SRC_DIR ../libi2pd)
|
||||||
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client)
|
||||||
|
|
||||||
@@ -79,7 +83,7 @@ if (WITH_WEBSOCKETS)
|
|||||||
find_package(websocketpp REQUIRED)
|
find_package(websocketpp REQUIRED)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
|
if (WIN32 OR MSYS)
|
||||||
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
@@ -190,20 +194,14 @@ if (WITH_HARDENING AND MSVC)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# compiler flags customization (by system)
|
# compiler flags customization (by system)
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
if (UNIX)
|
||||||
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
||||||
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
if (NOT (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE))
|
||||||
add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" )
|
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" )
|
||||||
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
endif ()
|
||||||
# "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8
|
elseif (WIN32 OR MSYS)
|
||||||
add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" )
|
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp")
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
|
||||||
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
|
||||||
list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp")
|
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
|
|
||||||
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp")
|
|
||||||
if (WITH_GUI)
|
if (WITH_GUI)
|
||||||
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp")
|
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp")
|
||||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp"
|
set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp"
|
||||||
@@ -366,11 +364,13 @@ if (NOT ZLIB_FOUND )
|
|||||||
if (NOT WITH_STATIC)
|
if (NOT WITH_STATIC)
|
||||||
set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE)
|
set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE)
|
||||||
endif ()
|
endif ()
|
||||||
|
link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib)
|
||||||
|
else()
|
||||||
|
link_directories(${ZLIB_ROOT}/lib)
|
||||||
endif ()
|
endif ()
|
||||||
if (WITH_STATIC AND (MSVC OR MSYS))
|
if (WITH_STATIC AND (MSVC OR MSYS))
|
||||||
set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE)
|
set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE)
|
||||||
endif ()
|
endif ()
|
||||||
link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib ${ZLIB_ROOT}/lib)
|
|
||||||
|
|
||||||
# load includes
|
# load includes
|
||||||
include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
|
include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
|
||||||
@@ -382,6 +382,8 @@ if (WITH_MESHNET)
|
|||||||
message(WARNING "This build will NOT work on mainline i2p")
|
message(WARNING "This build will NOT work on mainline i2p")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CheckAtomic)
|
||||||
|
|
||||||
|
|
||||||
# show summary
|
# show summary
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
@@ -389,6 +391,7 @@ message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
|
|||||||
message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}")
|
message(STATUS "Compiler vendor : ${CMAKE_CXX_COMPILER_ID}")
|
||||||
message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}")
|
message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}")
|
||||||
message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}")
|
message(STATUS "Compiler path : ${CMAKE_CXX_COMPILER}")
|
||||||
|
message(STATUS "Architecture : ${ARCHITECTURE}")
|
||||||
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
|
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
|
||||||
message(STATUS "Options:")
|
message(STATUS "Options:")
|
||||||
message(STATUS " AESNI : ${WITH_AESNI}")
|
message(STATUS " AESNI : ${WITH_AESNI}")
|
||||||
@@ -448,7 +451,7 @@ if (WITH_BINARY)
|
|||||||
if (WITH_STATIC)
|
if (WITH_STATIC)
|
||||||
set(DL_LIB ${CMAKE_DL_LIBS})
|
set(DL_LIB ${CMAKE_DL_LIBS})
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB})
|
target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
||||||
set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
@@ -461,12 +464,6 @@ if (WITH_BINARY)
|
|||||||
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
|
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
|
||||||
" COMPONENT Runtime)
|
" COMPONENT Runtime)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
||||||
if (NOT (MSVC OR MSYS OR APPLE)) # for Clang build on Linux
|
|
||||||
target_link_libraries("${PROJECT_NAME}" stdc++)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
install(FILES ../LICENSE
|
install(FILES ../LICENSE
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ REM Copyright (c) 2013-2017, The PurpleI2P Project
|
|||||||
REM This file is part of Purple i2pd project and licensed under BSD3
|
REM This file is part of Purple i2pd project and licensed under BSD3
|
||||||
REM See full license text in LICENSE file at top of project tree
|
REM See full license text in LICENSE file at top of project tree
|
||||||
|
|
||||||
REM To use that script, you must have installed in your MSYS installation theese packages:
|
REM To use that script, you must have installed in your MSYS installation these packages:
|
||||||
REM Base: git make zip
|
REM Base: git make zip
|
||||||
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
|
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
|
||||||
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
||||||
@@ -58,6 +58,7 @@ pause
|
|||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
:BUILDING
|
:BUILDING
|
||||||
|
%xSH% "make clean" >> nul
|
||||||
echo Building i2pd %tag% for win%bitness%:
|
echo Building i2pd %tag% for win%bitness%:
|
||||||
echo Build AVX+AESNI...
|
echo Build AVX+AESNI...
|
||||||
%xSH% "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
|
%xSH% "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
|
||||||
|
|||||||
106
build/cmake_modules/CheckAtomic.cmake
Normal file
106
build/cmake_modules/CheckAtomic.cmake
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# atomic builtins are required for threading support.
|
||||||
|
|
||||||
|
INCLUDE(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
|
# Sometimes linking against libatomic is required for atomic ops, if
|
||||||
|
# the platform doesn't support lock-free atomics.
|
||||||
|
|
||||||
|
function(check_working_cxx_atomics varname)
|
||||||
|
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
|
||||||
|
CHECK_CXX_SOURCE_COMPILES("
|
||||||
|
#include <atomic>
|
||||||
|
std::atomic<int> x;
|
||||||
|
int main() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
" ${varname})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||||
|
endfunction(check_working_cxx_atomics)
|
||||||
|
|
||||||
|
function(check_working_cxx_atomics64 varname)
|
||||||
|
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
|
||||||
|
CHECK_CXX_SOURCE_COMPILES("
|
||||||
|
#include <atomic>
|
||||||
|
#include <cstdint>
|
||||||
|
std::atomic<uint64_t> x (0);
|
||||||
|
int main() {
|
||||||
|
uint64_t i = x.load(std::memory_order_relaxed);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
" ${varname})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||||
|
endfunction(check_working_cxx_atomics64)
|
||||||
|
|
||||||
|
|
||||||
|
# This isn't necessary on MSVC, so avoid command-line switch annoyance
|
||||||
|
# by only running on GCC-like hosts.
|
||||||
|
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||||
|
# First check if atomics work without the library.
|
||||||
|
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||||
|
# If not, check if the library exists, and atomics work with it.
|
||||||
|
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||||
|
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||||
|
if( HAVE_LIBATOMIC )
|
||||||
|
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||||
|
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
|
||||||
|
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
|
||||||
|
message(FATAL_ERROR "Host compiler must support std::atomic!")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for 64 bit atomic operations.
|
||||||
|
if(MSVC)
|
||||||
|
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
|
||||||
|
else()
|
||||||
|
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# If not, check if the library exists, and atomics work with it.
|
||||||
|
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||||
|
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||||
|
if(HAVE_CXX_LIBATOMICS64)
|
||||||
|
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||||
|
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||||
|
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||||
|
message(FATAL_ERROR "Host compiler must support std::atomic!")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## TODO: This define is only used for the legacy atomic operations in
|
||||||
|
## llvm's Atomic.h, which should be replaced. Other code simply
|
||||||
|
## assumes C++11 <atomic> works.
|
||||||
|
CHECK_CXX_SOURCE_COMPILES("
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <Intrin.h> /* Workaround for PR19898. */
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
int main() {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
volatile LONG val = 1;
|
||||||
|
MemoryBarrier();
|
||||||
|
InterlockedCompareExchange(&val, 0, 1);
|
||||||
|
InterlockedIncrement(&val);
|
||||||
|
InterlockedDecrement(&val);
|
||||||
|
#else
|
||||||
|
volatile unsigned long val = 1;
|
||||||
|
__sync_synchronize();
|
||||||
|
__sync_val_compare_and_swap(&val, 1, 0);
|
||||||
|
__sync_add_and_fetch(&val, 1);
|
||||||
|
__sync_sub_and_fetch(&val, 1);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
" LLVM_HAS_ATOMICS)
|
||||||
|
|
||||||
|
if( NOT LLVM_HAS_ATOMICS )
|
||||||
|
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
|
||||||
|
endif()
|
||||||
@@ -24,5 +24,5 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY)
|
mark_as_advanced(MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
134
build/cmake_modules/TargetArch.cmake
Normal file
134
build/cmake_modules/TargetArch.cmake
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# Based on the Qt 5 processor detection code, so should be very accurate
|
||||||
|
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
|
||||||
|
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
|
||||||
|
|
||||||
|
# Regarding POWER/PowerPC, just as is noted in the Qt source,
|
||||||
|
# "There are many more known variants/revisions that we do not handle/detect."
|
||||||
|
|
||||||
|
set(archdetect_c_code "
|
||||||
|
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
|
||||||
|
#if defined(__ARM_ARCH_7__) \\
|
||||||
|
|| defined(__ARM_ARCH_7A__) \\
|
||||||
|
|| defined(__ARM_ARCH_7R__) \\
|
||||||
|
|| defined(__ARM_ARCH_7M__) \\
|
||||||
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
|
||||||
|
#error cmake_ARCH armv7
|
||||||
|
#elif defined(__ARM_ARCH_6__) \\
|
||||||
|
|| defined(__ARM_ARCH_6J__) \\
|
||||||
|
|| defined(__ARM_ARCH_6T2__) \\
|
||||||
|
|| defined(__ARM_ARCH_6Z__) \\
|
||||||
|
|| defined(__ARM_ARCH_6K__) \\
|
||||||
|
|| defined(__ARM_ARCH_6ZK__) \\
|
||||||
|
|| defined(__ARM_ARCH_6M__) \\
|
||||||
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
|
||||||
|
#error cmake_ARCH armv6
|
||||||
|
#elif defined(__ARM_ARCH_5TEJ__) \\
|
||||||
|
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
|
||||||
|
#error cmake_ARCH armv5
|
||||||
|
#else
|
||||||
|
#error cmake_ARCH arm
|
||||||
|
#endif
|
||||||
|
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||||
|
#error cmake_ARCH i386
|
||||||
|
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||||
|
#error cmake_ARCH x86_64
|
||||||
|
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||||
|
#error cmake_ARCH ia64
|
||||||
|
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|
||||||
|
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|
||||||
|
|| defined(_M_MPPC) || defined(_M_PPC)
|
||||||
|
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||||
|
#error cmake_ARCH ppc64
|
||||||
|
#else
|
||||||
|
#error cmake_ARCH ppc
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#error cmake_ARCH unknown
|
||||||
|
")
|
||||||
|
|
||||||
|
# Set ppc_support to TRUE before including this file or ppc and ppc64
|
||||||
|
# will be treated as invalid architectures since they are no longer supported by Apple
|
||||||
|
|
||||||
|
function(target_architecture output_var)
|
||||||
|
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||||
|
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
|
||||||
|
# First let's normalize the order of the values
|
||||||
|
|
||||||
|
# Note that it's not possible to compile PowerPC applications if you are using
|
||||||
|
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
|
||||||
|
# disable it by default
|
||||||
|
# See this page for more information:
|
||||||
|
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
|
||||||
|
|
||||||
|
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
|
||||||
|
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
|
||||||
|
|
||||||
|
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||||
|
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
|
||||||
|
set(osx_arch_ppc TRUE)
|
||||||
|
elseif("${osx_arch}" STREQUAL "i386")
|
||||||
|
set(osx_arch_i386 TRUE)
|
||||||
|
elseif("${osx_arch}" STREQUAL "x86_64")
|
||||||
|
set(osx_arch_x86_64 TRUE)
|
||||||
|
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
|
||||||
|
set(osx_arch_ppc64 TRUE)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Now add all the architectures in our normalized order
|
||||||
|
if(osx_arch_ppc)
|
||||||
|
list(APPEND ARCH ppc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(osx_arch_i386)
|
||||||
|
list(APPEND ARCH i386)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(osx_arch_x86_64)
|
||||||
|
list(APPEND ARCH x86_64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(osx_arch_ppc64)
|
||||||
|
list(APPEND ARCH ppc64)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
|
||||||
|
|
||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
# Detect the architecture in a rather creative way...
|
||||||
|
# This compiles a small C program which is a series of ifdefs that selects a
|
||||||
|
# particular #error preprocessor directive whose message string contains the
|
||||||
|
# target architecture. The program will always fail to compile (both because
|
||||||
|
# file is not a valid C program, and obviously because of the presence of the
|
||||||
|
# #error preprocessor directives... but by exploiting the preprocessor in this
|
||||||
|
# way, we can detect the correct target architecture even when cross-compiling,
|
||||||
|
# since the program itself never needs to be run (only the compiler/preprocessor)
|
||||||
|
try_run(
|
||||||
|
run_result_unused
|
||||||
|
compile_result_unused
|
||||||
|
"${CMAKE_BINARY_DIR}"
|
||||||
|
"${CMAKE_BINARY_DIR}/arch.c"
|
||||||
|
COMPILE_OUTPUT_VARIABLE ARCH
|
||||||
|
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Parse the architecture name from the compiler output
|
||||||
|
string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
|
||||||
|
|
||||||
|
# Get rid of the value marker leaving just the architecture name
|
||||||
|
string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
|
||||||
|
|
||||||
|
# If we are compiling with an unknown architecture this variable should
|
||||||
|
# already be set to "unknown" but in the case that it's empty (i.e. due
|
||||||
|
# to a typo in the code), then set it to unknown
|
||||||
|
if (NOT ARCH)
|
||||||
|
set(ARCH unknown)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${output_var} "${ARCH}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
@@ -28,7 +28,7 @@ Options are set via docker environment variables. This can be set at run with -e
|
|||||||
|
|
||||||
**Logging**
|
**Logging**
|
||||||
|
|
||||||
Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automaticly forward the log to say, kibana or greylog without manual setup. :)
|
Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \
|
|||||||
libssl-dev git build-essential
|
libssl-dev git build-essential
|
||||||
|
|
||||||
RUN git clone https://github.com/PurpleI2P/i2pd.git
|
RUN git clone https://github.com/PurpleI2P/i2pd.git
|
||||||
WORKDIR /i2pd
|
WORKDIR /i2pd
|
||||||
RUN make
|
RUN make
|
||||||
|
|
||||||
CMD ./i2pd
|
CMD ./i2pd
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Basic profile for i2pd
|
# Basic profile for i2pd
|
||||||
# Should work without modifications with Ubuntu/Debian packages
|
# Should work without modifications with Ubuntu/Debian packages
|
||||||
# Author: Darknet Villain <supervillain@riseup.net>
|
# Author: Darknet Villain <supervillain@riseup.net>
|
||||||
#
|
#
|
||||||
@@ -21,10 +21,14 @@
|
|||||||
|
|
||||||
# path specific (feel free to modify if you have another paths)
|
# path specific (feel free to modify if you have another paths)
|
||||||
/etc/i2pd/** r,
|
/etc/i2pd/** r,
|
||||||
|
/run/i2pd/i2pd.pid rw,
|
||||||
/var/lib/i2pd/** rw,
|
/var/lib/i2pd/** rw,
|
||||||
/var/log/i2pd.log w,
|
/var/log/i2pd/i2pd.log w,
|
||||||
/var/run/i2pd/i2pd.pid rw,
|
/var/run/i2pd/i2pd.pid rw,
|
||||||
/usr/sbin/i2pd mr,
|
/usr/sbin/i2pd mr,
|
||||||
|
/usr/share/i2pd/** r,
|
||||||
|
|
||||||
|
# user homedir (if started not by init.d or systemd)
|
||||||
|
owner @{HOME}/.i2pd/ rw,
|
||||||
|
owner @{HOME}/.i2pd/** rwk,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFxzCCA6+gAwIBAgIQZfqn0yiJL3dGgCjeOeWS6DANBgkqhkiG9w0BAQsFADBw
|
|
||||||
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
|
||||||
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQ
|
|
||||||
aG90dHVuYUBtYWlsLmkycDAeFw0xNjExMDkwMzE1MzJaFw0yNjExMDkwMzE1MzJa
|
|
||||||
MHAxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNV
|
|
||||||
BAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQD
|
|
||||||
DBBob3R0dW5hQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
|
|
||||||
AgEA21Bfgcc9VVH4l2u1YvYlTw2OPUyQb16X2IOW0PzdsUO5W78Loueu974BkiKi
|
|
||||||
84lQZanLr0OwEopdfutGc6gegSLmwaWx5YCG5uwpLOPkDiObfX+nptH6As/B1cn+
|
|
||||||
mzejYdVKRnWd7EtHW0iseSsILBK1YbGw4AGpXJ8k18DJSzUt2+spOkpBW6XqectN
|
|
||||||
8y2JDSTns8yiNxietVeRN/clolDXT9ZwWHkd+QMHTKhgl3Uz1knOffU0L9l4ij4E
|
|
||||||
oFgPfQo8NL63kLM24hF1hM/At7XvE4iOlObFwPXE+H5EGZpT5+A7Oezepvd/VMzM
|
|
||||||
tCJ49hM0OlR393tKFONye5GCYeSDJGdPEB6+rBptpRrlch63tG9ktpCRrg2wQWgC
|
|
||||||
e3aOE1xVRrmwiTZ+jpfsOCbZrrSA/C4Bmp6AfGchyHuDGGkRU/FJwa1YLJe0dkWG
|
|
||||||
ITLWeh4zeVuAS5mctdv9NQ5wflSGz9S8HjsPBS5+CDOFHh4cexXRG3ITfk6aLhuY
|
|
||||||
KTMlkIO4SHKmnwAvy1sFlsqj6PbfVjpHPLg625fdNxBpe57TLxtIdBB3C7ccQSRW
|
|
||||||
+UG6Cmbcmh80PbsSR132NLMlzLhbaOjxeCWWJRo6cLuHBptAFMNwqsXt8xVf9M0N
|
|
||||||
NdJoKUmblyvjnq0N8aMEqtQ1uGMTaCB39cutHQq+reD/uzsCAwEAAaNdMFswDgYD
|
|
||||||
VR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNV
|
|
||||||
HRMBAf8EBTADAQH/MBkGA1UdDgQSBBBob3R0dW5hQG1haWwuaTJwMA0GCSqGSIb3
|
|
||||||
DQEBCwUAA4ICAQCibFV8t4pajP176u3jx31x1kgqX6Nd+0YFARPZQjq99kUyoZer
|
|
||||||
GyHGsMWgM281RxiZkveHxR7Hm7pEd1nkhG3rm+d7GdJ2p2hujr9xUvl0zEqAAqtm
|
|
||||||
lkYI6uJ13WBjFc9/QuRIdeIeSUN+eazSXNg2nJhoV4pF9n2Q2xDc9dH4GWO93cMX
|
|
||||||
JPKVGujT3s0b7LWsEguZBPdaPW7wwZd902Cg/M5fE1hZQ8/SIAGUtylb/ZilVeTS
|
|
||||||
spxWP1gX3NT1SSvv0s6oL7eADCgtggWaMxEjZhi6WMnPUeeFY8X+6trkTlnF9+r/
|
|
||||||
HiVvvzQKrPPtB3j1xfQCAF6gUKN4iY+2AOExv4rl/l+JJbPhpd/FuvD8AVkLMZ8X
|
|
||||||
uPe0Ew2xv30cc8JjGDzQvoSpBmVTra4f+xqH+w8UEmxnx97Ye2aUCtnPykACnFte
|
|
||||||
oT97K5052B1zq+4fu4xaHZnEzPYVK5POzOufNLPgciJsWrR5GDWtHd+ht/ZD37+b
|
|
||||||
+j1BXpeBWUBQgluFv+lNMVNPJxc2OMELR1EtEwXD7mTuuUEtF5Pi63IerQ5LzD3G
|
|
||||||
KBvXhMB0XhpE6WG6pBwAvkGf5zVv/CxClJH4BQbdZwj9HYddfEQlPl0z/XFR2M0+
|
|
||||||
9/8nBfGSPYIt6KeHBCeyQWTdE9gqSzMwTMFsennXmaT8gyc7eKqKF6adqw==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFhTCCA22gAwIBAgIELuRWgDANBgkqhkiG9w0BAQ0FADBzMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEcMBoGA1UEAwwTa2lsbHlvdXJ0dkBt
|
|
||||||
YWlsLmkycDAeFw0xMzEwMDYyMTM5MzFaFw0yMzEwMDYyMTM5MzFaMHMxCzAJBgNV
|
|
||||||
BAYTAlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBB
|
|
||||||
bm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRwwGgYDVQQDDBNraWxseW91
|
|
||||||
cnR2QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAig3u
|
|
||||||
niLWm0y/TFJtciHgmWUt20FOdQrxkiSZ87G8xjuGfq7TbGIiVDn7pQZcHidpq+Dk
|
|
||||||
47sm+Swqhb4psSijj0AXUEVKlV39jF5IZE+VUgmEtMqQbnBkWudaTJPWcEe9T/Kd
|
|
||||||
8Oz2jgsnrD/EGVTMKBBjt/gk8VqTWvpCdCF1GhqcCeUTFHzjhN9jtoRCaJ2DClpO
|
|
||||||
Px+86+d3s9PqUFo8gcD/dbbyJCMqUCMBLtIy/Ooouxb9cfWtXfyOlphU+enmdvuA
|
|
||||||
0BDewb9pOJg2/kVd9/9moDWcBGChLOlfSlxpDwyUtcclcpvwnG7c6o4or6gqLeOf
|
|
||||||
AbCpse623utV7fWlFWG7M4AQ/2emhhe4YoMJQnflydzV8bPRJxRTeW1j/9UfpvLT
|
|
||||||
nO5LHp0oBXE0GqAPjxuAr+r5IDXFbkKYNjK5oWQB/Ul3LkexulYdCzHWbGd1Ja5b
|
|
||||||
sbiOy6t/hH6G8DD75HYb+PQZaNZWBv90EyOq1JDSUPw6nxVbhiBldi3ipc8/1X51
|
|
||||||
FbzBqJ+QO1XKrKqxWxBKoTekuy38KRzsmkSCpY+WJ9f0gLOKtxzVO2HNNqqVFGQf
|
|
||||||
RGIbrNA0JSRQ1fgelccfrcRIXIZ3B8Tk/wxCIzCY6Yvg2jezz2xJkVdqOUsznS2v
|
|
||||||
+xJe67PYIAeMVtcfO4kmuCvyIYhsUEpob2n/5lkCAwEAAaMhMB8wHQYDVR0OBBYE
|
|
||||||
FCLneov6QMtvra5FSoSLhdymi++rMA0GCSqGSIb3DQEBDQUAA4ICAQAIcqbiwjdQ
|
|
||||||
M9VlGBiHe5eVsL6OM9zfRqR1wnRg4Q6ce65XDfEOYleBWaaNJA4BdykcA4fkUN1h
|
|
||||||
M2D9FDQScsyPTOuzJ6o75TYh0JOtF51yCi9iuemcosxAwsm90ZXGuMDfDYeyND5c
|
|
||||||
PAkWfyCP+jwLYbNo/hkNqyv+XWHXPQmT2adRnPXINVUQuBxVPC//C9wv2uDYWhgS
|
|
||||||
f8M425VPp4/R/uks9mlzTx08DwacvouD0YOC+HZE4sWq+2smgeBInMiyr/THYzl+
|
|
||||||
baMtYgVs8IKUD2gtjfXZoaQNg3eq5SedSf/5F0S/LCdu9/ccQ8CzSEoVTiQFtO78
|
|
||||||
SaU37xai8+QTSVpPuINigxCoXmkubBd+voEmWRcBd/XB5L+u+MFU/jXyyBj2BXVj
|
|
||||||
6agqVzY53KVYt23/63QliAUWyxT+ns9gRxVN1jrMhHdiDwsdT4NbzHxg1Su4eiHv
|
|
||||||
C/wjD3Dga0BRTEGylpHZGzb1U1rZRHM3ho3f1QkmRPPLcBUMTyUTxJm+GEeuhPvp
|
|
||||||
+TBf3Kg/YkdpnEMlagqcyHuIrf3m8Z/pTmpOIbekJWbbA7tluvWbMWw2ARB7dUOE
|
|
||||||
fHYVISh0DTw2oVXxM82/q8XXHnhEXv2nW3K40x1VabxUN+sF4M/7YA8nJqwsPJei
|
|
||||||
749STYJRfZXdIe69M9zpM5unxENAsiPJgQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFezCCA2OgAwIBAgIEHLJfZzANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOc3RyNGRAbWFpbC5p
|
|
||||||
MnAwHhcNMTMxMDI2MTExODQxWhcNMjMxMDI2MTExODQxWjBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOc3RyNGRAbWFpbC5p
|
|
||||||
MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvw0vTay1IPOgxvwe8
|
|
||||||
yt5jGakha20kw9qDb6zbEL87EWEkeOzdu7iUC69lkxVP9Ws8EbLtkeMf/CXg6CC1
|
|
||||||
e+w8WpOHj5prOsiOlrIO+2I1tKMaMUuJDX2wK4I5ZSw/Kieimh9xqOBZknDmtwjw
|
|
||||||
2HPW8rpxMqrScaGAP6sQD8Gh4XKKkLogfxYPzF8NnC6O8vBkFKVU2WSVZ0jPAQfv
|
|
||||||
6luPdA+5lES+5UPWr9Yhv/CX4siGKUTxchqJRf2VU4o5BzzXae4asVA/NY7lKgEw
|
|
||||||
eDDufbm0mRFWP4mbmXRlODuJ8GMnJbMQkNcAvZUnUcvpSTnGnIvxyxtXP5P6ic8V
|
|
||||||
3b9HV2eIsbfO1xrgyr6/9qgGpXcdDJejhvNg6fZgQeO40bOGQYwV8bNvsNQHqnZl
|
|
||||||
KsVhsMQkOubMxcHTBadcifi8PmdeJ5hxyyqJmyrwkmg2ijnN521M6YkoBzl+8VAi
|
|
||||||
zLmqKZfvN5t+pb9PZ3U3jHfkeIEwDRYRAOsvVqch5+ZfSv8x/Te6o15zDKPJQtWK
|
|
||||||
ty42GV1vERw30oSZQdrRRy/+4+HSRs3/Zb368OdAbcr+f/xPvwceYGWPeNNIoZ/x
|
|
||||||
xkIQE3xgEK+eJyPM9McjlCAezZZclT7fWfiEYNJAiS3fGALi+a+cGYWWULxCXpz+
|
|
||||||
y397OHhZBhnh7D9K8aPePB8tCwIDAQABoyEwHzAdBgNVHQ4EFgQUezvGHq3h1gbC
|
|
||||||
Hs2LLVoll5fIUWMwDQYJKoZIhvcNAQENBQADggIBAF7SG1WBcE1r5eyTp/BLFZfG
|
|
||||||
iPtvqu+B1L2HutPum/Xf8A5fxR4kcKAKpVdu6vnDzCRAsAC9YvyETgAzI2nfVgLk
|
|
||||||
l9YZ31tSi6qxnMsQsV5o9lt/q2Rvsf2Zi/Ir8AlWtvnP8YG0Aj/8AG8MyhMLaIdj
|
|
||||||
M2FuakPs8RqEjoJL9dTOC9VTQpNTwBH9guP9UalWYwlkaXDzMoyO4nswT/GpCpg8
|
|
||||||
4m4RO6grzdsEIamD/PCBM5f/vq+y08GaqfXpX9+8CbaX3tdzd3x48wPphmdpkptk
|
|
||||||
aRELIpLJZiK+Mos7W+0ZS8SHxGDIosjqVsgbZPmk12+VBcVgLOr8W1D7osS4OY59
|
|
||||||
2GMUVV/GhoDh8wR/Td5wpZlcPE0NWmljjVg9+1E8ePAyMZy+U1KCiMlRVdRy518O
|
|
||||||
dOzzUUQGqGQHosRrH0ypS3MGbMLmbuWFRiz7q/3mUmW2xikH9I1t/6ZMNUvh+IWL
|
|
||||||
kGAaEf2JIv/D8+QsC0Un1W09DgvYz7qmKSeHhBixlLe68vgXtz/Fa+rRMsmPrueo
|
|
||||||
4wk/u/VyILo0BJP860APJMZbm+DPfGhV9DF9L5Gx9+d/BlduBVGHc+AQSWbU70dS
|
|
||||||
eH4/rgUYRikWlgwUxjY8/QQTlfx5xl28tG0xdO9libN22z7UwTGfm48BQIdrTyER
|
|
||||||
hqQ7usTy3oaWD85MbJ0q
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFdzCCA1+gAwIBAgIEcwrwsjANBgkqhkiG9w0BAQ0FADBsMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
|
||||||
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEVMBMGA1UEAwwMenp6QG1haWwuaTJw
|
|
||||||
MB4XDTEzMDkzMDE3NDEyNVoXDTIzMDkzMDE3NDEyNVowbDELMAkGA1UEBhMCWFgx
|
|
||||||
CzAJBgNVBAgTAlhYMQswCQYDVQQHEwJYWDEeMBwGA1UEChMVSTJQIEFub255bW91
|
|
||||||
cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxFTATBgNVBAMMDHp6ekBtYWlsLmkycDCC
|
|
||||||
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJV4ptvhlfrcize9/ARz4lUy
|
|
||||||
iLtLMSvSST1BdZjLJTwus05EUs0oiqnv9qXYIWGRB97aKlAmqSxsn4ZgBttCgmev
|
|
||||||
IkuiZ8kbdqI5YaT98yKW5P2Prt9p9cPbnz5/qjwZ5L9W+k/Itx7bv2pkNEP0NLYo
|
|
||||||
NrgHHTb1hsyRxc0lfPYk2BwsIi8hIWBHNrRpR41EWFXfqPcdsxS8cQhxVj4zLG/R
|
|
||||||
aMm4H8T+V1R1Khl4R4qqRgXBP305xqqRoawHmZ/S9/RkF0Ji6IYwBq9iWthWol6W
|
|
||||||
sMDn1xhZk9765fk+ohAC2XWuGSFCr02JOILRV3x/8OUxT1GYgYjc7FfyWIekg/pZ
|
|
||||||
yotlhL2I3SMWOH3PdG58iDY121hq/LsSKM9aP20rwtvssnw+8Aex01YDkI3bM6yO
|
|
||||||
HNi+tRojaJcJciBWv6cuiFKvQdxj/mOhOr0u0lHLlJ4jqES8uvVJkS7X/C4BB7ra
|
|
||||||
bJYQgumZMYvVQJFIjo8vZxMXue53o65FRidvAUT29ay54UTiL7jRV9w1wHnzLapU
|
|
||||||
xT1v7kWpWJcZ1zzC8coJjW+6ijkk38cVLb80u1Q4kEbmP2rDxw6jRvmqg6DcCKjK
|
|
||||||
oqDt+XQ6P5grxAxLT+VMfB404WHHwNs6BB841//4ZnXvy3msMONY/5y0fsblURgh
|
|
||||||
IS2UG1TAjR+x7+XikGx9AgMBAAGjITAfMB0GA1UdDgQWBBSvx/fCCP8UeHwjN65p
|
|
||||||
EoHjgRfiIzANBgkqhkiG9w0BAQ0FAAOCAgEAYgVE1Aa/Ok5k+Jvujbx72bktRWXo
|
|
||||||
Y4UfbWH/426VdgqXt3n9XtJUNM2oI4ODwITM4O15SyXQTLJhnvJz5ELcJV8nqviZ
|
|
||||||
RjK2HNX1BW7IEta3tacCvVnjzZ265kCT59uW+qmd+5PiaAYI5lYUn8P6pe+6neSa
|
|
||||||
HW6ecXCrdxJetSYfUUuKeV6YHpdzfjtZClLmwl91sJUBKcjK+Q9G/cE6HnwcDH1s
|
|
||||||
uXr7SgkBt/qc/OlNuu4fnTqUA58TAumdq9cD+eLBilDFrux1HsUZMuBUp64x5oPi
|
|
||||||
gme+3VewsczfFEtrxaG6+l6UA40Lerdx9XECZcDCcFsK6MS1uQ2HYjsyZcWnNT3l
|
|
||||||
6eDNUbjrllwxDdRAk0cbWiMuc21CFq/1v2QMXk88EiBjEajqzyXUPmKzwFhit6pr
|
|
||||||
5kfjfXNq+pxQSCoaqjpzVKjb3CqMhSlC8cLgrPw6HEgGnjCy4cTLFHlVmD64M778
|
|
||||||
tj6rE7CntcmUi8GKmZKyaMyUo3QQUcrjO5IQ4+3iGUgMkZuujyjrZiOJbvircPmK
|
|
||||||
4IQEXzJ/G00upqtqKstRybaWSbJ/k6iuturtA2n8MJiCBjhLy8dtTgDbFaDaNF7F
|
|
||||||
NHeqQjIJDLhYDy6mi4gya3A0ort777Inl/rWYLo067pYM+EWDw66GdpbEIB0Bp71
|
|
||||||
pwvcQcjIzbUzEK0=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -8,18 +8,18 @@ Group=i2pd
|
|||||||
RuntimeDirectory=i2pd
|
RuntimeDirectory=i2pd
|
||||||
RuntimeDirectoryMode=0700
|
RuntimeDirectoryMode=0700
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
PIDFile=/var/run/i2pd/i2pd.pid
|
PIDFile=/var/run/i2pd/i2pd.pid
|
||||||
### Uncomment, if auto restart needed
|
### Uncomment, if auto restart needed
|
||||||
#Restart=on-failure
|
#Restart=on-failure
|
||||||
|
|
||||||
### Use SIGINT for gracefull stop daemon.
|
### Use SIGINT for graceful stop daemon.
|
||||||
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
|
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
|
||||||
KillSignal=SIGINT
|
KillSignal=SIGINT
|
||||||
TimeoutStopSec=10m
|
TimeoutStopSec=10m
|
||||||
|
|
||||||
# If you have problems with hunging i2pd, you can try enable this
|
# If you have problems with hanging i2pd, you can try enable this
|
||||||
#LimitNOFILE=4096
|
#LimitNOFILE=4096
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
|
|||||||
&& chown -R i2pd:nobody "$I2PD_HOME"
|
&& chown -R i2pd:nobody "$I2PD_HOME"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
||||||
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
|
# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
|
||||||
#
|
#
|
||||||
|
|
||||||
# 1. install deps, clone and build.
|
# 1. install deps, clone and build.
|
||||||
# 2. strip binaries.
|
# 2. strip binaries.
|
||||||
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
||||||
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
|
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
|
||||||
&& mkdir -p /tmp/build \
|
&& mkdir -p /tmp/build \
|
||||||
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
|
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
|
||||||
@@ -35,7 +35,7 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boos
|
|||||||
&& mv i2pd /usr/local/bin \
|
&& mv i2pd /usr/local/bin \
|
||||||
&& cd /usr/local/bin \
|
&& cd /usr/local/bin \
|
||||||
&& strip i2pd \
|
&& strip i2pd \
|
||||||
&& rm -fr /tmp/build && apk --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
|
&& rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
|
||||||
boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \
|
boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \
|
||||||
boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \
|
boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \
|
||||||
libtool g++ gcc pkgconfig
|
libtool g++ gcc pkgconfig
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ ipv4 = true
|
|||||||
ipv6 = false
|
ipv6 = false
|
||||||
|
|
||||||
## Network interface to bind to
|
## Network interface to bind to
|
||||||
# ifname =
|
# ifname =
|
||||||
|
|
||||||
## Enable NTCP transport (default = true)
|
## Enable NTCP transport (default = true)
|
||||||
# ntcp = true
|
# ntcp = true
|
||||||
@@ -88,18 +88,18 @@ ipv6 = false
|
|||||||
|
|
||||||
[upnp]
|
[upnp]
|
||||||
## Enable or disable UPnP: automatic port forwarding (enabled by default in WINDOWS, ANDROID)
|
## Enable or disable UPnP: automatic port forwarding (enabled by default in WINDOWS, ANDROID)
|
||||||
# enabled = false
|
# enabled = false
|
||||||
|
|
||||||
## Name i2pd appears in UPnP forwardings list (default = I2Pd)
|
## Name i2pd appears in UPnP forwardings list (default = I2Pd)
|
||||||
# name = I2Pd
|
# name = I2Pd
|
||||||
|
|
||||||
[reseed]
|
[reseed]
|
||||||
## Enable or disable reseed data verification.
|
## Enable or disable reseed data verification.
|
||||||
verify = true
|
verify = true
|
||||||
## URLs to request reseed data from, separated by comma
|
## URLs to request reseed data from, separated by comma
|
||||||
## Default: "mainline" I2P Network reseeds
|
## Default: "mainline" I2P Network reseeds
|
||||||
# urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/
|
# urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/
|
||||||
## Path to local reseed data file (.su3) for manual reseeding
|
## Path to local reseed data file (.su3) for manual reseeding
|
||||||
# file = /path/to/i2pseeds.su3
|
# file = /path/to/i2pseeds.su3
|
||||||
## or HTTPS URL to reseed from
|
## or HTTPS URL to reseed from
|
||||||
# file = https://legit-website.com/i2pseeds.su3
|
# file = https://legit-website.com/i2pseeds.su3
|
||||||
|
|||||||
@@ -1,16 +1,27 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=I2P router
|
Description=I2P Router written in C++
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=i2pd
|
User=i2pd
|
||||||
Group=i2pd
|
Group=i2pd
|
||||||
|
RuntimeDirectory=i2pd
|
||||||
|
RuntimeDirectoryMode=0700
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/i2pd --service
|
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
||||||
PIDFile=/var/lib/i2pd/i2pd.pid
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
Restart=always
|
PIDFile=/var/run/i2pd/i2pd.pid
|
||||||
PrivateTmp=true
|
### Uncomment, if auto restart needed
|
||||||
|
#Restart=on-failure
|
||||||
|
|
||||||
|
### Use SIGINT for graceful stop daemon.
|
||||||
|
# i2pd stops accepting new tunnels and waits ~10 min while old ones do not die.
|
||||||
|
KillSignal=SIGINT
|
||||||
|
TimeoutStopSec=10m
|
||||||
|
|
||||||
|
# If you have problems with hunging i2pd, you can try enable this
|
||||||
|
#LimitNOFILE=4096
|
||||||
|
PrivateDevices=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
%define build_timestamp %(date +"%Y%m%d")
|
%define build_timestamp %(date +"%Y%m%d")
|
||||||
|
|
||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.17.0
|
Version: 2.18.0
|
||||||
Release: %{build_timestamp}git%{?dist}
|
Release: %{build_timestamp}git%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
|
Obsoletes: %{name}-systemd
|
||||||
|
|
||||||
License: BSD
|
License: BSD
|
||||||
URL: https://github.com/PurpleI2P/i2pd
|
URL: https://github.com/PurpleI2P/i2pd
|
||||||
@@ -23,32 +24,19 @@ BuildRequires: openssl-devel
|
|||||||
BuildRequires: miniupnpc-devel
|
BuildRequires: miniupnpc-devel
|
||||||
BuildRequires: systemd-units
|
BuildRequires: systemd-units
|
||||||
|
|
||||||
%description
|
|
||||||
C++ implementation of I2P.
|
|
||||||
|
|
||||||
|
|
||||||
%package systemd
|
|
||||||
Summary: Files to run I2P router under systemd
|
|
||||||
Requires: i2pd
|
|
||||||
Requires: systemd
|
Requires: systemd
|
||||||
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
|
Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd
|
||||||
Obsoletes: %{name}-daemon
|
|
||||||
|
|
||||||
|
%description
|
||||||
%description systemd
|
|
||||||
C++ implementation of I2P.
|
C++ implementation of I2P.
|
||||||
|
|
||||||
This package contains systemd unit file to run i2pd as a system service
|
|
||||||
using dedicated user's permissions.
|
|
||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
cd build
|
cd build
|
||||||
%if 0%{?rhel} == 7
|
%if 0%{?rhel} == 7
|
||||||
%cmake3 \
|
%cmake3 \
|
||||||
-DWITH_LIBRARY=OFF \
|
-DWITH_LIBRARY=OFF \
|
||||||
-DWITH_UPNP=ON \
|
-DWITH_UPNP=ON \
|
||||||
@@ -68,114 +56,76 @@ make %{?_smp_mflags}
|
|||||||
%install
|
%install
|
||||||
cd build
|
cd build
|
||||||
chrpath -d i2pd
|
chrpath -d i2pd
|
||||||
install -D -m 755 i2pd %{buildroot}%{_bindir}/i2pd
|
install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
|
||||||
|
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
||||||
|
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
||||||
|
install -d -m 755 %{buildroot}/%{_datadir}/i2pd
|
||||||
|
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
||||||
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}/%{_unitdir}/i2pd.service
|
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}/%{_unitdir}/i2pd.service
|
||||||
install -d -m 700 %{buildroot}/%{_sharedstatedir}/i2pd
|
install -d -m 700 %{buildroot}/%{_sharedstatedir}/i2pd
|
||||||
|
install -d -m 700 %{buildroot}/%{_localstatedir}/log/i2pd
|
||||||
|
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/%{name}/certificates
|
||||||
|
|
||||||
|
|
||||||
%pre systemd
|
%pre
|
||||||
getent group i2pd >/dev/null || %{_sbindir}/groupadd -r i2pd
|
getent group i2pd >/dev/null || %{_sbindir}/groupadd -r i2pd
|
||||||
getent passwd i2pd >/dev/null || \
|
getent passwd i2pd >/dev/null || \
|
||||||
%{_sbindir}/useradd -r -g i2pd -s %{_sbindir}/nologin \
|
%{_sbindir}/useradd -r -g i2pd -s %{_sbindir}/nologin \
|
||||||
-d %{_sharedstatedir}/i2pd -c 'I2P Service' i2pd
|
-d %{_sharedstatedir}/i2pd -c 'I2P Service' i2pd
|
||||||
|
|
||||||
|
|
||||||
%post systemd
|
%post
|
||||||
%systemd_post i2pd.service
|
%systemd_post i2pd.service
|
||||||
|
|
||||||
|
|
||||||
%preun systemd
|
%preun
|
||||||
%systemd_preun i2pd.service
|
%systemd_preun i2pd.service
|
||||||
|
|
||||||
|
|
||||||
%postun systemd
|
%postun
|
||||||
%systemd_postun_with_restart i2pd.service
|
%systemd_postun_with_restart i2pd.service
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%doc LICENSE README.md
|
%doc LICENSE README.md
|
||||||
%_bindir/i2pd
|
%{_sbindir}/i2pd
|
||||||
|
%{_datadir}/i2pd/certificates
|
||||||
|
%config(noreplace) %{_sysconfdir}/i2pd/*
|
||||||
%files systemd
|
/%{_unitdir}/i2pd.service
|
||||||
/%_unitdir/i2pd.service
|
%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
|
||||||
%dir %attr(0700,i2pd,i2pd) %_sharedstatedir/i2pd
|
%dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
|
||||||
|
%{_sharedstatedir}/i2pd/certificates
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 30 2018 orignal <i2porignal@yandex.ru>> - 2.18.0
|
||||||
|
- update to 2.18.0
|
||||||
|
|
||||||
|
* Sat Jan 27 2018 l-n-s <supervillain@riseup.net> - 2.17.0-1
|
||||||
|
- Added certificates and default configuration files
|
||||||
|
- Merge i2pd with i2pd-systemd package
|
||||||
|
- Fixed package changelogs to comply with guidelines
|
||||||
|
|
||||||
* Mon Dec 04 2017 orignal <i2porignal@yandex.ru> - 2.17.0
|
* Mon Dec 04 2017 orignal <i2porignal@yandex.ru> - 2.17.0
|
||||||
- Added reseed through HTTP and SOCKS proxy
|
- update to 2.17.0
|
||||||
- Added show status of client services through web console
|
|
||||||
- Added change log level through web connsole
|
|
||||||
- Added transient keys for tunnels
|
|
||||||
- Added i2p.streaming.initialAckDelay parameter
|
|
||||||
- Added CRYPTO_TYPE for SAM destination
|
|
||||||
- Added signature and crypto type for newkeys BOB command
|
|
||||||
- Changed - correct publication of ECIES destinations
|
|
||||||
- Changed - disable RSA signatures completely
|
|
||||||
- Fixed CVE-2017-17066
|
|
||||||
- Fixed possible buffer overflow for RSA-4096
|
|
||||||
- Fixed shutdown from web console for Windows
|
|
||||||
- Fixed web console page layout
|
|
||||||
|
|
||||||
* Mon Nov 13 2017 orignal <i2porignal@yandex.ru> - 2.16.0
|
* Mon Nov 13 2017 orignal <i2porignal@yandex.ru> - 2.16.0
|
||||||
- Added https and "Connect" method for HTTP proxy
|
- update to 2.16.0
|
||||||
- Added outproxy for HTTP proxy
|
|
||||||
- Added initial support of ECIES crypto
|
|
||||||
- Added NTCP soft and hard descriptors limits
|
|
||||||
- Added support full timestamps in logs
|
|
||||||
- Changed faster implmentation of GOST R 34.11 hash
|
|
||||||
- Changed reject routers with RSA signtures
|
|
||||||
- Changed reload config and shudown from Windows GUI
|
|
||||||
- Changed update tunnels address(destination) without restart
|
|
||||||
- Fixed BOB crashes if destination is not set
|
|
||||||
- Fixed correct SAM tunnel name
|
|
||||||
- Fixed QT GUI issues
|
|
||||||
|
|
||||||
* Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0
|
* Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0
|
||||||
- Added QT GUI
|
- update to 2.15.0
|
||||||
- Added ability add and remove I2P tunnels without restart
|
|
||||||
- Added ability to disable SOCKS outproxy option
|
|
||||||
- Changed strip-out Accept-* hedaers in HTTP proxy
|
|
||||||
- Changed peer test if nat=false
|
|
||||||
- Changed separate output of NTCP and SSU sessions in Transports tab
|
|
||||||
- Fixed handle lines with comments in hosts.txt file for address book
|
|
||||||
- Fixed run router with empty netdb for testnet
|
|
||||||
- Fixed skip expired introducers by iexp
|
|
||||||
|
|
||||||
* Thu Jun 01 2017 orignal <i2porignal@yandex.ru> - 2.14.0
|
* Thu Jun 01 2017 orignal <i2porignal@yandex.ru> - 2.14.0
|
||||||
- Added transit traffic bandwidth limitation
|
- update to 2.14.0
|
||||||
- Added NTCP connections through HTTP and SOCKS proxies
|
|
||||||
- Added ability to disable address helper for HTTP proxy
|
|
||||||
- Changed reseed servers list
|
|
||||||
|
|
||||||
* Thu Apr 06 2017 orignal <i2porignal@yandex.ru> - 2.13.0
|
* Thu Apr 06 2017 orignal <i2porignal@yandex.ru> - 2.13.0
|
||||||
- Added persist local destination's tags
|
- update to 2.13.0
|
||||||
- Added GOST signature types 9 and 10
|
|
||||||
- Added exploratory tunnels configuration
|
|
||||||
- Changed reseed servers list
|
|
||||||
- Changed inactive NTCP sockets get closed faster
|
|
||||||
- Changed some EdDSA speed up
|
|
||||||
- Fixed multiple acceptors for SAM
|
|
||||||
- Fixed follow on data after STREAM CREATE for SAM
|
|
||||||
- Fixed memory leaks
|
|
||||||
|
|
||||||
* Tue Feb 14 2017 orignal <i2porignal@yandex.ru> - 2.12.0
|
* Tue Feb 14 2017 orignal <i2porignal@yandex.ru> - 2.12.0
|
||||||
- Additional HTTP and SOCKS proxy tunnels
|
- update to 2.12.0
|
||||||
- Reseed from ZIP archive
|
|
||||||
- 'X' bandwidth code
|
|
||||||
- Reduced memory and file descriptors usage
|
|
||||||
|
|
||||||
* Mon Dec 19 2016 orignal <i2porignal@yandex.ru> - 2.11.0
|
* Mon Dec 19 2016 orignal <i2porignal@yandex.ru> - 2.11.0
|
||||||
- Full support of zero-hops tunnels
|
- update to 2.11.0
|
||||||
- Tunnel configuration for HTTP and SOCKS proxy
|
|
||||||
- Websockets support
|
|
||||||
- Multiple acceptors for SAM destination
|
|
||||||
- Routing path for UDP tunnels
|
|
||||||
- Reseed through a floodfill
|
|
||||||
- Use AVX instructions for DHT and HMAC if applicable
|
|
||||||
- Fixed UPnP discovery bug, producing excessive CPU usage
|
|
||||||
- Handle multiple lookups of the same LeaseSet correctly
|
|
||||||
|
|
||||||
* Thu Oct 20 2016 Anatolii Vorona <vorona.tolik@gmail.com> - 2.10.0-3
|
* Thu Oct 20 2016 Anatolii Vorona <vorona.tolik@gmail.com> - 2.10.0-3
|
||||||
- add support C7
|
- add support C7
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace i2p
|
|||||||
LogPrint(eLogInfo, "AESNI enabled");
|
LogPrint(eLogInfo, "AESNI enabled");
|
||||||
#endif
|
#endif
|
||||||
#if defined(__AVX__)
|
#if defined(__AVX__)
|
||||||
LogPrint(eLogInfo, "AVX enabled");
|
LogPrint(eLogInfo, "AVX enabled");
|
||||||
#endif
|
#endif
|
||||||
LogPrint(eLogDebug, "FS: main config file: ", config);
|
LogPrint(eLogDebug, "FS: main config file: ", config);
|
||||||
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
||||||
|
|||||||
@@ -316,8 +316,9 @@ namespace http {
|
|||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
auto ident = dest->GetIdentHash ();
|
auto ident = dest->GetIdentHash ();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">";
|
auto& name = dest->GetNickname ();
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
s << "<a href=\"/?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
|
||||||
|
s << name << " ]</a> ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,7 +505,7 @@ namespace http {
|
|||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
||||||
#endif
|
#endif
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n";
|
||||||
|
|
||||||
s << "<br>\r\n<b>Logging level</b><br>\r\n";
|
s << "<br>\r\n<b>Logging level</b><br>\r\n";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\">[none]</a> ";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\">[none]</a> ";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\">[error]</a> ";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\">[error]</a> ";
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace http
|
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 HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
|
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ namespace http
|
|||||||
|
|
||||||
HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
HTTPConnection (std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
void Receive ();
|
void Receive ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
@@ -63,11 +63,11 @@ namespace http
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void Accept ();
|
void Accept ();
|
||||||
void HandleAccept(const boost::system::error_code& ecode,
|
void HandleAccept(const boost::system::error_code& ecode,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);
|
std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);
|
||||||
void CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);
|
void CreateConnection(std::shared_ptr<boost::asio::ip::tcp::socket> newSocket);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace client
|
|||||||
I2PControlService::I2PControlService (const std::string& address, int port):
|
I2PControlService::I2PControlService (const std::string& address, int port):
|
||||||
m_IsRunning (false), m_Thread (nullptr),
|
m_IsRunning (false), m_Thread (nullptr),
|
||||||
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
|
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
|
||||||
m_SSLContext (m_Service, boost::asio::ssl::context::sslv23),
|
m_SSLContext (boost::asio::ssl::context::sslv23),
|
||||||
m_ShutdownTimer (m_Service)
|
m_ShutdownTimer (m_Service)
|
||||||
{
|
{
|
||||||
i2p::config::GetOption("i2pcontrol.password", m_Password);
|
i2p::config::GetOption("i2pcontrol.password", m_Password);
|
||||||
@@ -67,7 +67,7 @@ namespace client
|
|||||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
|
|
||||||
// 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;
|
||||||
@@ -80,13 +80,13 @@ namespace client
|
|||||||
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"] =
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
|
||||||
&I2PControlService::TunnelsSuccessRateHandler;
|
&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;
|
||||||
|
|
||||||
// RouterManager
|
// RouterManager
|
||||||
m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler;
|
m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler;
|
||||||
m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler;
|
m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler;
|
||||||
m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler;
|
m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler;
|
||||||
|
|
||||||
// NetworkSetting
|
// NetworkSetting
|
||||||
@@ -133,8 +133,8 @@ namespace client
|
|||||||
m_Service.run ();
|
m_Service.run ();
|
||||||
} catch (std::exception& ex) {
|
} catch (std::exception& ex) {
|
||||||
LogPrint (eLogError, "I2PControl: runtime exception: ", ex.what ());
|
LogPrint (eLogError, "I2PControl: runtime exception: ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::Accept ()
|
void I2PControlService::Accept ()
|
||||||
@@ -160,7 +160,7 @@ namespace client
|
|||||||
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
|
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
|
||||||
{
|
{
|
||||||
socket->async_handshake(boost::asio::ssl::stream_base::server,
|
socket->async_handshake(boost::asio::ssl::stream_base::server,
|
||||||
std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket));
|
std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
|
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
|
||||||
@@ -168,7 +168,7 @@ namespace client
|
|||||||
if (ecode) {
|
if (ecode) {
|
||||||
LogPrint (eLogError, "I2PControl: handshake error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl: handshake error: ", ecode.message ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
//std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
||||||
ReadRequest (socket);
|
ReadRequest (socket);
|
||||||
}
|
}
|
||||||
@@ -187,15 +187,15 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
|
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
|
||||||
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
|
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf)
|
std::shared_ptr<I2PControlBuffer> buf)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool isHtml = !memcmp (buf->data (), "POST", 4);
|
bool isHtml = !memcmp (buf->data (), "POST", 4);
|
||||||
try
|
try
|
||||||
@@ -243,8 +243,8 @@ namespace client
|
|||||||
response << "{\"id\":" << id << ",\"result\":{";
|
response << "{\"id\":" << id << ",\"result\":{";
|
||||||
(this->*(it->second))(pt.get_child ("params"), response);
|
(this->*(it->second))(pt.get_child ("params"), response);
|
||||||
response << "},\"jsonrpc\":\"2.0\"}";
|
response << "},\"jsonrpc\":\"2.0\"}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "I2PControl: unknown method ", method);
|
LogPrint (eLogWarning, "I2PControl: unknown method ", method);
|
||||||
response << "{\"id\":null,\"error\":";
|
response << "{\"id\":null,\"error\":";
|
||||||
@@ -337,9 +337,9 @@ namespace client
|
|||||||
InsertParam (results, "API", api);
|
InsertParam (results, "API", api);
|
||||||
results << ",";
|
results << ",";
|
||||||
std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
|
std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
|
||||||
m_Tokens.insert (token);
|
m_Tokens.insert (token);
|
||||||
InsertParam (results, "Token", token);
|
InsertParam (results, "Token", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
@@ -364,7 +364,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2PControl: I2PControl unknown request: ", it.first);
|
LogPrint (eLogError, "I2PControl: I2PControl unknown request: ", it.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::PasswordHandler (const std::string& value)
|
void I2PControlService::PasswordHandler (const std::string& value)
|
||||||
@@ -394,28 +394,28 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000);
|
InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::VersionHandler (std::ostringstream& results)
|
void I2PControlService::VersionHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.version", VERSION);
|
InsertParam (results, "i2p.router.version", VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::StatusHandler (std::ostringstream& results)
|
void I2PControlService::StatusHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0");
|
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
|
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ());
|
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
|
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ());
|
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetStatusHandler (std::ostringstream& results)
|
void I2PControlService::NetStatusHandler (std::ostringstream& results)
|
||||||
@@ -463,11 +463,11 @@ namespace client
|
|||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
{
|
{
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
|
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
|
||||||
auto it1 = m_RouterManagerHandlers.find (it->first);
|
auto it1 = m_RouterManagerHandlers.find (it->first);
|
||||||
if (it1 != m_RouterManagerHandlers.end ()) {
|
if (it1 != m_RouterManagerHandlers.end ()) {
|
||||||
(this->*(it1->second))(results);
|
(this->*(it1->second))(results);
|
||||||
} else
|
} else
|
||||||
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);
|
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);
|
||||||
}
|
}
|
||||||
@@ -516,7 +516,7 @@ namespace client
|
|||||||
auto it1 = m_NetworkSettingHandlers.find (it->first);
|
auto it1 = m_NetworkSettingHandlers.find (it->first);
|
||||||
if (it1 != m_NetworkSettingHandlers.end ()) {
|
if (it1 != m_NetworkSettingHandlers.end ()) {
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
(this->*(it1->second))(it->second.data (), results);
|
(this->*(it1->second))(it->second.data (), results);
|
||||||
} else
|
} else
|
||||||
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
|
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
|
||||||
}
|
}
|
||||||
@@ -538,7 +538,7 @@ namespace client
|
|||||||
InsertParam (results, "i2p.router.net.bw.out", bw);
|
InsertParam (results, "i2p.router.net.bw.out", bw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// certificate
|
// certificate
|
||||||
void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path)
|
void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path)
|
||||||
{
|
{
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ namespace transport
|
|||||||
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::unique_ptr<std::thread> m_Thread;
|
std::unique_ptr<std::thread> m_Thread;
|
||||||
std::condition_variable m_Started;
|
std::condition_variable m_Started;
|
||||||
std::mutex m_StartedMutex;
|
std::mutex m_StartedMutex;
|
||||||
boost::asio::io_service m_Service;
|
boost::asio::io_service m_Service;
|
||||||
boost::asio::deadline_timer m_Timer;
|
boost::asio::deadline_timer m_Timer;
|
||||||
struct UPNPUrls m_upnpUrls;
|
struct UPNPUrls m_upnpUrls;
|
||||||
struct IGDdatas m_upnpData;
|
struct IGDdatas m_upnpData;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Tunnel.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
|
|
||||||
@@ -183,7 +184,7 @@ namespace i2p
|
|||||||
if (gracefulShutdownInterval)
|
if (gracefulShutdownInterval)
|
||||||
{
|
{
|
||||||
gracefulShutdownInterval--; // - 1 second
|
gracefulShutdownInterval--; // - 1 second
|
||||||
if (gracefulShutdownInterval <= 0)
|
if (gracefulShutdownInterval <= 0 || i2p::tunnel::tunnels.CountTransitTunnels() <= 0)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Graceful shutdown");
|
LogPrint(eLogInfo, "Graceful shutdown");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ int main( int argc, char* argv[] )
|
|||||||
{
|
{
|
||||||
if (Daemon.start())
|
if (Daemon.start())
|
||||||
Daemon.run ();
|
Daemon.run ();
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
Daemon.stop();
|
Daemon.stop();
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
10
debian/changelog
vendored
10
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
|||||||
|
i2pd (2.18.0-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* updated to version 2.18.0/0.9.33
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Tue, 30 Jan 2018 16:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.17.0-1) unstable; urgency=low
|
i2pd (2.17.0-1) unstable; urgency=low
|
||||||
|
|
||||||
* updated to version 2.17.0/0.9.32
|
* updated to version 2.17.0/0.9.32
|
||||||
@@ -62,7 +68,7 @@ i2pd (2.10.0-1) unstable; urgency=low
|
|||||||
|
|
||||||
* updated to version 2.10.0/0.9.27
|
* updated to version 2.10.0/0.9.27
|
||||||
* reseed.verify set to true by default
|
* reseed.verify set to true by default
|
||||||
|
|
||||||
-- orignal <orignal@i2pmail.org> Sun, 16 Oct 2016 13:55:40 +0000
|
-- orignal <orignal@i2pmail.org> Sun, 16 Oct 2016 13:55:40 +0000
|
||||||
|
|
||||||
i2pd (2.9.0-1) unstable; urgency=low
|
i2pd (2.9.0-1) unstable; urgency=low
|
||||||
@@ -73,7 +79,7 @@ i2pd (2.9.0-1) unstable; urgency=low
|
|||||||
* removed all port assigments in services files
|
* removed all port assigments in services files
|
||||||
* fixed logrotate
|
* fixed logrotate
|
||||||
* subscriptions.txt and tunnels.conf taken from docs folder
|
* subscriptions.txt and tunnels.conf taken from docs folder
|
||||||
|
|
||||||
-- orignal <orignal@i2pmail.org> Fri, 12 Aug 2016 14:25:40 +0000
|
-- orignal <orignal@i2pmail.org> Fri, 12 Aug 2016 14:25:40 +0000
|
||||||
|
|
||||||
i2pd (2.7.0-1) unstable; urgency=low
|
i2pd (2.7.0-1) unstable; urgency=low
|
||||||
|
|||||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
|||||||
9
|
9
|
||||||
4
debian/control
vendored
4
debian/control
vendored
@@ -2,11 +2,11 @@ Source: i2pd
|
|||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: R4SAS <r4sas@i2pmail.org>
|
Maintainer: R4SAS <r4sas@i2pmail.org>
|
||||||
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, libminiupnpc-dev, libssl-dev, zlib1g-dev, dh-apparmor
|
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev, dh-apparmor
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 3.9.6
|
||||||
Homepage: http://i2pd.website/
|
Homepage: http://i2pd.website/
|
||||||
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
|
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
|
||||||
Vcs-Browser: https://github.com/PurpleI2P/i2pd.git
|
Vcs-Browser: https://github.com/PurpleI2P/i2pd
|
||||||
|
|
||||||
Package: i2pd
|
Package: i2pd
|
||||||
Architecture: any
|
Architecture: any
|
||||||
|
|||||||
44
debian/copyright
vendored
44
debian/copyright
vendored
@@ -4,6 +4,22 @@ Source: https://github.com/PurpleI2P
|
|||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2013-2017 PurpleI2P
|
Copyright: 2013-2017 PurpleI2P
|
||||||
|
License: BSD-3-clause
|
||||||
|
|
||||||
|
Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl
|
||||||
|
qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
|
||||||
|
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java
|
||||||
|
qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java
|
||||||
|
Copyright: 2011-2013 BogDan Vatra <bogdan@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2013-2015 Kill Your TV <killyourtv@i2pmail.org>
|
||||||
|
2014-2016 hagen <hagen@i2pmail.org>
|
||||||
|
2016-2017 R4SAS <r4sas@i2pmail.org>
|
||||||
|
2017-2018 Yangfl <mmyangfl@gmail.com>
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
Copyright (c) 2013-2017, The PurpleI2P Project
|
Copyright (c) 2013-2017, The PurpleI2P Project
|
||||||
.
|
.
|
||||||
@@ -33,11 +49,29 @@ License: BSD-3-clause
|
|||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
Files: debian/*
|
License: BSD-2-Clause
|
||||||
Copyright: 2016-2017 R4SAS <r4sas@i2pmail.org>
|
Redistribution and use in source and binary forms, with or without
|
||||||
2014-2016 hagen <hagen@i2pmail.org>
|
modification, are permitted provided that the following conditions
|
||||||
2013-2015 Kill Your TV <killyourtv@i2pmail.org>
|
are met:
|
||||||
License: GPL-2.0+
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
License: GPL-2+
|
||||||
This package is free software; you can redistribute it and/or modify
|
This package is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
|||||||
2
debian/i2pd.default
vendored
2
debian/i2pd.default
vendored
@@ -7,5 +7,5 @@ I2PD_ENABLED="yes"
|
|||||||
# see possible switches in /usr/share/doc/i2pd/configuration.md.gz
|
# see possible switches in /usr/share/doc/i2pd/configuration.md.gz
|
||||||
DAEMON_OPTS=""
|
DAEMON_OPTS=""
|
||||||
|
|
||||||
# If you have problems with hunging i2pd, you can try enable this
|
# If you have problems with hunging i2pd, you can try enable this
|
||||||
ulimit -n 4096
|
ulimit -n 4096
|
||||||
|
|||||||
2
debian/lintian-overrides
vendored
Normal file
2
debian/lintian-overrides
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# GPL come from debian/
|
||||||
|
i2pd: possible-gpl-code-linked-with-openssl
|
||||||
5
debian/patches/01-tune-build-opts.patch
vendored
5
debian/patches/01-tune-build-opts.patch
vendored
@@ -1,12 +1,11 @@
|
|||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index bdadfe0..2f71eec 100644
|
index bdadfe0..2f71eec 100644
|
||||||
|
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -9,10 +9,10 @@ DEPS := obj/make.dep
|
@@ -9,10 +9,10 @@ DEPS := obj/make.dep
|
||||||
|
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
|
|
||||||
-USE_AESNI := yes
|
-USE_AESNI := yes
|
||||||
+USE_AESNI := no
|
+USE_AESNI := no
|
||||||
-USE_AVX := yes
|
-USE_AVX := yes
|
||||||
|
|||||||
@@ -1638,7 +1638,7 @@ EXTRA_PACKAGES =
|
|||||||
# following commands have a special meaning inside the header: $title,
|
# following commands have a special meaning inside the header: $title,
|
||||||
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
|
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
|
||||||
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
|
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
|
||||||
# for the replacement values of the other commands the user is refered to
|
# for the replacement values of the other commands the user is referred to
|
||||||
# HTML_HEADER.
|
# HTML_HEADER.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ namespace data
|
|||||||
const char * GetBase64SubstitutionTable ()
|
const char * GetBase64SubstitutionTable ()
|
||||||
{
|
{
|
||||||
return T64;
|
return T64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reverse Substitution Table (built in run time)
|
* Reverse Substitution Table (built in run time)
|
||||||
*/
|
*/
|
||||||
@@ -53,10 +53,10 @@ namespace data
|
|||||||
static int isFirstTime = 1;
|
static int isFirstTime = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Padding
|
* Padding
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char P64 = '=';
|
static char P64 = '=';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@@ -68,11 +68,11 @@ namespace data
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
size_t /* Number of bytes in the encoded buffer */
|
size_t /* Number of bytes in the encoded buffer */
|
||||||
ByteStreamToBase64 (
|
ByteStreamToBase64 (
|
||||||
const uint8_t * InBuffer, /* Input buffer, binary data */
|
const uint8_t * InBuffer, /* Input buffer, binary data */
|
||||||
size_t InCount, /* Number of bytes in the input buffer */
|
size_t InCount, /* Number of bytes in the input buffer */
|
||||||
char * OutBuffer, /* output buffer */
|
char * OutBuffer, /* output buffer */
|
||||||
size_t len /* length of output buffer */
|
size_t len /* length of output buffer */
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -80,9 +80,9 @@ namespace data
|
|||||||
unsigned char * pd;
|
unsigned char * pd;
|
||||||
unsigned char acc_1;
|
unsigned char acc_1;
|
||||||
unsigned char acc_2;
|
unsigned char acc_2;
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int m;
|
int m;
|
||||||
size_t outCount;
|
size_t outCount;
|
||||||
|
|
||||||
ps = (unsigned char *)InBuffer;
|
ps = (unsigned char *)InBuffer;
|
||||||
@@ -96,7 +96,7 @@ namespace data
|
|||||||
pd = (unsigned char *)OutBuffer;
|
pd = (unsigned char *)OutBuffer;
|
||||||
for ( i = 0; i<n; i++ ){
|
for ( i = 0; i<n; i++ ){
|
||||||
acc_1 = *ps++;
|
acc_1 = *ps++;
|
||||||
acc_2 = (acc_1<<4)&0x30;
|
acc_2 = (acc_1<<4)&0x30;
|
||||||
acc_1 >>= 2; /* base64 digit #1 */
|
acc_1 >>= 2; /* base64 digit #1 */
|
||||||
*pd++ = T64[acc_1];
|
*pd++ = T64[acc_1];
|
||||||
acc_1 = *ps++;
|
acc_1 = *ps++;
|
||||||
@@ -109,7 +109,7 @@ namespace data
|
|||||||
*pd++ = T64[acc_1];
|
*pd++ = T64[acc_1];
|
||||||
acc_2 &= 0x3f; /* base64 digit #4 */
|
acc_2 &= 0x3f; /* base64 digit #4 */
|
||||||
*pd++ = T64[acc_2];
|
*pd++ = T64[acc_2];
|
||||||
}
|
}
|
||||||
if ( m == 1 ){
|
if ( m == 1 ){
|
||||||
acc_1 = *ps++;
|
acc_1 = *ps++;
|
||||||
acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */
|
acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */
|
||||||
@@ -122,7 +122,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
else if ( m == 2 ){
|
else if ( m == 2 ){
|
||||||
acc_1 = *ps++;
|
acc_1 = *ps++;
|
||||||
acc_2 = (acc_1<<4)&0x3f;
|
acc_2 = (acc_1<<4)&0x3f;
|
||||||
acc_1 >>= 2; /* base64 digit #1 */
|
acc_1 >>= 2; /* base64 digit #1 */
|
||||||
*pd++ = T64[acc_1];
|
*pd++ = T64[acc_1];
|
||||||
acc_1 = *ps++;
|
acc_1 = *ps++;
|
||||||
@@ -133,7 +133,7 @@ namespace data
|
|||||||
*pd++ = T64[acc_1];
|
*pd++ = T64[acc_1];
|
||||||
*pd++ = P64;
|
*pd++ = P64;
|
||||||
}
|
}
|
||||||
|
|
||||||
return outCount;
|
return outCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,10 +148,10 @@ namespace data
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
size_t /* Number of output bytes */
|
size_t /* Number of output bytes */
|
||||||
Base64ToByteStream (
|
Base64ToByteStream (
|
||||||
const char * InBuffer, /* BASE64 encoded buffer */
|
const char * InBuffer, /* BASE64 encoded buffer */
|
||||||
size_t InCount, /* Number of input bytes */
|
size_t InCount, /* Number of input bytes */
|
||||||
uint8_t * OutBuffer, /* output buffer length */
|
uint8_t * OutBuffer, /* output buffer length */
|
||||||
size_t len /* length of output buffer */
|
size_t len /* length of output buffer */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -159,28 +159,28 @@ namespace data
|
|||||||
unsigned char * pd;
|
unsigned char * pd;
|
||||||
unsigned char acc_1;
|
unsigned char acc_1;
|
||||||
unsigned char acc_2;
|
unsigned char acc_2;
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int m;
|
int m;
|
||||||
size_t outCount;
|
size_t outCount;
|
||||||
|
|
||||||
if (isFirstTime) iT64Build();
|
if (isFirstTime) iT64Build();
|
||||||
n = InCount/4;
|
n = InCount/4;
|
||||||
m = InCount%4;
|
m = InCount%4;
|
||||||
if (InCount && !m)
|
if (InCount && !m)
|
||||||
outCount = 3*n;
|
outCount = 3*n;
|
||||||
else {
|
else {
|
||||||
outCount = 0;
|
outCount = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps = (unsigned char *)(InBuffer + InCount - 1);
|
ps = (unsigned char *)(InBuffer + InCount - 1);
|
||||||
while ( *ps-- == P64 ) outCount--;
|
while ( *ps-- == P64 ) outCount--;
|
||||||
ps = (unsigned char *)InBuffer;
|
ps = (unsigned char *)InBuffer;
|
||||||
|
|
||||||
if (outCount > len) return -1;
|
if (outCount > len) return -1;
|
||||||
pd = OutBuffer;
|
pd = OutBuffer;
|
||||||
auto endOfOutBuffer = OutBuffer + outCount;
|
auto endOfOutBuffer = OutBuffer + outCount;
|
||||||
for ( i = 0; i < n; i++ ){
|
for ( i = 0; i < n; i++ ){
|
||||||
acc_1 = iT64[*ps++];
|
acc_1 = iT64[*ps++];
|
||||||
acc_2 = iT64[*ps++];
|
acc_2 = iT64[*ps++];
|
||||||
@@ -193,7 +193,7 @@ namespace data
|
|||||||
acc_1 = iT64[*ps++];
|
acc_1 = iT64[*ps++];
|
||||||
acc_2 |= acc_1 >> 2;
|
acc_2 |= acc_1 >> 2;
|
||||||
*pd++ = acc_2;
|
*pd++ = acc_2;
|
||||||
if (pd >= endOfOutBuffer) break;
|
if (pd >= endOfOutBuffer) break;
|
||||||
|
|
||||||
acc_2 = iT64[*ps++];
|
acc_2 = iT64[*ps++];
|
||||||
acc_2 |= acc_1 << 6;
|
acc_2 |= acc_1 << 6;
|
||||||
@@ -203,13 +203,13 @@ namespace data
|
|||||||
return outCount;
|
return outCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Base64EncodingBufferSize (const size_t input_size)
|
size_t Base64EncodingBufferSize (const size_t input_size)
|
||||||
{
|
{
|
||||||
auto d = div (input_size, 3);
|
auto d = div (input_size, 3);
|
||||||
if (d.rem) d.quot++;
|
if (d.rem) d.quot++;
|
||||||
return 4*d.quot;
|
return 4*d.quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* iT64
|
* iT64
|
||||||
@@ -228,20 +228,20 @@ namespace data
|
|||||||
iT64[(int)P64] = 0;
|
iT64[(int)P64] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen)
|
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen)
|
||||||
{
|
{
|
||||||
int tmp = 0, bits = 0;
|
int tmp = 0, bits = 0;
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
for (size_t i = 0; i < len; i++)
|
for (size_t i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
char ch = inBuf[i];
|
char ch = inBuf[i];
|
||||||
if (ch >= '2' && ch <= '7') // digit
|
if (ch >= '2' && ch <= '7') // digit
|
||||||
ch = (ch - '2') + 26; // 26 means a-z
|
ch = (ch - '2') + 26; // 26 means a-z
|
||||||
else if (ch >= 'a' && ch <= 'z')
|
else if (ch >= 'a' && ch <= 'z')
|
||||||
ch = ch - 'a'; // a = 0
|
ch = ch - 'a'; // a = 0
|
||||||
else
|
else
|
||||||
return 0; // unexpected character
|
return 0; // unexpected character
|
||||||
|
|
||||||
tmp |= ch;
|
tmp |= ch;
|
||||||
bits += 5;
|
bits += 5;
|
||||||
if (bits >= 8)
|
if (bits >= 8)
|
||||||
@@ -261,23 +261,23 @@ namespace data
|
|||||||
size_t ret = 0, pos = 1;
|
size_t ret = 0, pos = 1;
|
||||||
int bits = 8, tmp = inBuf[0];
|
int bits = 8, tmp = inBuf[0];
|
||||||
while (ret < outLen && (bits > 0 || pos < len))
|
while (ret < outLen && (bits > 0 || pos < len))
|
||||||
{
|
{
|
||||||
if (bits < 5)
|
if (bits < 5)
|
||||||
{
|
{
|
||||||
if (pos < len)
|
if (pos < len)
|
||||||
{
|
{
|
||||||
tmp <<= 8;
|
tmp <<= 8;
|
||||||
tmp |= inBuf[pos] & 0xFF;
|
tmp |= inBuf[pos] & 0xFF;
|
||||||
pos++;
|
pos++;
|
||||||
bits += 8;
|
bits += 8;
|
||||||
}
|
}
|
||||||
else // last byte
|
else // last byte
|
||||||
{
|
{
|
||||||
tmp <<= (5 - bits);
|
tmp <<= (5 - bits);
|
||||||
bits = 5;
|
bits = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bits -= 5;
|
bits -= 5;
|
||||||
int ind = (tmp >> bits) & 0x1F;
|
int ind = (tmp >> bits) & 0x1F;
|
||||||
outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2');
|
outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2');
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ namespace data {
|
|||||||
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
|
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
|
||||||
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
||||||
const char * GetBase32SubstitutionTable ();
|
const char * GetBase32SubstitutionTable ();
|
||||||
const char * GetBase64SubstitutionTable ();
|
const char * GetBase64SubstitutionTable ();
|
||||||
|
|
||||||
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
||||||
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);
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace config {
|
|||||||
* @brief Load and parse given config file
|
* @brief Load and parse given config file
|
||||||
* @param path Path to config file
|
* @param path Path to config file
|
||||||
*
|
*
|
||||||
* If error occured when opening file path is points to,
|
* If error occurred when opening file path is points to,
|
||||||
* we show the error message and terminate program.
|
* we show the error message and terminate program.
|
||||||
*
|
*
|
||||||
* In case of parameter misuse boost throws an exception.
|
* In case of parameter misuse boost throws an exception.
|
||||||
@@ -79,10 +79,10 @@ namespace config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool GetOption(const std::string& name, T& value)
|
bool GetOption(const std::string& name, T& value)
|
||||||
{
|
{
|
||||||
return GetOption (name.c_str (), value);
|
return GetOption (name.c_str (), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOptionAsAny(const char *name, boost::any& value);
|
bool GetOptionAsAny(const char *name, boost::any& value);
|
||||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace crypto
|
|||||||
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
|
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
|
||||||
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
|
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
|
||||||
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
|
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
|
||||||
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
|
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
|
||||||
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||||
|
|||||||
160
libi2pd/Crypto.h
160
libi2pd/Crypto.h
@@ -24,7 +24,7 @@ namespace crypto
|
|||||||
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len);
|
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
// DSA
|
// DSA
|
||||||
DSA * CreateDSA ();
|
DSA * CreateDSA ();
|
||||||
|
|
||||||
// RSA
|
// RSA
|
||||||
const BIGNUM * GetRSAE ();
|
const BIGNUM * GetRSAE ();
|
||||||
@@ -33,20 +33,20 @@ namespace crypto
|
|||||||
class DHKeys
|
class DHKeys
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DHKeys ();
|
DHKeys ();
|
||||||
~DHKeys ();
|
~DHKeys ();
|
||||||
|
|
||||||
void GenerateKeys ();
|
void GenerateKeys ();
|
||||||
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
||||||
void Agree (const uint8_t * pub, uint8_t * shared);
|
void Agree (const uint8_t * pub, uint8_t * shared);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DH * m_DH;
|
DH * m_DH;
|
||||||
uint8_t m_PublicKey[256];
|
uint8_t m_PublicKey[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false);
|
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false);
|
||||||
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
|
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
|
||||||
@@ -54,15 +54,15 @@ namespace crypto
|
|||||||
|
|
||||||
// ECIES
|
// ECIES
|
||||||
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 514 bytes encrypted
|
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 514 bytes encrypted
|
||||||
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
||||||
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
||||||
|
|
||||||
// HMAC
|
// HMAC
|
||||||
typedef i2p::data::Tag<32> MACKey;
|
typedef i2p::data::Tag<32> MACKey;
|
||||||
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest);
|
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest);
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
struct ChipherBlock
|
struct ChipherBlock
|
||||||
{
|
{
|
||||||
uint8_t buf[16];
|
uint8_t buf[16];
|
||||||
|
|
||||||
@@ -71,40 +71,40 @@ namespace crypto
|
|||||||
#if defined(__AVX__) // AVX
|
#if defined(__AVX__) // AVX
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"vmovups (%[buf]), %%xmm0 \n"
|
"vmovups (%[buf]), %%xmm0 \n"
|
||||||
"vmovups (%[other]), %%xmm1 \n"
|
"vmovups (%[other]), %%xmm1 \n"
|
||||||
"vxorps %%xmm0, %%xmm1, %%xmm0 \n"
|
"vxorps %%xmm0, %%xmm1, %%xmm0 \n"
|
||||||
"vmovups %%xmm0, (%[buf]) \n"
|
"vmovups %%xmm0, (%[buf]) \n"
|
||||||
:
|
:
|
||||||
: [buf]"r"(buf), [other]"r"(other.buf)
|
: [buf]"r"(buf), [other]"r"(other.buf)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#elif defined(__SSE__) // SSE
|
#elif defined(__SSE__) // SSE
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[buf]), %%xmm0 \n"
|
"movups (%[buf]), %%xmm0 \n"
|
||||||
"movups (%[other]), %%xmm1 \n"
|
"movups (%[other]), %%xmm1 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[buf]) \n"
|
"movups %%xmm0, (%[buf]) \n"
|
||||||
:
|
:
|
||||||
: [buf]"r"(buf), [other]"r"(other.buf)
|
: [buf]"r"(buf), [other]"r"(other.buf)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
// TODO: implement it better
|
// TODO: implement it better
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
buf[i] ^= other.buf[i];
|
buf[i] ^= other.buf[i];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef i2p::data::Tag<32> AESKey;
|
typedef i2p::data::Tag<32> AESKey;
|
||||||
|
|
||||||
template<size_t sz>
|
template<size_t sz>
|
||||||
class AESAlignedBuffer // 16 bytes alignment
|
class AESAlignedBuffer // 16 bytes alignment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AESAlignedBuffer ()
|
AESAlignedBuffer ()
|
||||||
{
|
{
|
||||||
m_Buf = m_UnalignedBuffer;
|
m_Buf = m_UnalignedBuffer;
|
||||||
@@ -112,22 +112,22 @@ namespace crypto
|
|||||||
if (rem)
|
if (rem)
|
||||||
m_Buf += (16 - rem);
|
m_Buf += (16 - rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator uint8_t * () { return m_Buf; };
|
operator uint8_t * () { return m_Buf; };
|
||||||
operator const uint8_t * () const { return m_Buf; };
|
operator const uint8_t * () const { return m_Buf; };
|
||||||
ChipherBlock * GetChipherBlock () { return (ChipherBlock *)m_Buf; };
|
ChipherBlock * GetChipherBlock () { return (ChipherBlock *)m_Buf; };
|
||||||
const ChipherBlock * GetChipherBlock () const { return (const ChipherBlock *)m_Buf; };
|
const ChipherBlock * GetChipherBlock () const { return (const ChipherBlock *)m_Buf; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_UnalignedBuffer[sz + 15]; // up to 15 bytes alignment
|
uint8_t m_UnalignedBuffer[sz + 15]; // up to 15 bytes alignment
|
||||||
uint8_t * m_Buf;
|
uint8_t * m_Buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef AESNI
|
||||||
class ECBCryptoAESNI
|
class ECBCryptoAESNI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint8_t * GetKeySchedule () { return m_KeySchedule; };
|
uint8_t * GetKeySchedule () { return m_KeySchedule; };
|
||||||
@@ -135,27 +135,27 @@ namespace crypto
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
void ExpandKey (const AESKey& key);
|
void ExpandKey (const AESKey& key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
|
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
class ECBEncryptionAESNI: public ECBCryptoAESNI
|
class ECBEncryptionAESNI: public ECBCryptoAESNI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key) { ExpandKey (key); };
|
void SetKey (const AESKey& key) { ExpandKey (key); };
|
||||||
void Encrypt (const ChipherBlock * in, ChipherBlock * out);
|
void Encrypt (const ChipherBlock * in, ChipherBlock * out);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ECBDecryptionAESNI: public ECBCryptoAESNI
|
class ECBDecryptionAESNI: public ECBCryptoAESNI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key);
|
void SetKey (const AESKey& key);
|
||||||
void Decrypt (const ChipherBlock * in, ChipherBlock * out);
|
void Decrypt (const ChipherBlock * in, ChipherBlock * out);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ECBEncryptionAESNI ECBEncryption;
|
typedef ECBEncryptionAESNI ECBEncryption;
|
||||||
typedef ECBDecryptionAESNI ECBDecryption;
|
typedef ECBDecryptionAESNI ECBDecryption;
|
||||||
@@ -165,46 +165,46 @@ namespace crypto
|
|||||||
class ECBEncryption
|
class ECBEncryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key)
|
void SetKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
AES_set_encrypt_key (key, 256, &m_Key);
|
AES_set_encrypt_key (key, 256, &m_Key);
|
||||||
}
|
}
|
||||||
void Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
void Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
AES_encrypt (in->buf, out->buf, &m_Key);
|
AES_encrypt (in->buf, out->buf, &m_Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AES_KEY m_Key;
|
AES_KEY m_Key;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ECBDecryption
|
class ECBDecryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key)
|
void SetKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
AES_set_decrypt_key (key, 256, &m_Key);
|
AES_set_decrypt_key (key, 256, &m_Key);
|
||||||
}
|
}
|
||||||
void Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
void Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
AES_decrypt (in->buf, out->buf, &m_Key);
|
AES_decrypt (in->buf, out->buf, &m_Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AES_KEY m_Key;
|
AES_KEY m_Key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class CBCEncryption
|
class CBCEncryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CBCEncryption () { memset ((uint8_t *)m_LastBlock, 0, 16); };
|
CBCEncryption () { memset ((uint8_t *)m_LastBlock, 0, 16); };
|
||||||
|
|
||||||
void SetKey (const AESKey& key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
|
void SetKey (const AESKey& key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
|
||||||
@@ -217,14 +217,14 @@ namespace crypto
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<16> m_LastBlock;
|
AESAlignedBuffer<16> m_LastBlock;
|
||||||
|
|
||||||
ECBEncryption m_ECBEncryption;
|
ECBEncryption m_ECBEncryption;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBCDecryption
|
class CBCDecryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CBCDecryption () { memset ((uint8_t *)m_IV, 0, 16); };
|
CBCDecryption () { memset ((uint8_t *)m_IV, 0, 16); };
|
||||||
|
|
||||||
void SetKey (const AESKey& key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
|
void SetKey (const AESKey& key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
|
||||||
@@ -238,7 +238,7 @@ namespace crypto
|
|||||||
|
|
||||||
AESAlignedBuffer<16> m_IV;
|
AESAlignedBuffer<16> m_IV;
|
||||||
ECBDecryption m_ECBDecryption;
|
ECBDecryption m_ECBDecryption;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TunnelEncryption // with double IV encryption
|
class TunnelEncryption // with double IV encryption
|
||||||
{
|
{
|
||||||
@@ -248,9 +248,9 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
m_LayerEncryption.SetKey (layerKey);
|
m_LayerEncryption.SetKey (layerKey);
|
||||||
m_IVEncryption.SetKey (ivKey);
|
m_IVEncryption.SetKey (ivKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Encrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
|
void Encrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -270,9 +270,9 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
m_LayerDecryption.SetKey (layerKey);
|
m_LayerDecryption.SetKey (layerKey);
|
||||||
m_IVDecryption.SetKey (ivKey);
|
m_IVDecryption.SetKey (ivKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Decrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
|
void Decrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -282,72 +282,72 @@ namespace crypto
|
|||||||
#else
|
#else
|
||||||
CBCDecryption m_LayerDecryption;
|
CBCDecryption m_LayerDecryption;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitCrypto (bool precomputation);
|
void InitCrypto (bool precomputation);
|
||||||
void TerminateCrypto ();
|
void TerminateCrypto ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// take care about openssl version
|
// take care about openssl version
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER) // 1.1.0 or LibreSSL
|
#if (OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER) // 1.1.0 or LibreSSL
|
||||||
// define getters and setters introduced in 1.1.0
|
// define getters and setters introduced in 1.1.0
|
||||||
inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||||
{
|
{
|
||||||
if (d->p) BN_free (d->p);
|
if (d->p) BN_free (d->p);
|
||||||
if (d->q) BN_free (d->q);
|
if (d->q) BN_free (d->q);
|
||||||
if (d->g) BN_free (d->g);
|
if (d->g) BN_free (d->g);
|
||||||
d->p = p; d->q = q; d->g = g; return 1;
|
d->p = p; d->q = q; d->g = g; return 1;
|
||||||
}
|
}
|
||||||
inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||||
{
|
{
|
||||||
if (d->pub_key) BN_free (d->pub_key);
|
if (d->pub_key) BN_free (d->pub_key);
|
||||||
if (d->priv_key) BN_free (d->priv_key);
|
if (d->priv_key) BN_free (d->priv_key);
|
||||||
d->pub_key = pub_key; d->priv_key = priv_key; return 1;
|
d->pub_key = pub_key; d->priv_key = priv_key; return 1;
|
||||||
}
|
}
|
||||||
inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||||||
{ *pub_key = d->pub_key; *priv_key = d->priv_key; }
|
{ *pub_key = d->pub_key; *priv_key = d->priv_key; }
|
||||||
inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||||||
{
|
{
|
||||||
if (sig->r) BN_free (sig->r);
|
if (sig->r) BN_free (sig->r);
|
||||||
if (sig->s) BN_free (sig->s);
|
if (sig->s) BN_free (sig->s);
|
||||||
sig->r = r; sig->s = s; return 1;
|
sig->r = r; sig->s = s; return 1;
|
||||||
}
|
}
|
||||||
inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||||||
{ *pr = sig->r; *ps = sig->s; }
|
{ *pr = sig->r; *ps = sig->s; }
|
||||||
|
|
||||||
inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||||||
{
|
{
|
||||||
if (sig->r) BN_free (sig->r);
|
if (sig->r) BN_free (sig->r);
|
||||||
if (sig->s) BN_free (sig->s);
|
if (sig->s) BN_free (sig->s);
|
||||||
sig->r = r; sig->s = s; return 1;
|
sig->r = r; sig->s = s; return 1;
|
||||||
}
|
}
|
||||||
inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||||||
{ *pr = sig->r; *ps = sig->s; }
|
{ *pr = sig->r; *ps = sig->s; }
|
||||||
|
|
||||||
inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
||||||
{
|
{
|
||||||
if (r->n) BN_free (r->n);
|
if (r->n) BN_free (r->n);
|
||||||
if (r->e) BN_free (r->e);
|
if (r->e) BN_free (r->e);
|
||||||
if (r->d) BN_free (r->d);
|
if (r->d) BN_free (r->d);
|
||||||
r->n = n; r->e = e; r->d = d; return 1;
|
r->n = n; r->e = e; r->d = d; return 1;
|
||||||
}
|
}
|
||||||
inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
||||||
{ *n = r->n; *e = r->e; *d = r->d; }
|
{ *n = r->n; *e = r->e; *d = r->d; }
|
||||||
|
|
||||||
inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
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)
|
||||||
{
|
{
|
||||||
if (dh->pub_key) BN_free (dh->pub_key);
|
if (dh->pub_key) BN_free (dh->pub_key);
|
||||||
if (dh->priv_key) BN_free (dh->priv_key);
|
if (dh->priv_key) BN_free (dh->priv_key);
|
||||||
dh->pub_key = pub_key; dh->priv_key = priv_key; return 1;
|
dh->pub_key = pub_key; dh->priv_key = priv_key; return 1;
|
||||||
}
|
}
|
||||||
inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||||||
{ *pub_key = dh->pub_key; *priv_key = dh->priv_key; }
|
{ *pub_key = dh->pub_key; *priv_key = dh->priv_key; }
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace crypto
|
|||||||
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub)
|
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub)
|
||||||
{
|
{
|
||||||
EC_GROUP * curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
|
EC_GROUP * curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
|
||||||
EC_POINT * p = nullptr;
|
EC_POINT * p = nullptr;
|
||||||
BIGNUM * key = nullptr;
|
BIGNUM * key = nullptr;
|
||||||
GenerateECIESKeyPair (curve, key, p);
|
GenerateECIESKeyPair (curve, key, p);
|
||||||
bn2buf (key, priv, 32);
|
bn2buf (key, priv, 32);
|
||||||
@@ -81,11 +81,11 @@ namespace crypto
|
|||||||
BIGNUM * x = BN_new (), * y = BN_new ();
|
BIGNUM * x = BN_new (), * y = BN_new ();
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, NULL);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, NULL);
|
||||||
bn2buf (x, pub, 32);
|
bn2buf (x, pub, 32);
|
||||||
bn2buf (y, pub + 32, 32);
|
bn2buf (y, pub + 32, 32);
|
||||||
RAND_bytes (pub + 64, 192);
|
RAND_bytes (pub + 64, 192);
|
||||||
EC_POINT_free (p);
|
EC_POINT_free (p);
|
||||||
BN_free (x); BN_free (y);
|
BN_free (x); BN_free (y);
|
||||||
EC_GROUP_free (curve);
|
EC_GROUP_free (curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESGOSTR3410Encryptor::ECIESGOSTR3410Encryptor (const uint8_t * pub)
|
ECIESGOSTR3410Encryptor::ECIESGOSTR3410Encryptor (const uint8_t * pub)
|
||||||
@@ -131,7 +131,7 @@ namespace crypto
|
|||||||
void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub)
|
void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub)
|
||||||
{
|
{
|
||||||
auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
|
auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
|
||||||
EC_POINT * p = nullptr;
|
EC_POINT * p = nullptr;
|
||||||
BIGNUM * key = nullptr;
|
BIGNUM * key = nullptr;
|
||||||
GenerateECIESKeyPair (curve->GetGroup (), key, p);
|
GenerateECIESKeyPair (curve->GetGroup (), key, p);
|
||||||
bn2buf (key, priv, 32);
|
bn2buf (key, priv, 32);
|
||||||
@@ -140,9 +140,9 @@ namespace crypto
|
|||||||
BIGNUM * x = BN_new (), * y = BN_new ();
|
BIGNUM * x = BN_new (), * y = BN_new ();
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve->GetGroup (), p, x, y, NULL);
|
EC_POINT_get_affine_coordinates_GFp (curve->GetGroup (), p, x, y, NULL);
|
||||||
bn2buf (x, pub, 32);
|
bn2buf (x, pub, 32);
|
||||||
bn2buf (y, pub + 32, 32);
|
bn2buf (y, pub + 32, 32);
|
||||||
RAND_bytes (pub + 64, 192);
|
RAND_bytes (pub + 64, 192);
|
||||||
EC_POINT_free (p);
|
EC_POINT_free (p);
|
||||||
BN_free (x); BN_free (y);
|
BN_free (x); BN_free (y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
class CryptoKeyEncryptor
|
class CryptoKeyEncryptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~CryptoKeyEncryptor () {};
|
virtual ~CryptoKeyEncryptor () {};
|
||||||
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // 222 bytes data, 512 bytes encrypted
|
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // 222 bytes data, 512 bytes encrypted
|
||||||
};
|
};
|
||||||
|
|
||||||
class CryptoKeyDecryptor
|
class CryptoKeyDecryptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ElGamalEncryptor (const uint8_t * pub);
|
ElGamalEncryptor (const uint8_t * pub);
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ElGamalDecryptor (const uint8_t * priv);
|
ElGamalDecryptor (const uint8_t * priv);
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ namespace crypto
|
|||||||
|
|
||||||
// ECIES P256
|
// ECIES P256
|
||||||
|
|
||||||
class ECIESP256Encryptor: public CryptoKeyEncryptor
|
class ECIESP256Encryptor: public CryptoKeyEncryptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ECIESP256Encryptor (const uint8_t * pub);
|
ECIESP256Encryptor (const uint8_t * pub);
|
||||||
~ECIESP256Encryptor ();
|
~ECIESP256Encryptor ();
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESP256Decryptor (const uint8_t * priv);
|
ECIESP256Decryptor (const uint8_t * priv);
|
||||||
~ECIESP256Decryptor ();
|
~ECIESP256Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -80,17 +80,17 @@ namespace crypto
|
|||||||
BIGNUM * m_PrivateKey;
|
BIGNUM * m_PrivateKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub);
|
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub);
|
||||||
|
|
||||||
// ECIES GOST R 34.10
|
// ECIES GOST R 34.10
|
||||||
|
|
||||||
class ECIESGOSTR3410Encryptor: public CryptoKeyEncryptor
|
class ECIESGOSTR3410Encryptor: public CryptoKeyEncryptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ECIESGOSTR3410Encryptor (const uint8_t * pub);
|
ECIESGOSTR3410Encryptor (const uint8_t * pub);
|
||||||
~ECIESGOSTR3410Encryptor ();
|
~ECIESGOSTR3410Encryptor ();
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
||||||
~ECIESGOSTR3410Decryptor ();
|
~ECIESGOSTR3410Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -11,20 +11,20 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace datagram
|
namespace datagram
|
||||||
{
|
{
|
||||||
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
||||||
m_Owner (owner.get()),
|
m_Owner (owner.get()),
|
||||||
m_Receiver (nullptr)
|
m_Receiver (nullptr)
|
||||||
{
|
{
|
||||||
m_Identity.FromBase64 (owner->GetIdentity()->ToBase64());
|
m_Identity.FromBase64 (owner->GetIdentity()->ToBase64());
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramDestination::~DatagramDestination ()
|
DatagramDestination::~DatagramDestination ()
|
||||||
{
|
{
|
||||||
m_Sessions.clear();
|
m_Sessions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort)
|
||||||
{
|
{
|
||||||
auto owner = m_Owner;
|
auto owner = m_Owner;
|
||||||
std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
|
std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
|
||||||
uint8_t * buf = v.data();
|
uint8_t * buf = v.data();
|
||||||
@@ -33,11 +33,11 @@ namespace datagram
|
|||||||
auto signatureLen = m_Identity.GetSignatureLen ();
|
auto signatureLen = m_Identity.GetSignatureLen ();
|
||||||
uint8_t * buf1 = signature + signatureLen;
|
uint8_t * buf1 = signature + signatureLen;
|
||||||
size_t headerLen = identityLen + signatureLen;
|
size_t headerLen = identityLen + signatureLen;
|
||||||
|
|
||||||
memcpy (buf1, payload, len);
|
memcpy (buf1, payload, len);
|
||||||
if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
{
|
{
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(buf1, len, hash);
|
SHA256(buf1, len, hash);
|
||||||
owner->Sign (hash, 32, signature);
|
owner->Sign (hash, 32, signature);
|
||||||
}
|
}
|
||||||
@@ -63,10 +63,10 @@ namespace datagram
|
|||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(buf + headerLen, len - headerLen, hash);
|
SHA256(buf + headerLen, len - headerLen, hash);
|
||||||
verified = identity.Verify (hash, 32, signature);
|
verified = identity.Verify (hash, 32, signature);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
verified = identity.Verify (buf + headerLen, len - headerLen, signature);
|
verified = identity.Verify (buf + headerLen, len - headerLen, signature);
|
||||||
|
|
||||||
if (verified)
|
if (verified)
|
||||||
{
|
{
|
||||||
auto h = identity.GetIdentHash();
|
auto h = identity.GetIdentHash();
|
||||||
@@ -79,7 +79,7 @@ namespace datagram
|
|||||||
LogPrint (eLogWarning, "DatagramDestination: no receiver for port ", toPort);
|
LogPrint (eLogWarning, "DatagramDestination: no receiver for port ", toPort);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Datagram signature verification failed");
|
LogPrint (eLogWarning, "Datagram signature verification failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
|
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
|
||||||
@@ -113,24 +113,24 @@ namespace datagram
|
|||||||
{
|
{
|
||||||
htobe32buf (msg->GetPayload (), size); // length
|
htobe32buf (msg->GetPayload (), size); // length
|
||||||
htobe16buf (buf + 4, fromPort); // source port
|
htobe16buf (buf + 4, fromPort); // source port
|
||||||
htobe16buf (buf + 6, toPort); // destination port
|
htobe16buf (buf + 6, toPort); // destination port
|
||||||
buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol
|
buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol
|
||||||
msg->len += size + 4;
|
msg->len += size + 4;
|
||||||
msg->FillI2NPMessageHeader (eI2NPData);
|
msg->FillI2NPMessageHeader (eI2NPData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
msg = nullptr;
|
msg = nullptr;
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatagramDestination::CleanUp ()
|
void DatagramDestination::CleanUp ()
|
||||||
{
|
{
|
||||||
if (m_Sessions.empty ()) return;
|
if (m_Sessions.empty ()) return;
|
||||||
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
||||||
std::unique_lock<std::mutex> lock(m_SessionsMutex);
|
std::unique_lock<std::mutex> lock(m_SessionsMutex);
|
||||||
// for each session ...
|
// for each session ...
|
||||||
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
||||||
{
|
{
|
||||||
// check if expired
|
// check if expired
|
||||||
if (now - it->second->LastActivity() >= DATAGRAM_SESSION_MAX_IDLE)
|
if (now - it->second->LastActivity() >= DATAGRAM_SESSION_MAX_IDLE)
|
||||||
@@ -143,7 +143,7 @@ namespace datagram
|
|||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DatagramSession> DatagramDestination::ObtainSession(const i2p::data::IdentHash & identity)
|
std::shared_ptr<DatagramSession> DatagramDestination::ObtainSession(const i2p::data::IdentHash & identity)
|
||||||
{
|
{
|
||||||
std::shared_ptr<DatagramSession> session = nullptr;
|
std::shared_ptr<DatagramSession> session = nullptr;
|
||||||
@@ -169,7 +169,7 @@ namespace datagram
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramSession::DatagramSession(i2p::client::ClientDestination * localDestination,
|
DatagramSession::DatagramSession(i2p::client::ClientDestination * localDestination,
|
||||||
const i2p::data::IdentHash & remoteIdent) :
|
const i2p::data::IdentHash & remoteIdent) :
|
||||||
m_LocalDestination(localDestination),
|
m_LocalDestination(localDestination),
|
||||||
@@ -203,7 +203,7 @@ namespace datagram
|
|||||||
{
|
{
|
||||||
if(!m_RoutingSession)
|
if(!m_RoutingSession)
|
||||||
return DatagramSession::Info(nullptr, nullptr, m_LastUse);
|
return DatagramSession::Info(nullptr, nullptr, m_LastUse);
|
||||||
|
|
||||||
auto routingPath = m_RoutingSession->GetSharedRoutingPath();
|
auto routingPath = m_RoutingSession->GetSharedRoutingPath();
|
||||||
if (!routingPath)
|
if (!routingPath)
|
||||||
return DatagramSession::Info(nullptr, nullptr, m_LastUse);
|
return DatagramSession::Info(nullptr, nullptr, m_LastUse);
|
||||||
@@ -318,7 +318,7 @@ namespace datagram
|
|||||||
m_RoutingSession->SetSharedRoutingPath(path);
|
m_RoutingSession->SetSharedRoutingPath(path);
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls)
|
void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace datagram
|
|||||||
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner);
|
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner);
|
||||||
~DatagramDestination ();
|
~DatagramDestination ();
|
||||||
|
|
||||||
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
|
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
|
||||||
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
|
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ namespace client
|
|||||||
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
|
||||||
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
|
||||||
{
|
{
|
||||||
if (params)
|
if (params)
|
||||||
{
|
{
|
||||||
auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH);
|
auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
@@ -59,10 +59,16 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = params->find (I2CP_PARAM_INBOUND_NICKNAME);
|
it = params->find (I2CP_PARAM_INBOUND_NICKNAME);
|
||||||
if (it != params->end ()) m_Nickname = it->second; // otherwise we set deafult nickname in Start when we know local address
|
if (it != params->end ()) m_Nickname = it->second;
|
||||||
|
else // try outbound
|
||||||
|
{
|
||||||
|
it = params->find (I2CP_PARAM_OUTBOUND_NICKNAME);
|
||||||
|
if (it != params->end ()) m_Nickname = it->second;
|
||||||
|
// otherwise we set deafult nickname in Start when we know local address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception & ex)
|
catch (std::exception & ex)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
|
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
|
||||||
}
|
}
|
||||||
@@ -486,7 +492,7 @@ namespace client
|
|||||||
m_PublishReplyToken = 0;
|
m_PublishReplyToken = 0;
|
||||||
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
||||||
Publish ();
|
Publish ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -497,7 +503,7 @@ namespace client
|
|||||||
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
||||||
m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer,
|
m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,14 +728,14 @@ namespace client
|
|||||||
if (isPublic)
|
if (isPublic)
|
||||||
PersistTemporaryKeys ();
|
PersistTemporaryKeys ();
|
||||||
else
|
else
|
||||||
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
||||||
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
||||||
m_Decryptor = m_Keys.CreateDecryptor (m_EncryptionPrivateKey);
|
m_Decryptor = m_Keys.CreateDecryptor (m_EncryptionPrivateKey);
|
||||||
if (isPublic)
|
if (isPublic)
|
||||||
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
||||||
|
|
||||||
// extract streaming params
|
// extract streaming params
|
||||||
if (params)
|
if (params)
|
||||||
{
|
{
|
||||||
auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY);
|
auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
@@ -774,7 +780,7 @@ namespace client
|
|||||||
delete m_DatagramDestination;
|
delete m_DatagramDestination;
|
||||||
m_DatagramDestination = nullptr;
|
m_DatagramDestination = nullptr;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@@ -950,7 +956,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogPrint (eLogInfo, "Destination: Creating new temporary keys for address ", ident, ".b32.i2p");
|
LogPrint (eLogInfo, "Destination: Creating new temporary keys for address ", ident, ".b32.i2p");
|
||||||
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
||||||
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
||||||
|
|
||||||
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace client
|
|||||||
const uint8_t PROTOCOL_TYPE_DATAGRAM = 17;
|
const uint8_t PROTOCOL_TYPE_DATAGRAM = 17;
|
||||||
const uint8_t PROTOCOL_TYPE_RAW = 18;
|
const uint8_t PROTOCOL_TYPE_RAW = 18;
|
||||||
const int PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
|
const int PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
|
||||||
const int PUBLISH_VERIFICATION_TIMEOUT = 10; // in seconds after successfull publish
|
const int PUBLISH_VERIFICATION_TIMEOUT = 10; // in seconds after successful publish
|
||||||
const int PUBLISH_MIN_INTERVAL = 20; // in seconds
|
const int PUBLISH_MIN_INTERVAL = 20; // in seconds
|
||||||
const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically
|
const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically
|
||||||
const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds
|
const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds
|
||||||
@@ -51,6 +51,7 @@ namespace client
|
|||||||
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
|
const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend";
|
||||||
const int DEFAULT_TAGS_TO_SEND = 40;
|
const int DEFAULT_TAGS_TO_SEND = 40;
|
||||||
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
|
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
|
||||||
|
const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname";
|
||||||
|
|
||||||
// latency
|
// latency
|
||||||
const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min";
|
const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min";
|
||||||
@@ -189,9 +190,9 @@ namespace client
|
|||||||
void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); };
|
void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); };
|
||||||
|
|
||||||
// ref counter
|
// ref counter
|
||||||
int Acquire () { return ++m_RefCounter; };
|
int Acquire () { return ++m_RefCounter; };
|
||||||
int Release () { return --m_RefCounter; };
|
int Release () { return --m_RefCounter; };
|
||||||
int GetRefCounter () const { return m_RefCounter; };
|
int GetRefCounter () const { return m_RefCounter; };
|
||||||
|
|
||||||
// streaming
|
// streaming
|
||||||
std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (int port, bool gzip = true); // additional
|
std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (int port, bool gzip = true); // additional
|
||||||
@@ -238,7 +239,7 @@ namespace client
|
|||||||
int m_StreamingAckDelay;
|
int m_StreamingAckDelay;
|
||||||
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
|
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
|
||||||
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
|
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
|
||||||
i2p::datagram::DatagramDestination * m_DatagramDestination;
|
i2p::datagram::DatagramDestination * m_DatagramDestination;
|
||||||
int m_RefCounter; // how many clients(tunnels) use this destination
|
int m_RefCounter; // how many clients(tunnels) use this destination
|
||||||
|
|
||||||
boost::asio::deadline_timer m_ReadyChecker;
|
boost::asio::deadline_timer m_ReadyChecker;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
m_collected[key].Val += val;
|
m_collected[key].Val += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventCore::PumpCollected(EventListener * listener)
|
void EventCore::PumpCollected(EventListener * listener)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_collect_mutex);
|
std::unique_lock<std::mutex> lock(m_collect_mutex);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace i2p
|
|||||||
void CollectEvent(const std::string & type, const std::string & ident, uint64_t val);
|
void CollectEvent(const std::string & type, const std::string & ident, uint64_t val);
|
||||||
void SetListener(EventListener * l);
|
void SetListener(EventListener * l);
|
||||||
void PumpCollected(EventListener * l);
|
void PumpCollected(EventListener * l);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex m_collect_mutex;
|
std::mutex m_collect_mutex;
|
||||||
struct CollectedEvent
|
struct CollectedEvent
|
||||||
@@ -41,7 +41,7 @@ namespace i2p
|
|||||||
std::map<std::string, CollectedEvent> m_collected;
|
std::map<std::string, CollectedEvent> m_collected;
|
||||||
EventListener * m_listener = nullptr;
|
EventListener * m_listener = nullptr;
|
||||||
};
|
};
|
||||||
#ifdef WITH_EVENTS
|
#ifdef WITH_EVENTS
|
||||||
extern EventCore core;
|
extern EventCore core;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace fs {
|
|||||||
#else /* other unix */
|
#else /* other unix */
|
||||||
#if defined(ANDROID)
|
#if defined(ANDROID)
|
||||||
const char * ext = getenv("EXTERNAL_STORAGE");
|
const char * ext = getenv("EXTERNAL_STORAGE");
|
||||||
if (!ext) ext = "/sdcard";
|
if (!ext) ext = "/sdcard";
|
||||||
if (boost::filesystem::exists(ext))
|
if (boost::filesystem::exists(ext))
|
||||||
{
|
{
|
||||||
dataDir = std::string (ext) + "/" + appName;
|
dataDir = std::string (ext) + "/" + appName;
|
||||||
@@ -96,7 +96,7 @@ namespace fs {
|
|||||||
boost::filesystem::create_directory(destinations);
|
boost::filesystem::create_directory(destinations);
|
||||||
std::string tags = DataDirPath("tags");
|
std::string tags = DataDirPath("tags");
|
||||||
if (!boost::filesystem::exists(tags))
|
if (!boost::filesystem::exists(tags))
|
||||||
boost::filesystem::create_directory(tags);
|
boost::filesystem::create_directory(tags);
|
||||||
else
|
else
|
||||||
i2p::garlic::CleanUpTagsFiles ();
|
i2p::garlic::CleanUpTagsFiles ();
|
||||||
|
|
||||||
@@ -123,12 +123,12 @@ namespace fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetLastUpdateTime (const std::string & path)
|
uint32_t GetLastUpdateTime (const std::string & path)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::exists(path)) return 0;
|
if (!boost::filesystem::exists(path)) return 0;
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
auto t = boost::filesystem::last_write_time (path, ec);
|
auto t = boost::filesystem::last_write_time (path, ec);
|
||||||
return ec ? 0 : t;
|
return ec ? 0 : t;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Remove(const std::string & path) {
|
bool Remove(const std::string & path) {
|
||||||
if (!boost::filesystem::exists(path))
|
if (!boost::filesystem::exists(path))
|
||||||
@@ -136,7 +136,7 @@ namespace fs {
|
|||||||
return boost::filesystem::remove(path);
|
return boost::filesystem::remove(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreateDirectory (const std::string& path)
|
bool CreateDirectory (const std::string& path)
|
||||||
{
|
{
|
||||||
if (boost::filesystem::exists(path) &&
|
if (boost::filesystem::exists(path) &&
|
||||||
boost::filesystem::is_directory (boost::filesystem::status (path))) return true;
|
boost::filesystem::is_directory (boost::filesystem::status (path))) return true;
|
||||||
|
|||||||
10
libi2pd/FS.h
10
libi2pd/FS.h
@@ -97,7 +97,7 @@ namespace fs {
|
|||||||
* @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
|
||||||
*/
|
*/
|
||||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove file with given path
|
* @brief Remove file with given path
|
||||||
@@ -113,9 +113,9 @@ namespace fs {
|
|||||||
*/
|
*/
|
||||||
bool Exists(const std::string & path);
|
bool Exists(const std::string & path);
|
||||||
|
|
||||||
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
|
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
|
||||||
|
|
||||||
bool CreateDirectory (const std::string& path);
|
bool CreateDirectory (const std::string& path);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void _ExpandPath(std::stringstream & path, T c) {
|
void _ExpandPath(std::stringstream & path, T c) {
|
||||||
@@ -153,7 +153,7 @@ namespace fs {
|
|||||||
_ExpandPath(s, filenames...);
|
_ExpandPath(s, filenames...);
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // fs
|
} // fs
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|||||||
@@ -21,24 +21,24 @@ namespace data
|
|||||||
void Families::LoadCertificate (const std::string& filename)
|
void Families::LoadCertificate (const std::string& filename)
|
||||||
{
|
{
|
||||||
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
||||||
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
SSL * ssl = SSL_new (ctx);
|
SSL * ssl = SSL_new (ctx);
|
||||||
X509 * cert = SSL_get_certificate (ssl);
|
X509 * cert = SSL_get_certificate (ssl);
|
||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
std::shared_ptr<i2p::crypto::Verifier> verifier;
|
std::shared_ptr<i2p::crypto::Verifier> verifier;
|
||||||
// extract issuer name
|
// extract issuer name
|
||||||
char name[100];
|
char name[100];
|
||||||
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
||||||
char * cn = strstr (name, "CN=");
|
char * cn = strstr (name, "CN=");
|
||||||
if (cn)
|
if (cn)
|
||||||
{
|
{
|
||||||
cn += 3;
|
cn += 3;
|
||||||
char * family = strstr (cn, ".family");
|
char * family = strstr (cn, ".family");
|
||||||
if (family) family[0] = 0;
|
if (family) family[0] = 0;
|
||||||
}
|
}
|
||||||
auto pkey = X509_get_pubkey (cert);
|
auto pkey = X509_get_pubkey (cert);
|
||||||
int keyType = EVP_PKEY_base_id (pkey);
|
int keyType = EVP_PKEY_base_id (pkey);
|
||||||
switch (keyType)
|
switch (keyType)
|
||||||
@@ -65,7 +65,7 @@ namespace data
|
|||||||
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
||||||
BN_free (x); BN_free (y);
|
BN_free (x); BN_free (y);
|
||||||
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(signingKey);
|
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(signingKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||||
}
|
}
|
||||||
@@ -79,12 +79,12 @@ namespace data
|
|||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
if (verifier && cn)
|
if (verifier && cn)
|
||||||
m_SigningKeys[cn] = verifier;
|
m_SigningKeys[cn] = verifier;
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Family: Can't open certificate file ", filename);
|
LogPrint (eLogError, "Family: Can't open certificate file ", filename);
|
||||||
SSL_CTX_free (ctx);
|
SSL_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Families::LoadCertificates ()
|
void Families::LoadCertificates ()
|
||||||
@@ -105,11 +105,11 @@ namespace data
|
|||||||
}
|
}
|
||||||
LoadCertificate (file);
|
LoadCertificate (file);
|
||||||
numCertificates++;
|
numCertificates++;
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded");
|
LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
|
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
const char * signature, const char * key)
|
const char * signature, const char * key)
|
||||||
{
|
{
|
||||||
uint8_t buf[50], signatureBuf[64];
|
uint8_t buf[50], signatureBuf[64];
|
||||||
@@ -118,12 +118,12 @@ namespace data
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Family: ", family, " is too long");
|
LogPrint (eLogError, "Family: ", family, " is too long");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (buf, family.c_str (), len);
|
memcpy (buf, family.c_str (), len);
|
||||||
memcpy (buf + len, (const uint8_t *)ident, 32);
|
memcpy (buf + len, (const uint8_t *)ident, 32);
|
||||||
len += 32;
|
len += 32;
|
||||||
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
|
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
|
||||||
auto it = m_SigningKeys.find (family);
|
auto it = m_SigningKeys.find (family);
|
||||||
if (it != m_SigningKeys.end ())
|
if (it != m_SigningKeys.end ())
|
||||||
return it->second->Verify (buf, len, signatureBuf);
|
return it->second->Verify (buf, len, signatureBuf);
|
||||||
@@ -136,7 +136,7 @@ namespace data
|
|||||||
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
|
||||||
std::string sig;
|
std::string sig;
|
||||||
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
||||||
int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
SSL * ssl = SSL_new (ctx);
|
SSL * ssl = SSL_new (ctx);
|
||||||
@@ -167,15 +167,15 @@ namespace data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Family: Can't open keys file: ", filename);
|
LogPrint (eLogError, "Family: Can't open keys file: ", filename);
|
||||||
SSL_CTX_free (ctx);
|
SSL_CTX_free (ctx);
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace data
|
|||||||
Families ();
|
Families ();
|
||||||
~Families ();
|
~Families ();
|
||||||
void LoadCertificates ();
|
void LoadCertificates ();
|
||||||
bool VerifyFamily (const std::string& family, const IdentHash& ident,
|
bool VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
const char * signature, const char * key = nullptr);
|
const char * signature, const char * key = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -28,7 +28,7 @@ namespace data
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
|
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
|
||||||
// return base64 signature of empty string in case of failure
|
// return base64 signature of empty string in case of failure
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace garlic
|
namespace garlic
|
||||||
{
|
{
|
||||||
GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner,
|
GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner,
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
||||||
m_Owner (owner), m_Destination (destination), m_NumTags (numTags),
|
m_Owner (owner), m_Destination (destination), m_NumTags (numTags),
|
||||||
m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend),
|
m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend),
|
||||||
m_LeaseSetUpdateMsgID (0)
|
m_LeaseSetUpdateMsgID (0)
|
||||||
{
|
{
|
||||||
// create new session tags and session key
|
// create new session tags and session key
|
||||||
RAND_bytes (m_SessionKey, 32);
|
RAND_bytes (m_SessionKey, 32);
|
||||||
m_Encryption.SetKey (m_SessionKey);
|
m_Encryption.SetKey (m_SessionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag):
|
GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag):
|
||||||
m_Owner (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0)
|
m_Owner (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0)
|
||||||
@@ -35,10 +35,10 @@ namespace garlic
|
|||||||
m_Encryption.SetKey (m_SessionKey);
|
m_Encryption.SetKey (m_SessionKey);
|
||||||
m_SessionTags.push_back (sessionTag);
|
m_SessionTags.push_back (sessionTag);
|
||||||
m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch ();
|
m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GarlicRoutingSession::~GarlicRoutingSession ()
|
GarlicRoutingSession::~GarlicRoutingSession ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GarlicRoutingPath> GarlicRoutingSession::GetSharedRoutingPath ()
|
std::shared_ptr<GarlicRoutingPath> GarlicRoutingSession::GetSharedRoutingPath ()
|
||||||
@@ -53,56 +53,56 @@ namespace garlic
|
|||||||
if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++;
|
if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++;
|
||||||
return m_SharedRoutingPath;
|
return m_SharedRoutingPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicRoutingSession::SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path)
|
void GarlicRoutingSession::SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path)
|
||||||
{
|
{
|
||||||
if (path && path->outboundTunnel && path->remoteLease)
|
if (path && path->outboundTunnel && path->remoteLease)
|
||||||
{
|
{
|
||||||
path->updateTime = i2p::util::GetSecondsSinceEpoch ();
|
path->updateTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
path->numTimesUsed = 0;
|
path->numTimesUsed = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
path = nullptr;
|
path = nullptr;
|
||||||
m_SharedRoutingPath = path;
|
m_SharedRoutingPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
GarlicRoutingSession::UnconfirmedTags * GarlicRoutingSession::GenerateSessionTags ()
|
GarlicRoutingSession::UnconfirmedTags * GarlicRoutingSession::GenerateSessionTags ()
|
||||||
{
|
{
|
||||||
auto tags = new UnconfirmedTags (m_NumTags);
|
auto tags = new UnconfirmedTags (m_NumTags);
|
||||||
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
|
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (int i = 0; i < m_NumTags; i++)
|
for (int i = 0; i < m_NumTags; i++)
|
||||||
{
|
{
|
||||||
RAND_bytes (tags->sessionTags[i], 32);
|
RAND_bytes (tags->sessionTags[i], 32);
|
||||||
tags->sessionTags[i].creationTime = tags->tagsCreationTime;
|
tags->sessionTags[i].creationTime = tags->tagsCreationTime;
|
||||||
}
|
}
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicRoutingSession::MessageConfirmed (uint32_t msgID)
|
void GarlicRoutingSession::MessageConfirmed (uint32_t msgID)
|
||||||
{
|
{
|
||||||
TagsConfirmed (msgID);
|
TagsConfirmed (msgID);
|
||||||
if (msgID == m_LeaseSetUpdateMsgID)
|
if (msgID == m_LeaseSetUpdateMsgID)
|
||||||
{
|
{
|
||||||
m_LeaseSetUpdateStatus = eLeaseSetUpToDate;
|
m_LeaseSetUpdateStatus = eLeaseSetUpToDate;
|
||||||
m_LeaseSetUpdateMsgID = 0;
|
m_LeaseSetUpdateMsgID = 0;
|
||||||
LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed");
|
LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CleanupExpiredTags ();
|
CleanupExpiredTags ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
|
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
|
||||||
{
|
{
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
auto it = m_UnconfirmedTagsMsgs.find (msgID);
|
auto it = m_UnconfirmedTagsMsgs.find (msgID);
|
||||||
if (it != m_UnconfirmedTagsMsgs.end ())
|
if (it != m_UnconfirmedTagsMsgs.end ())
|
||||||
{
|
{
|
||||||
auto& tags = it->second;
|
auto& tags = it->second;
|
||||||
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tags->numTags; i++)
|
for (int i = 0; i < tags->numTags; i++)
|
||||||
m_SessionTags.push_back (tags->sessionTags[i]);
|
m_SessionTags.push_back (tags->sessionTags[i]);
|
||||||
}
|
}
|
||||||
m_UnconfirmedTagsMsgs.erase (it);
|
m_UnconfirmedTagsMsgs.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
it = m_SessionTags.erase (it);
|
it = m_SessionTags.erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
CleanupUnconfirmedTags ();
|
CleanupUnconfirmedTags ();
|
||||||
@@ -123,9 +123,9 @@ namespace garlic
|
|||||||
if (m_Owner)
|
if (m_Owner)
|
||||||
m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID);
|
m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID);
|
||||||
m_LeaseSetUpdateMsgID = 0;
|
m_LeaseSetUpdateMsgID = 0;
|
||||||
}
|
}
|
||||||
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GarlicRoutingSession::CleanupUnconfirmedTags ()
|
bool GarlicRoutingSession::CleanupUnconfirmedTags ()
|
||||||
{
|
{
|
||||||
@@ -140,10 +140,10 @@ namespace garlic
|
|||||||
m_Owner->RemoveDeliveryStatusSession (it->first);
|
m_Owner->RemoveDeliveryStatusSession (it->first);
|
||||||
it = m_UnconfirmedTagsMsgs.erase (it);
|
it = m_UnconfirmedTagsMsgs.erase (it);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +155,10 @@ namespace garlic
|
|||||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
|
|
||||||
// find non-expired tag
|
// find non-expired tag
|
||||||
bool tagFound = false;
|
bool tagFound = false;
|
||||||
SessionTag tag;
|
SessionTag tag;
|
||||||
if (m_NumTags > 0)
|
if (m_NumTags > 0)
|
||||||
{
|
{
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
while (!m_SessionTags.empty ())
|
while (!m_SessionTags.empty ())
|
||||||
{
|
{
|
||||||
@@ -168,11 +168,11 @@ namespace garlic
|
|||||||
m_SessionTags.pop_front (); // use same tag only once
|
m_SessionTags.pop_front (); // use same tag only once
|
||||||
tagFound = true;
|
tagFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_SessionTags.pop_front (); // remove expired tag
|
m_SessionTags.pop_front (); // remove expired tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create message
|
// create message
|
||||||
if (!tagFound) // new session
|
if (!tagFound) // new session
|
||||||
{
|
{
|
||||||
@@ -184,34 +184,34 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
// create ElGamal block
|
// create ElGamal block
|
||||||
ElGamalBlock elGamal;
|
ElGamalBlock elGamal;
|
||||||
memcpy (elGamal.sessionKey, m_SessionKey, 32);
|
memcpy (elGamal.sessionKey, m_SessionKey, 32);
|
||||||
RAND_bytes (elGamal.preIV, 32); // Pre-IV
|
RAND_bytes (elGamal.preIV, 32); // Pre-IV
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
SHA256(elGamal.preIV, 32, iv);
|
SHA256(elGamal.preIV, 32, iv);
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
m_Destination->Encrypt ((uint8_t *)&elGamal, buf, ctx);
|
m_Destination->Encrypt ((uint8_t *)&elGamal, buf, ctx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
m_Encryption.SetIV (iv);
|
m_Encryption.SetIV (iv);
|
||||||
buf += 514;
|
buf += 514;
|
||||||
len += 514;
|
len += 514;
|
||||||
}
|
}
|
||||||
else // existing session
|
else // existing session
|
||||||
{
|
{
|
||||||
// session tag
|
// session tag
|
||||||
memcpy (buf, tag, 32);
|
memcpy (buf, tag, 32);
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
SHA256(tag, 32, iv);
|
SHA256(tag, 32, iv);
|
||||||
m_Encryption.SetIV (iv);
|
m_Encryption.SetIV (iv);
|
||||||
buf += 32;
|
buf += 32;
|
||||||
len += 32;
|
len += 32;
|
||||||
}
|
}
|
||||||
// AES block
|
// AES block
|
||||||
len += CreateAESBlock (buf, msg);
|
len += CreateAESBlock (buf, msg);
|
||||||
htobe32buf (m->GetPayload (), len);
|
htobe32buf (m->GetPayload (), len);
|
||||||
m->len += len + 4;
|
m->len += len + 4;
|
||||||
m->FillI2NPMessageHeader (eI2NPGarlic);
|
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg)
|
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
@@ -221,13 +221,13 @@ namespace garlic
|
|||||||
htobuf16 (buf, newTags ? htobe16 (newTags->numTags) : 0); // tag count
|
htobuf16 (buf, newTags ? htobe16 (newTags->numTags) : 0); // tag count
|
||||||
blockSize += 2;
|
blockSize += 2;
|
||||||
if (newTags) // session tags recreated
|
if (newTags) // session tags recreated
|
||||||
{
|
{
|
||||||
for (int i = 0; i < newTags->numTags; i++)
|
for (int i = 0; i < newTags->numTags; i++)
|
||||||
{
|
{
|
||||||
memcpy (buf + blockSize, newTags->sessionTags[i], 32); // tags
|
memcpy (buf + blockSize, newTags->sessionTags[i], 32); // tags
|
||||||
blockSize += 32;
|
blockSize += 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t * payloadSize = (uint32_t *)(buf + blockSize);
|
uint32_t * payloadSize = (uint32_t *)(buf + blockSize);
|
||||||
blockSize += 4;
|
blockSize += 4;
|
||||||
uint8_t * payloadHash = buf + blockSize;
|
uint8_t * payloadHash = buf + blockSize;
|
||||||
@@ -243,7 +243,7 @@ namespace garlic
|
|||||||
blockSize += (16-rem); //padding
|
blockSize += (16-rem); //padding
|
||||||
m_Encryption.Encrypt(buf, blockSize, buf);
|
m_Encryption.Encrypt(buf, blockSize, buf);
|
||||||
return blockSize;
|
return blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags)
|
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags)
|
||||||
{
|
{
|
||||||
@@ -256,7 +256,7 @@ namespace garlic
|
|||||||
size++;
|
size++;
|
||||||
|
|
||||||
if (m_Owner)
|
if (m_Owner)
|
||||||
{
|
{
|
||||||
// resubmit non-confirmed LeaseSet
|
// resubmit non-confirmed LeaseSet
|
||||||
if (m_LeaseSetUpdateStatus == eLeaseSetSubmitted && ts > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT)
|
if (m_LeaseSetUpdateStatus == eLeaseSetSubmitted && ts > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
@@ -267,7 +267,7 @@ namespace garlic
|
|||||||
// attach DeviveryStatus if necessary
|
// attach DeviveryStatus if necessary
|
||||||
if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated
|
if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated
|
||||||
{
|
{
|
||||||
// clove is DeliveryStatus
|
// clove is DeliveryStatus
|
||||||
auto cloveSize = CreateDeliveryStatusClove (payload + size, msgID);
|
auto cloveSize = CreateDeliveryStatusClove (payload + size, msgID);
|
||||||
if (cloveSize > 0) // successive?
|
if (cloveSize > 0) // successive?
|
||||||
{
|
{
|
||||||
@@ -278,14 +278,14 @@ namespace garlic
|
|||||||
newTags->msgID = msgID;
|
newTags->msgID = msgID;
|
||||||
m_UnconfirmedTagsMsgs.insert (std::make_pair(msgID, std::unique_ptr<UnconfirmedTags>(newTags)));
|
m_UnconfirmedTagsMsgs.insert (std::make_pair(msgID, std::unique_ptr<UnconfirmedTags>(newTags)));
|
||||||
newTags = nullptr; // got acquired
|
newTags = nullptr; // got acquired
|
||||||
}
|
}
|
||||||
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
|
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: DeliveryStatus clove was not created");
|
LogPrint (eLogWarning, "Garlic: DeliveryStatus clove was not created");
|
||||||
}
|
}
|
||||||
// attach LeaseSet
|
// attach LeaseSet
|
||||||
if (m_LeaseSetUpdateStatus == eLeaseSetUpdated)
|
if (m_LeaseSetUpdateStatus == eLeaseSetUpdated)
|
||||||
{
|
{
|
||||||
if (m_LeaseSetUpdateMsgID) m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); // remove previous
|
if (m_LeaseSetUpdateMsgID) m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); // remove previous
|
||||||
m_LeaseSetUpdateStatus = eLeaseSetSubmitted;
|
m_LeaseSetUpdateStatus = eLeaseSetSubmitted;
|
||||||
@@ -293,25 +293,25 @@ namespace garlic
|
|||||||
m_LeaseSetSubmissionTime = ts;
|
m_LeaseSetSubmissionTime = ts;
|
||||||
// clove if our leaseSet must be attached
|
// clove if our leaseSet must be attached
|
||||||
auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ());
|
auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ());
|
||||||
size += CreateGarlicClove (payload + size, leaseSet, false);
|
size += CreateGarlicClove (payload + size, leaseSet, false);
|
||||||
(*numCloves)++;
|
(*numCloves)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg) // clove message ifself if presented
|
if (msg) // clove message ifself if presented
|
||||||
{
|
{
|
||||||
size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false);
|
size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false);
|
||||||
(*numCloves)++;
|
(*numCloves)++;
|
||||||
}
|
}
|
||||||
memset (payload + size, 0, 3); // certificate of message
|
memset (payload + size, 0, 3); // certificate of message
|
||||||
size += 3;
|
size += 3;
|
||||||
htobe32buf (payload + size, msgID); // MessageID
|
htobe32buf (payload + size, msgID); // MessageID
|
||||||
size += 4;
|
size += 4;
|
||||||
htobe64buf (payload + size, ts + 8000); // Expiration of message, 8 sec
|
htobe64buf (payload + size, ts + 8000); // Expiration of message, 8 sec
|
||||||
size += 8;
|
size += 8;
|
||||||
|
|
||||||
if (newTags) delete newTags; // not acquired, delete
|
if (newTags) delete newTags; // not acquired, delete
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg, bool isDestination)
|
size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg, bool isDestination)
|
||||||
{
|
{
|
||||||
@@ -323,13 +323,13 @@ namespace garlic
|
|||||||
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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
|
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
|
||||||
size += msg->GetLength ();
|
size += msg->GetLength ();
|
||||||
uint32_t cloveID;
|
uint32_t cloveID;
|
||||||
@@ -341,34 +341,34 @@ namespace garlic
|
|||||||
memset (buf + size, 0, 3); // certificate of clove
|
memset (buf + size, 0, 3); // certificate of clove
|
||||||
size += 3;
|
size += 3;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID)
|
size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (m_Owner)
|
if (m_Owner)
|
||||||
{
|
{
|
||||||
auto inboundTunnel = m_Owner->GetTunnelPool ()->GetNextInboundTunnel ();
|
auto inboundTunnel = m_Owner->GetTunnelPool ()->GetNextInboundTunnel ();
|
||||||
if (inboundTunnel)
|
if (inboundTunnel)
|
||||||
{
|
{
|
||||||
buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel
|
buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel
|
||||||
size++;
|
size++;
|
||||||
// hash and tunnelID sequence is reversed for Garlic
|
// hash and tunnelID sequence is reversed for Garlic
|
||||||
memcpy (buf + size, inboundTunnel->GetNextIdentHash (), 32); // To Hash
|
memcpy (buf + size, inboundTunnel->GetNextIdentHash (), 32); // To Hash
|
||||||
size += 32;
|
size += 32;
|
||||||
htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID
|
htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID
|
||||||
size += 4;
|
size += 4;
|
||||||
// create msg
|
// create msg
|
||||||
auto msg = CreateDeliveryStatusMsg (msgID);
|
auto msg = CreateDeliveryStatusMsg (msgID);
|
||||||
if (m_Owner)
|
if (m_Owner)
|
||||||
{
|
{
|
||||||
//encrypt
|
//encrypt
|
||||||
uint8_t key[32], tag[32];
|
uint8_t key[32], tag[32];
|
||||||
RAND_bytes (key, 32); // random session key
|
RAND_bytes (key, 32); // random session key
|
||||||
RAND_bytes (tag, 32); // random session tag
|
RAND_bytes (tag, 32); // random session tag
|
||||||
m_Owner->SubmitSessionKey (key, tag);
|
m_Owner->SubmitSessionKey (key, tag);
|
||||||
GarlicRoutingSession garlic (key, tag);
|
GarlicRoutingSession garlic (key, tag);
|
||||||
msg = garlic.WrapSingleMessage (msg);
|
msg = garlic.WrapSingleMessage (msg);
|
||||||
}
|
}
|
||||||
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
|
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
|
||||||
size += msg->GetLength ();
|
size += msg->GetLength ();
|
||||||
@@ -383,7 +383,7 @@ namespace garlic
|
|||||||
memset (buf + size, 0, 3); // certificate of clove
|
memset (buf + size, 0, 3); // certificate of clove
|
||||||
size += 3;
|
size += 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus");
|
LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -395,19 +395,19 @@ namespace garlic
|
|||||||
GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default
|
GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default
|
||||||
{
|
{
|
||||||
m_Ctx = BN_CTX_new ();
|
m_Ctx = BN_CTX_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GarlicDestination::~GarlicDestination ()
|
GarlicDestination::~GarlicDestination ()
|
||||||
{
|
{
|
||||||
BN_CTX_free (m_Ctx);
|
BN_CTX_free (m_Ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::CleanUp ()
|
void GarlicDestination::CleanUp ()
|
||||||
{
|
{
|
||||||
m_Sessions.clear ();
|
m_Sessions.clear ();
|
||||||
m_DeliveryStatusSessions.clear ();
|
m_DeliveryStatusSessions.clear ();
|
||||||
m_Tags.clear ();
|
m_Tags.clear ();
|
||||||
}
|
}
|
||||||
void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag)
|
void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag)
|
||||||
{
|
{
|
||||||
if (key)
|
if (key)
|
||||||
@@ -417,7 +417,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
|
bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
|
||||||
{
|
{
|
||||||
AddSessionKey (key, tag);
|
AddSessionKey (key, tag);
|
||||||
return true;
|
return true;
|
||||||
@@ -431,22 +431,22 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: message length ", length, " exceeds I2NP message length ", msg->GetLength ());
|
LogPrint (eLogWarning, "Garlic: message length ", length, " exceeds I2NP message length ", msg->GetLength ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buf += 4; // length
|
buf += 4; // length
|
||||||
auto it = m_Tags.find (SessionTag(buf));
|
auto it = m_Tags.find (SessionTag(buf));
|
||||||
if (it != m_Tags.end ())
|
if (it != m_Tags.end ())
|
||||||
{
|
{
|
||||||
// tag found. Use AES
|
// tag found. Use AES
|
||||||
auto decryption = it->second;
|
auto decryption = it->second;
|
||||||
m_Tags.erase (it); // tag might be used only once
|
m_Tags.erase (it); // tag might be used only once
|
||||||
if (length >= 32)
|
if (length >= 32)
|
||||||
{
|
{
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
SHA256(buf, 32, iv);
|
SHA256(buf, 32, iv);
|
||||||
decryption->SetIV (iv);
|
decryption->SetIV (iv);
|
||||||
decryption->Decrypt (buf + 32, length - 32, buf + 32);
|
decryption->Decrypt (buf + 32, length - 32, buf + 32);
|
||||||
HandleAESBlock (buf + 32, length - 32, decryption, msg->from);
|
HandleAESBlock (buf + 32, length - 32, decryption, msg->from);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes");
|
LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes");
|
||||||
}
|
}
|
||||||
@@ -455,35 +455,35 @@ namespace garlic
|
|||||||
// tag not found. Use ElGamal
|
// tag not found. Use ElGamal
|
||||||
ElGamalBlock elGamal;
|
ElGamalBlock elGamal;
|
||||||
if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx))
|
if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx))
|
||||||
{
|
{
|
||||||
auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey);
|
auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey);
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
SHA256(elGamal.preIV, 32, iv);
|
SHA256(elGamal.preIV, 32, iv);
|
||||||
decryption->SetIV (iv);
|
decryption->SetIV (iv);
|
||||||
decryption->Decrypt(buf + 514, length - 514, buf + 514);
|
decryption->Decrypt(buf + 514, length - 514, buf + 514);
|
||||||
HandleAESBlock (buf + 514, length - 514, decryption, msg->from);
|
HandleAESBlock (buf + 514, length - 514, decryption, msg->from);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||||
{
|
{
|
||||||
uint16_t tagCount = bufbe16toh (buf);
|
uint16_t tagCount = bufbe16toh (buf);
|
||||||
buf += 2; len -= 2;
|
buf += 2; len -= 2;
|
||||||
if (tagCount > 0)
|
if (tagCount > 0)
|
||||||
{
|
{
|
||||||
if (tagCount*32 > len)
|
if (tagCount*32 > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Tag count ", tagCount, " exceeds length ", len);
|
LogPrint (eLogError, "Garlic: Tag count ", tagCount, " exceeds length ", len);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (int i = 0; i < tagCount; i++)
|
for (int i = 0; i < tagCount; i++)
|
||||||
m_Tags[SessionTag(buf + i*32, ts)] = decryption;
|
m_Tags[SessionTag(buf + i*32, ts)] = decryption;
|
||||||
}
|
}
|
||||||
buf += tagCount*32;
|
buf += tagCount*32;
|
||||||
len -= tagCount*32;
|
len -= tagCount*32;
|
||||||
uint32_t payloadSize = bufbe32toh (buf);
|
uint32_t payloadSize = bufbe32toh (buf);
|
||||||
@@ -491,10 +491,10 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Unexpected payload size ", payloadSize);
|
LogPrint (eLogError, "Garlic: Unexpected payload size ", payloadSize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buf += 4;
|
buf += 4;
|
||||||
uint8_t * payloadHash = buf;
|
uint8_t * payloadHash = buf;
|
||||||
buf += 32;// payload hash.
|
buf += 32;// payload hash.
|
||||||
if (*buf) // session key?
|
if (*buf) // session key?
|
||||||
buf += 32; // new session key
|
buf += 32; // new session key
|
||||||
buf++; // flag
|
buf++; // flag
|
||||||
@@ -506,9 +506,9 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: wrong payload hash");
|
LogPrint (eLogError, "Garlic: wrong payload hash");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HandleGarlicPayload (buf, payloadSize, from);
|
HandleGarlicPayload (buf, payloadSize, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
void GarlicDestination::HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||||
{
|
{
|
||||||
@@ -530,8 +530,8 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
LogPrint (eLogWarning, "Garlic: clove encrypted");
|
LogPrint (eLogWarning, "Garlic: clove encrypted");
|
||||||
buf += 32;
|
buf += 32;
|
||||||
}
|
}
|
||||||
ptrdiff_t offset = buf - buf1;
|
ptrdiff_t offset = buf - buf1;
|
||||||
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
|
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
|
||||||
switch (deliveryType)
|
switch (deliveryType)
|
||||||
@@ -542,27 +542,27 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: message is too short");
|
LogPrint (eLogError, "Garlic: message is too short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HandleI2NPMessage (buf, len - offset, from);
|
HandleI2NPMessage (buf, len - offset, from);
|
||||||
break;
|
break;
|
||||||
case eGarlicDeliveryTypeDestination:
|
case eGarlicDeliveryTypeDestination:
|
||||||
LogPrint (eLogDebug, "Garlic: type destination");
|
LogPrint (eLogDebug, "Garlic: type destination");
|
||||||
buf += 32; // destination. check it later or for multiple destinations
|
buf += 32; // destination. check it later or for multiple destinations
|
||||||
offset = buf1 - buf;
|
offset = buf - buf1;
|
||||||
if (offset > (int)len)
|
if (offset > (int)len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: message is too short");
|
LogPrint (eLogError, "Garlic: message is too short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HandleI2NPMessage (buf, len - offset, from);
|
HandleI2NPMessage (buf, len - offset, from);
|
||||||
break;
|
break;
|
||||||
case eGarlicDeliveryTypeTunnel:
|
case eGarlicDeliveryTypeTunnel:
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||||
// gwHash and gwTunnel sequence is reverted
|
// gwHash and gwTunnel sequence is reverted
|
||||||
uint8_t * gwHash = buf;
|
uint8_t * gwHash = buf;
|
||||||
buf += 32;
|
buf += 32;
|
||||||
offset = buf1 - buf;
|
offset = buf - buf1;
|
||||||
if (offset + 4 > (int)len)
|
if (offset + 4 > (int)len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: message is too short");
|
LogPrint (eLogError, "Garlic: message is too short");
|
||||||
@@ -591,7 +591,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
uint8_t * ident = buf;
|
uint8_t * ident = buf;
|
||||||
buf += 32;
|
buf += 32;
|
||||||
offset = buf1 - buf;
|
offset = buf - buf1;
|
||||||
if (!from) // received directly
|
if (!from) // received directly
|
||||||
{
|
{
|
||||||
if (offset > (int)len)
|
if (offset > (int)len)
|
||||||
@@ -604,7 +604,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
|
LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
|
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
|
||||||
@@ -618,28 +618,28 @@ namespace garlic
|
|||||||
buf += 4; // CloveID
|
buf += 4; // CloveID
|
||||||
buf += 8; // Date
|
buf += 8; // Date
|
||||||
buf += 3; // Certificate
|
buf += 3; // Certificate
|
||||||
offset = buf1 - buf;
|
offset = buf - buf1;
|
||||||
if (offset > (int)len)
|
if (offset > (int)len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: clove is too long");
|
LogPrint (eLogError, "Garlic: clove is too long");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len -= offset;
|
len -= offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> GarlicDestination::WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
std::shared_ptr<I2NPMessage> GarlicDestination::WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
||||||
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet)
|
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet)
|
||||||
{
|
{
|
||||||
auto session = GetRoutingSession (destination, attachLeaseSet);
|
auto session = GetRoutingSession (destination, attachLeaseSet);
|
||||||
return session->WrapSingleMessage (msg);
|
return session->WrapSingleMessage (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
|
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
|
||||||
{
|
{
|
||||||
GarlicRoutingSessionPtr session;
|
GarlicRoutingSessionPtr session;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
auto it = m_Sessions.find (destination->GetIdentHash ());
|
auto it = m_Sessions.find (destination->GetIdentHash ());
|
||||||
if (it != m_Sessions.end ())
|
if (it != m_Sessions.end ())
|
||||||
@@ -647,14 +647,14 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
session = std::make_shared<GarlicRoutingSession> (this, destination,
|
session = std::make_shared<GarlicRoutingSession> (this, destination,
|
||||||
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
m_Sessions[destination->GetIdentHash ()] = session;
|
m_Sessions[destination->GetIdentHash ()] = session;
|
||||||
}
|
}
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::CleanupExpiredTags ()
|
void GarlicDestination::CleanupExpiredTags ()
|
||||||
{
|
{
|
||||||
// incoming
|
// incoming
|
||||||
@@ -666,7 +666,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
numExpiredTags++;
|
numExpiredTags++;
|
||||||
it = m_Tags.erase (it);
|
it = m_Tags.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
@@ -690,7 +690,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// delivery status sessions
|
// delivery status sessions
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_DeliveryStatusSessionsMutex);
|
std::unique_lock<std::mutex> l(m_DeliveryStatusSessionsMutex);
|
||||||
for (auto it = m_DeliveryStatusSessions.begin (); it != m_DeliveryStatusSessions.end (); )
|
for (auto it = m_DeliveryStatusSessions.begin (); it != m_DeliveryStatusSessions.end (); )
|
||||||
{
|
{
|
||||||
@@ -699,7 +699,7 @@ namespace garlic
|
|||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID)
|
void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID)
|
||||||
@@ -756,7 +756,7 @@ namespace garlic
|
|||||||
if (m_Tags.empty ()) return;
|
if (m_Tags.empty ()) return;
|
||||||
std::string ident = GetIdentHash().ToBase32();
|
std::string ident = GetIdentHash().ToBase32();
|
||||||
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
||||||
std::ofstream f (path, std::ofstream::binary | std::ofstream::out | std::ofstream::trunc);
|
std::ofstream f (path, std::ofstream::binary | std::ofstream::out | std::ofstream::trunc);
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
||||||
for (auto it: m_Tags)
|
for (auto it: m_Tags)
|
||||||
@@ -766,7 +766,7 @@ namespace garlic
|
|||||||
f.write ((char *)&it.first.creationTime, 4);
|
f.write ((char *)&it.first.creationTime, 4);
|
||||||
f.write ((char *)it.first.data (), 32);
|
f.write ((char *)it.first.data (), 32);
|
||||||
f.write ((char *)it.second->GetKey ().data (), 32);
|
f.write ((char *)it.second->GetKey ().data (), 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,11 +775,11 @@ namespace garlic
|
|||||||
std::string ident = GetIdentHash().ToBase32();
|
std::string ident = GetIdentHash().ToBase32();
|
||||||
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (ts < i2p::fs::GetLastUpdateTime (path) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts < i2p::fs::GetLastUpdateTime (path) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
// might contain non-expired tags
|
// might contain non-expired tags
|
||||||
std::ifstream f (path, std::ifstream::binary);
|
std::ifstream f (path, std::ifstream::binary);
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
std::map<i2p::crypto::AESKey, std::shared_ptr<AESDecryption> > keys;
|
std::map<i2p::crypto::AESKey, std::shared_ptr<AESDecryption> > keys;
|
||||||
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
||||||
@@ -794,7 +794,7 @@ namespace garlic
|
|||||||
f.read ((char *)key, 32);
|
f.read ((char *)key, 32);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
f.seekg (64, std::ios::cur); // skip
|
f.seekg (64, std::ios::cur); // skip
|
||||||
if (f.eof ()) break;
|
if (f.eof ()) break;
|
||||||
|
|
||||||
std::shared_ptr<AESDecryption> decryption;
|
std::shared_ptr<AESDecryption> decryption;
|
||||||
@@ -805,21 +805,21 @@ namespace garlic
|
|||||||
decryption = std::make_shared<AESDecryption>(key);
|
decryption = std::make_shared<AESDecryption>(key);
|
||||||
m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption));
|
m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption));
|
||||||
}
|
}
|
||||||
if (!m_Tags.empty ())
|
if (!m_Tags.empty ())
|
||||||
LogPrint (eLogInfo, m_Tags.size (), " loaded for ", ident);
|
LogPrint (eLogInfo, m_Tags.size (), " loaded for ", ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2p::fs::Remove (path);
|
i2p::fs::Remove (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUpTagsFiles ()
|
void CleanUpTagsFiles ()
|
||||||
{
|
{
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
100
libi2pd/Garlic.h
100
libi2pd/Garlic.h
@@ -17,46 +17,46 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
class OutboundTunnel;
|
class OutboundTunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace garlic
|
namespace garlic
|
||||||
{
|
{
|
||||||
|
|
||||||
enum GarlicDeliveryType
|
enum GarlicDeliveryType
|
||||||
{
|
{
|
||||||
eGarlicDeliveryTypeLocal = 0,
|
eGarlicDeliveryTypeLocal = 0,
|
||||||
eGarlicDeliveryTypeDestination = 1,
|
eGarlicDeliveryTypeDestination = 1,
|
||||||
eGarlicDeliveryTypeRouter = 2,
|
eGarlicDeliveryTypeRouter = 2,
|
||||||
eGarlicDeliveryTypeTunnel = 3
|
eGarlicDeliveryTypeTunnel = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ElGamalBlock
|
struct ElGamalBlock
|
||||||
{
|
{
|
||||||
uint8_t sessionKey[32];
|
uint8_t sessionKey[32];
|
||||||
uint8_t preIV[32];
|
uint8_t preIV[32];
|
||||||
uint8_t padding[158];
|
uint8_t padding[158];
|
||||||
};
|
};
|
||||||
|
|
||||||
const int INCOMING_TAGS_EXPIRATION_TIMEOUT = 960; // 16 minutes
|
const int INCOMING_TAGS_EXPIRATION_TIMEOUT = 960; // 16 minutes
|
||||||
const int OUTGOING_TAGS_EXPIRATION_TIMEOUT = 720; // 12 minutes
|
const int OUTGOING_TAGS_EXPIRATION_TIMEOUT = 720; // 12 minutes
|
||||||
const int OUTGOING_TAGS_CONFIRMATION_TIMEOUT = 10; // 10 seconds
|
const int OUTGOING_TAGS_CONFIRMATION_TIMEOUT = 10; // 10 seconds
|
||||||
const int LEASET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds
|
const int LEASET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds
|
||||||
const int ROUTING_PATH_EXPIRATION_TIMEOUT = 30; // 30 seconds
|
const int ROUTING_PATH_EXPIRATION_TIMEOUT = 30; // 30 seconds
|
||||||
const int ROUTING_PATH_MAX_NUM_TIMES_USED = 100; // how many times might be used
|
const int ROUTING_PATH_MAX_NUM_TIMES_USED = 100; // how many times might be used
|
||||||
|
|
||||||
struct SessionTag: public i2p::data::Tag<32>
|
struct SessionTag: public i2p::data::Tag<32>
|
||||||
{
|
{
|
||||||
SessionTag (const uint8_t * buf, uint32_t ts = 0): Tag<32>(buf), creationTime (ts) {};
|
SessionTag (const uint8_t * buf, uint32_t ts = 0): Tag<32>(buf), creationTime (ts) {};
|
||||||
SessionTag () = default;
|
SessionTag () = default;
|
||||||
SessionTag (const SessionTag& ) = default;
|
SessionTag (const SessionTag& ) = default;
|
||||||
SessionTag& operator= (const SessionTag& ) = default;
|
SessionTag& operator= (const SessionTag& ) = default;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
SessionTag (SessionTag&& ) = default;
|
SessionTag (SessionTag&& ) = default;
|
||||||
SessionTag& operator= (SessionTag&& ) = default;
|
SessionTag& operator= (SessionTag&& ) = default;
|
||||||
#endif
|
#endif
|
||||||
uint32_t creationTime; // seconds since epoch
|
uint32_t creationTime; // seconds since epoch
|
||||||
};
|
};
|
||||||
|
|
||||||
// AESDecryption is associated with session tags and store key
|
// AESDecryption is associated with session tags and store key
|
||||||
@@ -67,7 +67,7 @@ namespace garlic
|
|||||||
AESDecryption (const uint8_t * key): m_Key (key)
|
AESDecryption (const uint8_t * key): m_Key (key)
|
||||||
{
|
{
|
||||||
SetKey (key);
|
SetKey (key);
|
||||||
}
|
}
|
||||||
const i2p::crypto::AESKey& GetKey () const { return m_Key; };
|
const i2p::crypto::AESKey& GetKey () const { return m_Key; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -81,8 +81,8 @@ namespace garlic
|
|||||||
std::shared_ptr<const i2p::data::Lease> remoteLease;
|
std::shared_ptr<const i2p::data::Lease> remoteLease;
|
||||||
int rtt; // RTT
|
int rtt; // RTT
|
||||||
uint32_t updateTime; // seconds since epoch
|
uint32_t updateTime; // seconds since epoch
|
||||||
int numTimesUsed;
|
int numTimesUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GarlicDestination;
|
class GarlicDestination;
|
||||||
class GarlicRoutingSession: public std::enable_shared_from_this<GarlicRoutingSession>
|
class GarlicRoutingSession: public std::enable_shared_from_this<GarlicRoutingSession>
|
||||||
@@ -94,7 +94,7 @@ namespace garlic
|
|||||||
eLeaseSetSubmitted,
|
eLeaseSetSubmitted,
|
||||||
eLeaseSetDoNotSend
|
eLeaseSetDoNotSend
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnconfirmedTags
|
struct UnconfirmedTags
|
||||||
{
|
{
|
||||||
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
||||||
@@ -107,23 +107,23 @@ namespace garlic
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
||||||
int numTags, bool attachLeaseSet);
|
int numTags, bool attachLeaseSet);
|
||||||
GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
|
GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
|
||||||
~GarlicRoutingSession ();
|
~GarlicRoutingSession ();
|
||||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void MessageConfirmed (uint32_t msgID);
|
void MessageConfirmed (uint32_t msgID);
|
||||||
bool CleanupExpiredTags (); // returns true if something left
|
bool CleanupExpiredTags (); // returns true if something left
|
||||||
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
|
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
|
||||||
|
|
||||||
void SetLeaseSetUpdated ()
|
void SetLeaseSetUpdated ()
|
||||||
{
|
{
|
||||||
if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated;
|
if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated;
|
||||||
};
|
};
|
||||||
bool IsLeaseSetNonConfirmed () const { return m_LeaseSetUpdateStatus == eLeaseSetSubmitted; };
|
bool IsLeaseSetNonConfirmed () const { return m_LeaseSetUpdateStatus == eLeaseSetSubmitted; };
|
||||||
bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; };
|
bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; };
|
||||||
uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; }
|
uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; }
|
||||||
|
|
||||||
std::shared_ptr<GarlicRoutingPath> GetSharedRoutingPath ();
|
std::shared_ptr<GarlicRoutingPath> GetSharedRoutingPath ();
|
||||||
void SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path);
|
void SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path);
|
||||||
|
|
||||||
@@ -144,26 +144,26 @@ namespace garlic
|
|||||||
|
|
||||||
GarlicDestination * m_Owner;
|
GarlicDestination * m_Owner;
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> m_Destination;
|
std::shared_ptr<const i2p::data::RoutingDestination> m_Destination;
|
||||||
|
|
||||||
i2p::crypto::AESKey m_SessionKey;
|
i2p::crypto::AESKey m_SessionKey;
|
||||||
std::list<SessionTag> m_SessionTags;
|
std::list<SessionTag> m_SessionTags;
|
||||||
int m_NumTags;
|
int m_NumTags;
|
||||||
std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
|
std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
|
||||||
|
|
||||||
LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
|
LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
|
||||||
uint32_t m_LeaseSetUpdateMsgID;
|
uint32_t m_LeaseSetUpdateMsgID;
|
||||||
uint64_t m_LeaseSetSubmissionTime; // in milliseconds
|
uint64_t m_LeaseSetSubmissionTime; // in milliseconds
|
||||||
|
|
||||||
i2p::crypto::CBCEncryption m_Encryption;
|
i2p::crypto::CBCEncryption m_Encryption;
|
||||||
|
|
||||||
std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
|
std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
||||||
};
|
};
|
||||||
//using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
|
//using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
|
||||||
typedef std::shared_ptr<GarlicRoutingSession> GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8
|
typedef std::shared_ptr<GarlicRoutingSession> GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8
|
||||||
|
|
||||||
class GarlicDestination: public i2p::data::LocalDestination
|
class GarlicDestination: public i2p::data::LocalDestination
|
||||||
{
|
{
|
||||||
@@ -173,36 +173,36 @@ namespace garlic
|
|||||||
~GarlicDestination ();
|
~GarlicDestination ();
|
||||||
|
|
||||||
void CleanUp ();
|
void CleanUp ();
|
||||||
void SetNumTags (int numTags) { m_NumTags = numTags; };
|
void SetNumTags (int numTags) { m_NumTags = numTags; };
|
||||||
std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet);
|
std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet);
|
||||||
void CleanupExpiredTags ();
|
void CleanupExpiredTags ();
|
||||||
void RemoveDeliveryStatusSession (uint32_t msgID);
|
void RemoveDeliveryStatusSession (uint32_t msgID);
|
||||||
std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
||||||
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
|
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
|
||||||
|
|
||||||
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
||||||
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
||||||
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
||||||
|
|
||||||
virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
virtual void SetLeaseSetUpdated ();
|
virtual void SetLeaseSetUpdated ();
|
||||||
|
|
||||||
virtual std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet () = 0; // TODO
|
virtual std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet () = 0; // TODO
|
||||||
virtual std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const = 0;
|
virtual std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const = 0;
|
||||||
virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from) = 0;
|
virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
void SaveTags ();
|
void SaveTags ();
|
||||||
void LoadTags ();
|
void LoadTags ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
||||||
void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
||||||
|
|
||||||
@@ -218,17 +218,17 @@ namespace garlic
|
|||||||
// DeliveryStatus
|
// DeliveryStatus
|
||||||
std::mutex m_DeliveryStatusSessionsMutex;
|
std::mutex m_DeliveryStatusSessionsMutex;
|
||||||
std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
size_t GetNumIncomingTags () const { return m_Tags.size (); }
|
size_t GetNumIncomingTags () const { return m_Tags.size (); }
|
||||||
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
||||||
};
|
};
|
||||||
|
|
||||||
void CleanUpTagsFiles ();
|
void CleanUpTagsFiles ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
134
libi2pd/Gost.cpp
134
libi2pd/Gost.cpp
@@ -28,7 +28,7 @@ namespace crypto
|
|||||||
GOSTR3410Curve::~GOSTR3410Curve ()
|
GOSTR3410Curve::~GOSTR3410Curve ()
|
||||||
{
|
{
|
||||||
EC_GROUP_free (m_Group);
|
EC_GROUP_free (m_Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_POINT * GOSTR3410Curve::MulP (const BIGNUM * n) const
|
EC_POINT * GOSTR3410Curve::MulP (const BIGNUM * n) const
|
||||||
{
|
{
|
||||||
@@ -81,12 +81,12 @@ namespace crypto
|
|||||||
BN_mod_inverse (h, h, q, ctx); // 1/h mod q
|
BN_mod_inverse (h, h, q, ctx); // 1/h mod q
|
||||||
BIGNUM * z1 = BN_CTX_get (ctx);
|
BIGNUM * z1 = BN_CTX_get (ctx);
|
||||||
BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h
|
BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h
|
||||||
BIGNUM * z2 = BN_CTX_get (ctx);
|
BIGNUM * z2 = BN_CTX_get (ctx);
|
||||||
BN_sub (z2, q, r); // z2 = -r
|
BN_sub (z2, q, r); // z2 = -r
|
||||||
BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h
|
BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h
|
||||||
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 ?
|
||||||
@@ -94,9 +94,9 @@ namespace crypto
|
|||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_POINT * GOSTR3410Curve::RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY) const
|
EC_POINT * GOSTR3410Curve::RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY) const
|
||||||
{
|
{
|
||||||
// s*P = r*Q + h*C
|
// s*P = r*Q + h*C
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
@@ -104,7 +104,7 @@ namespace crypto
|
|||||||
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);
|
||||||
BIGNUM * q = BN_CTX_get (ctx);
|
BIGNUM * q = BN_CTX_get (ctx);
|
||||||
@@ -112,28 +112,28 @@ namespace crypto
|
|||||||
BIGNUM * h = BN_CTX_get (ctx);
|
BIGNUM * h = BN_CTX_get (ctx);
|
||||||
BN_mod (h, digest, q, ctx); // h = digest % q
|
BN_mod (h, digest, q, ctx); // h = digest % q
|
||||||
BN_sub (h, q, h); // h = -h
|
BN_sub (h, q, h); // h = -h
|
||||||
EC_POINT * H = EC_POINT_new (m_Group);
|
EC_POINT * H = EC_POINT_new (m_Group);
|
||||||
EC_POINT_mul (m_Group, H, nullptr, C, h, ctx); // -h*C
|
EC_POINT_mul (m_Group, H, nullptr, C, h, ctx); // -h*C
|
||||||
EC_POINT_add (m_Group, C, S, H, ctx); // s*P - h*C
|
EC_POINT_add (m_Group, C, S, H, ctx); // s*P - h*C
|
||||||
EC_POINT_free (H);
|
EC_POINT_free (H);
|
||||||
EC_POINT_free (S);
|
EC_POINT_free (S);
|
||||||
BIGNUM * r1 = BN_CTX_get (ctx);
|
BIGNUM * r1 = BN_CTX_get (ctx);
|
||||||
BN_mod_inverse (r1, r, q, ctx);
|
BN_mod_inverse (r1, r, q, ctx);
|
||||||
Q = EC_POINT_new (m_Group);
|
Q = EC_POINT_new (m_Group);
|
||||||
EC_POINT_mul (m_Group, Q, nullptr, C, r1, ctx); // (s*P - h*C)/r
|
EC_POINT_mul (m_Group, Q, nullptr, C, r1, ctx); // (s*P - h*C)/r
|
||||||
}
|
}
|
||||||
EC_POINT_free (C);
|
EC_POINT_free (C);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
return Q;
|
return Q;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GOSTR3410Curve * CreateGOSTR3410Curve (GOSTR3410ParamSet paramSet)
|
static GOSTR3410Curve * CreateGOSTR3410Curve (GOSTR3410ParamSet paramSet)
|
||||||
{
|
{
|
||||||
// a, b, p, q, x, y
|
// a, b, p, q, x, y
|
||||||
static const char * params[eGOSTR3410NumParamSets][6] =
|
static const char * params[eGOSTR3410NumParamSets][6] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
|
||||||
"A6",
|
"A6",
|
||||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
|
||||||
@@ -147,10 +147,10 @@ namespace crypto
|
|||||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",
|
||||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275",
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275",
|
||||||
"3",
|
"3",
|
||||||
"7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4"
|
"7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4"
|
||||||
} // tc26-2012-paramSetA-512
|
} // tc26-2012-paramSetA-512
|
||||||
};
|
};
|
||||||
|
|
||||||
BIGNUM * a = nullptr, * b = nullptr, * p = nullptr, * q =nullptr, * x = nullptr, * y = nullptr;
|
BIGNUM * a = nullptr, * b = nullptr, * p = nullptr, * q =nullptr, * x = nullptr, * y = nullptr;
|
||||||
BN_hex2bn(&a, params[paramSet][0]);
|
BN_hex2bn(&a, params[paramSet][0]);
|
||||||
BN_hex2bn(&b, params[paramSet][1]);
|
BN_hex2bn(&b, params[paramSet][1]);
|
||||||
@@ -161,25 +161,25 @@ namespace crypto
|
|||||||
auto curve = new GOSTR3410Curve (a, b, p, q, x, y);
|
auto curve = new GOSTR3410Curve (a, b, p, q, x, y);
|
||||||
BN_free (a); BN_free (b); BN_free (p); BN_free (q); BN_free (x); BN_free (y);
|
BN_free (a); BN_free (b); BN_free (p); BN_free (q); BN_free (x); BN_free (y);
|
||||||
return curve;
|
return curve;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::array<std::unique_ptr<GOSTR3410Curve>, eGOSTR3410NumParamSets> g_GOSTR3410Curves;
|
static std::array<std::unique_ptr<GOSTR3410Curve>, eGOSTR3410NumParamSets> g_GOSTR3410Curves;
|
||||||
std::unique_ptr<GOSTR3410Curve>& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet)
|
std::unique_ptr<GOSTR3410Curve>& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet)
|
||||||
{
|
{
|
||||||
if (!g_GOSTR3410Curves[paramSet])
|
if (!g_GOSTR3410Curves[paramSet])
|
||||||
{
|
{
|
||||||
auto c = CreateGOSTR3410Curve (paramSet);
|
auto c = CreateGOSTR3410Curve (paramSet);
|
||||||
if (!g_GOSTR3410Curves[paramSet]) // make sure it was not created already
|
if (!g_GOSTR3410Curves[paramSet]) // make sure it was not created already
|
||||||
g_GOSTR3410Curves[paramSet].reset (c);
|
g_GOSTR3410Curves[paramSet].reset (c);
|
||||||
else
|
else
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
return g_GOSTR3410Curves[paramSet];
|
return g_GOSTR3410Curves[paramSet];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ГОСТ 34.11-2012
|
// ГОСТ 34.11-2012
|
||||||
|
|
||||||
static const uint64_t T0[256] =
|
static const uint64_t T0[256] =
|
||||||
{
|
{
|
||||||
0xE6F87E5C5B711FD0, 0x258377800924FA16, 0xC849E07E852EA4A8, 0x5B4686A18F06C16A,
|
0xE6F87E5C5B711FD0, 0x258377800924FA16, 0xC849E07E852EA4A8, 0x5B4686A18F06C16A,
|
||||||
0x0B32E9A2D77B416E, 0xABDA37A467815C66, 0xF61796A81A686676, 0xF5DC0B706391954B,
|
0x0B32E9A2D77B416E, 0xABDA37A467815C66, 0xF61796A81A686676, 0xF5DC0B706391954B,
|
||||||
@@ -246,7 +246,7 @@ namespace crypto
|
|||||||
0x92BDE697D67F3422, 0xC78933E10514BC61, 0xE1C1D9B975C9B54A, 0xD2266160CF1BCD80,
|
0x92BDE697D67F3422, 0xC78933E10514BC61, 0xE1C1D9B975C9B54A, 0xD2266160CF1BCD80,
|
||||||
0x9A4492ED78FD8671, 0xB3CCAB2A881A9793, 0x72CEBF667FE1D088, 0xD6D45B5D985A9427
|
0x9A4492ED78FD8671, 0xB3CCAB2A881A9793, 0x72CEBF667FE1D088, 0xD6D45B5D985A9427
|
||||||
};
|
};
|
||||||
static const uint64_t T1[256] =
|
static const uint64_t T1[256] =
|
||||||
{
|
{
|
||||||
0xC811A8058C3F55DE, 0x65F5B43196B50619, 0xF74F96B1D6706E43, 0x859D1E8BCB43D336,
|
0xC811A8058C3F55DE, 0x65F5B43196B50619, 0xF74F96B1D6706E43, 0x859D1E8BCB43D336,
|
||||||
0x5AAB8A85CCFA3D84, 0xF9C7BF99C295FCFD, 0xA21FD5A1DE4B630F, 0xCDB3EF763B8B456D,
|
0x5AAB8A85CCFA3D84, 0xF9C7BF99C295FCFD, 0xA21FD5A1DE4B630F, 0xCDB3EF763B8B456D,
|
||||||
@@ -313,7 +313,7 @@ namespace crypto
|
|||||||
0x57B69E77B57354A0, 0x3969441D8097D0B4, 0x3330CAFBF3E2F0CF, 0xE28E77DDE0BE8CC3,
|
0x57B69E77B57354A0, 0x3969441D8097D0B4, 0x3330CAFBF3E2F0CF, 0xE28E77DDE0BE8CC3,
|
||||||
0x62B12E259C494F46, 0xA6CE726FB9DBD1CA, 0x41E242C1EED14DBA, 0x76032FF47AA30FB0
|
0x62B12E259C494F46, 0xA6CE726FB9DBD1CA, 0x41E242C1EED14DBA, 0x76032FF47AA30FB0
|
||||||
};
|
};
|
||||||
static const uint64_t T2[256] =
|
static const uint64_t T2[256] =
|
||||||
{
|
{
|
||||||
0x45B268A93ACDE4CC, 0xAF7F0BE884549D08, 0x048354B3C1468263, 0x925435C2C80EFED2,
|
0x45B268A93ACDE4CC, 0xAF7F0BE884549D08, 0x048354B3C1468263, 0x925435C2C80EFED2,
|
||||||
0xEE4E37F27FDFFBA7, 0x167A33920C60F14D, 0xFB123B52EA03E584, 0x4A0CAB53FDBB9007,
|
0xEE4E37F27FDFFBA7, 0x167A33920C60F14D, 0xFB123B52EA03E584, 0x4A0CAB53FDBB9007,
|
||||||
@@ -380,7 +380,7 @@ namespace crypto
|
|||||||
0xF9DD11850420A43B, 0x4BE5BEB68A243ED6, 0x5584255F19C8D65D, 0x3B67404E633FA006,
|
0xF9DD11850420A43B, 0x4BE5BEB68A243ED6, 0x5584255F19C8D65D, 0x3B67404E633FA006,
|
||||||
0xA68DB6766C472A1F, 0xF78AC79AB4C97E21, 0xC353442E1080AAEC, 0x9A4F9DB95782E714
|
0xA68DB6766C472A1F, 0xF78AC79AB4C97E21, 0xC353442E1080AAEC, 0x9A4F9DB95782E714
|
||||||
};
|
};
|
||||||
static const uint64_t T3[256] =
|
static const uint64_t T3[256] =
|
||||||
{
|
{
|
||||||
0x05BA7BC82C9B3220, 0x31A54665F8B65E4F, 0xB1B651F77547F4D4, 0x8BFA0D857BA46682,
|
0x05BA7BC82C9B3220, 0x31A54665F8B65E4F, 0xB1B651F77547F4D4, 0x8BFA0D857BA46682,
|
||||||
0x85A96C5AA16A98BB, 0x990FAEF908EB79C9, 0xA15E37A247F4A62D, 0x76857DCD5D27741E,
|
0x85A96C5AA16A98BB, 0x990FAEF908EB79C9, 0xA15E37A247F4A62D, 0x76857DCD5D27741E,
|
||||||
@@ -447,7 +447,7 @@ namespace crypto
|
|||||||
0x77059157F359DC47, 0x1D262E3907FF492B, 0xFB582233E59AC557, 0xDDB2BCE242F8B673,
|
0x77059157F359DC47, 0x1D262E3907FF492B, 0xFB582233E59AC557, 0xDDB2BCE242F8B673,
|
||||||
0x2577B76248E096CF, 0x6F99C4A6D83DA74C, 0xC1147E41EB795701, 0xF48BAF76912A9337
|
0x2577B76248E096CF, 0x6F99C4A6D83DA74C, 0xC1147E41EB795701, 0xF48BAF76912A9337
|
||||||
};
|
};
|
||||||
static const uint64_t T4[256] =
|
static const uint64_t T4[256] =
|
||||||
{
|
{
|
||||||
0x3EF29D249B2C0A19, 0xE9E16322B6F8622F, 0x5536994047757F7A, 0x9F4D56D5A47B0B33,
|
0x3EF29D249B2C0A19, 0xE9E16322B6F8622F, 0x5536994047757F7A, 0x9F4D56D5A47B0B33,
|
||||||
0x822567466AA1174C, 0xB8F5057DEB082FB2, 0xCC48C10BF4475F53, 0x373088D4275DEC3A,
|
0x822567466AA1174C, 0xB8F5057DEB082FB2, 0xCC48C10BF4475F53, 0x373088D4275DEC3A,
|
||||||
@@ -514,7 +514,7 @@ namespace crypto
|
|||||||
0x6853032B59F3EE6E, 0x65B3E9C4FF073AAA, 0x772AC3399AE5EBEC, 0x87816E97F842A75B,
|
0x6853032B59F3EE6E, 0x65B3E9C4FF073AAA, 0x772AC3399AE5EBEC, 0x87816E97F842A75B,
|
||||||
0x110E2DB2E0484A4B, 0x331277CB3DD8DEDD, 0xBD510CAC79EB9FA5, 0x352179552A91F5C7
|
0x110E2DB2E0484A4B, 0x331277CB3DD8DEDD, 0xBD510CAC79EB9FA5, 0x352179552A91F5C7
|
||||||
};
|
};
|
||||||
static const uint64_t T5[256] =
|
static const uint64_t T5[256] =
|
||||||
{
|
{
|
||||||
0x8AB0A96846E06A6D, 0x43C7E80B4BF0B33A, 0x08C9B3546B161EE5, 0x39F1C235EBA990BE,
|
0x8AB0A96846E06A6D, 0x43C7E80B4BF0B33A, 0x08C9B3546B161EE5, 0x39F1C235EBA990BE,
|
||||||
0xC1BEF2376606C7B2, 0x2C209233614569AA, 0xEB01523B6FC3289A, 0x946953AB935ACEDD,
|
0xC1BEF2376606C7B2, 0x2C209233614569AA, 0xEB01523B6FC3289A, 0x946953AB935ACEDD,
|
||||||
@@ -581,7 +581,7 @@ namespace crypto
|
|||||||
0xEFEB8511D4C82766, 0x961CB6BE40D147A3, 0xAAB35F25F7B812DE, 0x76154E407044329D,
|
0xEFEB8511D4C82766, 0x961CB6BE40D147A3, 0xAAB35F25F7B812DE, 0x76154E407044329D,
|
||||||
0x513D76B64E570693, 0xF3479AC7D2F90AA8, 0x9B8B2E4477079C85, 0x297EB99D3D85AC69
|
0x513D76B64E570693, 0xF3479AC7D2F90AA8, 0x9B8B2E4477079C85, 0x297EB99D3D85AC69
|
||||||
};
|
};
|
||||||
static const uint64_t T6[256] =
|
static const uint64_t T6[256] =
|
||||||
{
|
{
|
||||||
0x7E37E62DFC7D40C3, 0x776F25A4EE939E5B, 0xE045C850DD8FB5AD, 0x86ED5BA711FF1952,
|
0x7E37E62DFC7D40C3, 0x776F25A4EE939E5B, 0xE045C850DD8FB5AD, 0x86ED5BA711FF1952,
|
||||||
0xE91D0BD9CF616B35, 0x37E0AB256E408FFB, 0x9607F6C031025A7A, 0x0B02F5E116D23C9D,
|
0xE91D0BD9CF616B35, 0x37E0AB256E408FFB, 0x9607F6C031025A7A, 0x0B02F5E116D23C9D,
|
||||||
@@ -648,7 +648,7 @@ namespace crypto
|
|||||||
0xE6AB92E8D1CB8EA2, 0x3354C7F5663856F1, 0xD93EE170AF7BAE4D, 0x616BD27BC22AE67C,
|
0xE6AB92E8D1CB8EA2, 0x3354C7F5663856F1, 0xD93EE170AF7BAE4D, 0x616BD27BC22AE67C,
|
||||||
0x92B39A10397A8370, 0xABC8B3304B8E9890, 0xBF967287630B02B2, 0x5B67D607B6FC6E15
|
0x92B39A10397A8370, 0xABC8B3304B8E9890, 0xBF967287630B02B2, 0x5B67D607B6FC6E15
|
||||||
};
|
};
|
||||||
static uint64_t T7[256] =
|
static uint64_t T7[256] =
|
||||||
{
|
{
|
||||||
0xD031C397CE553FE6, 0x16BA5B01B006B525, 0xA89BADE6296E70C8, 0x6A1F525D77D3435B,
|
0xD031C397CE553FE6, 0x16BA5B01B006B525, 0xA89BADE6296E70C8, 0x6A1F525D77D3435B,
|
||||||
0x6E103570573DFA0B, 0x660EFB2A17FC95AB, 0x76327A9E97634BF6, 0x4BAD9D6462458BF5,
|
0x6E103570573DFA0B, 0x660EFB2A17FC95AB, 0x76327A9E97634BF6, 0x4BAD9D6462458BF5,
|
||||||
@@ -716,59 +716,59 @@ namespace crypto
|
|||||||
0x717E7067AF4F499A, 0x938290A9ECD1DBB3, 0x88E3B293344DD172, 0x2734158C250FA3D6
|
0x717E7067AF4F499A, 0x938290A9ECD1DBB3, 0x88E3B293344DD172, 0x2734158C250FA3D6
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint64_t C_[12][8] =
|
static const uint64_t C_[12][8] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
0xe9daca1eda5b08b1, 0x1f7c65c0812fcbeb, 0x16d0452e43766a2f, 0xfcc485758db84e71,
|
0xe9daca1eda5b08b1, 0x1f7c65c0812fcbeb, 0x16d0452e43766a2f, 0xfcc485758db84e71,
|
||||||
0x0169679291e07c4b, 0x15d360a4082a42a2, 0x234d74cc36747605, 0x0745a6f2596580dd
|
0x0169679291e07c4b, 0x15d360a4082a42a2, 0x234d74cc36747605, 0x0745a6f2596580dd
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x1a2f9da98ab5a36f, 0xd7b5700f469de34f, 0x982b230a72eafef3, 0x3101b5160f5ed561,
|
0x1a2f9da98ab5a36f, 0xd7b5700f469de34f, 0x982b230a72eafef3, 0x3101b5160f5ed561,
|
||||||
0x5899d6126b17b59a, 0xcaa70adbc261b55c, 0x56cdcbd71ba2dd55, 0xb79bb121700479e6
|
0x5899d6126b17b59a, 0xcaa70adbc261b55c, 0x56cdcbd71ba2dd55, 0xb79bb121700479e6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xc72fce2bacdc74f5, 0x35843d6a28fc390a, 0x8b1f9c525f5ef106, 0x7b7b29b11475eaf2,
|
0xc72fce2bacdc74f5, 0x35843d6a28fc390a, 0x8b1f9c525f5ef106, 0x7b7b29b11475eaf2,
|
||||||
0xb19e3590e40fe2d3, 0x09db6260373ac9c1, 0x31db7a8643f4b6c2, 0xb20aba0af5961e99
|
0xb19e3590e40fe2d3, 0x09db6260373ac9c1, 0x31db7a8643f4b6c2, 0xb20aba0af5961e99
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xd26615e8b3df1fef, 0xdde4715da0e148f9, 0x7d3c5c337e858e48, 0x3f355e68ad1c729d,
|
0xd26615e8b3df1fef, 0xdde4715da0e148f9, 0x7d3c5c337e858e48, 0x3f355e68ad1c729d,
|
||||||
0x75d603ed822cd7a9, 0xbe0352933313b7d8, 0xf137e893a1ea5334, 0x2ed1e384bcbe0c22
|
0x75d603ed822cd7a9, 0xbe0352933313b7d8, 0xf137e893a1ea5334, 0x2ed1e384bcbe0c22
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x994747adac6bea4b, 0x6323a96c0c413f9a, 0x4a1086161f1c157f, 0xbdff0f80d7359e35,
|
0x994747adac6bea4b, 0x6323a96c0c413f9a, 0x4a1086161f1c157f, 0xbdff0f80d7359e35,
|
||||||
0xa3f53a254717cdbf, 0x161a2723b700ffdf, 0xf563eaa97ea2567a, 0x57fe6c7cfd581760
|
0xa3f53a254717cdbf, 0x161a2723b700ffdf, 0xf563eaa97ea2567a, 0x57fe6c7cfd581760
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xd9d33a1daeae4fae, 0xc039307a3bc3a46f, 0x6ca44251f9c4662d, 0xc68ef09ab49a7f18,
|
0xd9d33a1daeae4fae, 0xc039307a3bc3a46f, 0x6ca44251f9c4662d, 0xc68ef09ab49a7f18,
|
||||||
0xb4b79a1cb7a6facf, 0xb6c6bec2661ff20a, 0x354f903672c571bf, 0x6e7d64467a4068fa
|
0xb4b79a1cb7a6facf, 0xb6c6bec2661ff20a, 0x354f903672c571bf, 0x6e7d64467a4068fa
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xecc5aaee160ec7f4, 0x540924bffe86ac51, 0xc987bfe6c7c69e39, 0xc9937a19333e47d3,
|
0xecc5aaee160ec7f4, 0x540924bffe86ac51, 0xc987bfe6c7c69e39, 0xc9937a19333e47d3,
|
||||||
0x372c822dc5ab9209, 0x04054a2883694706, 0xf34a3ca24c451735, 0x93d4143a4d568688
|
0x372c822dc5ab9209, 0x04054a2883694706, 0xf34a3ca24c451735, 0x93d4143a4d568688
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xa7c9934d425b1f9b, 0x41416e0c02aae703, 0x1ede369c71f8b74e, 0x9ac4db4d3b44b489,
|
0xa7c9934d425b1f9b, 0x41416e0c02aae703, 0x1ede369c71f8b74e, 0x9ac4db4d3b44b489,
|
||||||
0x90069b92cb2b89f4, 0x2fc4a5d12b8dd169, 0xd9a8515935c2ac36, 0x1ee702bfd40d7fa4
|
0x90069b92cb2b89f4, 0x2fc4a5d12b8dd169, 0xd9a8515935c2ac36, 0x1ee702bfd40d7fa4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x9b223116545a8f37, 0xde5f16ecd89a4c94, 0x244289251b3a7d3a, 0x84090de0b755d93c,
|
0x9b223116545a8f37, 0xde5f16ecd89a4c94, 0x244289251b3a7d3a, 0x84090de0b755d93c,
|
||||||
0xb1ceb2db0b440a80, 0x549c07a69a8a2b7b, 0x602a1fcb92dc380e, 0xdb5a238351446172
|
0xb1ceb2db0b440a80, 0x549c07a69a8a2b7b, 0x602a1fcb92dc380e, 0xdb5a238351446172
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x526f0580a6debeab, 0xf3f3e4b248e52a38, 0xdb788aff1ce74189, 0x0361331b8ae1ff1f,
|
0x526f0580a6debeab, 0xf3f3e4b248e52a38, 0xdb788aff1ce74189, 0x0361331b8ae1ff1f,
|
||||||
0x4b3369af0267e79f, 0xf452763b306c1e7a, 0xc3b63b15d1fa9836, 0xed9c4598fbc7b474
|
0x4b3369af0267e79f, 0xf452763b306c1e7a, 0xc3b63b15d1fa9836, 0xed9c4598fbc7b474
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xfb89c8efd09ecd7b, 0x94fe5a63cdc60230, 0x6107abebbb6bfad8, 0x7966841421800120,
|
0xfb89c8efd09ecd7b, 0x94fe5a63cdc60230, 0x6107abebbb6bfad8, 0x7966841421800120,
|
||||||
0xcab948eaef711d8a, 0x986e477d1dcdbaef, 0x5dd86fc04a59a2de, 0x1b2df381cda4ca6b
|
0xcab948eaef711d8a, 0x986e477d1dcdbaef, 0x5dd86fc04a59a2de, 0x1b2df381cda4ca6b
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0xba3116f167e78e37, 0x7ab14904b08013d2, 0x771ddfbc323ca4cd, 0x9b9f2130d41220f8,
|
0xba3116f167e78e37, 0x7ab14904b08013d2, 0x771ddfbc323ca4cd, 0x9b9f2130d41220f8,
|
||||||
0x86cc91189def805d, 0x5228e188aaa41de7, 0x991bb2d9d517f4fa, 0x20d71bf14a92bc48
|
0x86cc91189def805d, 0x5228e188aaa41de7, 0x991bb2d9d517f4fa, 0x20d71bf14a92bc48
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
union GOST3411Block // 8 bytes aligned
|
union GOST3411Block // 8 bytes aligned
|
||||||
{
|
{
|
||||||
uint8_t buf[64];
|
uint8_t buf[64];
|
||||||
@@ -780,15 +780,15 @@ namespace crypto
|
|||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
ret.ll[i] = ll[i]^other.ll[i];
|
ret.ll[i] = ll[i]^other.ll[i];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
GOST3411Block operator^(const uint64_t * other) const
|
GOST3411Block operator^(const uint64_t * other) const
|
||||||
{
|
{
|
||||||
GOST3411Block ret;
|
GOST3411Block ret;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
ret.ll[i] = ll[i]^other[i];
|
ret.ll[i] = ll[i]^other[i];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
GOST3411Block operator+(const GOST3411Block& other) const
|
GOST3411Block operator+(const GOST3411Block& other) const
|
||||||
{
|
{
|
||||||
@@ -799,7 +799,7 @@ namespace crypto
|
|||||||
uint16_t sum = buf[i] + other.buf[i] + carry;
|
uint16_t sum = buf[i] + other.buf[i] + carry;
|
||||||
ret.buf[i] = sum;
|
ret.buf[i] = sum;
|
||||||
carry = sum >> 8;
|
carry = sum >> 8;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,17 +807,17 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
for (int i = 63; i >= 0; i--)
|
for (int i = 63; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
c += buf[i];
|
c += buf[i];
|
||||||
buf[i] = c;
|
buf[i] = c;
|
||||||
c >>= 8;
|
c >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void F ()
|
void F ()
|
||||||
{
|
{
|
||||||
uint64_t res[8];
|
uint64_t res[8];
|
||||||
for (int b=0; b<8; b++)
|
for (int b=0; b<8; b++)
|
||||||
{
|
{
|
||||||
uint64_t r;
|
uint64_t r;
|
||||||
r = T0[buf[b+56]];
|
r = T0[buf[b+56]];
|
||||||
@@ -843,11 +843,11 @@ namespace crypto
|
|||||||
k = k^C_[i];
|
k = k^C_[i];
|
||||||
k.F ();
|
k.F ();
|
||||||
res = k^res;
|
res = k^res;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static GOST3411Block gN (const GOST3411Block& N, const GOST3411Block& h, const GOST3411Block& m)
|
static GOST3411Block gN (const GOST3411Block& N, const GOST3411Block& h, const GOST3411Block& m)
|
||||||
{
|
{
|
||||||
GOST3411Block res = N ^ h;
|
GOST3411Block res = N ^ h;
|
||||||
@@ -855,12 +855,12 @@ namespace crypto
|
|||||||
res = res.E (m);
|
res = res.E (m);
|
||||||
res = res^h;
|
res = res^h;
|
||||||
res = res^m;
|
res = res^m;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void H (const uint8_t * iv, const uint8_t * buf, size_t len, uint8_t * digest)
|
static void H (const uint8_t * iv, const uint8_t * buf, size_t len, uint8_t * digest)
|
||||||
{
|
{
|
||||||
// stage 1
|
// stage 1
|
||||||
GOST3411Block h, N, s, m;
|
GOST3411Block h, N, s, m;
|
||||||
memcpy (h.buf, iv, 64);
|
memcpy (h.buf, iv, 64);
|
||||||
memset (N.buf, 0, 64);
|
memset (N.buf, 0, 64);
|
||||||
@@ -885,15 +885,15 @@ namespace crypto
|
|||||||
memcpy (m.buf + padding, buf, l);
|
memcpy (m.buf + padding, buf, l);
|
||||||
|
|
||||||
h = gN (N, h, m);
|
h = gN (N, h, m);
|
||||||
N.Add (l*8);
|
N.Add (l*8);
|
||||||
s = m + s;
|
s = m + s;
|
||||||
|
|
||||||
GOST3411Block N0;
|
GOST3411Block N0;
|
||||||
memset (N0.buf, 0, 64);
|
memset (N0.buf, 0, 64);
|
||||||
h = gN (N0, h, N);
|
h = gN (N0, h, N);
|
||||||
h = gN (N0, h, s);
|
h = gN (N0, h, s);
|
||||||
|
|
||||||
memcpy (digest, h.buf, 64);
|
memcpy (digest, h.buf, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GOSTR3411_2012_256 (const uint8_t * buf, size_t len, uint8_t * digest)
|
void GOSTR3411_2012_256 (const uint8_t * buf, size_t len, uint8_t * digest)
|
||||||
@@ -919,7 +919,7 @@ namespace crypto
|
|||||||
size_t len;
|
size_t len;
|
||||||
bool is512;
|
bool is512;
|
||||||
};
|
};
|
||||||
|
|
||||||
GOSTR3411_2012_CTX * GOSTR3411_2012_CTX_new ()
|
GOSTR3411_2012_CTX * GOSTR3411_2012_CTX_new ()
|
||||||
{
|
{
|
||||||
return new GOSTR3411_2012_CTX;
|
return new GOSTR3411_2012_CTX;
|
||||||
@@ -949,7 +949,7 @@ namespace crypto
|
|||||||
size_t l = 64 - ctx->len;
|
size_t l = 64 - ctx->len;
|
||||||
if (len < l) l = len;
|
if (len < l) l = len;
|
||||||
for (size_t i = 0; i < l; i++)
|
for (size_t i = 0; i < l; i++)
|
||||||
ctx->m.buf[ctx->len + i] = buf[l-i-1]; // invert
|
ctx->m.buf[ctx->len + i] = buf[l-i-1]; // invert
|
||||||
ctx->len += l; len -= l; buf += l;
|
ctx->len += l; len -= l; buf += l;
|
||||||
|
|
||||||
ctx->h = gN (ctx->N, ctx->h, ctx->m);
|
ctx->h = gN (ctx->N, ctx->h, ctx->m);
|
||||||
@@ -959,7 +959,7 @@ namespace crypto
|
|||||||
while (len >= 64)
|
while (len >= 64)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < 64; i++)
|
for (size_t i = 0; i < 64; i++)
|
||||||
ctx->m.buf[i] = buf[63-i]; // invert
|
ctx->m.buf[i] = buf[63-i]; // invert
|
||||||
len -= 64; buf += 64;
|
len -= 64; buf += 64;
|
||||||
ctx->h = gN (ctx->N, ctx->h, ctx->m);
|
ctx->h = gN (ctx->N, ctx->h, ctx->m);
|
||||||
ctx->N.Add (512);
|
ctx->N.Add (512);
|
||||||
@@ -975,7 +975,7 @@ namespace crypto
|
|||||||
|
|
||||||
void GOSTR3411_2012_CTX_Finish (uint8_t * digest, GOSTR3411_2012_CTX * ctx)
|
void GOSTR3411_2012_CTX_Finish (uint8_t * digest, GOSTR3411_2012_CTX * ctx)
|
||||||
{
|
{
|
||||||
GOST3411Block m;
|
GOST3411Block m;
|
||||||
size_t padding = 64 - ctx->len;
|
size_t padding = 64 - ctx->len;
|
||||||
if (padding)
|
if (padding)
|
||||||
{
|
{
|
||||||
@@ -985,14 +985,14 @@ namespace crypto
|
|||||||
memcpy (m.buf + padding, ctx->m.buf, ctx->len);
|
memcpy (m.buf + padding, ctx->m.buf, ctx->len);
|
||||||
|
|
||||||
ctx->h = gN (ctx->N, ctx->h, m);
|
ctx->h = gN (ctx->N, ctx->h, m);
|
||||||
ctx->N.Add (ctx->len*8);
|
ctx->N.Add (ctx->len*8);
|
||||||
ctx->s = m + ctx->s;
|
ctx->s = m + ctx->s;
|
||||||
|
|
||||||
GOST3411Block N0;
|
GOST3411Block N0;
|
||||||
memset (N0.buf, 0, 64);
|
memset (N0.buf, 0, 64);
|
||||||
ctx->h = gN (N0, ctx->h, ctx->N);
|
ctx->h = gN (N0, ctx->h, ctx->N);
|
||||||
ctx->h = gN (N0, ctx->h, ctx->s);
|
ctx->h = gN (N0, ctx->h, ctx->s);
|
||||||
|
|
||||||
size_t sz = ctx->is512 ? 64 : 32;
|
size_t sz = ctx->is512 ? 64 : 32;
|
||||||
for (size_t i = 0; i < sz; i++)
|
for (size_t i = 0; i < sz; i++)
|
||||||
digest[i] = ctx->h.buf[sz - i - 1];
|
digest[i] = ctx->h.buf[sz - i - 1];
|
||||||
|
|||||||
@@ -10,25 +10,25 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
|
|
||||||
// ГОСТ Р 34.10
|
// ГОСТ Р 34.10
|
||||||
|
|
||||||
enum GOSTR3410ParamSet
|
enum GOSTR3410ParamSet
|
||||||
{
|
{
|
||||||
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
||||||
// XchA = A, XchB = C
|
// XchA = A, XchB = C
|
||||||
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
||||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||||
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
||||||
eGOSTR3410NumParamSets
|
eGOSTR3410NumParamSets
|
||||||
};
|
};
|
||||||
|
|
||||||
class GOSTR3410Curve
|
class GOSTR3410Curve
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y);
|
GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y);
|
||||||
~GOSTR3410Curve ();
|
~GOSTR3410Curve ();
|
||||||
|
|
||||||
size_t GetKeyLen () const { return m_KeyLen; };
|
size_t GetKeyLen () const { return m_KeyLen; };
|
||||||
const EC_GROUP * GetGroup () const { return m_Group; };
|
const EC_GROUP * GetGroup () const { return m_Group; };
|
||||||
EC_POINT * MulP (const BIGNUM * n) const;
|
EC_POINT * MulP (const BIGNUM * n) const;
|
||||||
bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const;
|
bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const;
|
||||||
@@ -36,7 +36,7 @@ namespace crypto
|
|||||||
void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s);
|
void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s);
|
||||||
bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s);
|
bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s);
|
||||||
EC_POINT * RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY = false) const;
|
EC_POINT * RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY = false) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EC_GROUP * m_Group;
|
EC_GROUP * m_Group;
|
||||||
@@ -47,14 +47,14 @@ namespace crypto
|
|||||||
|
|
||||||
// Big Endian
|
// Big Endian
|
||||||
void GOSTR3411_2012_256 (const uint8_t * buf, size_t len, uint8_t * digest);
|
void GOSTR3411_2012_256 (const uint8_t * buf, size_t len, uint8_t * digest);
|
||||||
void GOSTR3411_2012_512 (const uint8_t * buf, size_t len, uint8_t * digest);
|
void GOSTR3411_2012_512 (const uint8_t * buf, size_t len, uint8_t * digest);
|
||||||
|
|
||||||
// Little Endian
|
// Little Endian
|
||||||
struct GOSTR3411_2012_CTX;
|
struct GOSTR3411_2012_CTX;
|
||||||
GOSTR3411_2012_CTX * GOSTR3411_2012_CTX_new ();
|
GOSTR3411_2012_CTX * GOSTR3411_2012_CTX_new ();
|
||||||
void GOSTR3411_2012_CTX_Init (GOSTR3411_2012_CTX * ctx, bool is512 = true);
|
void GOSTR3411_2012_CTX_Init (GOSTR3411_2012_CTX * ctx, bool is512 = true);
|
||||||
void GOSTR3411_2012_CTX_Update (const uint8_t * buf, size_t len, GOSTR3411_2012_CTX * ctx);
|
void GOSTR3411_2012_CTX_Update (const uint8_t * buf, size_t len, GOSTR3411_2012_CTX * ctx);
|
||||||
void GOSTR3411_2012_CTX_Finish (uint8_t * digest, GOSTR3411_2012_CTX * ctx);
|
void GOSTR3411_2012_CTX_Finish (uint8_t * digest, GOSTR3411_2012_CTX * ctx);
|
||||||
void GOSTR3411_2012_CTX_free (GOSTR3411_2012_CTX * ctx);
|
void GOSTR3411_2012_CTX_free (GOSTR3411_2012_CTX * ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Gzip.h"
|
#include "Gzip.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
const size_t GZIP_CHUNK_SIZE = 16384;
|
const size_t GZIP_CHUNK_SIZE = 16384;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ namespace data
|
|||||||
m_Inflator.next_out = out;
|
m_Inflator.next_out = out;
|
||||||
m_Inflator.avail_out = outLen;
|
m_Inflator.avail_out = outLen;
|
||||||
int err;
|
int err;
|
||||||
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END)
|
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END)
|
||||||
return outLen - m_Inflator.avail_out;
|
return outLen - m_Inflator.avail_out;
|
||||||
// else
|
// else
|
||||||
LogPrint (eLogError, "Gzip: Inflate error ", err);
|
LogPrint (eLogError, "Gzip: Inflate error ", err);
|
||||||
@@ -52,19 +52,19 @@ namespace data
|
|||||||
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
||||||
m_Inflator.avail_in = inLen;
|
m_Inflator.avail_in = inLen;
|
||||||
int ret;
|
int ret;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
m_Inflator.next_out = out;
|
m_Inflator.next_out = out;
|
||||||
m_Inflator.avail_out = GZIP_CHUNK_SIZE;
|
m_Inflator.avail_out = GZIP_CHUNK_SIZE;
|
||||||
ret = inflate (&m_Inflator, Z_NO_FLUSH);
|
ret = inflate (&m_Inflator, Z_NO_FLUSH);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
inflateEnd (&m_Inflator);
|
inflateEnd (&m_Inflator);
|
||||||
os.setstate(std::ios_base::failbit);
|
os.setstate(std::ios_base::failbit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
|
os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
|
||||||
}
|
}
|
||||||
while (!m_Inflator.avail_out); // more data to read
|
while (!m_Inflator.avail_out); // more data to read
|
||||||
delete[] out;
|
delete[] out;
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ namespace data
|
|||||||
m_Deflator.next_out = out;
|
m_Deflator.next_out = out;
|
||||||
m_Deflator.avail_out = outLen;
|
m_Deflator.avail_out = outLen;
|
||||||
int err;
|
int err;
|
||||||
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END)
|
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END)
|
||||||
return outLen - m_Deflator.avail_out;
|
return outLen - m_Deflator.avail_out;
|
||||||
// else
|
// else
|
||||||
LogPrint (eLogError, "Gzip: Deflate error ", err);
|
LogPrint (eLogError, "Gzip: Deflate error ", err);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::pair<std::string, std::string> parse_header_line(const std::string& line)
|
static std::pair<std::string, std::string> parse_header_line(const std::string& line)
|
||||||
{
|
{
|
||||||
std::size_t pos = 0;
|
std::size_t pos = 0;
|
||||||
std::size_t len = 2; /* strlen(": ") */
|
std::size_t len = 2; /* strlen(": ") */
|
||||||
@@ -251,14 +251,14 @@ namespace http {
|
|||||||
uri = tokens[1];
|
uri = tokens[1];
|
||||||
version = tokens[2];
|
version = 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);
|
||||||
if (p.first.length () > 0)
|
if (p.first.length () > 0)
|
||||||
headers.push_back (p);
|
headers.push_back (p);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pos = eol + strlen(CRLF);
|
pos = eol + strlen(CRLF);
|
||||||
@@ -268,11 +268,11 @@ namespace http {
|
|||||||
return eoh + strlen(HTTP_EOH);
|
return eoh + strlen(HTTP_EOH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReq::write(std::ostream & o)
|
void HTTPReq::write(std::ostream & o)
|
||||||
{
|
{
|
||||||
o << method << " " << uri << " " << version << CRLF;
|
o << method << " " << uri << " " << version << CRLF;
|
||||||
for (auto & h : headers)
|
for (auto & h : headers)
|
||||||
o << h.first << ": " << h.second << CRLF;
|
o << h.first << ": " << h.second << CRLF;
|
||||||
o << CRLF;
|
o << CRLF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReq::AddHeader (const std::string& name, const std::string& value)
|
void HTTPReq::AddHeader (const std::string& name, const std::string& value)
|
||||||
{
|
{
|
||||||
headers.push_back (std::make_pair(name, value));
|
headers.push_back (std::make_pair(name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,28 +295,28 @@ namespace http {
|
|||||||
{
|
{
|
||||||
it.second = value;
|
it.second = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReq::RemoveHeader (const std::string& name, const std::string& exempt)
|
void HTTPReq::RemoveHeader (const std::string& name, const std::string& exempt)
|
||||||
{
|
{
|
||||||
for (auto it = headers.begin (); it != headers.end ();)
|
for (auto it = headers.begin (); it != headers.end ();)
|
||||||
{
|
{
|
||||||
if (!it->first.compare(0, name.length (), name) && it->first != exempt)
|
if (!it->first.compare(0, name.length (), name) && it->first != exempt)
|
||||||
it = headers.erase (it);
|
it = headers.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HTTPReq::GetHeader (const std::string& name) const
|
std::string HTTPReq::GetHeader (const std::string& name) const
|
||||||
{
|
{
|
||||||
for (auto& it : headers)
|
for (auto& it : headers)
|
||||||
if (it.first == name)
|
if (it.first == name)
|
||||||
return it.second;
|
return it.second;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTTPRes::is_chunked() const
|
bool HTTPRes::is_chunked() const
|
||||||
{
|
{
|
||||||
auto it = headers.find("Transfer-Encoding");
|
auto it = headers.find("Transfer-Encoding");
|
||||||
@@ -335,10 +335,10 @@ namespace http {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
long int HTTPMsg::content_length() const
|
long int HTTPMsg::content_length() const
|
||||||
{
|
{
|
||||||
unsigned long int length = 0;
|
unsigned long int length = 0;
|
||||||
@@ -385,8 +385,8 @@ namespace http {
|
|||||||
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);
|
||||||
if (p.first.length () > 0)
|
if (p.first.length () > 0)
|
||||||
headers.insert (p);
|
headers.insert (p);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pos = eol + strlen(CRLF);
|
pos = eol + strlen(CRLF);
|
||||||
|
|||||||
@@ -16,16 +16,16 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
const char CRLF[] = "\r\n"; /**< HTTP line terminator */
|
const char CRLF[] = "\r\n"; /**< HTTP line terminator */
|
||||||
const char HTTP_EOH[] = "\r\n\r\n"; /**< HTTP end-of-headers mark */
|
const char HTTP_EOH[] = "\r\n\r\n"; /**< HTTP end-of-headers mark */
|
||||||
extern const std::vector<std::string> HTTP_METHODS; /**< list of valid HTTP methods */
|
extern const std::vector<std::string> HTTP_METHODS; /**< list of valid HTTP methods */
|
||||||
extern const std::vector<std::string> HTTP_VERSIONS; /**< list of valid HTTP versions */
|
extern const std::vector<std::string> HTTP_VERSIONS; /**< list of valid HTTP versions */
|
||||||
|
|
||||||
struct URL
|
struct URL
|
||||||
{
|
{
|
||||||
std::string schema;
|
std::string schema;
|
||||||
std::string user;
|
std::string user;
|
||||||
@@ -63,7 +63,7 @@ namespace http
|
|||||||
bool is_i2p() const;
|
bool is_i2p() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HTTPMsg
|
struct HTTPMsg
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> headers;
|
std::map<std::string, std::string> headers;
|
||||||
|
|
||||||
@@ -75,9 +75,9 @@ namespace http
|
|||||||
long int content_length() const;
|
long int content_length() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HTTPReq
|
struct HTTPReq
|
||||||
{
|
{
|
||||||
std::list<std::pair<std::string, std::string> > headers;
|
std::list<std::pair<std::string, std::string> > headers;
|
||||||
std::string version;
|
std::string version;
|
||||||
std::string method;
|
std::string method;
|
||||||
std::string uri;
|
std::string uri;
|
||||||
@@ -97,10 +97,10 @@ namespace http
|
|||||||
void write(std::ostream & o);
|
void write(std::ostream & o);
|
||||||
|
|
||||||
void AddHeader (const std::string& name, const std::string& value);
|
void AddHeader (const std::string& name, const std::string& value);
|
||||||
void UpdateHeader (const std::string& name, const std::string& value);
|
void UpdateHeader (const std::string& name, const std::string& value);
|
||||||
void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt
|
void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt
|
||||||
void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); };
|
void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); };
|
||||||
std::string GetHeader (const std::string& name) const;
|
std::string GetHeader (const std::string& name) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HTTPRes : HTTPMsg {
|
struct HTTPRes : HTTPMsg {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> >();
|
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ()
|
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ()
|
||||||
{
|
{
|
||||||
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
||||||
@@ -32,38 +32,38 @@ namespace i2p
|
|||||||
auto msg = new I2NPMessageBuffer<i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12
|
auto msg = new I2NPMessageBuffer<i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12
|
||||||
msg->Align (12);
|
msg->Align (12);
|
||||||
return std::shared_ptr<I2NPMessage>(msg);
|
return std::shared_ptr<I2NPMessage>(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len)
|
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len)
|
||||||
{
|
{
|
||||||
return (len < I2NP_MAX_SHORT_MESSAGE_SIZE/2) ? NewI2NPShortMessage () : NewI2NPMessage ();
|
return (len < I2NP_MAX_SHORT_MESSAGE_SIZE/2) ? NewI2NPShortMessage () : NewI2NPMessage ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID)
|
void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID)
|
||||||
{
|
{
|
||||||
SetTypeID (msgType);
|
SetTypeID (msgType);
|
||||||
if (!replyMsgID) RAND_bytes ((uint8_t *)&replyMsgID, 4);
|
if (!replyMsgID) RAND_bytes ((uint8_t *)&replyMsgID, 4);
|
||||||
SetMsgID (replyMsgID);
|
SetMsgID (replyMsgID);
|
||||||
SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT);
|
SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT);
|
||||||
UpdateSize ();
|
UpdateSize ();
|
||||||
UpdateChks ();
|
UpdateChks ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessage::RenewI2NPMessageHeader ()
|
void I2NPMessage::RenewI2NPMessageHeader ()
|
||||||
{
|
{
|
||||||
uint32_t msgID;
|
uint32_t msgID;
|
||||||
RAND_bytes ((uint8_t *)&msgID, 4);
|
RAND_bytes ((uint8_t *)&msgID, 4);
|
||||||
SetMsgID (msgID);
|
SetMsgID (msgID);
|
||||||
SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT);
|
SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2NPMessage::IsExpired () const
|
bool I2NPMessage::IsExpired () const
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
auto exp = GetExpiration ();
|
auto exp = GetExpiration ();
|
||||||
return (ts > exp + I2NP_MESSAGE_CLOCK_SKEW) || (ts < exp - 3*I2NP_MESSAGE_CLOCK_SKEW); // check if expired or too far in future
|
return (ts > exp + I2NP_MESSAGE_CLOCK_SKEW) || (ts < exp - 3*I2NP_MESSAGE_CLOCK_SKEW); // check if expired or too far in future
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID)
|
std::shared_ptr<I2NPMessage> CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPMessage (len);
|
auto msg = NewI2NPMessage (len);
|
||||||
@@ -71,7 +71,7 @@ namespace i2p
|
|||||||
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length ", msg->maxLen);
|
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length ", msg->maxLen);
|
||||||
msg->FillI2NPMessageHeader (msgType, replyMsgID);
|
msg->FillI2NPMessageHeader (msgType, replyMsgID);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
std::shared_ptr<I2NPMessage> CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||||
{
|
{
|
||||||
@@ -85,7 +85,7 @@ namespace i2p
|
|||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length");
|
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length");
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CopyI2NPMessage (std::shared_ptr<I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> CopyI2NPMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
@@ -94,8 +94,8 @@ namespace i2p
|
|||||||
newMsg->offset = msg->offset;
|
newMsg->offset = msg->offset;
|
||||||
*newMsg = *msg;
|
*newMsg = *msg;
|
||||||
return newMsg;
|
return newMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDeliveryStatusMsg (uint32_t msgID)
|
std::shared_ptr<I2NPMessage> CreateDeliveryStatusMsg (uint32_t msgID)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
@@ -109,14 +109,14 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
RAND_bytes ((uint8_t *)&msgID, 4);
|
RAND_bytes ((uint8_t *)&msgID, 4);
|
||||||
htobe32buf (buf + DELIVERY_STATUS_MSGID_OFFSET, msgID);
|
htobe32buf (buf + DELIVERY_STATUS_MSGID_OFFSET, msgID);
|
||||||
htobe64buf (buf + DELIVERY_STATUS_TIMESTAMP_OFFSET, i2p::context.GetNetID ());
|
htobe64buf (buf + DELIVERY_STATUS_TIMESTAMP_OFFSET, i2p::context.GetNetID ());
|
||||||
}
|
}
|
||||||
m->len += DELIVERY_STATUS_SIZE;
|
m->len += DELIVERY_STATUS_SIZE;
|
||||||
m->FillI2NPMessageHeader (eI2NPDeliveryStatus);
|
m->FillI2NPMessageHeader (eI2NPDeliveryStatus);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
||||||
uint32_t replyTunnelID, bool exploratory, std::set<i2p::data::IdentHash> * excludedPeers)
|
uint32_t replyTunnelID, bool exploratory, std::set<i2p::data::IdentHash> * excludedPeers)
|
||||||
{
|
{
|
||||||
auto m = excludedPeers ? NewI2NPMessage () : NewI2NPShortMessage ();
|
auto m = excludedPeers ? NewI2NPMessage () : NewI2NPShortMessage ();
|
||||||
@@ -125,7 +125,7 @@ namespace i2p
|
|||||||
buf += 32;
|
buf += 32;
|
||||||
memcpy (buf, from, 32); // from
|
memcpy (buf, from, 32); // from
|
||||||
buf += 32;
|
buf += 32;
|
||||||
uint8_t flag = exploratory ? DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP : DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP;
|
uint8_t flag = exploratory ? DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP : DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP;
|
||||||
if (replyTunnelID)
|
if (replyTunnelID)
|
||||||
{
|
{
|
||||||
*buf = flag | DATABASE_LOOKUP_DELIVERY_FLAG; // set delivery flag
|
*buf = flag | DATABASE_LOOKUP_DELIVERY_FLAG; // set delivery flag
|
||||||
@@ -133,11 +133,11 @@ namespace i2p
|
|||||||
buf += 5;
|
buf += 5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*buf = flag; // flag
|
*buf = flag; // flag
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (excludedPeers)
|
if (excludedPeers)
|
||||||
{
|
{
|
||||||
int cnt = excludedPeers->size ();
|
int cnt = excludedPeers->size ();
|
||||||
@@ -147,21 +147,21 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
memcpy (buf, it, 32);
|
memcpy (buf, it, 32);
|
||||||
buf += 32;
|
buf += 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// nothing to exclude
|
// nothing to exclude
|
||||||
htobuf16 (buf, 0);
|
htobuf16 (buf, 0);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->len += (buf - m->GetPayload ());
|
|
||||||
m->FillI2NPMessageHeader (eI2NPDatabaseLookup);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
m->len += (buf - m->GetPayload ());
|
||||||
|
m->FillI2NPMessageHeader (eI2NPDatabaseLookup);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, const uint8_t * replyTag)
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag)
|
||||||
{
|
{
|
||||||
@@ -176,7 +176,7 @@ namespace i2p
|
|||||||
buf ++;
|
buf ++;
|
||||||
htobe32buf (buf, replyTunnel->GetNextTunnelID ()); // reply tunnel ID
|
htobe32buf (buf, replyTunnel->GetNextTunnelID ()); // reply tunnel ID
|
||||||
buf += 4;
|
buf += 4;
|
||||||
|
|
||||||
// excluded
|
// excluded
|
||||||
htobe16buf (buf, cnt);
|
htobe16buf (buf, cnt);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
@@ -187,19 +187,19 @@ namespace i2p
|
|||||||
memcpy (buf, it, 32);
|
memcpy (buf, it, 32);
|
||||||
buf += 32;
|
buf += 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// encryption
|
// encryption
|
||||||
memcpy (buf, replyKey, 32);
|
memcpy (buf, replyKey, 32);
|
||||||
buf[32] = uint8_t( 1 ); // 1 tag
|
buf[32] = uint8_t( 1 ); // 1 tag
|
||||||
memcpy (buf + 33, replyTag, 32);
|
memcpy (buf + 33, replyTag, 32);
|
||||||
buf += 65;
|
buf += 65;
|
||||||
|
|
||||||
m->len += (buf - m->GetPayload ());
|
m->len += (buf - m->GetPayload ());
|
||||||
m->FillI2NPMessageHeader (eI2NPDatabaseLookup);
|
m->FillI2NPMessageHeader (eI2NPDatabaseLookup);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident,
|
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident,
|
||||||
std::vector<i2p::data::IdentHash> routers)
|
std::vector<i2p::data::IdentHash> routers)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
@@ -207,27 +207,27 @@ namespace i2p
|
|||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
memcpy (buf, ident, 32);
|
memcpy (buf, ident, 32);
|
||||||
len += 32;
|
len += 32;
|
||||||
buf[len] = routers.size ();
|
buf[len] = routers.size ();
|
||||||
len++;
|
len++;
|
||||||
for (const auto& it: routers)
|
for (const auto& it: routers)
|
||||||
{
|
{
|
||||||
memcpy (buf + len, it, 32);
|
memcpy (buf + len, it, 32);
|
||||||
len += 32;
|
len += 32;
|
||||||
}
|
}
|
||||||
memcpy (buf + len, i2p::context.GetRouterInfo ().GetIdentHash (), 32);
|
memcpy (buf + len, i2p::context.GetRouterInfo ().GetIdentHash (), 32);
|
||||||
len += 32;
|
len += 32;
|
||||||
m->len += len;
|
m->len += len;
|
||||||
m->FillI2NPMessageHeader (eI2NPDatabaseSearchReply);
|
m->FillI2NPMessageHeader (eI2NPDatabaseSearchReply);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router, uint32_t replyToken)
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router, uint32_t replyToken)
|
||||||
{
|
{
|
||||||
if (!router) // we send own RouterInfo
|
if (!router) // we send own RouterInfo
|
||||||
router = context.GetSharedRouterInfo ();
|
router = context.GetSharedRouterInfo ();
|
||||||
|
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
uint8_t * payload = m->GetPayload ();
|
uint8_t * payload = m->GetPayload ();
|
||||||
|
|
||||||
memcpy (payload + DATABASE_STORE_KEY_OFFSET, router->GetIdentHash (), 32);
|
memcpy (payload + DATABASE_STORE_KEY_OFFSET, router->GetIdentHash (), 32);
|
||||||
payload[DATABASE_STORE_TYPE_OFFSET] = 0; // RouterInfo
|
payload[DATABASE_STORE_TYPE_OFFSET] = 0; // RouterInfo
|
||||||
@@ -239,7 +239,7 @@ namespace i2p
|
|||||||
buf += 4;
|
buf += 4;
|
||||||
memcpy (buf, router->GetIdentHash (), 32);
|
memcpy (buf, router->GetIdentHash (), 32);
|
||||||
buf += 32;
|
buf += 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t * sizePtr = buf;
|
uint8_t * sizePtr = buf;
|
||||||
buf += 2;
|
buf += 2;
|
||||||
@@ -247,22 +247,22 @@ namespace i2p
|
|||||||
i2p::data::GzipDeflator deflator;
|
i2p::data::GzipDeflator deflator;
|
||||||
size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len);
|
size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len);
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
htobe16buf (sizePtr, size); // size
|
htobe16buf (sizePtr, size); // size
|
||||||
m->len += size;
|
m->len += size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m = nullptr;
|
m = nullptr;
|
||||||
if (m)
|
if (m)
|
||||||
m->FillI2NPMessageHeader (eI2NPDatabaseStore);
|
m->FillI2NPMessageHeader (eI2NPDatabaseStore);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LeaseSet> leaseSet)
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LeaseSet> leaseSet)
|
||||||
{
|
{
|
||||||
if (!leaseSet) return nullptr;
|
if (!leaseSet) return nullptr;
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
uint8_t * payload = m->GetPayload ();
|
uint8_t * payload = m->GetPayload ();
|
||||||
memcpy (payload + DATABASE_STORE_KEY_OFFSET, leaseSet->GetIdentHash (), 32);
|
memcpy (payload + DATABASE_STORE_KEY_OFFSET, leaseSet->GetIdentHash (), 32);
|
||||||
payload[DATABASE_STORE_TYPE_OFFSET] = 1; // LeaseSet
|
payload[DATABASE_STORE_TYPE_OFFSET] = 1; // LeaseSet
|
||||||
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0);
|
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0);
|
||||||
@@ -278,7 +278,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
if (!leaseSet) return nullptr;
|
if (!leaseSet) return nullptr;
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
uint8_t * payload = m->GetPayload ();
|
uint8_t * payload = m->GetPayload ();
|
||||||
memcpy (payload + DATABASE_STORE_KEY_OFFSET, leaseSet->GetIdentHash (), 32);
|
memcpy (payload + DATABASE_STORE_KEY_OFFSET, leaseSet->GetIdentHash (), 32);
|
||||||
payload[DATABASE_STORE_TYPE_OFFSET] = 1; // LeaseSet
|
payload[DATABASE_STORE_TYPE_OFFSET] = 1; // LeaseSet
|
||||||
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, replyToken);
|
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, replyToken);
|
||||||
@@ -306,8 +306,8 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
if (!msg || msg->GetTypeID () != eI2NPDatabaseStore) return false;
|
if (!msg || msg->GetTypeID () != eI2NPDatabaseStore) return false;
|
||||||
return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo
|
return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO:
|
static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO:
|
||||||
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels)
|
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels)
|
||||||
{
|
{
|
||||||
@@ -321,37 +321,37 @@ namespace i2p
|
|||||||
bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText)
|
bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
uint8_t * record = records + i*TUNNEL_BUILD_RECORD_SIZE;
|
uint8_t * record = records + i*TUNNEL_BUILD_RECORD_SIZE;
|
||||||
if (!memcmp (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16))
|
if (!memcmp (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16))
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours");
|
LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours");
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKeys ().GetPrivateKey () , record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx);
|
i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKeys ().GetPrivateKey () , record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
// replace record to reply
|
// replace record to reply
|
||||||
if (i2p::context.AcceptsTunnels () &&
|
if (i2p::context.AcceptsTunnels () &&
|
||||||
i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels &&
|
i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels &&
|
||||||
!i2p::transport::transports.IsBandwidthExceeded () &&
|
!i2p::transport::transports.IsBandwidthExceeded () &&
|
||||||
!i2p::transport::transports.IsTransitBandwidthExceeded ())
|
!i2p::transport::transports.IsTransitBandwidthExceeded ())
|
||||||
{
|
{
|
||||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
||||||
clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
||||||
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80,
|
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80,
|
||||||
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40);
|
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40);
|
||||||
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel);
|
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel);
|
||||||
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0;
|
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 30; // always reject with bandwidth reason (30)
|
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 30; // always reject with bandwidth reason (30)
|
||||||
|
|
||||||
//TODO: fill filler
|
//TODO: fill filler
|
||||||
SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret
|
SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret
|
||||||
record + BUILD_RESPONSE_RECORD_HASH_OFFSET);
|
record + BUILD_RESPONSE_RECORD_HASH_OFFSET);
|
||||||
// encrypt reply
|
// encrypt reply
|
||||||
i2p::crypto::CBCEncryption encryption;
|
i2p::crypto::CBCEncryption encryption;
|
||||||
for (int j = 0; j < num; j++)
|
for (int j = 0; j < num; j++)
|
||||||
@@ -359,23 +359,23 @@ namespace i2p
|
|||||||
encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET);
|
encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET);
|
||||||
encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
||||||
uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE;
|
uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE;
|
||||||
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply);
|
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
|
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
int num = buf[0];
|
int num = buf[0];
|
||||||
LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records");
|
LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records");
|
||||||
if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1)
|
if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "VaribleTunnelBuild message of ", num, " records is too short ", len);
|
LogPrint (eLogError, "VaribleTunnelBuild message of ", num, " records is too short ", len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
||||||
if (tunnel)
|
if (tunnel)
|
||||||
@@ -385,34 +385,34 @@ namespace i2p
|
|||||||
if (tunnel->HandleTunnelBuildResponse (buf, len))
|
if (tunnel->HandleTunnelBuildResponse (buf, len))
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been created");
|
LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been created");
|
||||||
tunnel->SetState (i2p::tunnel::eTunnelStateEstablished);
|
tunnel->SetState (i2p::tunnel::eTunnelStateEstablished);
|
||||||
i2p::tunnel::tunnels.AddInboundTunnel (tunnel);
|
i2p::tunnel::tunnels.AddInboundTunnel (tunnel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
||||||
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
||||||
if (HandleBuildRequestRecords (num, buf + 1, clearText))
|
if (HandleBuildRequestRecords (num, buf + 1, clearText))
|
||||||
{
|
{
|
||||||
if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel
|
if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel
|
||||||
{
|
{
|
||||||
// so we send it to reply tunnel
|
// so we send it to reply tunnel
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
eI2NPVariableTunnelBuildReply, buf, len,
|
eI2NPVariableTunnelBuildReply, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len,
|
CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleTunnelBuildMsg (uint8_t * buf, size_t len)
|
void HandleTunnelBuildMsg (uint8_t * buf, size_t len)
|
||||||
@@ -421,51 +421,51 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "TunnelBuild message is too short ", len);
|
LogPrint (eLogError, "TunnelBuild message is too short ", len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
||||||
if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText))
|
if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText))
|
||||||
{
|
{
|
||||||
if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outbound tunnel
|
if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outbound tunnel
|
||||||
{
|
{
|
||||||
// so we send it to reply tunnel
|
// so we send it to reply tunnel
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
eI2NPTunnelBuildReply, buf, len,
|
eI2NPTunnelBuildReply, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateI2NPMessage (eI2NPTunnelBuild, buf, len,
|
CreateI2NPMessage (eI2NPTunnelBuild, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
|
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
int num = buf[0];
|
int num = buf[0];
|
||||||
LogPrint (eLogDebug, "I2NP: VariableTunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID);
|
LogPrint (eLogDebug, "I2NP: VariableTunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID);
|
||||||
if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1)
|
if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "VaribleTunnelBuildReply message of ", num, " records is too short ", len);
|
LogPrint (eLogError, "VaribleTunnelBuildReply message of ", num, " records is too short ", len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tunnel = i2p::tunnel::tunnels.GetPendingOutboundTunnel (replyMsgID);
|
auto tunnel = i2p::tunnel::tunnels.GetPendingOutboundTunnel (replyMsgID);
|
||||||
if (tunnel)
|
if (tunnel)
|
||||||
{
|
{
|
||||||
// reply for outbound tunnel
|
// reply for outbound tunnel
|
||||||
if (tunnel->HandleTunnelBuildResponse (buf, len))
|
if (tunnel->HandleTunnelBuildResponse (buf, len))
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "I2NP: Outbound tunnel ", tunnel->GetTunnelID (), " has been created");
|
LogPrint (eLogInfo, "I2NP: Outbound tunnel ", tunnel->GetTunnelID (), " has been created");
|
||||||
tunnel->SetState (i2p::tunnel::eTunnelStateEstablished);
|
tunnel->SetState (i2p::tunnel::eTunnelStateEstablished);
|
||||||
i2p::tunnel::tunnels.AddOutboundTunnel (tunnel);
|
i2p::tunnel::tunnels.AddOutboundTunnel (tunnel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "I2NP: Outbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
LogPrint (eLogInfo, "I2NP: Outbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
||||||
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "I2NP: Pending tunnel for message ", replyMsgID, " not found");
|
LogPrint (eLogWarning, "I2NP: Pending tunnel for message ", replyMsgID, " not found");
|
||||||
}
|
}
|
||||||
@@ -474,12 +474,12 @@ namespace i2p
|
|||||||
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (const uint8_t * buf)
|
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (const uint8_t * buf)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPTunnelMessage ();
|
auto msg = NewI2NPTunnelMessage ();
|
||||||
msg->Concat (buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE);
|
msg->Concat (buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE);
|
||||||
msg->FillI2NPMessageHeader (eI2NPTunnelData);
|
msg->FillI2NPMessageHeader (eI2NPTunnelData);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload)
|
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPTunnelMessage ();
|
auto msg = NewI2NPTunnelMessage ();
|
||||||
htobe32buf (msg->GetPayload (), tunnelID);
|
htobe32buf (msg->GetPayload (), tunnelID);
|
||||||
@@ -487,15 +487,15 @@ namespace i2p
|
|||||||
msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4);
|
msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4);
|
||||||
msg->FillI2NPMessageHeader (eI2NPTunnelData);
|
msg->FillI2NPMessageHeader (eI2NPTunnelData);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg ()
|
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg ()
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPTunnelMessage ();
|
auto msg = NewI2NPTunnelMessage ();
|
||||||
msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE;
|
msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE;
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len)
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPMessage (len);
|
auto msg = NewI2NPMessage (len);
|
||||||
@@ -504,10 +504,10 @@ namespace i2p
|
|||||||
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
||||||
msg->len += TUNNEL_GATEWAY_HEADER_SIZE;
|
msg->len += TUNNEL_GATEWAY_HEADER_SIZE;
|
||||||
if (msg->Concat (buf, len) < len)
|
if (msg->Concat (buf, len) < len)
|
||||||
LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen);
|
LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen);
|
||||||
msg->FillI2NPMessageHeader (eI2NPTunnelGateway);
|
msg->FillI2NPMessageHeader (eI2NPTunnelGateway);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
@@ -520,14 +520,14 @@ namespace i2p
|
|||||||
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
||||||
msg->offset -= (I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE);
|
msg->offset -= (I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE);
|
||||||
msg->len = msg->offset + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE +len;
|
msg->len = msg->offset + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE +len;
|
||||||
msg->FillI2NPMessageHeader (eI2NPTunnelGateway);
|
msg->FillI2NPMessageHeader (eI2NPTunnelGateway);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ());
|
return CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType,
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType,
|
||||||
const uint8_t * buf, size_t len, uint32_t replyMsgID)
|
const uint8_t * buf, size_t len, uint32_t replyMsgID)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPMessage (len);
|
auto msg = NewI2NPMessage (len);
|
||||||
@@ -544,7 +544,7 @@ namespace i2p
|
|||||||
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
||||||
msg->FillI2NPMessageHeader (eI2NPTunnelGateway); // gateway message
|
msg->FillI2NPMessageHeader (eI2NPTunnelGateway); // gateway message
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetI2NPMessageLength (const uint8_t * msg, size_t len)
|
size_t GetI2NPMessageLength (const uint8_t * msg, size_t len)
|
||||||
{
|
{
|
||||||
@@ -552,25 +552,25 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
auto l = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE;
|
auto l = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE;
|
||||||
if (l > len)
|
if (l > len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2NP: message length ", l, " exceeds buffer length ", len);
|
LogPrint (eLogError, "I2NP: message length ", l, " exceeds buffer length ", len);
|
||||||
l = len;
|
l = len;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleI2NPMessage (uint8_t * msg, size_t len)
|
void HandleI2NPMessage (uint8_t * msg, size_t len)
|
||||||
{
|
{
|
||||||
if (len < I2NP_HEADER_SIZE)
|
if (len < I2NP_HEADER_SIZE)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
|
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
|
||||||
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
|
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
|
||||||
LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
||||||
uint8_t * buf = msg + I2NP_HEADER_SIZE;
|
uint8_t * buf = msg + I2NP_HEADER_SIZE;
|
||||||
auto size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
|
auto size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
|
||||||
@@ -581,35 +581,35 @@ namespace i2p
|
|||||||
size = len;
|
size = len;
|
||||||
}
|
}
|
||||||
switch (typeID)
|
switch (typeID)
|
||||||
{
|
{
|
||||||
case eI2NPVariableTunnelBuild:
|
case eI2NPVariableTunnelBuild:
|
||||||
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPVariableTunnelBuildReply:
|
case eI2NPVariableTunnelBuildReply:
|
||||||
HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
|
HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelBuild:
|
case eI2NPTunnelBuild:
|
||||||
HandleTunnelBuildMsg (buf, size);
|
HandleTunnelBuildMsg (buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelBuildReply:
|
case eI2NPTunnelBuildReply:
|
||||||
// TODO:
|
// TODO:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "I2NP: Unexpected message ", (int)typeID);
|
LogPrint (eLogWarning, "I2NP: Unexpected message ", (int)typeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleI2NPMessage (std::shared_ptr<I2NPMessage> msg)
|
void HandleI2NPMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
if (msg)
|
if (msg)
|
||||||
{
|
{
|
||||||
uint8_t typeID = msg->GetTypeID ();
|
uint8_t typeID = msg->GetTypeID ();
|
||||||
LogPrint (eLogDebug, "I2NP: Handling message with type ", (int)typeID);
|
LogPrint (eLogDebug, "I2NP: Handling message with type ", (int)typeID);
|
||||||
switch (typeID)
|
switch (typeID)
|
||||||
{
|
{
|
||||||
case eI2NPTunnelData:
|
case eI2NPTunnelData:
|
||||||
i2p::tunnel::tunnels.PostTunnelData (msg);
|
i2p::tunnel::tunnels.PostTunnelData (msg);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelGateway:
|
case eI2NPTunnelGateway:
|
||||||
i2p::tunnel::tunnels.PostTunnelData (msg);
|
i2p::tunnel::tunnels.PostTunnelData (msg);
|
||||||
break;
|
break;
|
||||||
@@ -623,7 +623,7 @@ namespace i2p
|
|||||||
LogPrint (eLogInfo, "I2NP: Local destination for garlic doesn't exist anymore");
|
LogPrint (eLogInfo, "I2NP: Local destination for garlic doesn't exist anymore");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i2p::context.ProcessGarlicMessage (msg);
|
i2p::context.ProcessGarlicMessage (msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eI2NPDatabaseStore:
|
case eI2NPDatabaseStore:
|
||||||
@@ -638,55 +638,55 @@ namespace i2p
|
|||||||
msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg);
|
msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg);
|
||||||
else
|
else
|
||||||
i2p::context.ProcessDeliveryStatusMessage (msg);
|
i2p::context.ProcessDeliveryStatusMessage (msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eI2NPVariableTunnelBuild:
|
case eI2NPVariableTunnelBuild:
|
||||||
case eI2NPVariableTunnelBuildReply:
|
case eI2NPVariableTunnelBuildReply:
|
||||||
case eI2NPTunnelBuild:
|
case eI2NPTunnelBuild:
|
||||||
case eI2NPTunnelBuildReply:
|
case eI2NPTunnelBuildReply:
|
||||||
// forward to tunnel thread
|
// forward to tunnel thread
|
||||||
i2p::tunnel::tunnels.PostTunnelData (msg);
|
i2p::tunnel::tunnels.PostTunnelData (msg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
|
HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessagesHandler::~I2NPMessagesHandler ()
|
I2NPMessagesHandler::~I2NPMessagesHandler ()
|
||||||
{
|
{
|
||||||
Flush ();
|
Flush ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
if (msg)
|
if (msg)
|
||||||
{
|
{
|
||||||
switch (msg->GetTypeID ())
|
switch (msg->GetTypeID ())
|
||||||
{
|
{
|
||||||
case eI2NPTunnelData:
|
case eI2NPTunnelData:
|
||||||
m_TunnelMsgs.push_back (msg);
|
m_TunnelMsgs.push_back (msg);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelGateway:
|
case eI2NPTunnelGateway:
|
||||||
m_TunnelGatewayMsgs.push_back (msg);
|
m_TunnelGatewayMsgs.push_back (msg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
HandleI2NPMessage (msg);
|
HandleI2NPMessage (msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessagesHandler::Flush ()
|
void I2NPMessagesHandler::Flush ()
|
||||||
{
|
{
|
||||||
if (!m_TunnelMsgs.empty ())
|
if (!m_TunnelMsgs.empty ())
|
||||||
{
|
{
|
||||||
i2p::tunnel::tunnels.PostTunnelData (m_TunnelMsgs);
|
i2p::tunnel::tunnels.PostTunnelData (m_TunnelMsgs);
|
||||||
m_TunnelMsgs.clear ();
|
m_TunnelMsgs.clear ();
|
||||||
}
|
}
|
||||||
if (!m_TunnelGatewayMsgs.empty ())
|
if (!m_TunnelGatewayMsgs.empty ())
|
||||||
{
|
{
|
||||||
i2p::tunnel::tunnels.PostTunnelData (m_TunnelGatewayMsgs);
|
i2p::tunnel::tunnels.PostTunnelData (m_TunnelGatewayMsgs);
|
||||||
m_TunnelGatewayMsgs.clear ();
|
m_TunnelGatewayMsgs.clear ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "LeaseSet.h"
|
#include "LeaseSet.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
// I2NP header
|
// I2NP header
|
||||||
const size_t I2NP_HEADER_TYPEID_OFFSET = 0;
|
const size_t I2NP_HEADER_TYPEID_OFFSET = 0;
|
||||||
const size_t I2NP_HEADER_MSGID_OFFSET = I2NP_HEADER_TYPEID_OFFSET + 1;
|
const size_t I2NP_HEADER_MSGID_OFFSET = I2NP_HEADER_TYPEID_OFFSET + 1;
|
||||||
@@ -25,13 +25,13 @@ namespace i2p
|
|||||||
const size_t I2NP_SHORT_HEADER_TYPEID_OFFSET = 0;
|
const size_t I2NP_SHORT_HEADER_TYPEID_OFFSET = 0;
|
||||||
const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1;
|
const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1;
|
||||||
const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4;
|
const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4;
|
||||||
|
|
||||||
// Tunnel Gateway header
|
// Tunnel Gateway header
|
||||||
const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0;
|
const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0;
|
||||||
const size_t TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET = TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET + 4;
|
const size_t TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET = TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET + 4;
|
||||||
const size_t TUNNEL_GATEWAY_HEADER_SIZE = TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET + 2;
|
const size_t TUNNEL_GATEWAY_HEADER_SIZE = TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET + 2;
|
||||||
|
|
||||||
// DeliveryStatus
|
// DeliveryStatus
|
||||||
const size_t DELIVERY_STATUS_MSGID_OFFSET = 0;
|
const size_t DELIVERY_STATUS_MSGID_OFFSET = 0;
|
||||||
const size_t DELIVERY_STATUS_TIMESTAMP_OFFSET = DELIVERY_STATUS_MSGID_OFFSET + 4;
|
const size_t DELIVERY_STATUS_TIMESTAMP_OFFSET = DELIVERY_STATUS_MSGID_OFFSET + 4;
|
||||||
const size_t DELIVERY_STATUS_SIZE = DELIVERY_STATUS_TIMESTAMP_OFFSET + 8;
|
const size_t DELIVERY_STATUS_SIZE = DELIVERY_STATUS_TIMESTAMP_OFFSET + 8;
|
||||||
@@ -42,7 +42,7 @@ namespace i2p
|
|||||||
const size_t DATABASE_STORE_REPLY_TOKEN_OFFSET = DATABASE_STORE_TYPE_OFFSET + 1;
|
const size_t DATABASE_STORE_REPLY_TOKEN_OFFSET = DATABASE_STORE_TYPE_OFFSET + 1;
|
||||||
const size_t DATABASE_STORE_HEADER_SIZE = DATABASE_STORE_REPLY_TOKEN_OFFSET + 4;
|
const size_t DATABASE_STORE_HEADER_SIZE = DATABASE_STORE_REPLY_TOKEN_OFFSET + 4;
|
||||||
|
|
||||||
// TunnelBuild
|
// TunnelBuild
|
||||||
const size_t TUNNEL_BUILD_RECORD_SIZE = 528;
|
const size_t TUNNEL_BUILD_RECORD_SIZE = 528;
|
||||||
|
|
||||||
//BuildRequestRecordClearText
|
//BuildRequestRecordClearText
|
||||||
@@ -59,11 +59,11 @@ namespace i2p
|
|||||||
const size_t BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4;
|
const size_t BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4;
|
||||||
const size_t BUILD_REQUEST_RECORD_PADDING_OFFSET = BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4;
|
const size_t BUILD_REQUEST_RECORD_PADDING_OFFSET = BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4;
|
||||||
const size_t BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 222;
|
const size_t BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 222;
|
||||||
|
|
||||||
// BuildRequestRecordEncrypted
|
// BuildRequestRecordEncrypted
|
||||||
const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0;
|
const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0;
|
||||||
const size_t BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET = BUILD_REQUEST_RECORD_TO_PEER_OFFSET + 16;
|
const size_t BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET = BUILD_REQUEST_RECORD_TO_PEER_OFFSET + 16;
|
||||||
|
|
||||||
// BuildResponseRecord
|
// BuildResponseRecord
|
||||||
const size_t BUILD_RESPONSE_RECORD_HASH_OFFSET = 0;
|
const size_t BUILD_RESPONSE_RECORD_HASH_OFFSET = 0;
|
||||||
const size_t BUILD_RESPONSE_RECORD_PADDING_OFFSET = 32;
|
const size_t BUILD_RESPONSE_RECORD_PADDING_OFFSET = 32;
|
||||||
@@ -83,40 +83,40 @@ namespace i2p
|
|||||||
eI2NPTunnelBuild = 21,
|
eI2NPTunnelBuild = 21,
|
||||||
eI2NPTunnelBuildReply = 22,
|
eI2NPTunnelBuildReply = 22,
|
||||||
eI2NPVariableTunnelBuild = 23,
|
eI2NPVariableTunnelBuild = 23,
|
||||||
eI2NPVariableTunnelBuildReply = 24
|
eI2NPVariableTunnelBuildReply = 24
|
||||||
};
|
};
|
||||||
|
|
||||||
const int NUM_TUNNEL_BUILD_RECORDS = 8;
|
const int NUM_TUNNEL_BUILD_RECORDS = 8;
|
||||||
|
|
||||||
// DatabaseLookup flags
|
// DatabaseLookup flags
|
||||||
const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01;
|
const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01;
|
||||||
const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02;
|
const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02;
|
||||||
const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C;
|
const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C;
|
||||||
const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0;
|
const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0;
|
||||||
const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100
|
const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100
|
||||||
const uint8_t DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP = 0x08; // 1000
|
const uint8_t DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP = 0x08; // 1000
|
||||||
const uint8_t DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP = 0x0C; // 1100
|
const uint8_t DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP = 0x0C; // 1100
|
||||||
|
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
class InboundTunnel;
|
class InboundTunnel;
|
||||||
class TunnelPool;
|
class TunnelPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t I2NP_MAX_MESSAGE_SIZE = 32768;
|
const size_t I2NP_MAX_MESSAGE_SIZE = 32768;
|
||||||
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096;
|
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096;
|
||||||
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT)
|
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT)
|
||||||
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
|
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
|
||||||
|
|
||||||
struct I2NPMessage
|
struct I2NPMessage
|
||||||
{
|
{
|
||||||
uint8_t * buf;
|
uint8_t * buf;
|
||||||
size_t len, offset, maxLen;
|
size_t len, offset, maxLen;
|
||||||
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 (); };
|
||||||
const uint8_t * GetHeader () const { return GetBuffer (); };
|
const uint8_t * GetHeader () const { return GetBuffer (); };
|
||||||
@@ -128,24 +128,24 @@ namespace tunnel
|
|||||||
uint64_t GetExpiration () const { return bufbe64toh (GetHeader () + I2NP_HEADER_EXPIRATION_OFFSET); };
|
uint64_t GetExpiration () const { return bufbe64toh (GetHeader () + I2NP_HEADER_EXPIRATION_OFFSET); };
|
||||||
void SetSize (uint16_t size) { htobe16buf (GetHeader () + I2NP_HEADER_SIZE_OFFSET, size); };
|
void SetSize (uint16_t size) { htobe16buf (GetHeader () + I2NP_HEADER_SIZE_OFFSET, size); };
|
||||||
uint16_t GetSize () const { return bufbe16toh (GetHeader () + I2NP_HEADER_SIZE_OFFSET); };
|
uint16_t GetSize () const { return bufbe16toh (GetHeader () + I2NP_HEADER_SIZE_OFFSET); };
|
||||||
void UpdateSize () { SetSize (GetPayloadLength ()); };
|
void UpdateSize () { SetSize (GetPayloadLength ()); };
|
||||||
void SetChks (uint8_t chks) { GetHeader ()[I2NP_HEADER_CHKS_OFFSET] = chks; };
|
void SetChks (uint8_t chks) { GetHeader ()[I2NP_HEADER_CHKS_OFFSET] = chks; };
|
||||||
void UpdateChks ()
|
void UpdateChks ()
|
||||||
{
|
{
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(GetPayload (), GetPayloadLength (), hash);
|
SHA256(GetPayload (), GetPayloadLength (), hash);
|
||||||
GetHeader ()[I2NP_HEADER_CHKS_OFFSET] = hash[0];
|
GetHeader ()[I2NP_HEADER_CHKS_OFFSET] = hash[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
uint8_t * GetPayload () { return GetBuffer () + I2NP_HEADER_SIZE; };
|
uint8_t * GetPayload () { return GetBuffer () + I2NP_HEADER_SIZE; };
|
||||||
const uint8_t * GetPayload () const { return GetBuffer () + I2NP_HEADER_SIZE; };
|
const uint8_t * GetPayload () const { return GetBuffer () + I2NP_HEADER_SIZE; };
|
||||||
uint8_t * GetBuffer () { return buf + offset; };
|
uint8_t * GetBuffer () { return buf + offset; };
|
||||||
const uint8_t * GetBuffer () const { return buf + offset; };
|
const uint8_t * GetBuffer () const { return buf + offset; };
|
||||||
size_t GetLength () const { return len - offset; };
|
size_t GetLength () const { return len - offset; };
|
||||||
size_t GetPayloadLength () const { return GetLength () - I2NP_HEADER_SIZE; };
|
size_t GetPayloadLength () const { return GetLength () - I2NP_HEADER_SIZE; };
|
||||||
|
|
||||||
void Align (size_t alignment)
|
void Align (size_t alignment)
|
||||||
{
|
{
|
||||||
if (len + alignment > maxLen) return;
|
if (len + alignment > maxLen) return;
|
||||||
size_t rem = ((size_t)GetBuffer ()) % alignment;
|
size_t rem = ((size_t)GetBuffer ()) % alignment;
|
||||||
@@ -153,7 +153,7 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
offset += (alignment - rem);
|
offset += (alignment - rem);
|
||||||
len += (alignment - rem);
|
len += (alignment - rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Concat (const uint8_t * buf1, size_t len1)
|
size_t Concat (const uint8_t * buf1, size_t len1)
|
||||||
@@ -171,10 +171,10 @@ namespace tunnel
|
|||||||
len = offset + other.GetLength ();
|
len = offset + other.GetLength ();
|
||||||
from = other.from;
|
from = other.from;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for SSU only
|
// for SSU only
|
||||||
uint8_t * GetSSUHeader () { return buf + offset + I2NP_HEADER_SIZE - I2NP_SHORT_HEADER_SIZE; };
|
uint8_t * GetSSUHeader () { return buf + offset + I2NP_HEADER_SIZE - I2NP_SHORT_HEADER_SIZE; };
|
||||||
void FromSSU (uint32_t msgID) // we have received SSU message and convert it to regular
|
void FromSSU (uint32_t msgID) // we have received SSU message and convert it to regular
|
||||||
{
|
{
|
||||||
const uint8_t * ssu = GetSSUHeader ();
|
const uint8_t * ssu = GetSSUHeader ();
|
||||||
@@ -193,12 +193,12 @@ namespace tunnel
|
|||||||
htobe32buf (ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET, bufbe64toh (header + I2NP_HEADER_EXPIRATION_OFFSET)/1000LL);
|
htobe32buf (ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET, bufbe64toh (header + I2NP_HEADER_EXPIRATION_OFFSET)/1000LL);
|
||||||
len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET);
|
len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET);
|
||||||
return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET);
|
return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0);
|
void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0);
|
||||||
void RenewI2NPMessageHeader ();
|
void RenewI2NPMessageHeader ();
|
||||||
bool IsExpired () const;
|
bool IsExpired () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int sz>
|
template<int sz>
|
||||||
struct I2NPMessageBuffer: public I2NPMessage
|
struct I2NPMessageBuffer: public I2NPMessage
|
||||||
@@ -211,35 +211,35 @@ namespace tunnel
|
|||||||
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len);
|
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0);
|
std::shared_ptr<I2NPMessage> CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0);
|
||||||
std::shared_ptr<I2NPMessage> CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from = nullptr);
|
std::shared_ptr<I2NPMessage> CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from = nullptr);
|
||||||
std::shared_ptr<I2NPMessage> CopyI2NPMessage (std::shared_ptr<I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> CopyI2NPMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDeliveryStatusMsg (uint32_t msgID);
|
std::shared_ptr<I2NPMessage> CreateDeliveryStatusMsg (uint32_t msgID);
|
||||||
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
std::shared_ptr<I2NPMessage> CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
|
||||||
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, const uint8_t * replyKey, const uint8_t * replyTag);
|
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag);
|
||||||
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<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0);
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LeaseSet> leaseSet); // for floodfill only
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LeaseSet> leaseSet); // for floodfill only
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
|
||||||
bool IsRouterInfoMsg (std::shared_ptr<I2NPMessage> msg);
|
bool IsRouterInfoMsg (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText);
|
bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText);
|
||||||
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len);
|
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len);
|
||||||
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len);
|
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len);
|
||||||
void HandleTunnelBuildMsg (uint8_t * buf, size_t len);
|
void HandleTunnelBuildMsg (uint8_t * buf, size_t len);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (const uint8_t * buf);
|
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (const uint8_t * buf);
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload);
|
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload);
|
||||||
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg ();
|
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg ();
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len);
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len);
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType,
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType,
|
||||||
const uint8_t * buf, size_t len, uint32_t replyMsgID = 0);
|
const uint8_t * buf, size_t len, uint32_t replyMsgID = 0);
|
||||||
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ namespace tunnel
|
|||||||
~I2NPMessagesHandler ();
|
~I2NPMessagesHandler ();
|
||||||
void PutNextMessage (std::shared_ptr<I2NPMessage> msg);
|
void PutNextMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void Flush ();
|
void Flush ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
|
std::vector<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
|
||||||
@@ -262,6 +262,6 @@ namespace tunnel
|
|||||||
|
|
||||||
const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500;
|
const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500;
|
||||||
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels);
|
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
|
#if defined(__FreeBSD__)
|
||||||
#include <endian.h>
|
|
||||||
#elif __FreeBSD__
|
|
||||||
#include <sys/endian.h>
|
#include <sys/endian.h>
|
||||||
|
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
|
||||||
|
#include <endian.h>
|
||||||
#elif defined(__APPLE__) && defined(__MACH__)
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
|
||||||
#include <libkern/OSByteOrder.h>
|
#include <libkern/OSByteOrder.h>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace data
|
|||||||
|
|
||||||
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType):
|
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType):
|
||||||
m_IsVerifierCreated (false)
|
m_IsVerifierCreated (false)
|
||||||
{
|
{
|
||||||
memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of
|
memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of
|
||||||
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
|
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
{
|
{
|
||||||
@@ -450,7 +450,7 @@ namespace data
|
|||||||
|
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (const uint8_t * key) const
|
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (const uint8_t * key) const
|
||||||
{
|
{
|
||||||
if (!key) key = GetEncryptionPublicKey (); // use publicKey
|
if (!key) key = GetEncryptionPublicKey (); // use publicKey
|
||||||
switch (GetCryptoKeyType ())
|
switch (GetCryptoKeyType ())
|
||||||
{
|
{
|
||||||
case CRYPTO_KEY_TYPE_ELGAMAL:
|
case CRYPTO_KEY_TYPE_ELGAMAL:
|
||||||
@@ -542,7 +542,7 @@ namespace data
|
|||||||
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
|
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
|
||||||
{
|
{
|
||||||
if (!m_Signer)
|
if (!m_Signer)
|
||||||
CreateSigner();
|
CreateSigner();
|
||||||
m_Signer->Sign (buf, len, signature);
|
m_Signer->Sign (buf, len, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,12 +596,12 @@ namespace data
|
|||||||
|
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> PrivateKeys::CreateDecryptor (const uint8_t * key) const
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> PrivateKeys::CreateDecryptor (const uint8_t * key) const
|
||||||
{
|
{
|
||||||
if (!key) key = m_PrivateKey; // use privateKey
|
if (!key) key = m_PrivateKey; // use privateKey
|
||||||
return CreateDecryptor (m_Public->GetCryptoKeyType (), key);
|
return CreateDecryptor (m_Public->GetCryptoKeyType (), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> PrivateKeys::CreateDecryptor (CryptoKeyType cryptoType, const uint8_t * key)
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> PrivateKeys::CreateDecryptor (CryptoKeyType cryptoType, const uint8_t * key)
|
||||||
{
|
{
|
||||||
if (!key) return nullptr;
|
if (!key) return nullptr;
|
||||||
switch (cryptoType)
|
switch (cryptoType)
|
||||||
{
|
{
|
||||||
@@ -618,7 +618,7 @@ namespace data
|
|||||||
default:
|
default:
|
||||||
LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)cryptoType);
|
LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)cryptoType);
|
||||||
};
|
};
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type, CryptoKeyType cryptoType)
|
PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type, CryptoKeyType cryptoType)
|
||||||
@@ -643,7 +643,7 @@ namespace data
|
|||||||
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||||
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||||
LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Create EdDSA");
|
LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Create EdDSA");
|
||||||
// no break here
|
// no break here
|
||||||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||||
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
||||||
break;
|
break;
|
||||||
@@ -685,7 +685,7 @@ namespace data
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported");
|
LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys CreateRandomKeys ()
|
Keys CreateRandomKeys ()
|
||||||
|
|||||||
@@ -91,12 +91,12 @@ namespace data
|
|||||||
size_t ToBuffer (uint8_t * buf, size_t len) const;
|
size_t ToBuffer (uint8_t * buf, size_t len) const;
|
||||||
size_t FromBase64(const std::string& s);
|
size_t FromBase64(const std::string& s);
|
||||||
std::string ToBase64 () const;
|
std::string ToBase64 () const;
|
||||||
const Identity& GetStandardIdentity () const { return m_StandardIdentity; };
|
const Identity& GetStandardIdentity () const { return m_StandardIdentity; };
|
||||||
|
|
||||||
const IdentHash& GetIdentHash () const { return m_IdentHash; };
|
const IdentHash& GetIdentHash () const { return m_IdentHash; };
|
||||||
const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; };
|
const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; };
|
||||||
uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; };
|
uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; };
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const;
|
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const;
|
||||||
size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; };
|
size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; };
|
||||||
size_t GetSigningPublicKeyLen () const;
|
size_t GetSigningPublicKeyLen () const;
|
||||||
size_t GetSigningPrivateKeyLen () const;
|
size_t GetSigningPrivateKeyLen () const;
|
||||||
@@ -141,7 +141,7 @@ namespace data
|
|||||||
const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
|
const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
|
||||||
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
||||||
uint8_t * GetPadding();
|
uint8_t * GetPadding();
|
||||||
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
||||||
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
|
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
|
||||||
|
|
||||||
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
|
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
|
|
||||||
LeaseSet::LeaseSet (const uint8_t * buf, size_t len, bool storeLeases):
|
LeaseSet::LeaseSet (const uint8_t * buf, size_t len, bool storeLeases):
|
||||||
m_IsValid (true), m_StoreLeases (storeLeases), m_ExpirationTime (0)
|
m_IsValid (true), m_StoreLeases (storeLeases), m_ExpirationTime (0)
|
||||||
{
|
{
|
||||||
@@ -21,27 +21,27 @@ namespace data
|
|||||||
ReadFromBuffer ();
|
ReadFromBuffer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSet::Update (const uint8_t * buf, size_t len)
|
void LeaseSet::Update (const uint8_t * buf, size_t len, bool verifySignature)
|
||||||
{
|
{
|
||||||
if (len > m_BufferLen)
|
if (len > m_BufferLen)
|
||||||
{
|
{
|
||||||
auto oldBuffer = m_Buffer;
|
auto oldBuffer = m_Buffer;
|
||||||
m_Buffer = new uint8_t[len];
|
m_Buffer = new uint8_t[len];
|
||||||
delete[] oldBuffer;
|
delete[] oldBuffer;
|
||||||
}
|
}
|
||||||
memcpy (m_Buffer, buf, len);
|
memcpy (m_Buffer, buf, len);
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
ReadFromBuffer (false);
|
ReadFromBuffer (false, verifySignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSet::PopulateLeases ()
|
void LeaseSet::PopulateLeases ()
|
||||||
{
|
{
|
||||||
m_StoreLeases = true;
|
m_StoreLeases = true;
|
||||||
ReadFromBuffer (false);
|
ReadFromBuffer (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSet::ReadFromBuffer (bool readIdentity)
|
void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature)
|
||||||
{
|
{
|
||||||
if (readIdentity || !m_Identity)
|
if (readIdentity || !m_Identity)
|
||||||
m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
|
m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
|
||||||
size_t size = m_Identity->GetFullLen ();
|
size_t size = m_Identity->GetFullLen ();
|
||||||
@@ -58,17 +58,17 @@ namespace data
|
|||||||
size++; // num
|
size++; // num
|
||||||
LogPrint (eLogDebug, "LeaseSet: read num=", (int)num);
|
LogPrint (eLogDebug, "LeaseSet: read num=", (int)num);
|
||||||
if (!num || num > MAX_NUM_LEASES)
|
if (!num || num > MAX_NUM_LEASES)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)num);
|
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)num);
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset existing leases
|
// reset existing leases
|
||||||
if (m_StoreLeases)
|
if (m_StoreLeases)
|
||||||
for (auto& it: m_Leases)
|
for (auto& it: m_Leases)
|
||||||
it->isUpdated = false;
|
it->isUpdated = false;
|
||||||
else
|
else
|
||||||
m_Leases.clear ();
|
m_Leases.clear ();
|
||||||
|
|
||||||
// process leases
|
// process leases
|
||||||
@@ -82,14 +82,14 @@ namespace data
|
|||||||
leases += 32; // gateway
|
leases += 32; // gateway
|
||||||
lease.tunnelID = bufbe32toh (leases);
|
lease.tunnelID = bufbe32toh (leases);
|
||||||
leases += 4; // tunnel ID
|
leases += 4; // tunnel ID
|
||||||
lease.endDate = bufbe64toh (leases);
|
lease.endDate = bufbe64toh (leases);
|
||||||
leases += 8; // end date
|
leases += 8; // end date
|
||||||
if (ts < lease.endDate + LEASE_ENDDATE_THRESHOLD)
|
if (ts < lease.endDate + LEASE_ENDDATE_THRESHOLD)
|
||||||
{
|
{
|
||||||
if (lease.endDate > m_ExpirationTime)
|
if (lease.endDate > m_ExpirationTime)
|
||||||
m_ExpirationTime = lease.endDate;
|
m_ExpirationTime = lease.endDate;
|
||||||
if (m_StoreLeases)
|
if (m_StoreLeases)
|
||||||
{
|
{
|
||||||
auto ret = m_Leases.insert (std::make_shared<Lease>(lease));
|
auto ret = m_Leases.insert (std::make_shared<Lease>(lease));
|
||||||
if (!ret.second) (*ret.first)->endDate = lease.endDate; // update existing
|
if (!ret.second) (*ret.first)->endDate = lease.endDate; // update existing
|
||||||
(*ret.first)->isUpdated = true;
|
(*ret.first)->isUpdated = true;
|
||||||
@@ -100,42 +100,42 @@ namespace data
|
|||||||
LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting");
|
LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting");
|
||||||
netdb.RequestDestination (lease.tunnelGateway);
|
netdb.RequestDestination (lease.tunnelGateway);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "LeaseSet: Lease is expired already ");
|
LogPrint (eLogWarning, "LeaseSet: Lease is expired already ");
|
||||||
}
|
}
|
||||||
if (!m_ExpirationTime)
|
if (!m_ExpirationTime)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "LeaseSet: all leases are expired. Dropped");
|
LogPrint (eLogWarning, "LeaseSet: all leases are expired. Dropped");
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_ExpirationTime += LEASE_ENDDATE_THRESHOLD;
|
m_ExpirationTime += LEASE_ENDDATE_THRESHOLD;
|
||||||
// delete old leases
|
// delete old leases
|
||||||
if (m_StoreLeases)
|
if (m_StoreLeases)
|
||||||
{
|
{
|
||||||
for (auto it = m_Leases.begin (); it != m_Leases.end ();)
|
for (auto it = m_Leases.begin (); it != m_Leases.end ();)
|
||||||
{
|
{
|
||||||
if (!(*it)->isUpdated)
|
if (!(*it)->isUpdated)
|
||||||
{
|
{
|
||||||
(*it)->endDate = 0; // somebody might still hold it
|
(*it)->endDate = 0; // somebody might still hold it
|
||||||
m_Leases.erase (it++);
|
m_Leases.erase (it++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
if (!m_Identity->Verify (m_Buffer, leases - m_Buffer, leases))
|
if (verifySignature && !m_Identity->Verify (m_Buffer, leases - m_Buffer, leases))
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "LeaseSet: verification failed");
|
LogPrint (eLogWarning, "LeaseSet: verification failed");
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const
|
uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const
|
||||||
{
|
{
|
||||||
if (!m_Identity) return 0;
|
if (!m_Identity) return 0;
|
||||||
size_t size = m_Identity->GetFullLen ();
|
size_t size = m_Identity->GetFullLen ();
|
||||||
@@ -150,18 +150,18 @@ namespace data
|
|||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
size += 36; // gateway (32) + tunnelId(4)
|
size += 36; // gateway (32) + tunnelId(4)
|
||||||
auto endDate = bufbe64toh (buf + size);
|
auto endDate = bufbe64toh (buf + size);
|
||||||
size += 8; // end date
|
size += 8; // end date
|
||||||
if (!timestamp || endDate < timestamp)
|
if (!timestamp || endDate < timestamp)
|
||||||
timestamp = endDate;
|
timestamp = endDate;
|
||||||
}
|
}
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const
|
bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const
|
||||||
{
|
{
|
||||||
return ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen);
|
return ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const
|
bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const
|
||||||
{
|
{
|
||||||
@@ -175,7 +175,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const
|
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
@@ -189,17 +189,17 @@ namespace data
|
|||||||
endDate -= LEASE_ENDDATE_THRESHOLD;
|
endDate -= LEASE_ENDDATE_THRESHOLD;
|
||||||
if (ts < endDate && !exclude(*it))
|
if (ts < endDate && !exclude(*it))
|
||||||
leases.push_back (it);
|
leases.push_back (it);
|
||||||
}
|
}
|
||||||
return leases;
|
return leases;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeaseSet::HasExpiredLeases () const
|
bool LeaseSet::HasExpiredLeases () const
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
for (const auto& it: m_Leases)
|
for (const auto& it: m_Leases)
|
||||||
if (ts >= it->endDate) return true;
|
if (ts >= it->endDate) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeaseSet::IsExpired () const
|
bool LeaseSet::IsExpired () const
|
||||||
{
|
{
|
||||||
@@ -222,15 +222,15 @@ namespace data
|
|||||||
if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES;
|
if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES;
|
||||||
// identity
|
// identity
|
||||||
auto signingKeyLen = m_Identity->GetSigningPublicKeyLen ();
|
auto signingKeyLen = m_Identity->GetSigningPublicKeyLen ();
|
||||||
m_BufferLen = m_Identity->GetFullLen () + 256 + signingKeyLen + 1 + num*LEASE_SIZE + m_Identity->GetSignatureLen ();
|
m_BufferLen = m_Identity->GetFullLen () + 256 + signingKeyLen + 1 + num*LEASE_SIZE + m_Identity->GetSignatureLen ();
|
||||||
m_Buffer = new uint8_t[m_BufferLen];
|
m_Buffer = new uint8_t[m_BufferLen];
|
||||||
auto offset = m_Identity->ToBuffer (m_Buffer, m_BufferLen);
|
auto offset = m_Identity->ToBuffer (m_Buffer, m_BufferLen);
|
||||||
memcpy (m_Buffer + offset, encryptionPublicKey, 256);
|
memcpy (m_Buffer + offset, encryptionPublicKey, 256);
|
||||||
offset += 256;
|
offset += 256;
|
||||||
memset (m_Buffer + offset, 0, signingKeyLen);
|
memset (m_Buffer + offset, 0, signingKeyLen);
|
||||||
offset += signingKeyLen;
|
offset += signingKeyLen;
|
||||||
// num leases
|
// num leases
|
||||||
m_Buffer[offset] = num;
|
m_Buffer[offset] = num;
|
||||||
offset++;
|
offset++;
|
||||||
// leases
|
// leases
|
||||||
m_Leases = m_Buffer + offset;
|
m_Leases = m_Buffer + offset;
|
||||||
@@ -257,13 +257,47 @@ namespace data
|
|||||||
{
|
{
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
m_Buffer = new uint8_t[m_BufferLen];
|
m_Buffer = new uint8_t[m_BufferLen];
|
||||||
memcpy (m_Buffer, buf, len);
|
memcpy (m_Buffer, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocalLeaseSet::IsExpired () const
|
bool LocalLeaseSet::IsExpired () const
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
return ts > m_ExpirationTime;
|
return ts > m_ExpirationTime;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires)
|
||||||
|
{
|
||||||
|
IdentityEx ident(ptr, sz);
|
||||||
|
size_t size = ident.GetFullLen ();
|
||||||
|
if (size > sz)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "LeaseSet: identity length ", size, " exceeds buffer size ", sz);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// encryption key
|
||||||
|
size += 256;
|
||||||
|
// signing key (unused)
|
||||||
|
size += ident.GetSigningPublicKeyLen ();
|
||||||
|
uint8_t numLeases = ptr[size];
|
||||||
|
++size;
|
||||||
|
if (!numLeases || numLeases > MAX_NUM_LEASES)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)numLeases);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const uint8_t * leases = ptr + size;
|
||||||
|
expires = 0;
|
||||||
|
/** find lease with the max expiration timestamp */
|
||||||
|
for (int i = 0; i < numLeases; i++)
|
||||||
|
{
|
||||||
|
leases += 36; // gateway + tunnel ID
|
||||||
|
uint64_t endDate = bufbe64toh (leases);
|
||||||
|
leases += 8; // end date
|
||||||
|
if(endDate > expires)
|
||||||
|
expires = endDate;
|
||||||
|
}
|
||||||
|
return ident.Verify(ptr, leases - ptr, leases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ namespace i2p
|
|||||||
|
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
class InboundTunnel;
|
class InboundTunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
const int LEASE_ENDDATE_THRESHOLD = 51000; // in milliseconds
|
const int LEASE_ENDDATE_THRESHOLD = 51000; // in milliseconds
|
||||||
struct Lease
|
struct Lease
|
||||||
{
|
{
|
||||||
@@ -33,36 +33,36 @@ namespace data
|
|||||||
if (endDate < expire) return true;
|
if (endDate < expire) return true;
|
||||||
return (endDate - expire) < t;
|
return (endDate - expire) < t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LeaseCmp
|
struct LeaseCmp
|
||||||
{
|
{
|
||||||
bool operator() (std::shared_ptr<const Lease> l1, std::shared_ptr<const Lease> l2) const
|
bool operator() (std::shared_ptr<const Lease> l1, std::shared_ptr<const Lease> l2) const
|
||||||
{
|
{
|
||||||
if (l1->tunnelID != l2->tunnelID)
|
if (l1->tunnelID != l2->tunnelID)
|
||||||
return l1->tunnelID < l2->tunnelID;
|
return l1->tunnelID < l2->tunnelID;
|
||||||
else
|
else
|
||||||
return l1->tunnelGateway < l2->tunnelGateway;
|
return l1->tunnelGateway < l2->tunnelGateway;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<bool(const Lease & l)> LeaseInspectFunc;
|
typedef std::function<bool(const Lease & l)> LeaseInspectFunc;
|
||||||
|
|
||||||
const size_t MAX_LS_BUFFER_SIZE = 3072;
|
const size_t MAX_LS_BUFFER_SIZE = 3072;
|
||||||
const size_t LEASE_SIZE = 44; // 32 + 4 + 8
|
const size_t LEASE_SIZE = 44; // 32 + 4 + 8
|
||||||
const uint8_t MAX_NUM_LEASES = 16;
|
const uint8_t MAX_NUM_LEASES = 16;
|
||||||
class LeaseSet: public RoutingDestination
|
class LeaseSet: public RoutingDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true);
|
LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true);
|
||||||
~LeaseSet () { delete[] m_Buffer; };
|
~LeaseSet () { delete[] m_Buffer; };
|
||||||
void Update (const uint8_t * buf, size_t len);
|
void Update (const uint8_t * buf, size_t len, bool verifySignature = true);
|
||||||
bool IsNewer (const uint8_t * buf, size_t len) const;
|
bool IsNewer (const uint8_t * buf, size_t len) const;
|
||||||
void PopulateLeases (); // from buffer
|
void PopulateLeases (); // from buffer
|
||||||
|
|
||||||
const uint8_t * GetBuffer () const { return m_Buffer; };
|
const uint8_t * GetBuffer () const { return m_Buffer; };
|
||||||
size_t GetBufferLen () const { return m_BufferLen; };
|
size_t GetBufferLen () const { return m_BufferLen; };
|
||||||
bool IsValid () const { return m_IsValid; };
|
bool IsValid () const { return m_IsValid; };
|
||||||
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeases (bool withThreshold = true) const;
|
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeases (bool withThreshold = true) const;
|
||||||
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const;
|
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const;
|
||||||
@@ -71,8 +71,8 @@ namespace data
|
|||||||
bool IsEmpty () const { return m_Leases.empty (); };
|
bool IsEmpty () const { return m_Leases.empty (); };
|
||||||
uint64_t GetExpirationTime () const { return m_ExpirationTime; };
|
uint64_t GetExpirationTime () const { return m_ExpirationTime; };
|
||||||
bool ExpiresSoon(const uint64_t dlt=1000 * 5, const uint64_t fudge = 0) const ;
|
bool ExpiresSoon(const uint64_t dlt=1000 * 5, const uint64_t fudge = 0) const ;
|
||||||
bool operator== (const LeaseSet& other) const
|
bool operator== (const LeaseSet& other) const
|
||||||
{ return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); };
|
{ return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); };
|
||||||
|
|
||||||
// implements RoutingDestination
|
// implements RoutingDestination
|
||||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
|
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
|
||||||
@@ -81,9 +81,9 @@ namespace data
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadFromBuffer (bool readIdentity = true);
|
void ReadFromBuffer (bool readIdentity = true, bool verifySignature = true);
|
||||||
uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // min expiration time
|
uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsValid, m_StoreLeases; // we don't need to store leases for floodfill
|
bool m_IsValid, m_StoreLeases; // we don't need to store leases for floodfill
|
||||||
@@ -93,7 +93,13 @@ namespace data
|
|||||||
uint8_t m_EncryptionKey[256];
|
uint8_t m_EncryptionKey[256];
|
||||||
uint8_t * m_Buffer;
|
uint8_t * m_Buffer;
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
validate lease set buffer signature and extract expiration timestamp
|
||||||
|
@returns true if the leaseset is well formed and signature is valid
|
||||||
|
*/
|
||||||
|
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
|
||||||
|
|
||||||
class LocalLeaseSet
|
class LocalLeaseSet
|
||||||
{
|
{
|
||||||
@@ -104,27 +110,27 @@ namespace data
|
|||||||
~LocalLeaseSet () { delete[] m_Buffer; };
|
~LocalLeaseSet () { delete[] m_Buffer; };
|
||||||
|
|
||||||
const uint8_t * GetBuffer () const { return m_Buffer; };
|
const uint8_t * GetBuffer () const { return m_Buffer; };
|
||||||
uint8_t * GetSignature () { return m_Buffer + m_BufferLen - GetSignatureLen (); };
|
uint8_t * GetSignature () { return m_Buffer + m_BufferLen - GetSignatureLen (); };
|
||||||
size_t GetBufferLen () const { return m_BufferLen; };
|
size_t GetBufferLen () const { return m_BufferLen; };
|
||||||
size_t GetSignatureLen () const { return m_Identity->GetSignatureLen (); };
|
size_t GetSignatureLen () const { return m_Identity->GetSignatureLen (); };
|
||||||
uint8_t * GetLeases () { return m_Leases; };
|
uint8_t * GetLeases () { return m_Leases; };
|
||||||
|
|
||||||
const IdentHash& GetIdentHash () const { return m_Identity->GetIdentHash (); };
|
const IdentHash& GetIdentHash () const { return m_Identity->GetIdentHash (); };
|
||||||
bool IsExpired () const;
|
bool IsExpired () const;
|
||||||
uint64_t GetExpirationTime () const { return m_ExpirationTime; };
|
uint64_t GetExpirationTime () const { return m_ExpirationTime; };
|
||||||
void SetExpirationTime (uint64_t expirationTime) { m_ExpirationTime = expirationTime; };
|
void SetExpirationTime (uint64_t expirationTime) { m_ExpirationTime = expirationTime; };
|
||||||
bool operator== (const LeaseSet& other) const
|
bool operator== (const LeaseSet& other) const
|
||||||
{ return m_BufferLen == other.GetBufferLen () && !memcmp (other.GetBuffer (), other.GetBuffer (), m_BufferLen); };
|
{ return m_BufferLen == other.GetBufferLen () && !memcmp (other.GetBuffer (), other.GetBuffer (), m_BufferLen); };
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint64_t m_ExpirationTime; // in milliseconds
|
uint64_t m_ExpirationTime; // in milliseconds
|
||||||
std::shared_ptr<const IdentityEx> m_Identity;
|
std::shared_ptr<const IdentityEx> m_Identity;
|
||||||
uint8_t * m_Buffer, * m_Leases;
|
uint8_t * m_Buffer, * m_Leases;
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ enum LogType {
|
|||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace log {
|
namespace log {
|
||||||
|
|
||||||
struct LogMsg; /* forward declaration */
|
struct LogMsg; /* forward declaration */
|
||||||
|
|
||||||
class Log
|
class Log
|
||||||
@@ -146,7 +146,7 @@ namespace log {
|
|||||||
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, const std::string & txt): timestamp(ts), text(txt), level(lvl) {};
|
LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept
|
|||||||
std::stringstream ss("");
|
std::stringstream ss("");
|
||||||
|
|
||||||
LogPrint (ss, std::forward<TArgs>(args)...);
|
LogPrint (ss, std::forward<TArgs>(args)...);
|
||||||
|
|
||||||
auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str());
|
auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str());
|
||||||
msg->tid = std::this_thread::get_id();
|
msg->tid = std::this_thread::get_id();
|
||||||
log.Append(msg);
|
log.Append(msg);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
const int NETDB_MIN_ROUTERS = 90;
|
const int NETDB_MIN_ROUTERS = 90;
|
||||||
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60*60; // 1 hour, in seconds
|
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60*60; // 1 hour, in seconds
|
||||||
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65*60;
|
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65*60;
|
||||||
@@ -37,11 +37,11 @@ namespace data
|
|||||||
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
|
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
|
||||||
|
|
||||||
/** function for visiting a router info we have locally */
|
/** function for visiting a router info we have locally */
|
||||||
typedef std::function<void(std::shared_ptr<const i2p::data::RouterInfo>)> RouterInfoVisitor;
|
typedef std::function<void(std::shared_ptr<const i2p::data::RouterInfo>)> RouterInfoVisitor;
|
||||||
|
|
||||||
/** function for visiting a router info and determining if we want to use it */
|
/** function for visiting a router info and determining if we want to use it */
|
||||||
typedef std::function<bool(std::shared_ptr<const i2p::data::RouterInfo>)> RouterInfoFilter;
|
typedef std::function<bool(std::shared_ptr<const i2p::data::RouterInfo>)> RouterInfoFilter;
|
||||||
|
|
||||||
class NetDb
|
class NetDb
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -51,7 +51,7 @@ namespace data
|
|||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
bool AddRouterInfo (const uint8_t * buf, int len);
|
bool AddRouterInfo (const uint8_t * buf, int len);
|
||||||
bool AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len);
|
bool AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len);
|
||||||
bool AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
bool AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
||||||
@@ -59,12 +59,12 @@ namespace data
|
|||||||
std::shared_ptr<LeaseSet> FindLeaseSet (const IdentHash& destination) const;
|
std::shared_ptr<LeaseSet> FindLeaseSet (const IdentHash& destination) const;
|
||||||
std::shared_ptr<RouterProfile> FindRouterProfile (const IdentHash& ident) const;
|
std::shared_ptr<RouterProfile> FindRouterProfile (const IdentHash& ident) const;
|
||||||
|
|
||||||
void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr);
|
void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
|
|
||||||
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
||||||
@@ -76,13 +76,13 @@ namespace data
|
|||||||
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||||
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily(const std::string & fam) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily(const std::string & fam) const;
|
||||||
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
||||||
|
|
||||||
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
||||||
void SetHidden(bool hide);
|
void SetHidden(bool hide);
|
||||||
|
|
||||||
void Reseed ();
|
void Reseed ();
|
||||||
Families& GetFamilies () { return m_Families; };
|
Families& GetFamilies () { return m_Families; };
|
||||||
|
|
||||||
@@ -108,28 +108,28 @@ namespace data
|
|||||||
bool LoadRouterInfo (const std::string & path);
|
bool LoadRouterInfo (const std::string & path);
|
||||||
void SaveUpdated ();
|
void SaveUpdated ();
|
||||||
void Run (); // exploratory thread
|
void Run (); // exploratory thread
|
||||||
void Explore (int numDestinations);
|
void Explore (int numDestinations);
|
||||||
void Publish ();
|
void Publish ();
|
||||||
void ManageLeaseSets ();
|
void ManageLeaseSets ();
|
||||||
void ManageRequests ();
|
void ManageRequests ();
|
||||||
|
|
||||||
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20);
|
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20);
|
||||||
|
|
||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
mutable std::mutex m_LeaseSetsMutex;
|
mutable std::mutex m_LeaseSetsMutex;
|
||||||
std::map<IdentHash, std::shared_ptr<LeaseSet> > m_LeaseSets;
|
std::map<IdentHash, std::shared_ptr<LeaseSet> > m_LeaseSets;
|
||||||
mutable std::mutex m_RouterInfosMutex;
|
mutable std::mutex m_RouterInfosMutex;
|
||||||
std::map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
|
std::map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
|
||||||
mutable std::mutex m_FloodfillsMutex;
|
mutable std::mutex m_FloodfillsMutex;
|
||||||
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
uint64_t m_LastLoad;
|
uint64_t m_LastLoad;
|
||||||
std::thread * m_Thread;
|
std::thread * m_Thread;
|
||||||
i2p::util::Queue<std::shared_ptr<const I2NPMessage> > m_Queue; // of I2NPDatabaseStoreMsg
|
i2p::util::Queue<std::shared_ptr<const I2NPMessage> > m_Queue; // of I2NPDatabaseStoreMsg
|
||||||
|
|
||||||
GzipInflator m_Inflator;
|
GzipInflator m_Inflator;
|
||||||
@@ -137,12 +137,12 @@ namespace data
|
|||||||
Families m_Families;
|
Families m_Families;
|
||||||
i2p::fs::HashedStorage m_Storage;
|
i2p::fs::HashedStorage m_Storage;
|
||||||
|
|
||||||
friend class NetDbRequests;
|
friend class NetDbRequests;
|
||||||
NetDbRequests m_Requests;
|
NetDbRequests m_Requests;
|
||||||
|
|
||||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||||
|
|
||||||
|
|
||||||
/** true if in hidden mode */
|
/** true if in hidden mode */
|
||||||
bool m_HiddenMode;
|
bool m_HiddenMode;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
std::shared_ptr<I2NPMessage> msg;
|
std::shared_ptr<I2NPMessage> msg;
|
||||||
if(replyTunnel)
|
if(replyTunnel)
|
||||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
||||||
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
||||||
&m_ExcludedPeers);
|
&m_ExcludedPeers);
|
||||||
else
|
else
|
||||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
||||||
@@ -22,22 +22,22 @@ namespace data
|
|||||||
m_ExcludedPeers.insert (router->GetIdentHash ());
|
m_ExcludedPeers.insert (router->GetIdentHash ());
|
||||||
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> RequestedDestination::CreateRequestMessage (const IdentHash& floodfill)
|
std::shared_ptr<I2NPMessage> RequestedDestination::CreateRequestMessage (const IdentHash& floodfill)
|
||||||
{
|
{
|
||||||
auto msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
auto msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
||||||
i2p::context.GetRouterInfo ().GetIdentHash () , 0, false, &m_ExcludedPeers);
|
i2p::context.GetRouterInfo ().GetIdentHash () , 0, false, &m_ExcludedPeers);
|
||||||
m_ExcludedPeers.insert (floodfill);
|
m_ExcludedPeers.insert (floodfill);
|
||||||
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
m_CreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestedDestination::ClearExcludedPeers ()
|
void RequestedDestination::ClearExcludedPeers ()
|
||||||
{
|
{
|
||||||
m_ExcludedPeers.clear ();
|
m_ExcludedPeers.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestedDestination::Success (std::shared_ptr<RouterInfo> r)
|
void RequestedDestination::Success (std::shared_ptr<RouterInfo> r)
|
||||||
{
|
{
|
||||||
if (m_RequestComplete)
|
if (m_RequestComplete)
|
||||||
@@ -69,15 +69,15 @@ namespace data
|
|||||||
std::shared_ptr<RequestedDestination> NetDbRequests::CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete)
|
std::shared_ptr<RequestedDestination> NetDbRequests::CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete)
|
||||||
{
|
{
|
||||||
// request RouterInfo directly
|
// request RouterInfo directly
|
||||||
auto dest = std::make_shared<RequestedDestination> (destination, isExploratory);
|
auto dest = std::make_shared<RequestedDestination> (destination, isExploratory);
|
||||||
dest->SetRequestComplete (requestComplete);
|
dest->SetRequestComplete (requestComplete);
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
||||||
if (!m_RequestedDestinations.insert (std::make_pair (destination, dest)).second) // not inserted
|
if (!m_RequestedDestinations.insert (std::make_pair (destination, dest)).second) // not inserted
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDbRequests::RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r)
|
void NetDbRequests::RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r)
|
||||||
{
|
{
|
||||||
@@ -86,18 +86,18 @@ namespace data
|
|||||||
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
||||||
auto it = m_RequestedDestinations.find (ident);
|
auto it = m_RequestedDestinations.find (ident);
|
||||||
if (it != m_RequestedDestinations.end ())
|
if (it != m_RequestedDestinations.end ())
|
||||||
{
|
{
|
||||||
request = it->second;
|
request = it->second;
|
||||||
m_RequestedDestinations.erase (it);
|
m_RequestedDestinations.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (request)
|
if (request)
|
||||||
{
|
{
|
||||||
if (r)
|
if (r)
|
||||||
request->Success (r);
|
request->Success (r);
|
||||||
else
|
else
|
||||||
request->Fail ();
|
request->Fail ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RequestedDestination> NetDbRequests::FindRequest (const IdentHash& ident) const
|
std::shared_ptr<RequestedDestination> NetDbRequests::FindRequest (const IdentHash& ident) const
|
||||||
@@ -107,12 +107,12 @@ namespace data
|
|||||||
if (it != m_RequestedDestinations.end ())
|
if (it != m_RequestedDestinations.end ())
|
||||||
return it->second;
|
return it->second;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDbRequests::ManageRequests ()
|
void NetDbRequests::ManageRequests ()
|
||||||
{
|
{
|
||||||
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex);
|
||||||
for (auto it = m_RequestedDestinations.begin (); it != m_RequestedDestinations.end ();)
|
for (auto it = m_RequestedDestinations.begin (); it != m_RequestedDestinations.end ();)
|
||||||
{
|
{
|
||||||
auto& dest = it->second;
|
auto& dest = it->second;
|
||||||
@@ -126,7 +126,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
auto outbound = pool->GetNextOutboundTunnel ();
|
auto outbound = pool->GetNextOutboundTunnel ();
|
||||||
auto inbound = pool->GetNextInboundTunnel ();
|
auto inbound = pool->GetNextInboundTunnel ();
|
||||||
auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
|
auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
|
||||||
if (nextFloodfill && outbound && inbound)
|
if (nextFloodfill && outbound && inbound)
|
||||||
outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0,
|
outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0,
|
||||||
@@ -138,15 +138,15 @@ namespace data
|
|||||||
if (!outbound) LogPrint (eLogWarning, "NetDbReq: No outbound tunnels");
|
if (!outbound) LogPrint (eLogWarning, "NetDbReq: No outbound tunnels");
|
||||||
if (!nextFloodfill) LogPrint (eLogWarning, "NetDbReq: No more floodfills");
|
if (!nextFloodfill) LogPrint (eLogWarning, "NetDbReq: No more floodfills");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!dest->IsExploratory ())
|
if (!dest->IsExploratory ())
|
||||||
LogPrint (eLogWarning, "NetDbReq: ", dest->GetDestination ().ToBase64 (), " not found after 7 attempts");
|
LogPrint (eLogWarning, "NetDbReq: ", dest->GetDestination ().ToBase64 (), " not found after 7 attempts");
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // delete obsolete request
|
else // delete obsolete request
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ namespace data
|
|||||||
it = m_RequestedDestinations.erase (it);
|
it = m_RequestedDestinations.erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ namespace i2p
|
|||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
class RequestedDestination
|
class RequestedDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::function<void (std::shared_ptr<RouterInfo>)> RequestComplete;
|
typedef std::function<void (std::shared_ptr<RouterInfo>)> RequestComplete;
|
||||||
|
|
||||||
RequestedDestination (const IdentHash& destination, bool isExploratory = false):
|
RequestedDestination (const IdentHash& destination, bool isExploratory = false):
|
||||||
m_Destination (destination), m_IsExploratory (isExploratory), m_CreationTime (0) {};
|
m_Destination (destination), m_IsExploratory (isExploratory), m_CreationTime (0) {};
|
||||||
~RequestedDestination () { if (m_RequestComplete) m_RequestComplete (nullptr); };
|
~RequestedDestination () { if (m_RequestComplete) m_RequestComplete (nullptr); };
|
||||||
|
|
||||||
const IdentHash& GetDestination () const { return m_Destination; };
|
const IdentHash& GetDestination () const { return m_Destination; };
|
||||||
int GetNumExcludedPeers () const { return m_ExcludedPeers.size (); };
|
int GetNumExcludedPeers () const { return m_ExcludedPeers.size (); };
|
||||||
@@ -30,12 +30,12 @@ namespace data
|
|||||||
uint64_t GetCreationTime () const { return m_CreationTime; };
|
uint64_t GetCreationTime () const { return m_CreationTime; };
|
||||||
std::shared_ptr<I2NPMessage> CreateRequestMessage (std::shared_ptr<const RouterInfo>, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel);
|
std::shared_ptr<I2NPMessage> CreateRequestMessage (std::shared_ptr<const RouterInfo>, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel);
|
||||||
std::shared_ptr<I2NPMessage> CreateRequestMessage (const IdentHash& floodfill);
|
std::shared_ptr<I2NPMessage> CreateRequestMessage (const IdentHash& floodfill);
|
||||||
|
|
||||||
void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; };
|
void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; };
|
||||||
bool IsRequestComplete () const { return m_RequestComplete != nullptr; };
|
bool IsRequestComplete () const { return m_RequestComplete != nullptr; };
|
||||||
void Success (std::shared_ptr<RouterInfo> r);
|
void Success (std::shared_ptr<RouterInfo> r);
|
||||||
void Fail ();
|
void Fail ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
IdentHash m_Destination;
|
IdentHash m_Destination;
|
||||||
@@ -43,7 +43,7 @@ namespace data
|
|||||||
std::set<IdentHash> m_ExcludedPeers;
|
std::set<IdentHash> m_ExcludedPeers;
|
||||||
uint64_t m_CreationTime;
|
uint64_t m_CreationTime;
|
||||||
RequestComplete m_RequestComplete;
|
RequestComplete m_RequestComplete;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetDbRequests
|
class NetDbRequests
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,20 +15,20 @@ namespace data
|
|||||||
RouterProfile::RouterProfile ():
|
RouterProfile::RouterProfile ():
|
||||||
m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
|
m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
|
||||||
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
|
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
|
||||||
m_NumTimesTaken (0), m_NumTimesRejected (0)
|
m_NumTimesTaken (0), m_NumTimesRejected (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::posix_time::ptime RouterProfile::GetTime () const
|
boost::posix_time::ptime RouterProfile::GetTime () const
|
||||||
{
|
{
|
||||||
return boost::posix_time::second_clock::local_time();
|
return boost::posix_time::second_clock::local_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterProfile::UpdateTime ()
|
void RouterProfile::UpdateTime ()
|
||||||
{
|
{
|
||||||
m_LastUpdateTime = GetTime ();
|
m_LastUpdateTime = GetTime ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterProfile::Save (const IdentHash& identHash)
|
void RouterProfile::Save (const IdentHash& identHash)
|
||||||
{
|
{
|
||||||
// fill sections
|
// fill sections
|
||||||
@@ -63,57 +63,57 @@ namespace data
|
|||||||
std::string path = m_ProfilesStorage.Path(ident);
|
std::string path = m_ProfilesStorage.Path(ident);
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
|
|
||||||
if (!i2p::fs::Exists(path))
|
if (!i2p::fs::Exists(path))
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "Profiling: no profile yet for ", ident);
|
LogPrint(eLogWarning, "Profiling: no profile yet for ", ident);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boost::property_tree::read_ini (path, pt);
|
boost::property_tree::read_ini (path, pt);
|
||||||
} catch (std::exception& ex)
|
} catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
/* boost exception verbose enough */
|
/* boost exception verbose enough */
|
||||||
LogPrint (eLogError, "Profiling: ", ex.what ());
|
LogPrint (eLogError, "Profiling: ", ex.what ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, "");
|
auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, "");
|
||||||
if (t.length () > 0)
|
if (t.length () > 0)
|
||||||
m_LastUpdateTime = boost::posix_time::time_from_string (t);
|
m_LastUpdateTime = boost::posix_time::time_from_string (t);
|
||||||
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT)
|
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// read participations
|
// read participations
|
||||||
auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION);
|
auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION);
|
||||||
m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0);
|
m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0);
|
||||||
m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0);
|
m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0);
|
||||||
m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0);
|
m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0);
|
||||||
}
|
}
|
||||||
catch (boost::property_tree::ptree_bad_path& ex)
|
catch (boost::property_tree::ptree_bad_path& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Profiling: Missing section ", PEER_PROFILE_SECTION_PARTICIPATION, " in profile for ", ident);
|
LogPrint (eLogWarning, "Profiling: Missing section ", PEER_PROFILE_SECTION_PARTICIPATION, " in profile for ", ident);
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// read usage
|
// read usage
|
||||||
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
|
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
|
||||||
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
|
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
|
||||||
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
|
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
|
||||||
}
|
}
|
||||||
catch (boost::property_tree::ptree_bad_path& ex)
|
catch (boost::property_tree::ptree_bad_path& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE, " in profile for ", ident);
|
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE, " in profile for ", ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*this = RouterProfile ();
|
*this = RouterProfile ();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Profiling: Can't read profile ", ident, " :", ex.what ());
|
LogPrint (eLogError, "Profiling: Can't read profile ", ident, " :", ex.what ());
|
||||||
}
|
}
|
||||||
@@ -126,46 +126,46 @@ namespace data
|
|||||||
m_NumTunnelsDeclined++;
|
m_NumTunnelsDeclined++;
|
||||||
else
|
else
|
||||||
m_NumTunnelsAgreed++;
|
m_NumTunnelsAgreed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterProfile::TunnelNonReplied ()
|
void RouterProfile::TunnelNonReplied ()
|
||||||
{
|
{
|
||||||
m_NumTunnelsNonReplied++;
|
m_NumTunnelsNonReplied++;
|
||||||
UpdateTime ();
|
UpdateTime ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsLowPartcipationRate () const
|
bool RouterProfile::IsLowPartcipationRate () const
|
||||||
{
|
{
|
||||||
return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate
|
return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsLowReplyRate () const
|
bool RouterProfile::IsLowReplyRate () const
|
||||||
{
|
{
|
||||||
auto total = m_NumTunnelsAgreed + m_NumTunnelsDeclined;
|
auto total = m_NumTunnelsAgreed + m_NumTunnelsDeclined;
|
||||||
return m_NumTunnelsNonReplied > 10*(total + 1);
|
return m_NumTunnelsNonReplied > 10*(total + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsBad ()
|
bool RouterProfile::IsBad ()
|
||||||
{
|
{
|
||||||
auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/;
|
auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/;
|
||||||
if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1))
|
if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1))
|
||||||
{
|
{
|
||||||
// reset profile
|
// reset profile
|
||||||
m_NumTunnelsAgreed = 0;
|
m_NumTunnelsAgreed = 0;
|
||||||
m_NumTunnelsDeclined = 0;
|
m_NumTunnelsDeclined = 0;
|
||||||
m_NumTunnelsNonReplied = 0;
|
m_NumTunnelsNonReplied = 0;
|
||||||
isBad = false;
|
isBad = false;
|
||||||
}
|
}
|
||||||
if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++;
|
if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++;
|
||||||
return isBad;
|
return isBad;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
|
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
|
||||||
{
|
{
|
||||||
auto profile = std::make_shared<RouterProfile> ();
|
auto profile = std::make_shared<RouterProfile> ();
|
||||||
profile->Load (identHash); // if possible
|
profile->Load (identHash); // if possible
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitProfilesStorage ()
|
void InitProfilesStorage ()
|
||||||
{
|
{
|
||||||
@@ -191,5 +191,5 @@ namespace data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,32 +8,32 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
// sections
|
// sections
|
||||||
const char PEER_PROFILE_SECTION_PARTICIPATION[] = "participation";
|
const char PEER_PROFILE_SECTION_PARTICIPATION[] = "participation";
|
||||||
const char PEER_PROFILE_SECTION_USAGE[] = "usage";
|
const char PEER_PROFILE_SECTION_USAGE[] = "usage";
|
||||||
// params
|
// params
|
||||||
const char PEER_PROFILE_LAST_UPDATE_TIME[] = "lastupdatetime";
|
const char PEER_PROFILE_LAST_UPDATE_TIME[] = "lastupdatetime";
|
||||||
const char PEER_PROFILE_PARTICIPATION_AGREED[] = "agreed";
|
const char PEER_PROFILE_PARTICIPATION_AGREED[] = "agreed";
|
||||||
const char PEER_PROFILE_PARTICIPATION_DECLINED[] = "declined";
|
const char PEER_PROFILE_PARTICIPATION_DECLINED[] = "declined";
|
||||||
const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied";
|
const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied";
|
||||||
const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
|
const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
|
||||||
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)
|
||||||
|
|
||||||
class RouterProfile
|
class RouterProfile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RouterProfile ();
|
RouterProfile ();
|
||||||
RouterProfile& operator= (const RouterProfile& ) = default;
|
RouterProfile& operator= (const RouterProfile& ) = default;
|
||||||
|
|
||||||
void Save (const IdentHash& identHash);
|
void Save (const IdentHash& identHash);
|
||||||
void Load (const IdentHash& identHash);
|
void Load (const IdentHash& identHash);
|
||||||
|
|
||||||
bool IsBad ();
|
bool IsBad ();
|
||||||
|
|
||||||
void TunnelBuildResponse (uint8_t ret);
|
void TunnelBuildResponse (uint8_t ret);
|
||||||
void TunnelNonReplied ();
|
void TunnelNonReplied ();
|
||||||
|
|
||||||
@@ -45,23 +45,23 @@ namespace data
|
|||||||
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
|
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
|
||||||
bool IsLowPartcipationRate () const;
|
bool IsLowPartcipationRate () const;
|
||||||
bool IsLowReplyRate () const;
|
bool IsLowReplyRate () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::posix_time::ptime m_LastUpdateTime;
|
boost::posix_time::ptime m_LastUpdateTime;
|
||||||
// participation
|
// participation
|
||||||
uint32_t m_NumTunnelsAgreed;
|
uint32_t m_NumTunnelsAgreed;
|
||||||
uint32_t m_NumTunnelsDeclined;
|
uint32_t m_NumTunnelsDeclined;
|
||||||
uint32_t m_NumTunnelsNonReplied;
|
uint32_t m_NumTunnelsNonReplied;
|
||||||
// usage
|
// usage
|
||||||
uint32_t m_NumTimesTaken;
|
uint32_t m_NumTimesTaken;
|
||||||
uint32_t m_NumTimesRejected;
|
uint32_t m_NumTimesRejected;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
||||||
void InitProfilesStorage ();
|
void InitProfilesStorage ();
|
||||||
void DeleteObsoleteProfiles ();
|
void DeleteObsoleteProfiles ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
template<typename Element>
|
template<typename Element>
|
||||||
class Queue
|
class Queue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void Put (Element e)
|
void Put (Element e)
|
||||||
@@ -29,14 +29,14 @@ namespace util
|
|||||||
void Put (const Container<Element, R...>& vec)
|
void Put (const Container<Element, R...>& vec)
|
||||||
{
|
{
|
||||||
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 (it);
|
m_Queue.push (it);
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Element GetNext ()
|
Element GetNext ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
@@ -45,7 +45,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
m_NonEmpty.wait (l);
|
m_NonEmpty.wait (l);
|
||||||
el = GetNonThreadSafe ();
|
el = GetNonThreadSafe ();
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
m_NonEmpty.wait_for (l, std::chrono::milliseconds (usec));
|
m_NonEmpty.wait_for (l, std::chrono::milliseconds (usec));
|
||||||
el = GetNonThreadSafe ();
|
el = GetNonThreadSafe ();
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,17 +73,17 @@ namespace util
|
|||||||
return m_NonEmpty.wait_for (l, std::chrono::seconds (sec) + std::chrono::milliseconds (usec)) != std::cv_status::timeout;
|
return m_NonEmpty.wait_for (l, std::chrono::seconds (sec) + std::chrono::milliseconds (usec)) != std::cv_status::timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEmpty ()
|
bool IsEmpty ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
return m_Queue.empty ();
|
return m_Queue.empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetSize ()
|
int GetSize ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
return m_Queue.size ();
|
return m_Queue.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WakeUp () { m_NonEmpty.notify_all (); };
|
void WakeUp () { m_NonEmpty.notify_all (); };
|
||||||
|
|
||||||
@@ -91,14 +91,14 @@ namespace util
|
|||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
return GetNonThreadSafe ();
|
return GetNonThreadSafe ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Element Peek ()
|
Element Peek ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
return GetNonThreadSafe (true);
|
return GetNonThreadSafe (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Element GetNonThreadSafe (bool peek = false)
|
Element GetNonThreadSafe (bool peek = false)
|
||||||
@@ -109,17 +109,17 @@ namespace util
|
|||||||
if (!peek)
|
if (!peek)
|
||||||
m_Queue.pop ();
|
m_Queue.pop ();
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::queue<Element> m_Queue;
|
std::queue<Element> m_Queue;
|
||||||
std::mutex m_QueueMutex;
|
std::mutex m_QueueMutex;
|
||||||
std::condition_variable m_NonEmpty;
|
std::condition_variable m_NonEmpty;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@@ -23,7 +23,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
|
|
||||||
Reseeder::Reseeder()
|
Reseeder::Reseeder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -114,11 +114,11 @@ namespace data
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Reseeder::ProcessSU3File (const char * filename)
|
int Reseeder::ProcessSU3File (const char * filename)
|
||||||
{
|
{
|
||||||
std::ifstream s(filename, std::ifstream::binary);
|
std::ifstream s(filename, std::ifstream::binary);
|
||||||
if (s.is_open ())
|
if (s.is_open ())
|
||||||
return ProcessSU3Stream (s);
|
return ProcessSU3Stream (s);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,21 +130,21 @@ namespace data
|
|||||||
int Reseeder::ProcessZIPFile (const char * filename)
|
int Reseeder::ProcessZIPFile (const char * filename)
|
||||||
{
|
{
|
||||||
std::ifstream s(filename, std::ifstream::binary);
|
std::ifstream s(filename, std::ifstream::binary);
|
||||||
if (s.is_open ())
|
if (s.is_open ())
|
||||||
{
|
{
|
||||||
s.seekg (0, std::ios::end);
|
s.seekg (0, std::ios::end);
|
||||||
auto len = s.tellg ();
|
auto len = s.tellg ();
|
||||||
s.seekg (0, std::ios::beg);
|
s.seekg (0, std::ios::beg);
|
||||||
return ProcessZIPStream (s, len);
|
return ProcessZIPStream (s, len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Can't open file ", filename);
|
LogPrint (eLogError, "Reseed: Can't open file ", filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SU3_MAGIC_NUMBER[]="I2Psu3";
|
const char SU3_MAGIC_NUMBER[]="I2Psu3";
|
||||||
int Reseeder::ProcessSU3Stream (std::istream& s)
|
int Reseeder::ProcessSU3Stream (std::istream& s)
|
||||||
{
|
{
|
||||||
char magicNumber[7];
|
char magicNumber[7];
|
||||||
@@ -153,7 +153,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: Unexpected SU3 magic number");
|
LogPrint (eLogError, "Reseed: Unexpected SU3 magic number");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -163,16 +163,16 @@ namespace data
|
|||||||
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);
|
||||||
@@ -180,7 +180,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
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);
|
||||||
@@ -192,10 +192,10 @@ namespace data
|
|||||||
char signerID[256];
|
char signerID[256];
|
||||||
s.read (signerID, signerIDLength); // signerID
|
s.read (signerID, signerIDLength); // signerID
|
||||||
signerID[signerIDLength] = 0;
|
signerID[signerIDLength] = 0;
|
||||||
|
|
||||||
bool verify; i2p::config::GetOption("reseed.verify", verify);
|
bool verify; i2p::config::GetOption("reseed.verify", verify);
|
||||||
if (verify)
|
if (verify)
|
||||||
{
|
{
|
||||||
//try to verify signature
|
//try to verify signature
|
||||||
auto it = m_SigningKeys.find (signerID);
|
auto it = m_SigningKeys.find (signerID);
|
||||||
if (it != m_SigningKeys.end ())
|
if (it != m_SigningKeys.end ())
|
||||||
@@ -220,7 +220,7 @@ namespace data
|
|||||||
BIGNUM * s = BN_new (), * n = BN_new ();
|
BIGNUM * s = BN_new (), * n = BN_new ();
|
||||||
BN_bin2bn (signature, signatureLength, s);
|
BN_bin2bn (signature, signatureLength, s);
|
||||||
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
|
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
|
||||||
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
|
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
|
||||||
uint8_t * enSigBuf = new uint8_t[signatureLength];
|
uint8_t * enSigBuf = new uint8_t[signatureLength];
|
||||||
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
|
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
|
||||||
// digest is right aligned
|
// digest is right aligned
|
||||||
@@ -232,8 +232,8 @@ namespace data
|
|||||||
delete[] enSigBuf;
|
delete[] enSigBuf;
|
||||||
BN_free (s); BN_free (n);
|
BN_free (s); BN_free (n);
|
||||||
BN_CTX_free (bnctx);
|
BN_CTX_free (bnctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] signature;
|
delete[] signature;
|
||||||
delete[] tbs;
|
delete[] tbs;
|
||||||
s.seekg (pos, std::ios::beg);
|
s.seekg (pos, std::ios::beg);
|
||||||
@@ -249,21 +249,21 @@ namespace data
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: SU3 verification failed");
|
LogPrint (eLogError, "Reseed: SU3 verification failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle content
|
// handle content
|
||||||
return ProcessZIPStream (s, contentLength);
|
return ProcessZIPStream (s, contentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t ZIP_HEADER_SIGNATURE = 0x04034B50;
|
const uint32_t ZIP_HEADER_SIGNATURE = 0x04034B50;
|
||||||
const uint32_t ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014B50;
|
const uint32_t ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014B50;
|
||||||
const uint16_t ZIP_BIT_FLAG_DATA_DESCRIPTOR = 0x0008;
|
const uint16_t ZIP_BIT_FLAG_DATA_DESCRIPTOR = 0x0008;
|
||||||
int Reseeder::ProcessZIPStream (std::istream& s, uint64_t contentLength)
|
int Reseeder::ProcessZIPStream (std::istream& s, uint64_t contentLength)
|
||||||
{
|
{
|
||||||
int numFiles = 0;
|
int numFiles = 0;
|
||||||
size_t contentPos = s.tellg ();
|
size_t contentPos = s.tellg ();
|
||||||
while (!s.eof ())
|
while (!s.eof ())
|
||||||
{
|
{
|
||||||
uint32_t signature;
|
uint32_t signature;
|
||||||
s.read ((char *)&signature, 4);
|
s.read ((char *)&signature, 4);
|
||||||
signature = le32toh (signature);
|
signature = le32toh (signature);
|
||||||
@@ -272,22 +272,22 @@ namespace data
|
|||||||
// next local file
|
// next local file
|
||||||
s.seekg (2, std::ios::cur); // version
|
s.seekg (2, std::ios::cur); // version
|
||||||
uint16_t bitFlag;
|
uint16_t bitFlag;
|
||||||
s.read ((char *)&bitFlag, 2);
|
s.read ((char *)&bitFlag, 2);
|
||||||
bitFlag = le16toh (bitFlag);
|
bitFlag = le16toh (bitFlag);
|
||||||
uint16_t compressionMethod;
|
uint16_t compressionMethod;
|
||||||
s.read ((char *)&compressionMethod, 2);
|
s.read ((char *)&compressionMethod, 2);
|
||||||
compressionMethod = le16toh (compressionMethod);
|
compressionMethod = le16toh (compressionMethod);
|
||||||
s.seekg (4, std::ios::cur); // skip fields we don't care about
|
s.seekg (4, std::ios::cur); // skip fields we don't care about
|
||||||
uint32_t compressedSize, uncompressedSize;
|
uint32_t compressedSize, uncompressedSize;
|
||||||
uint32_t crc_32;
|
uint32_t crc_32;
|
||||||
s.read ((char *)&crc_32, 4);
|
s.read ((char *)&crc_32, 4);
|
||||||
crc_32 = le32toh (crc_32);
|
crc_32 = le32toh (crc_32);
|
||||||
s.read ((char *)&compressedSize, 4);
|
s.read ((char *)&compressedSize, 4);
|
||||||
compressedSize = le32toh (compressedSize);
|
compressedSize = le32toh (compressedSize);
|
||||||
s.read ((char *)&uncompressedSize, 4);
|
s.read ((char *)&uncompressedSize, 4);
|
||||||
uncompressedSize = le32toh (uncompressedSize);
|
uncompressedSize = le32toh (uncompressedSize);
|
||||||
uint16_t fileNameLength, extraFieldLength;
|
uint16_t fileNameLength, extraFieldLength;
|
||||||
s.read ((char *)&fileNameLength, 2);
|
s.read ((char *)&fileNameLength, 2);
|
||||||
fileNameLength = le16toh (fileNameLength);
|
fileNameLength = le16toh (fileNameLength);
|
||||||
if ( fileNameLength > 255 ) {
|
if ( fileNameLength > 255 ) {
|
||||||
// too big
|
// too big
|
||||||
@@ -308,25 +308,25 @@ namespace data
|
|||||||
{
|
{
|
||||||
LogPrint (eLogError, "Reseed: SU3 archive data descriptor not found");
|
LogPrint (eLogError, "Reseed: SU3 archive data descriptor not found");
|
||||||
return numFiles;
|
return numFiles;
|
||||||
}
|
}
|
||||||
s.read ((char *)&crc_32, 4);
|
s.read ((char *)&crc_32, 4);
|
||||||
crc_32 = le32toh (crc_32);
|
crc_32 = le32toh (crc_32);
|
||||||
s.read ((char *)&compressedSize, 4);
|
s.read ((char *)&compressedSize, 4);
|
||||||
compressedSize = le32toh (compressedSize) + 4; // ??? we must consider signature as part of compressed data
|
compressedSize = le32toh (compressedSize) + 4; // ??? we must consider signature as part of compressed data
|
||||||
s.read ((char *)&uncompressedSize, 4);
|
s.read ((char *)&uncompressedSize, 4);
|
||||||
uncompressedSize = le32toh (uncompressedSize);
|
uncompressedSize = le32toh (uncompressedSize);
|
||||||
|
|
||||||
// now we know compressed and uncompressed size
|
// now we know compressed and uncompressed size
|
||||||
s.seekg (pos, std::ios::beg); // back to compressed data
|
s.seekg (pos, std::ios::beg); // back to compressed data
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint (eLogDebug, "Reseed: Proccessing file ", localFileName, " ", compressedSize, " bytes");
|
LogPrint (eLogDebug, "Reseed: Processing file ", localFileName, " ", compressedSize, " bytes");
|
||||||
if (!compressedSize)
|
if (!compressedSize)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Reseed: Unexpected size 0. Skipped");
|
LogPrint (eLogWarning, "Reseed: Unexpected size 0. Skipped");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t * compressed = new uint8_t[compressedSize];
|
uint8_t * compressed = new uint8_t[compressedSize];
|
||||||
s.read ((char *)compressed, compressedSize);
|
s.read ((char *)compressed, compressedSize);
|
||||||
if (compressionMethod) // we assume Deflate
|
if (compressionMethod) // we assume Deflate
|
||||||
@@ -338,29 +338,29 @@ namespace data
|
|||||||
inflator.next_in = compressed;
|
inflator.next_in = compressed;
|
||||||
inflator.avail_in = compressedSize;
|
inflator.avail_in = compressedSize;
|
||||||
inflator.next_out = uncompressed;
|
inflator.next_out = uncompressed;
|
||||||
inflator.avail_out = uncompressedSize;
|
inflator.avail_out = uncompressedSize;
|
||||||
int err;
|
int err;
|
||||||
if ((err = inflate (&inflator, Z_SYNC_FLUSH)) >= 0)
|
if ((err = inflate (&inflator, Z_SYNC_FLUSH)) >= 0)
|
||||||
{
|
{
|
||||||
uncompressedSize -= inflator.avail_out;
|
uncompressedSize -= inflator.avail_out;
|
||||||
if (crc32 (0, uncompressed, uncompressedSize) == crc_32)
|
if (crc32 (0, uncompressed, uncompressedSize) == crc_32)
|
||||||
{
|
{
|
||||||
i2p::data::netdb.AddRouterInfo (uncompressed, uncompressedSize);
|
i2p::data::netdb.AddRouterInfo (uncompressed, uncompressedSize);
|
||||||
numFiles++;
|
numFiles++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: CRC32 verification failed");
|
LogPrint (eLogError, "Reseed: CRC32 verification failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: SU3 decompression error ", err);
|
LogPrint (eLogError, "Reseed: SU3 decompression error ", err);
|
||||||
delete[] uncompressed;
|
delete[] uncompressed;
|
||||||
inflateEnd (&inflator);
|
inflateEnd (&inflator);
|
||||||
}
|
}
|
||||||
else // no compression
|
else // no compression
|
||||||
{
|
{
|
||||||
i2p::data::netdb.AddRouterInfo (compressed, compressedSize);
|
i2p::data::netdb.AddRouterInfo (compressed, compressedSize);
|
||||||
numFiles++;
|
numFiles++;
|
||||||
}
|
}
|
||||||
delete[] compressed;
|
delete[] compressed;
|
||||||
if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR)
|
if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR)
|
||||||
s.seekg (12, std::ios::cur); // skip data descriptor section if presented (12 = 16 - 4)
|
s.seekg (12, std::ios::cur); // skip data descriptor section if presented (12 = 16 - 4)
|
||||||
@@ -406,15 +406,15 @@ namespace data
|
|||||||
return numFiles;
|
return numFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t ZIP_DATA_DESCRIPTOR_SIGNATURE[] = { 0x50, 0x4B, 0x07, 0x08 };
|
const uint8_t ZIP_DATA_DESCRIPTOR_SIGNATURE[] = { 0x50, 0x4B, 0x07, 0x08 };
|
||||||
bool Reseeder::FindZipDataDescriptor (std::istream& s)
|
bool Reseeder::FindZipDataDescriptor (std::istream& s)
|
||||||
{
|
{
|
||||||
size_t nextInd = 0;
|
size_t nextInd = 0;
|
||||||
while (!s.eof ())
|
while (!s.eof ())
|
||||||
{
|
{
|
||||||
uint8_t nextByte;
|
uint8_t nextByte;
|
||||||
s.read ((char *)&nextByte, 1);
|
s.read ((char *)&nextByte, 1);
|
||||||
if (nextByte == ZIP_DATA_DESCRIPTOR_SIGNATURE[nextInd])
|
if (nextByte == ZIP_DATA_DESCRIPTOR_SIGNATURE[nextInd])
|
||||||
{
|
{
|
||||||
nextInd++;
|
nextInd++;
|
||||||
if (nextInd >= sizeof (ZIP_DATA_DESCRIPTOR_SIGNATURE))
|
if (nextInd >= sizeof (ZIP_DATA_DESCRIPTOR_SIGNATURE))
|
||||||
@@ -429,24 +429,24 @@ namespace data
|
|||||||
void Reseeder::LoadCertificate (const std::string& filename)
|
void Reseeder::LoadCertificate (const std::string& filename)
|
||||||
{
|
{
|
||||||
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
|
||||||
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
SSL * ssl = SSL_new (ctx);
|
SSL * ssl = SSL_new (ctx);
|
||||||
X509 * cert = SSL_get_certificate (ssl);
|
X509 * cert = SSL_get_certificate (ssl);
|
||||||
// verify
|
// verify
|
||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
// extract issuer name
|
// extract issuer name
|
||||||
char name[100];
|
char name[100];
|
||||||
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
||||||
char * cn = strstr (name, "CN=");
|
char * cn = strstr (name, "CN=");
|
||||||
if (cn)
|
if (cn)
|
||||||
{
|
{
|
||||||
cn += 3;
|
cn += 3;
|
||||||
char * terminator = strchr (cn, '/');
|
char * terminator = strchr (cn, '/');
|
||||||
if (terminator) terminator[0] = 0;
|
if (terminator) terminator[0] = 0;
|
||||||
}
|
}
|
||||||
// extract RSA key (we need n only, e = 65537)
|
// extract RSA key (we need n only, e = 65537)
|
||||||
RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert));
|
RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert));
|
||||||
const BIGNUM * n, * e, * d;
|
const BIGNUM * n, * e, * d;
|
||||||
@@ -457,12 +457,12 @@ namespace data
|
|||||||
m_SigningKeys[cn] = value;
|
m_SigningKeys[cn] = value;
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Can't find CN field in ", filename);
|
LogPrint (eLogError, "Reseed: Can't find CN field in ", filename);
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Can't open certificate file ", filename);
|
LogPrint (eLogError, "Reseed: Can't open certificate file ", filename);
|
||||||
SSL_CTX_free (ctx);
|
SSL_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reseeder::LoadCertificates ()
|
void Reseeder::LoadCertificates ()
|
||||||
@@ -483,9 +483,9 @@ namespace data
|
|||||||
}
|
}
|
||||||
LoadCertificate (file);
|
LoadCertificate (file);
|
||||||
numCertificates++;
|
numCertificates++;
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Reseed: ", numCertificates, " certificates loaded");
|
LogPrint (eLogInfo, "Reseed: ", numCertificates, " certificates loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Reseeder::HttpsRequest (const std::string& address)
|
std::string Reseeder::HttpsRequest (const std::string& address)
|
||||||
{
|
{
|
||||||
@@ -522,7 +522,7 @@ namespace data
|
|||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::system::error_code ecode;
|
boost::system::error_code ecode;
|
||||||
|
|
||||||
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
|
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
|
||||||
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
||||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ namespace data
|
|||||||
|
|
||||||
class Reseeder
|
class Reseeder
|
||||||
{
|
{
|
||||||
typedef Tag<512> PublicKey;
|
typedef Tag<512> PublicKey;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Reseeder();
|
Reseeder();
|
||||||
~Reseeder();
|
~Reseeder();
|
||||||
void Bootstrap ();
|
void Bootstrap ();
|
||||||
@@ -28,19 +28,19 @@ namespace data
|
|||||||
int ProcessZIPFile (const char * filename);
|
int ProcessZIPFile (const char * filename);
|
||||||
|
|
||||||
void LoadCertificates ();
|
void LoadCertificates ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void LoadCertificate (const std::string& filename);
|
void LoadCertificate (const std::string& filename);
|
||||||
|
|
||||||
int ProcessSU3Stream (std::istream& s);
|
int ProcessSU3Stream (std::istream& s);
|
||||||
int ProcessZIPStream (std::istream& s, uint64_t contentLength);
|
int ProcessZIPStream (std::istream& s, uint64_t contentLength);
|
||||||
|
|
||||||
bool FindZipDataDescriptor (std::istream& s);
|
bool FindZipDataDescriptor (std::istream& s);
|
||||||
|
|
||||||
std::string HttpsRequest (const std::string& address);
|
std::string HttpsRequest (const std::string& address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string, PublicKey> m_SigningKeys;
|
std::map<std::string, PublicKey> m_SigningKeys;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace i2p
|
|||||||
m_StartupTime = i2p::util::GetSecondsSinceEpoch ();
|
m_StartupTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (!Load ())
|
if (!Load ())
|
||||||
CreateNewRouter ();
|
CreateNewRouter ();
|
||||||
m_Decryptor = m_Keys.CreateDecryptor (nullptr);
|
m_Decryptor = m_Keys.CreateDecryptor (nullptr);
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::SetBandwidth (char L)
|
void RouterContext::SetBandwidth (char L)
|
||||||
{
|
{
|
||||||
uint32_t limit = 0;
|
uint32_t limit = 0;
|
||||||
enum { low, high, extra, unlim } type = high;
|
enum { low, high, extra, unlim } type = high;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
const char ROUTER_INFO[] = "router.info";
|
const char ROUTER_INFO[] = "router.info";
|
||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
||||||
|
|
||||||
enum RouterStatus
|
enum RouterStatus
|
||||||
@@ -21,16 +21,16 @@ namespace i2p
|
|||||||
eRouterStatusOK = 0,
|
eRouterStatusOK = 0,
|
||||||
eRouterStatusTesting = 1,
|
eRouterStatusTesting = 1,
|
||||||
eRouterStatusFirewalled = 2,
|
eRouterStatusFirewalled = 2,
|
||||||
eRouterStatusError = 3
|
eRouterStatusError = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RouterError
|
enum RouterError
|
||||||
{
|
{
|
||||||
eRouterErrorNone = 0,
|
eRouterErrorNone = 0,
|
||||||
eRouterErrorClockSkew = 1
|
eRouterErrorClockSkew = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
class RouterContext: public i2p::garlic::GarlicDestination
|
class RouterContext: public i2p::garlic::GarlicDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -39,17 +39,17 @@ namespace i2p
|
|||||||
|
|
||||||
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
||||||
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> GetSharedRouterInfo () const
|
std::shared_ptr<const i2p::data::RouterInfo> GetSharedRouterInfo () const
|
||||||
{
|
{
|
||||||
return std::shared_ptr<const i2p::data::RouterInfo> (&m_RouterInfo,
|
return std::shared_ptr<const i2p::data::RouterInfo> (&m_RouterInfo,
|
||||||
[](const i2p::data::RouterInfo *) {});
|
[](const i2p::data::RouterInfo *) {});
|
||||||
}
|
}
|
||||||
std::shared_ptr<i2p::garlic::GarlicDestination> GetSharedDestination ()
|
std::shared_ptr<i2p::garlic::GarlicDestination> GetSharedDestination ()
|
||||||
{
|
{
|
||||||
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
||||||
[](i2p::garlic::GarlicDestination *) {});
|
[](i2p::garlic::GarlicDestination *) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetUptime () const;
|
uint32_t GetUptime () const;
|
||||||
uint32_t GetStartupTime () const { return m_StartupTime; };
|
uint32_t GetStartupTime () const { return m_StartupTime; };
|
||||||
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
||||||
@@ -60,17 +60,17 @@ namespace i2p
|
|||||||
RouterError GetError () const { return m_Error; };
|
RouterError GetError () const { return m_Error; };
|
||||||
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
||||||
int GetNetID () const { return m_NetID; };
|
int GetNetID () const { return m_NetID; };
|
||||||
void SetNetID (int netID) { m_NetID = netID; };
|
void SetNetID (int netID) { m_NetID = netID; };
|
||||||
|
|
||||||
void UpdatePort (int port); // called from Daemon
|
void UpdatePort (int port); // called from Daemon
|
||||||
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
||||||
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
|
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
|
||||||
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||||
bool IsUnreachable () const;
|
bool IsUnreachable () const;
|
||||||
void SetUnreachable ();
|
void SetUnreachable ();
|
||||||
void SetReachable ();
|
void SetReachable ();
|
||||||
bool IsFloodfill () const { return m_IsFloodfill; };
|
bool IsFloodfill () const { return m_IsFloodfill; };
|
||||||
void SetFloodfill (bool floodfill);
|
void SetFloodfill (bool floodfill);
|
||||||
void SetFamily (const std::string& family);
|
void SetFamily (const std::string& family);
|
||||||
std::string GetFamily () const;
|
std::string GetFamily () const;
|
||||||
void SetBandwidth (int limit); /* in kilobytes */
|
void SetBandwidth (int limit); /* in kilobytes */
|
||||||
@@ -83,14 +83,14 @@ namespace i2p
|
|||||||
void SetSupportsV6 (bool supportsV6);
|
void SetSupportsV6 (bool supportsV6);
|
||||||
void SetSupportsV4 (bool supportsV4);
|
void SetSupportsV4 (bool supportsV4);
|
||||||
|
|
||||||
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
|
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
|
||||||
void UpdateStats ();
|
void UpdateStats ();
|
||||||
void CleanupDestination (); // garlic destination
|
void CleanupDestination (); // garlic destination
|
||||||
|
|
||||||
// implements LocalDestination
|
// implements LocalDestination
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
|
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const;
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const;
|
||||||
void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); };
|
void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); };
|
||||||
void SetLeaseSetUpdated () {};
|
void SetLeaseSetUpdated () {};
|
||||||
|
|
||||||
// implements GarlicDestination
|
// implements GarlicDestination
|
||||||
@@ -100,8 +100,8 @@ namespace i2p
|
|||||||
|
|
||||||
// override GarlicDestination
|
// override GarlicDestination
|
||||||
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void CreateNewRouter ();
|
void CreateNewRouter ();
|
||||||
@@ -109,11 +109,11 @@ namespace i2p
|
|||||||
void UpdateRouterInfo ();
|
void UpdateRouterInfo ();
|
||||||
bool Load ();
|
bool Load ();
|
||||||
void SaveKeys ();
|
void SaveKeys ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
i2p::data::RouterInfo m_RouterInfo;
|
i2p::data::RouterInfo m_RouterInfo;
|
||||||
i2p::data::PrivateKeys m_Keys;
|
i2p::data::PrivateKeys m_Keys;
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
||||||
uint64_t m_LastUpdateTime;
|
uint64_t m_LastUpdateTime;
|
||||||
bool m_AcceptsTunnels, m_IsFloodfill;
|
bool m_AcceptsTunnels, m_IsFloodfill;
|
||||||
@@ -127,6 +127,6 @@ namespace i2p
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,20 +19,20 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
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_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false),
|
m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false),
|
||||||
m_SupportedTransports (0), m_Caps (0)
|
m_SupportedTransports (0), m_Caps (0)
|
||||||
{
|
{
|
||||||
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
m_Addresses = boost::make_shared<Addresses>(); // create empty list
|
||||||
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
||||||
ReadFromFile ();
|
ReadFromFile ();
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (const uint8_t * buf, int len):
|
RouterInfo::RouterInfo (const uint8_t * buf, int len):
|
||||||
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
|
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
|
||||||
@@ -42,13 +42,13 @@ namespace data
|
|||||||
memcpy (m_Buffer, buf, len);
|
memcpy (m_Buffer, buf, len);
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
ReadFromBuffer (true);
|
ReadFromBuffer (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::~RouterInfo ()
|
RouterInfo::~RouterInfo ()
|
||||||
{
|
{
|
||||||
delete[] m_Buffer;
|
delete[] m_Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::Update (const uint8_t * buf, int len)
|
void RouterInfo::Update (const uint8_t * buf, int len)
|
||||||
{
|
{
|
||||||
// verify signature since we have indentity already
|
// verify signature since we have indentity already
|
||||||
@@ -63,35 +63,35 @@ namespace data
|
|||||||
// don't clean up m_Addresses, it will be replaced in ReadFromStream
|
// don't clean up m_Addresses, it will be replaced in ReadFromStream
|
||||||
m_Properties.clear ();
|
m_Properties.clear ();
|
||||||
// copy buffer
|
// copy buffer
|
||||||
if (!m_Buffer)
|
if (!m_Buffer)
|
||||||
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
||||||
memcpy (m_Buffer, buf, len);
|
memcpy (m_Buffer, buf, len);
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
// skip identity
|
// skip identity
|
||||||
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
size_t identityLen = m_RouterIdentity->GetFullLen ();
|
||||||
// read new RI
|
// read new RI
|
||||||
std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
|
std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
|
||||||
ReadFromStream (str);
|
ReadFromStream (str);
|
||||||
// don't delete buffer until saved to the file
|
// don't delete buffer until saved to the file
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "RouterInfo: signature verification failed");
|
LogPrint (eLogError, "RouterInfo: signature verification failed");
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
|
void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
|
||||||
{
|
{
|
||||||
m_RouterIdentity = identity;
|
m_RouterIdentity = identity;
|
||||||
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::LoadFile ()
|
bool RouterInfo::LoadFile ()
|
||||||
{
|
{
|
||||||
std::ifstream s(m_FullPath, std::ifstream::binary);
|
std::ifstream s(m_FullPath, std::ifstream::binary);
|
||||||
if (s.is_open ())
|
if (s.is_open ())
|
||||||
{
|
{
|
||||||
s.seekg (0,std::ios::end);
|
s.seekg (0,std::ios::end);
|
||||||
m_BufferLen = s.tellg ();
|
m_BufferLen = s.tellg ();
|
||||||
if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE)
|
if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE)
|
||||||
@@ -103,22 +103,22 @@ namespace data
|
|||||||
if (!m_Buffer)
|
if (!m_Buffer)
|
||||||
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
|
||||||
s.read((char *)m_Buffer, m_BufferLen);
|
s.read((char *)m_Buffer, m_BufferLen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath);
|
LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::ReadFromFile ()
|
void RouterInfo::ReadFromFile ()
|
||||||
{
|
{
|
||||||
if (LoadFile ())
|
if (LoadFile ())
|
||||||
ReadFromBuffer (false);
|
ReadFromBuffer (false);
|
||||||
else
|
else
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::ReadFromBuffer (bool verifySignature)
|
void RouterInfo::ReadFromBuffer (bool verifySignature)
|
||||||
{
|
{
|
||||||
@@ -131,7 +131,7 @@ namespace data
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (verifySignature)
|
if (verifySignature)
|
||||||
{
|
{
|
||||||
// reject RSA signatures
|
// reject RSA signatures
|
||||||
if (m_RouterIdentity->IsRSA ())
|
if (m_RouterIdentity->IsRSA ())
|
||||||
{
|
{
|
||||||
@@ -140,15 +140,15 @@ namespace data
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// verify signature
|
// verify signature
|
||||||
int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();
|
int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();
|
||||||
if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
|
if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "RouterInfo: signature verification failed");
|
LogPrint (eLogError, "RouterInfo: signature verification failed");
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_RouterIdentity->DropVerifier ();
|
m_RouterIdentity->DropVerifier ();
|
||||||
}
|
}
|
||||||
// parse RI
|
// parse RI
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str.write ((const char *)m_Buffer + identityLen, m_BufferLen - identityLen);
|
str.write ((const char *)m_Buffer + identityLen, m_BufferLen - identityLen);
|
||||||
@@ -158,17 +158,17 @@ namespace data
|
|||||||
LogPrint (eLogError, "RouterInfo: malformed message");
|
LogPrint (eLogError, "RouterInfo: malformed message");
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::ReadFromStream (std::istream& s)
|
void RouterInfo::ReadFromStream (std::istream& s)
|
||||||
{
|
{
|
||||||
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
|
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
|
||||||
m_Timestamp = be64toh (m_Timestamp);
|
m_Timestamp = be64toh (m_Timestamp);
|
||||||
// read addresses
|
// read addresses
|
||||||
auto addresses = boost::make_shared<Addresses>();
|
auto addresses = boost::make_shared<Addresses>();
|
||||||
uint8_t numAddresses;
|
uint8_t numAddresses;
|
||||||
s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return;
|
s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return;
|
||||||
bool introducers = false;
|
bool introducers = false;
|
||||||
for (int i = 0; i < numAddresses; i++)
|
for (int i = 0; i < numAddresses; i++)
|
||||||
{
|
{
|
||||||
@@ -181,11 +181,11 @@ namespace data
|
|||||||
if (!strcmp (transportStyle, "NTCP"))
|
if (!strcmp (transportStyle, "NTCP"))
|
||||||
address->transportStyle = eTransportNTCP;
|
address->transportStyle = eTransportNTCP;
|
||||||
else if (!strcmp (transportStyle, "SSU"))
|
else if (!strcmp (transportStyle, "SSU"))
|
||||||
{
|
{
|
||||||
address->transportStyle = eTransportSSU;
|
address->transportStyle = eTransportSSU;
|
||||||
address->ssu.reset (new SSUExt ());
|
address->ssu.reset (new SSUExt ());
|
||||||
address->ssu->mtu = 0;
|
address->ssu->mtu = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
address->transportStyle = eTransportUnknown;
|
address->transportStyle = eTransportUnknown;
|
||||||
address->port = 0;
|
address->port = 0;
|
||||||
@@ -197,35 +197,35 @@ namespace data
|
|||||||
char key[255], value[255];
|
char key[255], value[255];
|
||||||
r += ReadString (key, 255, s);
|
r += ReadString (key, 255, s);
|
||||||
s.seekg (1, std::ios_base::cur); r++; // =
|
s.seekg (1, std::ios_base::cur); r++; // =
|
||||||
r += ReadString (value, 255, s);
|
r += ReadString (value, 255, s);
|
||||||
s.seekg (1, std::ios_base::cur); r++; // ;
|
s.seekg (1, std::ios_base::cur); r++; // ;
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
if (!strcmp (key, "host"))
|
if (!strcmp (key, "host"))
|
||||||
{
|
{
|
||||||
boost::system::error_code ecode;
|
boost::system::error_code ecode;
|
||||||
address->host = boost::asio::ip::address::from_string (value, ecode);
|
address->host = boost::asio::ip::address::from_string (value, ecode);
|
||||||
if (ecode)
|
if (ecode)
|
||||||
{
|
{
|
||||||
if (address->transportStyle == eTransportNTCP)
|
if (address->transportStyle == eTransportNTCP)
|
||||||
{
|
{
|
||||||
supportedTransports |= eNTCPV4; // TODO:
|
supportedTransports |= eNTCPV4; // TODO:
|
||||||
address->addressString = value;
|
address->addressString = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
supportedTransports |= eSSUV4; // TODO:
|
supportedTransports |= eSSUV4; // TODO:
|
||||||
address->addressString = value;
|
address->addressString = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// add supported protocol
|
// add supported protocol
|
||||||
if (address->host.is_v4 ())
|
if (address->host.is_v4 ())
|
||||||
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4;
|
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4;
|
||||||
else
|
else
|
||||||
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6;
|
supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "port"))
|
else if (!strcmp (key, "port"))
|
||||||
address->port = boost::lexical_cast<int>(value);
|
address->port = boost::lexical_cast<int>(value);
|
||||||
else if (!strcmp (key, "mtu"))
|
else if (!strcmp (key, "mtu"))
|
||||||
@@ -234,21 +234,21 @@ namespace data
|
|||||||
address->ssu->mtu = boost::lexical_cast<int>(value);
|
address->ssu->mtu = boost::lexical_cast<int>(value);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "RouterInfo: Unexpected field 'mtu' for NTCP");
|
LogPrint (eLogWarning, "RouterInfo: Unexpected field 'mtu' for NTCP");
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "key"))
|
else if (!strcmp (key, "key"))
|
||||||
{
|
{
|
||||||
if (address->ssu)
|
if (address->ssu)
|
||||||
Base64ToByteStream (value, strlen (value), address->ssu->key, 32);
|
Base64ToByteStream (value, strlen (value), address->ssu->key, 32);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP");
|
LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP");
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "caps"))
|
else if (!strcmp (key, "caps"))
|
||||||
ExtractCaps (value);
|
ExtractCaps (value);
|
||||||
else if (key[0] == 'i')
|
else if (key[0] == 'i')
|
||||||
{
|
{
|
||||||
// introducers
|
// introducers
|
||||||
introducers = true;
|
introducers = true;
|
||||||
size_t l = strlen(key);
|
size_t l = strlen(key);
|
||||||
unsigned char index = key[l-1] - '0'; // TODO:
|
unsigned char index = key[l-1] - '0'; // TODO:
|
||||||
key[l-1] = 0;
|
key[l-1] = 0;
|
||||||
if (index > 9)
|
if (index > 9)
|
||||||
@@ -257,13 +257,13 @@ namespace data
|
|||||||
if (s) continue; else return;
|
if (s) continue; else return;
|
||||||
}
|
}
|
||||||
if (index >= address->ssu->introducers.size ())
|
if (index >= address->ssu->introducers.size ())
|
||||||
address->ssu->introducers.resize (index + 1);
|
address->ssu->introducers.resize (index + 1);
|
||||||
Introducer& introducer = address->ssu->introducers.at (index);
|
Introducer& introducer = address->ssu->introducers.at (index);
|
||||||
if (!strcmp (key, "ihost"))
|
if (!strcmp (key, "ihost"))
|
||||||
{
|
{
|
||||||
boost::system::error_code ecode;
|
boost::system::error_code ecode;
|
||||||
introducer.iHost = boost::asio::ip::address::from_string (value, ecode);
|
introducer.iHost = boost::asio::ip::address::from_string (value, ecode);
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "iport"))
|
else if (!strcmp (key, "iport"))
|
||||||
introducer.iPort = boost::lexical_cast<int>(value);
|
introducer.iPort = boost::lexical_cast<int>(value);
|
||||||
else if (!strcmp (key, "itag"))
|
else if (!strcmp (key, "itag"))
|
||||||
@@ -274,19 +274,19 @@ namespace data
|
|||||||
introducer.iExp = boost::lexical_cast<uint32_t>(value);
|
introducer.iExp = boost::lexical_cast<uint32_t>(value);
|
||||||
}
|
}
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
}
|
}
|
||||||
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
|
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
|
||||||
if (supportedTransports)
|
if (supportedTransports)
|
||||||
{
|
{
|
||||||
addresses->push_back(address);
|
addresses->push_back(address);
|
||||||
m_SupportedTransports |= supportedTransports;
|
m_SupportedTransports |= supportedTransports;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if (BOOST_VERSION >= 105300)
|
#if (BOOST_VERSION >= 105300)
|
||||||
boost::atomic_store (&m_Addresses, addresses);
|
boost::atomic_store (&m_Addresses, addresses);
|
||||||
#else
|
#else
|
||||||
m_Addresses = addresses; // race condition
|
m_Addresses = addresses; // race condition
|
||||||
#endif
|
#endif
|
||||||
// read peers
|
// read peers
|
||||||
uint8_t numPeers;
|
uint8_t numPeers;
|
||||||
s.read ((char *)&numPeers, sizeof (numPeers)); if (!s) return;
|
s.read ((char *)&numPeers, sizeof (numPeers)); if (!s) return;
|
||||||
@@ -297,23 +297,23 @@ namespace data
|
|||||||
size = be16toh (size);
|
size = be16toh (size);
|
||||||
while (r < size)
|
while (r < size)
|
||||||
{
|
{
|
||||||
char key[255], value[255];
|
char key[255], value[255];
|
||||||
r += ReadString (key, 255, s);
|
r += ReadString (key, 255, s);
|
||||||
s.seekg (1, std::ios_base::cur); r++; // =
|
s.seekg (1, std::ios_base::cur); r++; // =
|
||||||
r += ReadString (value, 255, s);
|
r += ReadString (value, 255, s);
|
||||||
s.seekg (1, std::ios_base::cur); r++; // ;
|
s.seekg (1, std::ios_base::cur); r++; // ;
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
m_Properties[key] = value;
|
m_Properties[key] = value;
|
||||||
|
|
||||||
// extract caps
|
// extract caps
|
||||||
if (!strcmp (key, "caps"))
|
if (!strcmp (key, "caps"))
|
||||||
ExtractCaps (value);
|
ExtractCaps (value);
|
||||||
// check netId
|
// check netId
|
||||||
else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ())
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && 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))
|
||||||
{
|
{
|
||||||
@@ -327,10 +327,10 @@ namespace data
|
|||||||
LogPrint (eLogWarning, "RouterInfo: family signature verification failed");
|
LogPrint (eLogWarning, "RouterInfo: family signature verification failed");
|
||||||
m_Family.clear ();
|
m_Family.clear ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_SupportedTransports || !m_Addresses->size() || (UsesIntroducer () && !introducers))
|
if (!m_SupportedTransports || !m_Addresses->size() || (UsesIntroducer () && !introducers))
|
||||||
SetUnreachable (true);
|
SetUnreachable (true);
|
||||||
@@ -358,56 +358,56 @@ namespace data
|
|||||||
case CAPS_FLAG_EXTRA_BANDWIDTH1:
|
case CAPS_FLAG_EXTRA_BANDWIDTH1:
|
||||||
case CAPS_FLAG_EXTRA_BANDWIDTH2:
|
case CAPS_FLAG_EXTRA_BANDWIDTH2:
|
||||||
m_Caps |= Caps::eExtraBandwidth;
|
m_Caps |= Caps::eExtraBandwidth;
|
||||||
break;
|
break;
|
||||||
case CAPS_FLAG_HIDDEN:
|
case CAPS_FLAG_HIDDEN:
|
||||||
m_Caps |= Caps::eHidden;
|
m_Caps |= Caps::eHidden;
|
||||||
break;
|
break;
|
||||||
case CAPS_FLAG_REACHABLE:
|
case CAPS_FLAG_REACHABLE:
|
||||||
m_Caps |= Caps::eReachable;
|
m_Caps |= Caps::eReachable;
|
||||||
break;
|
break;
|
||||||
case CAPS_FLAG_UNREACHABLE:
|
case CAPS_FLAG_UNREACHABLE:
|
||||||
m_Caps |= Caps::eUnreachable;
|
m_Caps |= Caps::eUnreachable;
|
||||||
break;
|
break;
|
||||||
case CAPS_FLAG_SSU_TESTING:
|
case CAPS_FLAG_SSU_TESTING:
|
||||||
m_Caps |= Caps::eSSUTesting;
|
m_Caps |= Caps::eSSUTesting;
|
||||||
break;
|
break;
|
||||||
case CAPS_FLAG_SSU_INTRODUCER:
|
case CAPS_FLAG_SSU_INTRODUCER:
|
||||||
m_Caps |= Caps::eSSUIntroducer;
|
m_Caps |= Caps::eSSUIntroducer;
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
cap++;
|
cap++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::UpdateCapsProperty ()
|
void RouterInfo::UpdateCapsProperty ()
|
||||||
{
|
{
|
||||||
std::string caps;
|
std::string caps;
|
||||||
if (m_Caps & eFloodfill)
|
if (m_Caps & eFloodfill)
|
||||||
{
|
{
|
||||||
if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ?
|
if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ?
|
||||||
CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X'
|
CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X'
|
||||||
CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P'
|
CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P'
|
||||||
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
|
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
|
||||||
caps += CAPS_FLAG_FLOODFILL; // floodfill
|
caps += CAPS_FLAG_FLOODFILL; // floodfill
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Caps & eExtraBandwidth)
|
if (m_Caps & eExtraBandwidth)
|
||||||
{
|
{
|
||||||
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */
|
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */
|
||||||
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
|
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth
|
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth
|
||||||
}
|
}
|
||||||
if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden
|
if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden
|
||||||
if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable
|
if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable
|
||||||
if (m_Caps & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable
|
if (m_Caps & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable
|
||||||
|
|
||||||
SetProperty ("caps", caps);
|
SetProperty ("caps", caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::WriteToStream (std::ostream& s) const
|
void RouterInfo::WriteToStream (std::ostream& s) const
|
||||||
{
|
{
|
||||||
uint64_t ts = htobe64 (m_Timestamp);
|
uint64_t ts = htobe64 (m_Timestamp);
|
||||||
@@ -425,7 +425,7 @@ namespace data
|
|||||||
if (address.transportStyle == eTransportNTCP)
|
if (address.transportStyle == eTransportNTCP)
|
||||||
WriteString ("NTCP", s);
|
WriteString ("NTCP", s);
|
||||||
else if (address.transportStyle == eTransportSSU)
|
else if (address.transportStyle == eTransportSSU)
|
||||||
{
|
{
|
||||||
WriteString ("SSU", s);
|
WriteString ("SSU", s);
|
||||||
// caps
|
// caps
|
||||||
WriteString ("caps", properties);
|
WriteString ("caps", properties);
|
||||||
@@ -435,7 +435,7 @@ namespace data
|
|||||||
if (IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
if (IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||||
WriteString (caps, properties);
|
WriteString (caps, properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WriteString ("", s);
|
WriteString ("", s);
|
||||||
|
|
||||||
@@ -447,7 +447,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
// write introducers if any
|
// write introducers if any
|
||||||
if (address.ssu->introducers.size () > 0)
|
if (address.ssu->introducers.size () > 0)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -456,7 +456,7 @@ namespace data
|
|||||||
WriteString (introducer.iHost.to_string (), properties);
|
WriteString (introducer.iHost.to_string (), properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -468,7 +468,7 @@ namespace data
|
|||||||
WriteString (value, properties);
|
WriteString (value, properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -477,7 +477,7 @@ namespace data
|
|||||||
WriteString (boost::lexical_cast<std::string>(introducer.iPort), properties);
|
WriteString (boost::lexical_cast<std::string>(introducer.iPort), properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -486,7 +486,7 @@ namespace data
|
|||||||
WriteString (boost::lexical_cast<std::string>(introducer.iTag), properties);
|
WriteString (boost::lexical_cast<std::string>(introducer.iTag), properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& introducer: address.ssu->introducers)
|
for (const auto& introducer: address.ssu->introducers)
|
||||||
{
|
{
|
||||||
@@ -498,8 +498,8 @@ namespace data
|
|||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write intro key
|
// write intro key
|
||||||
WriteString ("key", properties);
|
WriteString ("key", properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
@@ -515,17 +515,17 @@ namespace data
|
|||||||
properties << '=';
|
properties << '=';
|
||||||
WriteString (boost::lexical_cast<std::string>(address.ssu->mtu), properties);
|
WriteString (boost::lexical_cast<std::string>(address.ssu->mtu), properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteString ("port", properties);
|
WriteString ("port", properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
WriteString (boost::lexical_cast<std::string>(address.port), properties);
|
WriteString (boost::lexical_cast<std::string>(address.port), properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
|
|
||||||
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 ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// peers
|
// peers
|
||||||
uint8_t numPeers = 0;
|
uint8_t numPeers = 0;
|
||||||
@@ -539,18 +539,18 @@ namespace data
|
|||||||
properties << '=';
|
properties << '=';
|
||||||
WriteString (p.second, properties);
|
WriteString (p.second, properties);
|
||||||
properties << ';';
|
properties << ';';
|
||||||
}
|
}
|
||||||
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 ());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsNewer (const uint8_t * buf, size_t len) const
|
bool RouterInfo::IsNewer (const uint8_t * buf, size_t len) const
|
||||||
{
|
{
|
||||||
if (!m_RouterIdentity) return false;
|
if (!m_RouterIdentity) return false;
|
||||||
size_t size = m_RouterIdentity->GetFullLen ();
|
size_t size = m_RouterIdentity->GetFullLen ();
|
||||||
if (size + 8 > len) return false;
|
if (size + 8 > len) return false;
|
||||||
return bufbe64toh (buf + size) > m_Timestamp;
|
return bufbe64toh (buf + size) > m_Timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * RouterInfo::LoadBuffer ()
|
const uint8_t * RouterInfo::LoadBuffer ()
|
||||||
@@ -559,8 +559,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (LoadFile ())
|
if (LoadFile ())
|
||||||
LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file");
|
LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file");
|
||||||
}
|
}
|
||||||
return m_Buffer;
|
return m_Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
void RouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
||||||
@@ -569,7 +569,7 @@ namespace data
|
|||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
uint8_t ident[1024];
|
uint8_t ident[1024];
|
||||||
auto identLen = privateKeys.GetPublic ()->ToBuffer (ident, 1024);
|
auto identLen = privateKeys.GetPublic ()->ToBuffer (ident, 1024);
|
||||||
s.write ((char *)ident, identLen);
|
s.write ((char *)ident, identLen);
|
||||||
WriteToStream (s);
|
WriteToStream (s);
|
||||||
m_BufferLen = s.str ().size ();
|
m_BufferLen = s.str ().size ();
|
||||||
if (!m_Buffer)
|
if (!m_Buffer)
|
||||||
@@ -578,7 +578,7 @@ namespace data
|
|||||||
// signature
|
// signature
|
||||||
privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen);
|
privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen);
|
||||||
m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen ();
|
m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::SaveToFile (const std::string& fullPath)
|
bool RouterInfo::SaveToFile (const std::string& fullPath)
|
||||||
{
|
{
|
||||||
@@ -595,13 +595,13 @@ namespace data
|
|||||||
f.write ((char *)m_Buffer, m_BufferLen);
|
f.write ((char *)m_Buffer, m_BufferLen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RouterInfo::ReadString (char * str, size_t len, std::istream& s) const
|
size_t RouterInfo::ReadString (char * str, size_t len, std::istream& s) const
|
||||||
{
|
{
|
||||||
uint8_t l;
|
uint8_t l;
|
||||||
s.read ((char *)&l, 1);
|
s.read ((char *)&l, 1);
|
||||||
if (l < len)
|
if (l < len)
|
||||||
{
|
{
|
||||||
s.read (str, l);
|
s.read (str, l);
|
||||||
if (!s) l = 0; // failed, return empty string
|
if (!s) l = 0; // failed, return empty string
|
||||||
str[l] = 0;
|
str[l] = 0;
|
||||||
@@ -611,16 +611,16 @@ namespace data
|
|||||||
LogPrint (eLogWarning, "RouterInfo: string length ", (int)l, " exceeds buffer size ", len);
|
LogPrint (eLogWarning, "RouterInfo: string length ", (int)l, " exceeds buffer size ", len);
|
||||||
s.seekg (l, std::ios::cur); // skip
|
s.seekg (l, std::ios::cur); // skip
|
||||||
str[0] = 0;
|
str[0] = 0;
|
||||||
}
|
}
|
||||||
return l+1;
|
return l+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::WriteString (const std::string& str, std::ostream& s) const
|
void RouterInfo::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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::AddNTCPAddress (const char * host, int port)
|
void RouterInfo::AddNTCPAddress (const char * host, int port)
|
||||||
{
|
{
|
||||||
@@ -634,7 +634,7 @@ namespace data
|
|||||||
if (*it == *addr) return;
|
if (*it == *addr) return;
|
||||||
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
|
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
|
||||||
m_Addresses->push_back(std::move(addr));
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
|
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
|
||||||
{
|
{
|
||||||
@@ -645,7 +645,7 @@ namespace data
|
|||||||
addr->cost = 10; // NTCP should have priority over SSU
|
addr->cost = 10; // NTCP should have priority over SSU
|
||||||
addr->date = 0;
|
addr->date = 0;
|
||||||
addr->ssu.reset (new SSUExt ());
|
addr->ssu.reset (new SSUExt ());
|
||||||
addr->ssu->mtu = mtu;
|
addr->ssu->mtu = mtu;
|
||||||
memcpy (addr->ssu->key, key, 32);
|
memcpy (addr->ssu->key, key, 32);
|
||||||
for (const auto& it: *m_Addresses) // don't insert same address twice
|
for (const auto& it: *m_Addresses) // don't insert same address twice
|
||||||
if (*it == *addr) return;
|
if (*it == *addr) return;
|
||||||
@@ -654,37 +654,37 @@ namespace data
|
|||||||
|
|
||||||
m_Caps |= eSSUTesting;
|
m_Caps |= eSSUTesting;
|
||||||
m_Caps |= eSSUIntroducer;
|
m_Caps |= eSSUIntroducer;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 && addr->host.is_v4 ())
|
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
||||||
{
|
{
|
||||||
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
|
||||||
addr->ssu->introducers.push_back (introducer);
|
addr->ssu->introducers.push_back (introducer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
|
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
|
||||||
{
|
{
|
||||||
for (auto& addr: *m_Addresses)
|
for (auto& addr: *m_Addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
addr->ssu->introducers.erase (it);
|
addr->ssu->introducers.erase (it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,39 +693,39 @@ namespace data
|
|||||||
m_Caps = caps;
|
m_Caps = caps;
|
||||||
UpdateCapsProperty ();
|
UpdateCapsProperty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::SetCaps (const char * caps)
|
void RouterInfo::SetCaps (const char * caps)
|
||||||
{
|
{
|
||||||
SetProperty ("caps", caps);
|
SetProperty ("caps", caps);
|
||||||
m_Caps = 0;
|
m_Caps = 0;
|
||||||
ExtractCaps (caps);
|
ExtractCaps (caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::SetProperty (const std::string& key, const std::string& value)
|
void RouterInfo::SetProperty (const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
m_Properties[key] = value;
|
m_Properties[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::DeleteProperty (const std::string& key)
|
void RouterInfo::DeleteProperty (const std::string& key)
|
||||||
{
|
{
|
||||||
m_Properties.erase (key);
|
m_Properties.erase (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RouterInfo::GetProperty (const std::string& key) const
|
std::string RouterInfo::GetProperty (const std::string& key) const
|
||||||
{
|
{
|
||||||
auto it = m_Properties.find (key);
|
auto it = m_Properties.find (key);
|
||||||
if (it != m_Properties.end ())
|
if (it != m_Properties.end ())
|
||||||
return it->second;
|
return it->second;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsNTCP (bool v4only) const
|
bool RouterInfo::IsNTCP (bool v4only) const
|
||||||
{
|
{
|
||||||
if (v4only)
|
if (v4only)
|
||||||
return m_SupportedTransports & eNTCPV4;
|
return m_SupportedTransports & eNTCPV4;
|
||||||
else
|
else
|
||||||
return m_SupportedTransports & (eNTCPV4 | eNTCPV6);
|
return m_SupportedTransports & (eNTCPV4 | eNTCPV6);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsSSU (bool v4only) const
|
bool RouterInfo::IsSSU (bool v4only) const
|
||||||
{
|
{
|
||||||
@@ -744,7 +744,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
return m_SupportedTransports & (eNTCPV4 | eSSUV4);
|
return m_SupportedTransports & (eNTCPV4 | eSSUV4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::EnableV6 ()
|
void RouterInfo::EnableV6 ()
|
||||||
{
|
{
|
||||||
if (!IsV6 ())
|
if (!IsV6 ())
|
||||||
@@ -756,13 +756,13 @@ namespace data
|
|||||||
if (!IsV4 ())
|
if (!IsV4 ())
|
||||||
m_SupportedTransports |= eNTCPV4 | eSSUV4;
|
m_SupportedTransports |= eNTCPV4 | eSSUV4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RouterInfo::DisableV6 ()
|
void RouterInfo::DisableV6 ()
|
||||||
{
|
{
|
||||||
if (IsV6 ())
|
if (IsV6 ())
|
||||||
{
|
{
|
||||||
m_SupportedTransports &= ~(eNTCPV6 | eSSUV6);
|
m_SupportedTransports &= ~(eNTCPV6 | eSSUV6);
|
||||||
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
||||||
{
|
{
|
||||||
auto addr = *it;
|
auto addr = *it;
|
||||||
@@ -770,15 +770,15 @@ namespace data
|
|||||||
it = m_Addresses->erase (it);
|
it = m_Addresses->erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::DisableV4 ()
|
void RouterInfo::DisableV4 ()
|
||||||
{
|
{
|
||||||
if (IsV4 ())
|
if (IsV4 ())
|
||||||
{
|
{
|
||||||
m_SupportedTransports &= ~(eNTCPV4 | eSSUV4);
|
m_SupportedTransports &= ~(eNTCPV4 | eSSUV4);
|
||||||
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
||||||
{
|
{
|
||||||
auto addr = *it;
|
auto addr = *it;
|
||||||
@@ -786,55 +786,55 @@ namespace data
|
|||||||
it = m_Addresses->erase (it);
|
it = m_Addresses->erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RouterInfo::UsesIntroducer () const
|
bool RouterInfo::UsesIntroducer () const
|
||||||
{
|
{
|
||||||
return m_Caps & Caps::eUnreachable; // non-reachable
|
return m_Caps & Caps::eUnreachable; // non-reachable
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCPAddress (bool v4only) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCPAddress (bool v4only) const
|
||||||
{
|
{
|
||||||
return GetAddress (eTransportNTCP, v4only);
|
return GetAddress (eTransportNTCP, v4only);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
|
||||||
{
|
{
|
||||||
return GetAddress (eTransportSSU, v4only);
|
return GetAddress (eTransportSSU, v4only);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const
|
||||||
{
|
{
|
||||||
return GetAddress (eTransportSSU, false, true);
|
return GetAddress (eTransportSSU, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
||||||
{
|
{
|
||||||
#if (BOOST_VERSION >= 105300)
|
#if (BOOST_VERSION >= 105300)
|
||||||
auto addresses = boost::atomic_load (&m_Addresses);
|
auto addresses = boost::atomic_load (&m_Addresses);
|
||||||
#else
|
#else
|
||||||
auto addresses = m_Addresses;
|
auto addresses = m_Addresses;
|
||||||
#endif
|
#endif
|
||||||
for (const auto& address : *addresses)
|
for (const auto& address : *addresses)
|
||||||
{
|
{
|
||||||
if (address->transportStyle == s)
|
if (address->transportStyle == s)
|
||||||
{
|
{
|
||||||
if ((!v4only || address->host.is_v4 ()) && (!v6only || address->host.is_v6 ()))
|
if ((!v4only || address->host.is_v4 ()) && (!v6only || address->host.is_v6 ()))
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const
|
std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const
|
||||||
{
|
{
|
||||||
if (!m_Profile)
|
if (!m_Profile)
|
||||||
m_Profile = GetRouterProfile (GetIdentHash ());
|
m_Profile = GetRouterProfile (GetIdentHash ());
|
||||||
return m_Profile;
|
return m_Profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const
|
void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "Profiling.h"
|
#include "Profiling.h"
|
||||||
|
|
||||||
@@ -17,15 +17,15 @@ namespace i2p
|
|||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
|
const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
|
||||||
const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
|
const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
|
||||||
const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
|
const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
|
||||||
const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
|
const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
|
||||||
const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";
|
const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";
|
||||||
|
|
||||||
const char CAPS_FLAG_FLOODFILL = 'f';
|
const char CAPS_FLAG_FLOODFILL = 'f';
|
||||||
const char CAPS_FLAG_HIDDEN = 'H';
|
const char CAPS_FLAG_HIDDEN = 'H';
|
||||||
const char CAPS_FLAG_REACHABLE = 'R';
|
const char CAPS_FLAG_REACHABLE = 'R';
|
||||||
const char CAPS_FLAG_UNREACHABLE = 'U';
|
const char CAPS_FLAG_UNREACHABLE = 'U';
|
||||||
/* bandwidth flags */
|
/* bandwidth flags */
|
||||||
const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; /* < 12 KBps */
|
const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; /* < 12 KBps */
|
||||||
const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; /* 12-48 KBps */
|
const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; /* 12-48 KBps */
|
||||||
@@ -34,7 +34,7 @@ namespace data
|
|||||||
const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */
|
const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */
|
||||||
const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
|
const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
|
||||||
const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */
|
const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */
|
||||||
|
|
||||||
const char CAPS_FLAG_SSU_TESTING = 'B';
|
const char CAPS_FLAG_SSU_TESTING = 'B';
|
||||||
const char CAPS_FLAG_SSU_INTRODUCER = 'C';
|
const char CAPS_FLAG_SSU_INTRODUCER = 'C';
|
||||||
|
|
||||||
@@ -44,13 +44,13 @@ namespace data
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
enum SupportedTranports
|
enum SupportedTranports
|
||||||
{
|
{
|
||||||
eNTCPV4 = 0x01,
|
eNTCPV4 = 0x01,
|
||||||
eNTCPV6 = 0x02,
|
eNTCPV6 = 0x02,
|
||||||
eSSUV4 = 0x04,
|
eSSUV4 = 0x04,
|
||||||
eSSUV6 = 0x08
|
eSSUV6 = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Caps
|
enum Caps
|
||||||
{
|
{
|
||||||
eFloodfill = 0x01,
|
eFloodfill = 0x01,
|
||||||
@@ -71,7 +71,7 @@ namespace data
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
|
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
|
||||||
struct Introducer
|
struct Introducer
|
||||||
{
|
{
|
||||||
Introducer (): iExp (0) {};
|
Introducer (): iExp (0) {};
|
||||||
boost::asio::ip::address iHost;
|
boost::asio::ip::address iHost;
|
||||||
@@ -85,9 +85,9 @@ namespace data
|
|||||||
{
|
{
|
||||||
int mtu;
|
int mtu;
|
||||||
IntroKey key; // intro key for SSU
|
IntroKey key; // intro key for SSU
|
||||||
std::vector<Introducer> introducers;
|
std::vector<Introducer> introducers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Address
|
struct Address
|
||||||
{
|
{
|
||||||
TransportStyle transportStyle;
|
TransportStyle transportStyle;
|
||||||
@@ -98,23 +98,23 @@ namespace data
|
|||||||
uint8_t cost;
|
uint8_t cost;
|
||||||
std::unique_ptr<SSUExt> ssu; // not null for SSU
|
std::unique_ptr<SSUExt> ssu; // not null for SSU
|
||||||
|
|
||||||
bool IsCompatible (const boost::asio::ip::address& other) const
|
bool IsCompatible (const boost::asio::ip::address& other) const
|
||||||
{
|
{
|
||||||
return (host.is_v4 () && other.is_v4 ()) ||
|
return (host.is_v4 () && other.is_v4 ()) ||
|
||||||
(host.is_v6 () && other.is_v6 ());
|
(host.is_v6 () && other.is_v6 ());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Address& other) const
|
bool operator==(const Address& other) const
|
||||||
{
|
{
|
||||||
return transportStyle == other.transportStyle && host == other.host && port == other.port;
|
return transportStyle == other.transportStyle && host == other.host && port == other.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Address& other) const
|
bool operator!=(const Address& other) const
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::list<std::shared_ptr<Address> > Addresses;
|
typedef std::list<std::shared_ptr<Address> > Addresses;
|
||||||
|
|
||||||
RouterInfo ();
|
RouterInfo ();
|
||||||
RouterInfo (const std::string& fullPath);
|
RouterInfo (const std::string& fullPath);
|
||||||
@@ -122,7 +122,7 @@ namespace data
|
|||||||
RouterInfo& operator=(const RouterInfo& ) = default;
|
RouterInfo& operator=(const RouterInfo& ) = default;
|
||||||
RouterInfo (const uint8_t * buf, int len);
|
RouterInfo (const uint8_t * buf, int len);
|
||||||
~RouterInfo ();
|
~RouterInfo ();
|
||||||
|
|
||||||
std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
|
std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
|
||||||
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
|
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
|
||||||
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
|
||||||
@@ -131,7 +131,7 @@ namespace data
|
|||||||
std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const;
|
std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const;
|
||||||
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
|
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
|
||||||
std::shared_ptr<const Address> GetSSUV6Address () const;
|
std::shared_ptr<const Address> GetSSUV6Address () const;
|
||||||
|
|
||||||
void AddNTCPAddress (const char * host, int port);
|
void AddNTCPAddress (const char * host, int port);
|
||||||
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
|
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
|
||||||
bool AddIntroducer (const Introducer& introducer);
|
bool AddIntroducer (const Introducer& introducer);
|
||||||
@@ -156,37 +156,37 @@ namespace data
|
|||||||
bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
|
bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
|
||||||
bool IsHidden () const { return m_Caps & eHidden; };
|
bool IsHidden () const { return m_Caps & eHidden; };
|
||||||
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
|
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
|
||||||
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
|
||||||
|
|
||||||
uint8_t GetCaps () const { return m_Caps; };
|
uint8_t GetCaps () const { return m_Caps; };
|
||||||
void SetCaps (uint8_t caps);
|
void SetCaps (uint8_t caps);
|
||||||
void SetCaps (const char * caps);
|
void SetCaps (const char * caps);
|
||||||
|
|
||||||
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
||||||
bool IsUnreachable () const { return m_IsUnreachable; };
|
bool IsUnreachable () const { return m_IsUnreachable; };
|
||||||
|
|
||||||
const uint8_t * GetBuffer () const { return m_Buffer; };
|
const uint8_t * GetBuffer () const { return m_Buffer; };
|
||||||
const uint8_t * LoadBuffer (); // load if necessary
|
const uint8_t * LoadBuffer (); // load if necessary
|
||||||
int GetBufferLen () const { return m_BufferLen; };
|
int GetBufferLen () const { return m_BufferLen; };
|
||||||
void CreateBuffer (const PrivateKeys& privateKeys);
|
void CreateBuffer (const PrivateKeys& privateKeys);
|
||||||
|
|
||||||
bool IsUpdated () const { return m_IsUpdated; };
|
bool IsUpdated () const { return m_IsUpdated; };
|
||||||
void SetUpdated (bool updated) { m_IsUpdated = updated; };
|
void SetUpdated (bool updated) { m_IsUpdated = updated; };
|
||||||
bool SaveToFile (const std::string& fullPath);
|
bool SaveToFile (const std::string& fullPath);
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetProfile () const;
|
std::shared_ptr<RouterProfile> GetProfile () const;
|
||||||
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
|
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
|
||||||
|
|
||||||
void Update (const uint8_t * buf, int len);
|
void Update (const uint8_t * buf, int len);
|
||||||
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
||||||
bool IsNewer (const uint8_t * buf, size_t len) const;
|
bool IsNewer (const uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
|
/** return true if we are in a router family and the signature is valid */
|
||||||
|
bool IsFamily(const std::string & fam) const;
|
||||||
|
|
||||||
/** return true if we are in a router family and the signature is valid */
|
|
||||||
bool IsFamily(const std::string & fam) const;
|
|
||||||
|
|
||||||
// implements RoutingDestination
|
// implements RoutingDestination
|
||||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
|
||||||
|
|
||||||
bool IsDestination () const { return false; };
|
bool IsDestination () const { return false; };
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ namespace data
|
|||||||
void WriteString (const std::string& str, std::ostream& s) const;
|
void WriteString (const std::string& str, std::ostream& s) const;
|
||||||
void ExtractCaps (const char * value);
|
void ExtractCaps (const char * value);
|
||||||
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
|
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
|
||||||
void UpdateCapsProperty ();
|
void UpdateCapsProperty ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -210,13 +210,13 @@ namespace data
|
|||||||
uint8_t * m_Buffer;
|
uint8_t * m_Buffer;
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
uint64_t m_Timestamp;
|
uint64_t m_Timestamp;
|
||||||
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
|
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
|
||||||
std::map<std::string, std::string> m_Properties;
|
std::map<std::string, std::string> m_Properties;
|
||||||
bool m_IsUpdated, m_IsUnreachable;
|
bool m_IsUpdated, m_IsUnreachable;
|
||||||
uint8_t m_SupportedTransports, m_Caps;
|
uint8_t m_SupportedTransports, m_Caps;
|
||||||
mutable std::shared_ptr<RouterProfile> m_Profile;
|
mutable std::shared_ptr<RouterProfile> m_Profile;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
308
libi2pd/SSU.cpp
308
libi2pd/SSU.cpp
@@ -13,32 +13,32 @@ namespace transport
|
|||||||
|
|
||||||
SSUServer::SSUServer (const boost::asio::ip::address & addr, int port):
|
SSUServer::SSUServer (const boost::asio::ip::address & addr, int port):
|
||||||
m_OnlyV6(true), m_IsRunning(false),
|
m_OnlyV6(true), m_IsRunning(false),
|
||||||
m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
|
m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
|
||||||
m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
|
m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
|
||||||
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
|
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
|
||||||
m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint),
|
m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint),
|
||||||
m_SocketV6 (m_ReceiversServiceV6), m_IntroducersUpdateTimer (m_Service),
|
m_SocketV6 (m_ReceiversServiceV6), m_IntroducersUpdateTimer (m_Service),
|
||||||
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service),
|
m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service),
|
||||||
m_TerminationTimerV6 (m_ServiceV6)
|
m_TerminationTimerV6 (m_ServiceV6)
|
||||||
{
|
{
|
||||||
OpenSocketV6 ();
|
OpenSocketV6 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
SSUServer::SSUServer (int port):
|
SSUServer::SSUServer (int port):
|
||||||
m_OnlyV6(false), m_IsRunning(false),
|
m_OnlyV6(false), m_IsRunning(false),
|
||||||
m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
|
m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
|
||||||
m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
|
m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6),
|
||||||
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
|
m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6),
|
||||||
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
|
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
|
||||||
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
|
m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6),
|
||||||
m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
|
m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
|
||||||
m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6)
|
m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6)
|
||||||
{
|
{
|
||||||
OpenSocket ();
|
OpenSocket ();
|
||||||
if (context.SupportsV6 ())
|
if (context.SupportsV6 ())
|
||||||
OpenSocketV6 ();
|
OpenSocketV6 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
SSUServer::~SSUServer ()
|
SSUServer::~SSUServer ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -46,11 +46,11 @@ namespace transport
|
|||||||
void SSUServer::OpenSocket ()
|
void SSUServer::OpenSocket ()
|
||||||
{
|
{
|
||||||
m_Socket.open (boost::asio::ip::udp::v4());
|
m_Socket.open (boost::asio::ip::udp::v4());
|
||||||
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
||||||
m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
||||||
m_Socket.bind (m_Endpoint);
|
m_Socket.bind (m_Endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::OpenSocketV6 ()
|
void SSUServer::OpenSocketV6 ()
|
||||||
{
|
{
|
||||||
m_SocketV6.open (boost::asio::ip::udp::v6());
|
m_SocketV6.open (boost::asio::ip::udp::v6());
|
||||||
@@ -58,8 +58,8 @@ namespace transport
|
|||||||
m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE));
|
||||||
m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE));
|
||||||
m_SocketV6.bind (m_EndpointV6);
|
m_SocketV6.bind (m_EndpointV6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::Start ()
|
void SSUServer::Start ()
|
||||||
{
|
{
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
@@ -68,16 +68,16 @@ namespace transport
|
|||||||
m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this));
|
m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this));
|
||||||
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
|
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
|
||||||
m_ReceiversService.post (std::bind (&SSUServer::Receive, this));
|
m_ReceiversService.post (std::bind (&SSUServer::Receive, this));
|
||||||
ScheduleTermination ();
|
ScheduleTermination ();
|
||||||
}
|
}
|
||||||
if (context.SupportsV6 ())
|
if (context.SupportsV6 ())
|
||||||
{
|
{
|
||||||
m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this));
|
m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this));
|
||||||
m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this));
|
m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this));
|
||||||
m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this));
|
m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this));
|
||||||
ScheduleTerminationV6 ();
|
ScheduleTerminationV6 ();
|
||||||
}
|
}
|
||||||
SchedulePeerTestsCleanupTimer ();
|
SchedulePeerTestsCleanupTimer ();
|
||||||
ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers
|
ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ namespace transport
|
|||||||
DeleteAllSessions ();
|
DeleteAllSessions ();
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
m_TerminationTimer.cancel ();
|
m_TerminationTimer.cancel ();
|
||||||
m_TerminationTimerV6.cancel ();
|
m_TerminationTimerV6.cancel ();
|
||||||
m_Service.stop ();
|
m_Service.stop ();
|
||||||
m_Socket.close ();
|
m_Socket.close ();
|
||||||
m_ServiceV6.stop ();
|
m_ServiceV6.stop ();
|
||||||
@@ -94,135 +94,135 @@ namespace transport
|
|||||||
m_ReceiversService.stop ();
|
m_ReceiversService.stop ();
|
||||||
m_ReceiversServiceV6.stop ();
|
m_ReceiversServiceV6.stop ();
|
||||||
if (m_ReceiversThread)
|
if (m_ReceiversThread)
|
||||||
{
|
{
|
||||||
m_ReceiversThread->join ();
|
m_ReceiversThread->join ();
|
||||||
delete m_ReceiversThread;
|
delete m_ReceiversThread;
|
||||||
m_ReceiversThread = nullptr;
|
m_ReceiversThread = nullptr;
|
||||||
}
|
}
|
||||||
if (m_Thread)
|
if (m_Thread)
|
||||||
{
|
{
|
||||||
m_Thread->join ();
|
m_Thread->join ();
|
||||||
delete m_Thread;
|
delete m_Thread;
|
||||||
m_Thread = nullptr;
|
m_Thread = nullptr;
|
||||||
}
|
}
|
||||||
if (m_ReceiversThreadV6)
|
if (m_ReceiversThreadV6)
|
||||||
{
|
{
|
||||||
m_ReceiversThreadV6->join ();
|
m_ReceiversThreadV6->join ();
|
||||||
delete m_ReceiversThreadV6;
|
delete m_ReceiversThreadV6;
|
||||||
m_ReceiversThreadV6 = nullptr;
|
m_ReceiversThreadV6 = nullptr;
|
||||||
}
|
}
|
||||||
if (m_ThreadV6)
|
if (m_ThreadV6)
|
||||||
{
|
{
|
||||||
m_ThreadV6->join ();
|
m_ThreadV6->join ();
|
||||||
delete m_ThreadV6;
|
delete m_ThreadV6;
|
||||||
m_ThreadV6 = nullptr;
|
m_ThreadV6 = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::Run ()
|
void SSUServer::Run ()
|
||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_Service.run ();
|
m_Service.run ();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: server runtime exception: ", ex.what ());
|
LogPrint (eLogError, "SSU: server runtime exception: ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::RunV6 ()
|
void SSUServer::RunV6 ()
|
||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_ServiceV6.run ();
|
m_ServiceV6.run ();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: v6 server runtime exception: ", ex.what ());
|
LogPrint (eLogError, "SSU: v6 server runtime exception: ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::RunReceivers ()
|
void SSUServer::RunReceivers ()
|
||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_ReceiversService.run ();
|
m_ReceiversService.run ();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: receivers runtime exception: ", ex.what ());
|
LogPrint (eLogError, "SSU: receivers runtime exception: ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::RunReceiversV6 ()
|
void SSUServer::RunReceiversV6 ()
|
||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_ReceiversServiceV6.run ();
|
m_ReceiversServiceV6.run ();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: v6 receivers runtime exception: ", ex.what ());
|
LogPrint (eLogError, "SSU: v6 receivers runtime exception: ", ex.what ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay)
|
void SSUServer::AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay)
|
||||||
{
|
{
|
||||||
m_Relays[tag] = relay;
|
m_Relays[tag] = relay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::RemoveRelay (uint32_t tag)
|
void SSUServer::RemoveRelay (uint32_t tag)
|
||||||
{
|
{
|
||||||
m_Relays.erase (tag);
|
m_Relays.erase (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag)
|
std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag)
|
||||||
{
|
{
|
||||||
auto it = m_Relays.find (tag);
|
auto it = m_Relays.find (tag);
|
||||||
if (it != m_Relays.end ())
|
if (it != m_Relays.end ())
|
||||||
{
|
{
|
||||||
if (it->second->GetState () == eSessionStateEstablished)
|
if (it->second->GetState () == eSessionStateEstablished)
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
else
|
||||||
m_Relays.erase (it);
|
m_Relays.erase (it);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to)
|
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to)
|
||||||
{
|
{
|
||||||
if (to.protocol () == boost::asio::ip::udp::v4())
|
if (to.protocol () == boost::asio::ip::udp::v4())
|
||||||
m_Socket.send_to (boost::asio::buffer (buf, len), to);
|
m_Socket.send_to (boost::asio::buffer (buf, len), to);
|
||||||
else
|
else
|
||||||
m_SocketV6.send_to (boost::asio::buffer (buf, len), to);
|
m_SocketV6.send_to (boost::asio::buffer (buf, len), to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::Receive ()
|
void SSUServer::Receive ()
|
||||||
{
|
{
|
||||||
SSUPacket * packet = new SSUPacket ();
|
SSUPacket * packet = new SSUPacket ();
|
||||||
m_Socket.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from,
|
m_Socket.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from,
|
||||||
std::bind (&SSUServer::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet));
|
std::bind (&SSUServer::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::ReceiveV6 ()
|
void SSUServer::ReceiveV6 ()
|
||||||
{
|
{
|
||||||
SSUPacket * packet = new SSUPacket ();
|
SSUPacket * packet = new SSUPacket ();
|
||||||
m_SocketV6.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from,
|
m_SocketV6.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from,
|
||||||
std::bind (&SSUServer::HandleReceivedFromV6, this, std::placeholders::_1, std::placeholders::_2, packet));
|
std::bind (&SSUServer::HandleReceivedFromV6, this, std::placeholders::_1, std::placeholders::_2, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -235,13 +235,13 @@ namespace transport
|
|||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
size_t moreBytes = m_Socket.available(ec);
|
size_t moreBytes = m_Socket.available(ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
while (moreBytes && packets.size () < 25)
|
while (moreBytes && packets.size () < 25)
|
||||||
{
|
{
|
||||||
packet = new SSUPacket ();
|
packet = new SSUPacket ();
|
||||||
packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, 0, ec);
|
packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, 0, ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
packets.push_back (packet);
|
packets.push_back (packet);
|
||||||
moreBytes = m_Socket.available(ec);
|
moreBytes = m_Socket.available(ec);
|
||||||
if (ec) break;
|
if (ec) break;
|
||||||
@@ -251,15 +251,15 @@ namespace transport
|
|||||||
LogPrint (eLogError, "SSU: receive_from error: ", ec.message ());
|
LogPrint (eLogError, "SSU: receive_from error: ", ec.message ());
|
||||||
delete packet;
|
delete packet;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_Sessions));
|
m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_Sessions));
|
||||||
Receive ();
|
Receive ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete packet;
|
delete packet;
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
@@ -268,7 +268,7 @@ namespace transport
|
|||||||
OpenSocket ();
|
OpenSocket ();
|
||||||
Receive ();
|
Receive ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -298,15 +298,15 @@ namespace transport
|
|||||||
LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ());
|
LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ());
|
||||||
delete packet;
|
delete packet;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6));
|
m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6));
|
||||||
ReceiveV6 ();
|
ReceiveV6 ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete packet;
|
delete packet;
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
@@ -315,17 +315,17 @@ namespace transport
|
|||||||
OpenSocketV6 ();
|
OpenSocketV6 ();
|
||||||
ReceiveV6 ();
|
ReceiveV6 ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::HandleReceivedPackets (std::vector<SSUPacket *> packets,
|
void SSUServer::HandleReceivedPackets (std::vector<SSUPacket *> packets,
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > * sessions)
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > * sessions)
|
||||||
{
|
{
|
||||||
std::shared_ptr<SSUSession> session;
|
std::shared_ptr<SSUSession> session;
|
||||||
for (auto& packet: packets)
|
for (auto& packet: packets)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous
|
if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous
|
||||||
{
|
{
|
||||||
if (session) session->FlushData ();
|
if (session) session->FlushData ();
|
||||||
@@ -341,13 +341,13 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
session->ProcessNextMessage (packet->buf, packet->len, packet->from);
|
session->ProcessNextMessage (packet->buf, packet->len, packet->from);
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU: HandleReceivedPackets ", ex.what ());
|
LogPrint (eLogError, "SSU: HandleReceivedPackets ", ex.what ());
|
||||||
if (session) session->FlushData ();
|
if (session) session->FlushData ();
|
||||||
session = nullptr;
|
session = nullptr;
|
||||||
}
|
}
|
||||||
delete packet;
|
delete packet;
|
||||||
}
|
}
|
||||||
if (session) session->FlushData ();
|
if (session) session->FlushData ();
|
||||||
@@ -357,26 +357,26 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (!router) return nullptr;
|
if (!router) return nullptr;
|
||||||
auto address = router->GetSSUAddress (true); // v4 only
|
auto address = router->GetSSUAddress (true); // v4 only
|
||||||
if (!address) return nullptr;
|
if (!address) return nullptr;
|
||||||
auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
|
auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
|
||||||
if (session || !context.SupportsV6 ())
|
if (session || !context.SupportsV6 ())
|
||||||
return session;
|
return session;
|
||||||
// try v6
|
// try v6
|
||||||
address = router->GetSSUV6Address ();
|
address = router->GetSSUV6Address ();
|
||||||
if (!address) return nullptr;
|
if (!address) return nullptr;
|
||||||
return FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
|
return FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SSUSession> SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const
|
std::shared_ptr<SSUSession> SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const
|
||||||
{
|
{
|
||||||
auto& sessions = e.address ().is_v6 () ? m_SessionsV6 : m_Sessions;
|
auto& sessions = e.address ().is_v6 () ? m_SessionsV6 : m_Sessions;
|
||||||
auto it = sessions.find (e);
|
auto it = sessions.find (e);
|
||||||
if (it != sessions.end ())
|
if (it != sessions.end ())
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest, bool v4only)
|
void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest, bool v4only)
|
||||||
{
|
{
|
||||||
auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ());
|
auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ());
|
||||||
@@ -385,7 +385,7 @@ namespace transport
|
|||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address");
|
LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
const boost::asio::ip::address& addr, int port, bool peerTest)
|
const boost::asio::ip::address& addr, int port, bool peerTest)
|
||||||
{
|
{
|
||||||
@@ -403,27 +403,27 @@ namespace transport
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest)
|
void SSUServer::CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest)
|
||||||
{
|
{
|
||||||
auto& sessions = remoteEndpoint.address ().is_v6 () ? m_SessionsV6 : m_Sessions;
|
auto& sessions = remoteEndpoint.address ().is_v6 () ? m_SessionsV6 : m_Sessions;
|
||||||
auto it = sessions.find (remoteEndpoint);
|
auto it = sessions.find (remoteEndpoint);
|
||||||
if (it != sessions.end ())
|
if (it != sessions.end ())
|
||||||
{
|
{
|
||||||
auto session = it->second;
|
auto session = it->second;
|
||||||
if (peerTest && session->GetState () == eSessionStateEstablished)
|
if (peerTest && session->GetState () == eSessionStateEstablished)
|
||||||
session->SendPeerTest ();
|
session->SendPeerTest ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// otherwise create new session
|
// otherwise create new session
|
||||||
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
||||||
sessions[remoteEndpoint] = session;
|
sessions[remoteEndpoint] = session;
|
||||||
// connect
|
// connect
|
||||||
LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
|
LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
|
||||||
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
|
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
|
||||||
session->Connect ();
|
session->Connect ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
|
void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
|
||||||
{
|
{
|
||||||
if (router && router->UsesIntroducer ())
|
if (router && router->UsesIntroducer ())
|
||||||
@@ -435,13 +435,13 @@ namespace transport
|
|||||||
auto it = m_Sessions.find (remoteEndpoint);
|
auto it = m_Sessions.find (remoteEndpoint);
|
||||||
// check if session is presented already
|
// check if session is presented already
|
||||||
if (it != m_Sessions.end ())
|
if (it != m_Sessions.end ())
|
||||||
{
|
{
|
||||||
auto session = it->second;
|
auto session = it->second;
|
||||||
if (peerTest && session->GetState () == eSessionStateEstablished)
|
if (peerTest && session->GetState () == eSessionStateEstablished)
|
||||||
session->SendPeerTest ();
|
session->SendPeerTest ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// create new session
|
// create new session
|
||||||
int numIntroducers = address->ssu->introducers.size ();
|
int numIntroducers = address->ssu->introducers.size ();
|
||||||
if (numIntroducers > 0)
|
if (numIntroducers > 0)
|
||||||
{
|
{
|
||||||
@@ -455,52 +455,52 @@ namespace transport
|
|||||||
if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer
|
if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer
|
||||||
boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort);
|
boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort);
|
||||||
if (ep.address ().is_v4 ()) // ipv4 only
|
if (ep.address ().is_v4 ()) // ipv4 only
|
||||||
{
|
{
|
||||||
if (!introducer) introducer = intr; // we pick first one for now
|
if (!introducer) introducer = intr; // we pick first one for now
|
||||||
it = m_Sessions.find (ep);
|
it = m_Sessions.find (ep);
|
||||||
if (it != m_Sessions.end ())
|
if (it != m_Sessions.end ())
|
||||||
{
|
{
|
||||||
introducerSession = it->second;
|
introducerSession = it->second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!introducer)
|
if (!introducer)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented");
|
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (introducerSession) // session found
|
if (introducerSession) // session found
|
||||||
LogPrint (eLogWarning, "SSU: Session to introducer already exists");
|
LogPrint (eLogWarning, "SSU: Session to introducer already exists");
|
||||||
else // create new
|
else // create new
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
|
LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
|
||||||
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
|
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
|
||||||
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
|
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
|
||||||
m_Sessions[introducerEndpoint] = introducerSession;
|
m_Sessions[introducerEndpoint] = introducerSession;
|
||||||
}
|
}
|
||||||
#if BOOST_VERSION >= 104900
|
#if BOOST_VERSION >= 104900
|
||||||
if (!address->host.is_unspecified () && address->port)
|
if (!address->host.is_unspecified () && address->port)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// create session
|
// create session
|
||||||
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
||||||
m_Sessions[remoteEndpoint] = session;
|
m_Sessions[remoteEndpoint] = session;
|
||||||
|
|
||||||
// introduce
|
// introduce
|
||||||
LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()),
|
LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()),
|
||||||
"] through introducer ", introducer->iHost, ":", introducer->iPort);
|
"] through introducer ", introducer->iHost, ":", introducer->iPort);
|
||||||
session->WaitForIntroduction ();
|
session->WaitForIntroduction ();
|
||||||
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
|
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
|
||||||
{
|
{
|
||||||
uint8_t buf[1];
|
uint8_t buf[1];
|
||||||
Send (buf, 0, remoteEndpoint); // send HolePunch
|
Send (buf, 0, remoteEndpoint); // send HolePunch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
introducerSession->Introduce (*introducer, router);
|
introducerSession->Introduce (*introducer, router);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no introducers present");
|
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no introducers present");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -518,8 +518,8 @@ namespace transport
|
|||||||
m_SessionsV6.erase (ep);
|
m_SessionsV6.erase (ep);
|
||||||
else
|
else
|
||||||
m_Sessions.erase (ep);
|
m_Sessions.erase (ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::DeleteAllSessions ()
|
void SSUServer::DeleteAllSessions ()
|
||||||
{
|
{
|
||||||
@@ -543,15 +543,15 @@ namespace transport
|
|||||||
auto ind = rand () % filteredSessions.size ();
|
auto ind = rand () % filteredSessions.size ();
|
||||||
return filteredSessions[ind];
|
return filteredSessions[ind];
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded) // v4 only
|
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded) // v4 only
|
||||||
{
|
{
|
||||||
return GetRandomV4Session (
|
return GetRandomV4Session (
|
||||||
[excluded](std::shared_ptr<SSUSession> session)->bool
|
[excluded](std::shared_ptr<SSUSession> session)->bool
|
||||||
{
|
{
|
||||||
return session->GetState () == eSessionStateEstablished && session != excluded;
|
return session->GetState () == eSessionStateEstablished && session != excluded;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -567,15 +567,15 @@ namespace transport
|
|||||||
auto ind = rand () % filteredSessions.size ();
|
auto ind = rand () % filteredSessions.size ();
|
||||||
return filteredSessions[ind];
|
return filteredSessions[ind];
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedV6Session (std::shared_ptr<const SSUSession> excluded) // v6 only
|
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedV6Session (std::shared_ptr<const SSUSession> excluded) // v6 only
|
||||||
{
|
{
|
||||||
return GetRandomV6Session (
|
return GetRandomV6Session (
|
||||||
[excluded](std::shared_ptr<SSUSession> session)->bool
|
[excluded](std::shared_ptr<SSUSession> session)->bool
|
||||||
{
|
{
|
||||||
return session->GetState () == eSessionStateEstablished && session != excluded;
|
return session->GetState () == eSessionStateEstablished && session != excluded;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -587,18 +587,18 @@ namespace transport
|
|||||||
for (int i = 0; i < maxNumIntroducers; i++)
|
for (int i = 0; i < maxNumIntroducers; i++)
|
||||||
{
|
{
|
||||||
auto session = GetRandomV4Session (
|
auto session = GetRandomV4Session (
|
||||||
[&ret, ts](std::shared_ptr<SSUSession> session)->bool
|
[&ret, ts](std::shared_ptr<SSUSession> session)->bool
|
||||||
{
|
{
|
||||||
return session->GetRelayTag () && !ret.count (session.get ()) &&
|
return session->GetRelayTag () && !ret.count (session.get ()) &&
|
||||||
session->GetState () == eSessionStateEstablished &&
|
session->GetState () == eSessionStateEstablished &&
|
||||||
ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION;
|
ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (session)
|
if (session)
|
||||||
{
|
{
|
||||||
ret.insert (session.get ());
|
ret.insert (session.get ());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -607,7 +607,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL));
|
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL));
|
||||||
m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer,
|
m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode)
|
void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode)
|
||||||
@@ -620,7 +620,7 @@ namespace transport
|
|||||||
// we still don't know if we need introducers
|
// we still don't know if we need introducers
|
||||||
ScheduleIntroducersUpdateTimer ();
|
ScheduleIntroducersUpdateTimer ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (i2p::context.GetStatus () == eRouterStatusOK) return; // we don't need introducers anymore
|
if (i2p::context.GetStatus () == eRouterStatusOK) return; // we don't need introducers anymore
|
||||||
// we are firewalled
|
// we are firewalled
|
||||||
if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable ();
|
if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable ();
|
||||||
@@ -628,7 +628,7 @@ namespace transport
|
|||||||
size_t numIntroducers = 0;
|
size_t numIntroducers = 0;
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (const auto& it : m_Introducers)
|
for (const auto& it : m_Introducers)
|
||||||
{
|
{
|
||||||
auto session = FindSession (it);
|
auto session = FindSession (it);
|
||||||
if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION)
|
if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION)
|
||||||
{
|
{
|
||||||
@@ -636,7 +636,7 @@ namespace transport
|
|||||||
newList.push_back (it);
|
newList.push_back (it);
|
||||||
numIntroducers++;
|
numIntroducers++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i2p::context.RemoveIntroducer (it);
|
i2p::context.RemoveIntroducer (it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,16 +658,16 @@ namespace transport
|
|||||||
if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break;
|
if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_Introducers = newList;
|
m_Introducers = newList;
|
||||||
if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS)
|
if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS)
|
||||||
{
|
{
|
||||||
auto introducer = i2p::data::netdb.GetRandomIntroducer ();
|
auto introducer = i2p::data::netdb.GetRandomIntroducer ();
|
||||||
if (introducer)
|
if (introducer)
|
||||||
CreateSession (introducer);
|
CreateSession (introducer);
|
||||||
}
|
}
|
||||||
ScheduleIntroducersUpdateTimer ();
|
ScheduleIntroducersUpdateTimer ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr<SSUSession> session)
|
void SSUServer::NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr<SSUSession> session)
|
||||||
@@ -682,7 +682,7 @@ namespace transport
|
|||||||
return it->second.role;
|
return it->second.role;
|
||||||
else
|
else
|
||||||
return ePeerTestParticipantUnknown;
|
return ePeerTestParticipantUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SSUSession> SSUServer::GetPeerTestSession (uint32_t nonce)
|
std::shared_ptr<SSUSession> SSUServer::GetPeerTestSession (uint32_t nonce)
|
||||||
{
|
{
|
||||||
@@ -698,26 +698,26 @@ namespace transport
|
|||||||
auto it = m_PeerTests.find (nonce);
|
auto it = m_PeerTests.find (nonce);
|
||||||
if (it != m_PeerTests.end ())
|
if (it != m_PeerTests.end ())
|
||||||
it->second.role = role;
|
it->second.role = role;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::RemovePeerTest (uint32_t nonce)
|
void SSUServer::RemovePeerTest (uint32_t nonce)
|
||||||
{
|
{
|
||||||
m_PeerTests.erase (nonce);
|
m_PeerTests.erase (nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::SchedulePeerTestsCleanupTimer ()
|
void SSUServer::SchedulePeerTestsCleanupTimer ()
|
||||||
{
|
{
|
||||||
m_PeerTestsCleanupTimer.expires_from_now (boost::posix_time::seconds(SSU_PEER_TEST_TIMEOUT));
|
m_PeerTestsCleanupTimer.expires_from_now (boost::posix_time::seconds(SSU_PEER_TEST_TIMEOUT));
|
||||||
m_PeerTestsCleanupTimer.async_wait (std::bind (&SSUServer::HandlePeerTestsCleanupTimer,
|
m_PeerTestsCleanupTimer.async_wait (std::bind (&SSUServer::HandlePeerTestsCleanupTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::HandlePeerTestsCleanupTimer (const boost::system::error_code& ecode)
|
void SSUServer::HandlePeerTestsCleanupTimer (const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
int numDeleted = 0;
|
int numDeleted = 0;
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
for (auto it = m_PeerTests.begin (); it != m_PeerTests.end ();)
|
for (auto it = m_PeerTests.begin (); it != m_PeerTests.end ();)
|
||||||
{
|
{
|
||||||
if (ts > it->second.creationTime + SSU_PEER_TEST_TIMEOUT*1000LL)
|
if (ts > it->second.creationTime + SSU_PEER_TEST_TIMEOUT*1000LL)
|
||||||
@@ -744,21 +744,21 @@ namespace transport
|
|||||||
void SSUServer::HandleTerminationTimer (const boost::system::error_code& ecode)
|
void SSUServer::HandleTerminationTimer (const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto& it: m_Sessions)
|
for (auto& it: m_Sessions)
|
||||||
if (it.second->IsTerminationTimeoutExpired (ts))
|
if (it.second->IsTerminationTimeoutExpired (ts))
|
||||||
{
|
{
|
||||||
auto session = it.second;
|
auto session = it.second;
|
||||||
m_Service.post ([session]
|
m_Service.post ([session]
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||||
session->Failed ();
|
session->Failed ();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ScheduleTermination ();
|
ScheduleTermination ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::ScheduleTerminationV6 ()
|
void SSUServer::ScheduleTerminationV6 ()
|
||||||
{
|
{
|
||||||
@@ -770,21 +770,21 @@ namespace transport
|
|||||||
void SSUServer::HandleTerminationTimerV6 (const boost::system::error_code& ecode)
|
void SSUServer::HandleTerminationTimerV6 (const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto& it: m_SessionsV6)
|
for (auto& it: m_SessionsV6)
|
||||||
if (it.second->IsTerminationTimeoutExpired (ts))
|
if (it.second->IsTerminationTimeoutExpired (ts))
|
||||||
{
|
{
|
||||||
auto session = it.second;
|
auto session = it.second;
|
||||||
m_ServiceV6.post ([session]
|
m_ServiceV6.post ([session]
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||||
session->Failed ();
|
session->Failed ();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ScheduleTerminationV6 ();
|
ScheduleTerminationV6 ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace transport
|
namespace transport
|
||||||
{
|
{
|
||||||
const int SSU_KEEP_ALIVE_INTERVAL = 30; // 30 seconds
|
const int SSU_KEEP_ALIVE_INTERVAL = 30; // 30 seconds
|
||||||
const int SSU_PEER_TEST_TIMEOUT = 60; // 60 seconds
|
const int SSU_PEER_TEST_TIMEOUT = 60; // 60 seconds
|
||||||
const int SSU_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour
|
const int SSU_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour
|
||||||
const int SSU_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
const int SSU_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
|
||||||
const size_t SSU_MAX_NUM_INTRODUCERS = 3;
|
const size_t SSU_MAX_NUM_INTRODUCERS = 3;
|
||||||
@@ -33,8 +33,8 @@ namespace transport
|
|||||||
i2p::crypto::AESAlignedBuffer<SSU_MTU_V6 + 18> buf; // max MTU + iv + size
|
i2p::crypto::AESAlignedBuffer<SSU_MTU_V6 + 18> buf; // max MTU + iv + size
|
||||||
boost::asio::ip::udp::endpoint from;
|
boost::asio::ip::udp::endpoint from;
|
||||||
size_t len;
|
size_t len;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SSUServer
|
class SSUServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -45,7 +45,7 @@ namespace transport
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false, bool v4only = false);
|
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false, bool v4only = false);
|
||||||
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||||
const boost::asio::ip::address& addr, int port, bool peerTest = false);
|
const boost::asio::ip::address& addr, int port, bool peerTest = false);
|
||||||
void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest);
|
void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest);
|
||||||
std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const;
|
std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const;
|
||||||
@@ -53,11 +53,11 @@ namespace transport
|
|||||||
std::shared_ptr<SSUSession> GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded);
|
std::shared_ptr<SSUSession> GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded);
|
||||||
std::shared_ptr<SSUSession> GetRandomEstablishedV6Session (std::shared_ptr<const SSUSession> excluded);
|
std::shared_ptr<SSUSession> GetRandomEstablishedV6Session (std::shared_ptr<const SSUSession> excluded);
|
||||||
void DeleteSession (std::shared_ptr<SSUSession> session);
|
void DeleteSession (std::shared_ptr<SSUSession> session);
|
||||||
void DeleteAllSessions ();
|
void DeleteAllSessions ();
|
||||||
|
|
||||||
boost::asio::io_service& GetService () { return m_Service; };
|
boost::asio::io_service& GetService () { return m_Service; };
|
||||||
boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; };
|
boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; };
|
||||||
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
|
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
|
||||||
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
||||||
void AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay);
|
void AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay);
|
||||||
void RemoveRelay (uint32_t tag);
|
void RemoveRelay (uint32_t tag);
|
||||||
@@ -68,7 +68,7 @@ namespace transport
|
|||||||
std::shared_ptr<SSUSession> GetPeerTestSession (uint32_t nonce);
|
std::shared_ptr<SSUSession> GetPeerTestSession (uint32_t nonce);
|
||||||
void UpdatePeerTest (uint32_t nonce, PeerTestParticipant role);
|
void UpdatePeerTest (uint32_t nonce, PeerTestParticipant role);
|
||||||
void RemovePeerTest (uint32_t nonce);
|
void RemovePeerTest (uint32_t nonce);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void OpenSocket ();
|
void OpenSocket ();
|
||||||
@@ -84,13 +84,13 @@ namespace transport
|
|||||||
void HandleReceivedPackets (std::vector<SSUPacket *> packets,
|
void HandleReceivedPackets (std::vector<SSUPacket *> packets,
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> >* sessions);
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> >* sessions);
|
||||||
|
|
||||||
void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
|
void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
|
||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<SSUSession> GetRandomV4Session (Filter filter);
|
std::shared_ptr<SSUSession> GetRandomV4Session (Filter filter);
|
||||||
template<typename Filter>
|
template<typename Filter>
|
||||||
std::shared_ptr<SSUSession> GetRandomV6Session (Filter filter);
|
std::shared_ptr<SSUSession> GetRandomV6Session (Filter filter);
|
||||||
|
|
||||||
std::set<SSUSession *> FindIntroducers (int maxNumIntroducers);
|
std::set<SSUSession *> FindIntroducers (int maxNumIntroducers);
|
||||||
void ScheduleIntroducersUpdateTimer ();
|
void ScheduleIntroducersUpdateTimer ();
|
||||||
void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode);
|
void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
@@ -111,10 +111,10 @@ namespace transport
|
|||||||
PeerTestParticipant role;
|
PeerTestParticipant role;
|
||||||
std::shared_ptr<SSUSession> session; // for Bob to Alice
|
std::shared_ptr<SSUSession> session; // for Bob to Alice
|
||||||
};
|
};
|
||||||
|
|
||||||
bool m_OnlyV6;
|
bool m_OnlyV6;
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread, * m_ReceiversThreadV6;
|
std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread, * m_ReceiversThreadV6;
|
||||||
boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService, m_ReceiversServiceV6;
|
boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService, m_ReceiversServiceV6;
|
||||||
boost::asio::io_service::work m_Work, m_WorkV6, m_ReceiversWork, m_ReceiversWorkV6;
|
boost::asio::io_service::work m_Work, m_WorkV6, m_ReceiversWork, m_ReceiversWorkV6;
|
||||||
boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6;
|
boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6;
|
||||||
@@ -125,7 +125,7 @@ namespace transport
|
|||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
|
||||||
std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer
|
std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer
|
||||||
std::map<uint32_t, PeerTest> m_PeerTests; // nonce -> creation time in milliseconds
|
std::map<uint32_t, PeerTest> m_PeerTests; // nonce -> creation time in milliseconds
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user