mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
resolve merge conflicts
This commit is contained in:
commit
d62d2ed269
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,8 +7,10 @@ netDb
|
|||||||
/i2pd
|
/i2pd
|
||||||
/libi2pd.a
|
/libi2pd.a
|
||||||
/libi2pdclient.a
|
/libi2pdclient.a
|
||||||
|
/libi2pdlang.a
|
||||||
/libi2pd.so
|
/libi2pd.so
|
||||||
/libi2pdclient.so
|
/libi2pdclient.so
|
||||||
|
/libi2pdlang.so
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
|
||||||
|
54
.travis.yml
54
.travis.yml
@ -1,54 +0,0 @@
|
|||||||
language: cpp
|
|
||||||
cache:
|
|
||||||
apt: true
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
#- osx
|
|
||||||
dist: xenial
|
|
||||||
sudo: required
|
|
||||||
compiler:
|
|
||||||
- g++
|
|
||||||
- clang++
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- MAKEFLAGS="-j 2"
|
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
|
||||||
- BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
|
||||||
- BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
|
||||||
- BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
|
||||||
matrix:
|
|
||||||
exclude:
|
|
||||||
- os: osx
|
|
||||||
env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
|
||||||
- os: osx
|
|
||||||
env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
|
||||||
- os: linux
|
|
||||||
compiler: clang++
|
|
||||||
env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
|
||||||
- os: linux
|
|
||||||
compiler: clang++
|
|
||||||
env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
- g++
|
|
||||||
- clang
|
|
||||||
- libboost-chrono-dev
|
|
||||||
- libboost-date-time-dev
|
|
||||||
- libboost-filesystem-dev
|
|
||||||
- libboost-program-options-dev
|
|
||||||
- libboost-system-dev
|
|
||||||
- libboost-thread-dev
|
|
||||||
- libminiupnpc-dev
|
|
||||||
- libssl-dev
|
|
||||||
before_install:
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi
|
|
||||||
script:
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi
|
|
10
Makefile
10
Makefile
@ -79,7 +79,8 @@ api: mk_obj_dir $(SHLIB) $(ARLIB)
|
|||||||
client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
||||||
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP)
|
||||||
langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG)
|
lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG)
|
||||||
|
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
@ -94,7 +95,7 @@ obj/%.o: %.cpp
|
|||||||
# '-' is 'ignore if missing' on first run
|
# '-' is 'ignore if missing' on first run
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG)
|
||||||
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(LIB_OBJS)
|
$(SHLIB): $(LIB_OBJS)
|
||||||
@ -132,9 +133,9 @@ $(ARLIB_LANG): $(LANG_OBJS)
|
|||||||
clean:
|
clean:
|
||||||
$(RM) -r obj
|
$(RM) -r obj
|
||||||
$(RM) -r docs/generated
|
$(RM) -r docs/generated
|
||||||
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
|
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG)
|
||||||
|
|
||||||
strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
|
strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG)
|
||||||
strip $^
|
strip $^
|
||||||
|
|
||||||
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
||||||
@ -158,6 +159,7 @@ doxygen:
|
|||||||
.PHONY: api
|
.PHONY: api
|
||||||
.PHONY: api_client
|
.PHONY: api_client
|
||||||
.PHONY: client
|
.PHONY: client
|
||||||
|
.PHONY: lang
|
||||||
.PHONY: mk_obj_dir
|
.PHONY: mk_obj_dir
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
.PHONY: strip
|
.PHONY: strip
|
||||||
|
@ -73,7 +73,7 @@ Build instructions:
|
|||||||
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
|
* Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc.
|
||||||
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
|
* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml)
|
||||||
* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
|
* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml)
|
||||||
* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/)
|
* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml)
|
||||||
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
|
* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd)
|
||||||
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
|
* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml)
|
||||||
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
|
* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml)
|
||||||
|
57
appveyor.yml
57
appveyor.yml
@ -1,57 +0,0 @@
|
|||||||
version: 2.38.0.{build}
|
|
||||||
pull_requests:
|
|
||||||
do_not_increment_build_number: true
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- openssl
|
|
||||||
skip_tags: true
|
|
||||||
os: Visual Studio 2015
|
|
||||||
shallow_clone: true
|
|
||||||
clone_depth: 1
|
|
||||||
|
|
||||||
# avoid building 32-bit if 64-bit failed already
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
environment:
|
|
||||||
APPVEYOR_SAVE_CACHE_ON_ERROR: true
|
|
||||||
MSYS2_PATH_TYPE: inherit
|
|
||||||
CHERE_INVOKING: enabled_from_arguments
|
|
||||||
matrix:
|
|
||||||
- MSYSTEM: MINGW64
|
|
||||||
- MSYSTEM: MINGW32
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- c:\msys64\var\cache\pacman\pkg\
|
|
||||||
|
|
||||||
install:
|
|
||||||
# install new signing keyring
|
|
||||||
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
|
||||||
- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
|
|
||||||
# remove packages which can break build
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc"
|
|
||||||
# update runtime
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
|
||||||
# Kill bash before next try
|
|
||||||
- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0
|
|
||||||
# update packages and install required
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc"
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3"
|
|
||||||
# prepare archive for uploading
|
|
||||||
- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
|
||||||
- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt
|
|
||||||
- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST%
|
|
||||||
|
|
||||||
after_build:
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc"
|
|
||||||
|
|
||||||
test: off
|
|
||||||
|
|
||||||
deploy: off
|
|
||||||
|
|
||||||
artifacts:
|
|
||||||
- path: i2pd-*.zip
|
|
@ -69,6 +69,16 @@ if(WITH_LIBRARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp)
|
||||||
|
add_library(libi2pdlang ${LANG_SRC})
|
||||||
|
set_target_properties(libi2pdlang PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
if(WITH_LIBRARY)
|
||||||
|
install(TARGETS libi2pdlang
|
||||||
|
EXPORT libi2pdlang
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
COMPONENT Libraries)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(DAEMON_SRC
|
set(DAEMON_SRC
|
||||||
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
"${DAEMON_SRC_DIR}/Daemon.cpp"
|
||||||
@ -198,10 +208,11 @@ if(WITH_PCH)
|
|||||||
)
|
)
|
||||||
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
||||||
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
|
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
|
||||||
|
target_compile_options(libi2pdlang PRIVATE -include libi2pd/stdafx.h)
|
||||||
target_link_libraries(libi2pd stdafx)
|
target_link_libraries(libi2pd stdafx)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(libi2pdclient libi2pd)
|
target_link_libraries(libi2pdclient libi2pd libi2pdlang)
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED)
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||||
@ -265,7 +276,7 @@ message(STATUS "---------------------------------------")
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
if(WITH_BINARY)
|
if(WITH_BINARY)
|
||||||
add_executable("${PROJECT_NAME}" ${LANG_SRC} ${DAEMON_SRC})
|
add_executable("${PROJECT_NAME}" ${DAEMON_SRC})
|
||||||
|
|
||||||
if(WITH_STATIC)
|
if(WITH_STATIC)
|
||||||
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")
|
||||||
@ -295,7 +306,7 @@ if(WITH_BINARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY})
|
||||||
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${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}")
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
Howto build & run
|
|
||||||
==================
|
|
||||||
|
|
||||||
**Build**
|
|
||||||
|
|
||||||
Assuming you're in the root directory of the anoncoin source code.
|
|
||||||
|
|
||||||
$ `cd build/docker`
|
|
||||||
$ `docker -t meeh/i2pd:latest .`
|
|
||||||
|
|
||||||
**Run**
|
|
||||||
|
|
||||||
To run either the local build, or if not found - fetched prebuild from hub.docker.io, run the following command.
|
|
||||||
|
|
||||||
$ `docker run --name anonnode -v /path/to/i2pd/datadir/on/host:/var/lib/i2pd -p 7070:7070 -p 4444:4444 -p 4447:4447 -p 7656:7656 -p 2827:2827 -p 7654:7654 -p 7650:7650 -d meeh/i2pd`
|
|
||||||
|
|
||||||
All the ports ( -p HOSTPORT:DOCKERPORT ) is optional. However the command above enable all features (Webconsole, HTTP Proxy, BOB, SAM, i2cp, etc)
|
|
||||||
|
|
||||||
The volume ( -v HOSTDIR:DOCKERDIR ) is also optional, but if you don't use it, your config, routerid and private keys will die along with the container.
|
|
||||||
|
|
||||||
**Options**
|
|
||||||
|
|
||||||
Options are set via docker environment variables. This can be set at run with -e parameters.
|
|
||||||
|
|
||||||
* **ENABLE_IPV6** - Enable IPv6 support. Any value can be used - it triggers as long as it's not empty.
|
|
||||||
* **LOGLEVEL** - Set the loglevel.
|
|
||||||
* **ENABLE_AUTH** - Enable auth for the webconsole. Username and password needs to be set manually in i2pd.conf cause security reasons.
|
|
||||||
|
|
||||||
**Logging**
|
|
||||||
|
|
||||||
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. :)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
FROM ubuntu
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \
|
|
||||||
libboost-program-options-dev libboost-date-time-dev \
|
|
||||||
libssl-dev git build-essential
|
|
||||||
|
|
||||||
RUN git clone https://github.com/PurpleI2P/i2pd.git
|
|
||||||
WORKDIR /i2pd
|
|
||||||
RUN make
|
|
||||||
|
|
||||||
CMD ./i2pd
|
|
@ -1,2 +0,0 @@
|
|||||||
i2pd:
|
|
||||||
build: .
|
|
@ -1,4 +1,4 @@
|
|||||||
FROM alpine:3.13
|
FROM alpine:latest
|
||||||
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
|
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
|
||||||
|
|
||||||
# Expose git branch, tag and URL variables as arguments
|
# Expose git branch, tag and URL variables as arguments
|
||||||
|
@ -26,551 +26,551 @@ msgstr ""
|
|||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:141
|
#: daemon/HTTPServer.cpp:147
|
||||||
msgid "day"
|
msgid "day"
|
||||||
msgid_plural "days"
|
msgid_plural "days"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
#: daemon/HTTPServer.cpp:145
|
|
||||||
|
#: daemon/HTTPServer.cpp:151
|
||||||
msgid "hour"
|
msgid "hour"
|
||||||
msgid_plural "hours"
|
msgid_plural "hours"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
#: daemon/HTTPServer.cpp:149
|
|
||||||
|
#: daemon/HTTPServer.cpp:155
|
||||||
msgid "minute"
|
msgid "minute"
|
||||||
msgid_plural "minutes"
|
msgid_plural "minutes"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:152
|
#: daemon/HTTPServer.cpp:158
|
||||||
msgid "second"
|
msgid "second"
|
||||||
msgid_plural "seconds"
|
msgid_plural "seconds"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188
|
#. tr: Kibibit
|
||||||
|
#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194
|
||||||
msgid "KiB"
|
msgid "KiB"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:162
|
#. tr: Mebibit
|
||||||
|
#: daemon/HTTPServer.cpp:168
|
||||||
msgid "MiB"
|
msgid "MiB"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:164
|
#. tr: Gibibit
|
||||||
|
#: daemon/HTTPServer.cpp:170
|
||||||
msgid "GiB"
|
msgid "GiB"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:181
|
#: daemon/HTTPServer.cpp:187
|
||||||
msgid "building"
|
msgid "building"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:182
|
#: daemon/HTTPServer.cpp:188
|
||||||
msgid "failed"
|
msgid "failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:183
|
#: daemon/HTTPServer.cpp:189
|
||||||
msgid "expiring"
|
msgid "expiring"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:184
|
#: daemon/HTTPServer.cpp:190
|
||||||
msgid "established"
|
msgid "established"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:185
|
#: daemon/HTTPServer.cpp:191
|
||||||
msgid "unknown"
|
msgid "unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:187
|
#: daemon/HTTPServer.cpp:193
|
||||||
msgid "exploratory"
|
msgid "exploratory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:223
|
#: daemon/HTTPServer.cpp:229
|
||||||
msgid "<b>i2pd</b> webconsole"
|
msgid "<b>i2pd</b> webconsole"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:226
|
#: daemon/HTTPServer.cpp:232
|
||||||
msgid "Main page"
|
msgid "Main page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683
|
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:690
|
||||||
msgid "Router commands"
|
msgid "Router commands"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:228
|
#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:413
|
||||||
msgid "Local destinations"
|
#: daemon/HTTPServer.cpp:425
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:382
|
|
||||||
#: daemon/HTTPServer.cpp:463 daemon/HTTPServer.cpp:469
|
|
||||||
#: daemon/HTTPServer.cpp:599 daemon/HTTPServer.cpp:642
|
|
||||||
#: daemon/HTTPServer.cpp:646
|
|
||||||
msgid "LeaseSets"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652
|
|
||||||
msgid "Tunnels"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727
|
|
||||||
#: daemon/HTTPServer.cpp:743
|
|
||||||
msgid "Transit tunnels"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792
|
|
||||||
msgid "Transports"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:235
|
|
||||||
msgid "I2P tunnels"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854
|
|
||||||
#: daemon/HTTPServer.cpp:864
|
|
||||||
msgid "SAM sessions"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:253 daemon/HTTPServer.cpp:1254
|
|
||||||
#: daemon/HTTPServer.cpp:1257 daemon/HTTPServer.cpp:1260
|
|
||||||
#: daemon/HTTPServer.cpp:1274 daemon/HTTPServer.cpp:1319
|
|
||||||
#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1325
|
|
||||||
msgid "ERROR"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:260
|
|
||||||
msgid "OK"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:261
|
|
||||||
msgid "Testing"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:262
|
|
||||||
msgid "Firewalled"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284
|
|
||||||
#: daemon/HTTPServer.cpp:370
|
|
||||||
msgid "Unknown"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394
|
|
||||||
#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922
|
|
||||||
#: daemon/HTTPServer.cpp:931
|
|
||||||
msgid "Proxy"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:265
|
|
||||||
msgid "Mesh"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:268
|
|
||||||
msgid "Error"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:272
|
|
||||||
msgid "Clock skew"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:275
|
|
||||||
msgid "Offline"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:278
|
|
||||||
msgid "Symmetric NAT"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:290
|
|
||||||
msgid "Uptime"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:293
|
|
||||||
msgid "Network status"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:298
|
|
||||||
msgid "Network status v6"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311
|
|
||||||
msgid "Stopping in"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:318
|
|
||||||
msgid "Family"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:319
|
|
||||||
msgid "Tunnel creation success rate"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:320
|
|
||||||
msgid "Received"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325
|
|
||||||
#: daemon/HTTPServer.cpp:328
|
|
||||||
msgid "KiB/s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:323
|
|
||||||
msgid "Sent"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:326
|
|
||||||
msgid "Transit"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:329
|
|
||||||
msgid "Data path"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:332
|
|
||||||
msgid "Hidden content. Press on text to see."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:335
|
|
||||||
msgid "Router Ident"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:337
|
|
||||||
msgid "Router Family"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:338
|
|
||||||
msgid "Router Caps"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:339
|
|
||||||
msgid "Version"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:340
|
|
||||||
msgid "Our external address"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:348
|
|
||||||
msgid "supported"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:380
|
|
||||||
msgid "Routers"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:381
|
|
||||||
msgid "Floodfills"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908
|
|
||||||
msgid "Client Tunnels"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:389
|
|
||||||
msgid "Transit Tunnels"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:393
|
|
||||||
msgid "Services"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419
|
|
||||||
msgid "Local Destinations"
|
msgid "Local Destinations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:442
|
#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388
|
||||||
|
#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475
|
||||||
|
#: daemon/HTTPServer.cpp:606 daemon/HTTPServer.cpp:649
|
||||||
|
#: daemon/HTTPServer.cpp:653
|
||||||
|
msgid "LeaseSets"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:659
|
||||||
|
msgid "Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:395
|
||||||
|
#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:769
|
||||||
|
msgid "Transit Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:818
|
||||||
|
msgid "Transports"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:241
|
||||||
|
msgid "I2P tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:880
|
||||||
|
#: daemon/HTTPServer.cpp:890
|
||||||
|
msgid "SAM sessions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1280
|
||||||
|
#: daemon/HTTPServer.cpp:1283 daemon/HTTPServer.cpp:1286
|
||||||
|
#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1345
|
||||||
|
#: daemon/HTTPServer.cpp:1348 daemon/HTTPServer.cpp:1351
|
||||||
|
msgid "ERROR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:266
|
||||||
|
msgid "OK"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:267
|
||||||
|
msgid "Testing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:268
|
||||||
|
msgid "Firewalled"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290
|
||||||
|
#: daemon/HTTPServer.cpp:376
|
||||||
|
msgid "Unknown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400
|
||||||
|
#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:948
|
||||||
|
#: daemon/HTTPServer.cpp:957
|
||||||
|
msgid "Proxy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:271
|
||||||
|
msgid "Mesh"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:274
|
||||||
|
msgid "Error"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:278
|
||||||
|
msgid "Clock skew"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:281
|
||||||
|
msgid "Offline"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:284
|
||||||
|
msgid "Symmetric NAT"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:296
|
||||||
|
msgid "Uptime"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:299
|
||||||
|
msgid "Network status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:304
|
||||||
|
msgid "Network status v6"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317
|
||||||
|
msgid "Stopping in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:324
|
||||||
|
msgid "Family"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:325
|
||||||
|
msgid "Tunnel creation success rate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:326
|
||||||
|
msgid "Received"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. tr: Kibibit/s
|
||||||
|
#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331
|
||||||
|
#: daemon/HTTPServer.cpp:334
|
||||||
|
msgid "KiB/s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:329
|
||||||
|
msgid "Sent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:332
|
||||||
|
msgid "Transit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:335
|
||||||
|
msgid "Data path"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:338
|
||||||
|
msgid "Hidden content. Press on text to see."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:341
|
||||||
|
msgid "Router Ident"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:343
|
||||||
|
msgid "Router Family"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:344
|
||||||
|
msgid "Router Caps"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:345
|
||||||
|
msgid "Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:346
|
||||||
|
msgid "Our external address"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:354
|
||||||
|
msgid "supported"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:386
|
||||||
|
msgid "Routers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:387
|
||||||
|
msgid "Floodfills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:934
|
||||||
|
msgid "Client Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:399
|
||||||
|
msgid "Services"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:448
|
||||||
msgid "Encrypted B33 address"
|
msgid "Encrypted B33 address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:451
|
#: daemon/HTTPServer.cpp:457
|
||||||
msgid "Address registration line"
|
msgid "Address registration line"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:456
|
#: daemon/HTTPServer.cpp:462
|
||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:457
|
#: daemon/HTTPServer.cpp:463
|
||||||
msgid "Generate"
|
msgid "Generate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:458
|
#: daemon/HTTPServer.cpp:464
|
||||||
msgid ""
|
msgid ""
|
||||||
"<b>Note:</b> result string can be used only for registering 2LD domains "
|
"<b>Note:</b> result string can be used only for registering 2LD domains "
|
||||||
"(example.i2p). For registering subdomains please use i2pd-tools."
|
"(example.i2p). For registering subdomains please use i2pd-tools."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:464
|
#: daemon/HTTPServer.cpp:470
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:464
|
#: daemon/HTTPServer.cpp:470
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:464
|
#: daemon/HTTPServer.cpp:470
|
||||||
msgid "EncType"
|
msgid "EncType"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657
|
#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:664
|
||||||
msgid "Inbound tunnels"
|
msgid "Inbound tunnels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489
|
#. tr: Milliseconds
|
||||||
#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672
|
#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495
|
||||||
#: Means milliseconds
|
#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:679
|
||||||
msgid "ms"
|
msgid "ms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667
|
#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:674
|
||||||
msgid "Outbound tunnels"
|
msgid "Outbound tunnels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:496
|
#: daemon/HTTPServer.cpp:502
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:496
|
#: daemon/HTTPServer.cpp:502
|
||||||
msgid "Incoming"
|
msgid "Incoming"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506
|
#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512
|
||||||
msgid "Outgoing"
|
msgid "Outgoing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520
|
#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526
|
||||||
msgid "Destination"
|
msgid "Destination"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:504
|
#: daemon/HTTPServer.cpp:510
|
||||||
msgid "Amount"
|
msgid "Amount"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:511
|
#: daemon/HTTPServer.cpp:517
|
||||||
msgid "Incoming Tags"
|
msgid "Incoming Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522
|
#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528
|
||||||
msgid "Tags sessions"
|
msgid "Tags sessions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:520
|
#: daemon/HTTPServer.cpp:526
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584
|
#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:591
|
||||||
msgid "Local Destination"
|
msgid "Local Destination"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887
|
#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:913
|
||||||
msgid "Streams"
|
msgid "Streams"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:560
|
#: daemon/HTTPServer.cpp:567
|
||||||
msgid "Close stream"
|
msgid "Close stream"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:589
|
#: daemon/HTTPServer.cpp:596
|
||||||
msgid "I2CP session not found"
|
msgid "I2CP session not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:592
|
#: daemon/HTTPServer.cpp:599
|
||||||
msgid "I2CP is not enabled"
|
msgid "I2CP is not enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:618
|
#: daemon/HTTPServer.cpp:625
|
||||||
msgid "Invalid"
|
msgid "Invalid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:621
|
#: daemon/HTTPServer.cpp:628
|
||||||
msgid "Store type"
|
msgid "Store type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:622
|
#: daemon/HTTPServer.cpp:629
|
||||||
msgid "Expires"
|
msgid "Expires"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:627
|
#: daemon/HTTPServer.cpp:634
|
||||||
msgid "Non Expired Leases"
|
msgid "Non Expired Leases"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:630
|
#: daemon/HTTPServer.cpp:637
|
||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:631
|
#: daemon/HTTPServer.cpp:638
|
||||||
msgid "TunnelID"
|
msgid "TunnelID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:632
|
#: daemon/HTTPServer.cpp:639
|
||||||
msgid "EndDate"
|
msgid "EndDate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:642
|
#: daemon/HTTPServer.cpp:649
|
||||||
msgid "not floodfill"
|
msgid "not floodfill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:653
|
#: daemon/HTTPServer.cpp:660
|
||||||
msgid "Queue size"
|
msgid "Queue size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:684
|
#: daemon/HTTPServer.cpp:691
|
||||||
msgid "Run peer test"
|
msgid "Run peer test"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:687
|
#: daemon/HTTPServer.cpp:698
|
||||||
msgid "Decline transit tunnels"
|
msgid "Decline transit tunnels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:689
|
#: daemon/HTTPServer.cpp:700
|
||||||
msgid "Accept transit tunnels"
|
msgid "Accept transit tunnels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697
|
#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:709
|
||||||
msgid "Cancel graceful shutdown"
|
msgid "Cancel graceful shutdown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699
|
#: daemon/HTTPServer.cpp:706 daemon/HTTPServer.cpp:711
|
||||||
msgid "Start graceful shutdown"
|
msgid "Start graceful shutdown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:701
|
#: daemon/HTTPServer.cpp:714
|
||||||
msgid "Force shutdown"
|
msgid "Force shutdown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:704
|
#: daemon/HTTPServer.cpp:717
|
||||||
msgid ""
|
msgid ""
|
||||||
"<b>Note:</b> any action done here are not persistent and not changes your "
|
"<b>Note:</b> any action done here are not persistent and not changes your "
|
||||||
"config files."
|
"config files."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:706
|
#: daemon/HTTPServer.cpp:719
|
||||||
msgid "Logging level"
|
msgid "Logging level"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:714
|
#: daemon/HTTPServer.cpp:727
|
||||||
msgid "Transit tunnels limit"
|
msgid "Transit tunnels limit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:719
|
#: daemon/HTTPServer.cpp:732 daemon/HTTPServer.cpp:744
|
||||||
msgid "Change"
|
msgid "Change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:743
|
#: daemon/HTTPServer.cpp:736
|
||||||
|
msgid "Change language"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: daemon/HTTPServer.cpp:769
|
||||||
msgid "no transit tunnels currently built"
|
msgid "no transit tunnels currently built"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871
|
#: daemon/HTTPServer.cpp:874 daemon/HTTPServer.cpp:897
|
||||||
msgid "SAM disabled"
|
msgid "SAM disabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:864
|
#: daemon/HTTPServer.cpp:890
|
||||||
msgid "no sessions currently running"
|
msgid "no sessions currently running"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:877
|
#: daemon/HTTPServer.cpp:903
|
||||||
msgid "SAM session not found"
|
msgid "SAM session not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:882
|
#: daemon/HTTPServer.cpp:908
|
||||||
msgid "SAM Session"
|
msgid "SAM Session"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:939
|
#: daemon/HTTPServer.cpp:965
|
||||||
msgid "Server Tunnels"
|
msgid "Server Tunnels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:955
|
#: daemon/HTTPServer.cpp:981
|
||||||
msgid "Client Forwards"
|
msgid "Client Forwards"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:969
|
#: daemon/HTTPServer.cpp:995
|
||||||
msgid "Server Forwards"
|
msgid "Server Forwards"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1175
|
#: daemon/HTTPServer.cpp:1201
|
||||||
msgid "Unknown page"
|
msgid "Unknown page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1194
|
#: daemon/HTTPServer.cpp:1220
|
||||||
msgid "Invalid token"
|
msgid "Invalid token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309
|
#: daemon/HTTPServer.cpp:1278 daemon/HTTPServer.cpp:1335
|
||||||
#: daemon/HTTPServer.cpp:1337
|
#: daemon/HTTPServer.cpp:1371
|
||||||
msgid "SUCCESS"
|
msgid "SUCCESS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1252
|
#: daemon/HTTPServer.cpp:1278
|
||||||
msgid "Stream closed"
|
msgid "Stream closed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1254
|
#: daemon/HTTPServer.cpp:1280
|
||||||
msgid "Stream not found or already was closed"
|
msgid "Stream not found or already was closed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1257
|
#: daemon/HTTPServer.cpp:1283
|
||||||
msgid "Destination not found"
|
msgid "Destination not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1260
|
#: daemon/HTTPServer.cpp:1286
|
||||||
msgid "StreamID can't be null"
|
msgid "StreamID can't be null"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327
|
#: daemon/HTTPServer.cpp:1288 daemon/HTTPServer.cpp:1353
|
||||||
msgid "Return to destination page"
|
msgid "Return to destination page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276
|
#: daemon/HTTPServer.cpp:1289 daemon/HTTPServer.cpp:1302
|
||||||
msgid "You will be redirected back in 5 seconds"
|
#: daemon/HTTPServer.cpp:1373
|
||||||
|
msgid "You will be redirected in 5 seconds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1274
|
#: daemon/HTTPServer.cpp:1300
|
||||||
msgid "Transit tunnels count must not exceed 65535"
|
msgid "Transit tunnels count must not exceed 65535"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338
|
#: daemon/HTTPServer.cpp:1301 daemon/HTTPServer.cpp:1372
|
||||||
msgid "Back to commands list"
|
msgid "Back to commands list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1311
|
#: daemon/HTTPServer.cpp:1337
|
||||||
msgid "Register at reg.i2p"
|
msgid "Register at reg.i2p"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1312
|
#: daemon/HTTPServer.cpp:1338
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1312
|
#: daemon/HTTPServer.cpp:1338
|
||||||
msgid "A bit information about service on domain"
|
msgid "A bit information about service on domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1313
|
#: daemon/HTTPServer.cpp:1339
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1319
|
#: daemon/HTTPServer.cpp:1345
|
||||||
msgid "Domain can't end with .b32.i2p"
|
msgid "Domain can't end with .b32.i2p"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1322
|
#: daemon/HTTPServer.cpp:1348
|
||||||
msgid "Domain must end with .i2p"
|
msgid "Domain must end with .i2p"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1325
|
#: daemon/HTTPServer.cpp:1351
|
||||||
msgid "Such destination is not found"
|
msgid "Such destination is not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1333
|
#: daemon/HTTPServer.cpp:1367
|
||||||
msgid "Unknown command"
|
msgid "Unknown command"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1337
|
#: daemon/HTTPServer.cpp:1371
|
||||||
msgid "Command accepted"
|
msgid "Command accepted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: daemon/HTTPServer.cpp:1339
|
|
||||||
msgid "You will be redirected in 5 seconds"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: libi2pd_client/HTTPProxy.cpp:157
|
#: libi2pd_client/HTTPProxy.cpp:157
|
||||||
msgid "Proxy error"
|
msgid "Proxy error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -592,7 +592,7 @@ msgid "You may try to find this host on jump services below"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288
|
#: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288
|
||||||
#: libi2pd_client/HTTPProxy.cpp:365
|
#: libi2pd_client/HTTPProxy.cpp:322 libi2pd_client/HTTPProxy.cpp:365
|
||||||
msgid "Invalid request"
|
msgid "Invalid request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -637,10 +637,6 @@ msgstr ""
|
|||||||
msgid "to update record"
|
msgid "to update record"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libi2pd_client/HTTPProxy.cpp:322
|
|
||||||
msgid "Invalid Request"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: libi2pd_client/HTTPProxy.cpp:322
|
#: libi2pd_client/HTTPProxy.cpp:322
|
||||||
msgid "invalid request uri"
|
msgid "invalid request uri"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -5,3 +5,6 @@ msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(
|
|||||||
|
|
||||||
msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
|
msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n
|
||||||
{"$1", "$2"},\n
|
{"$1", "$2"},\n
|
||||||
|
|
||||||
|
^#:(.*)$\n
|
||||||
|
<to empty line>
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d
|
## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d
|
||||||
# tunnelsdir = /var/lib/i2pd/tunnels.d
|
# tunnelsdir = /var/lib/i2pd/tunnels.d
|
||||||
|
|
||||||
|
## Path to certificates used for verifying .su3, families
|
||||||
|
## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
|
||||||
|
# certsdir = /var/lib/i2pd/certificates
|
||||||
|
|
||||||
## Where to write pidfile (default: i2pd.pid, not used in Windows)
|
## Where to write pidfile (default: i2pd.pid, not used in Windows)
|
||||||
# pidfile = /run/i2pd.pid
|
# pidfile = /run/i2pd.pid
|
||||||
|
|
||||||
@ -104,7 +108,8 @@ port = 7070
|
|||||||
# user = i2pd
|
# user = i2pd
|
||||||
# pass = changeme
|
# pass = changeme
|
||||||
## Select webconsole language
|
## Select webconsole language
|
||||||
## Currently supported english (default), russian, turkmen and ukrainian languages
|
## Currently supported english (default), afrikaans, russian, turkmen and ukrainian languages
|
||||||
|
|
||||||
# lang = english
|
# lang = english
|
||||||
|
|
||||||
[httpproxy]
|
[httpproxy]
|
||||||
|
@ -94,6 +94,11 @@ namespace util
|
|||||||
|
|
||||||
i2p::config::GetOption("daemon", isDaemon);
|
i2p::config::GetOption("daemon", isDaemon);
|
||||||
|
|
||||||
|
std::string certsdir; i2p::config::GetOption("certsdir", certsdir);
|
||||||
|
i2p::fs::SetCertsDir(certsdir);
|
||||||
|
|
||||||
|
certsdir = i2p::fs::GetCertsDir();
|
||||||
|
|
||||||
std::string logs = ""; i2p::config::GetOption("log", logs);
|
std::string logs = ""; i2p::config::GetOption("log", logs);
|
||||||
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
||||||
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
||||||
@ -132,6 +137,7 @@ namespace util
|
|||||||
LogPrint(eLogNone, "i2pd v", VERSION, " starting");
|
LogPrint(eLogNone, "i2pd v", VERSION, " starting");
|
||||||
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);
|
||||||
|
LogPrint(eLogDebug, "FS: certificates directory: ", certsdir);
|
||||||
|
|
||||||
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
||||||
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
|
bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
|
||||||
|
@ -68,11 +68,11 @@ namespace http {
|
|||||||
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
<< " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
|
<< " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
|
||||||
<< " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
|
<< " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
|
||||||
<< " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n"
|
<< " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n"
|
||||||
<< " .menu { float: left; } .menu a, .commands a { display: block; }\r\n"
|
<< " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n"
|
||||||
<< " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
<< " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
<< " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
<< " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
<< " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n"
|
<< " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 48em; overflow: auto; }\r\n"
|
||||||
<< " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
|
<< " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||||
<< " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
|
<< " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
|
||||||
<< " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
<< " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
||||||
@ -84,19 +84,24 @@ namespace http {
|
|||||||
<< " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
|
<< " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
|
||||||
<< " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n"
|
<< " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n"
|
||||||
<< " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n"
|
<< " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n"
|
||||||
<< " @media screen and (max-width: 980px) {\r\n" /* adaptive style */
|
<< " @media screen and (max-width: 1150px) {\r\n" /* adaptive style */
|
||||||
|
<< " .wrapper { max-width: 58em; } .menu { max-width: 10em; }\r\n"
|
||||||
|
<< " .content { margin-left: 2em; max-width: 42em; }\r\n"
|
||||||
|
<< " }\r\n"
|
||||||
|
<< " @media screen and (max-width: 980px) {\r\n"
|
||||||
<< " body { padding: 1.5em 0 0 0; }\r\n"
|
<< " body { padding: 1.5em 0 0 0; }\r\n"
|
||||||
<< " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n"
|
<< " .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px;\r\n"
|
||||||
<< " text-align: center; }\r\n"
|
<< " text-align: center; }\r\n"
|
||||||
<< " .menu a, .commands a { padding: 2px; }\r\n"
|
<< " .menu a, .commands a { display: inline-block; padding: 4px; }\r\n"
|
||||||
<< " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
|
<< " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
|
||||||
<< " text-align: center; }\r\n"
|
<< " text-align: center; }\r\n"
|
||||||
<< " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
|
<< " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
|
||||||
<< " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
|
<< " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
|
||||||
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
<< " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
|
<< " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
|
||||||
<< " input { width: 35%; text-align: center; padding: 5px;\r\n"
|
<< " input, select { width: 35%; text-align: center; padding: 5px;\r\n"
|
||||||
<< " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
|
<< " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
|
||||||
|
<< " table.extaddr { margin: auto; text-align: unset; }\r\n"
|
||||||
<< " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
|
<< " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
|
||||||
<< " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
|
<< " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
|
||||||
<< " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
|
<< " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
|
||||||
@ -127,6 +132,7 @@ namespace http {
|
|||||||
const char HTTP_COMMAND_KILLSTREAM[] = "closestream";
|
const char HTTP_COMMAND_KILLSTREAM[] = "closestream";
|
||||||
const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit";
|
const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit";
|
||||||
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
|
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
|
||||||
|
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
|
||||||
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
||||||
const char HTTP_PARAM_ADDRESS[] = "address";
|
const char HTTP_PARAM_ADDRESS[] = "address";
|
||||||
|
|
||||||
@ -157,11 +163,11 @@ namespace http {
|
|||||||
s << std::fixed << std::setprecision(2);
|
s << std::fixed << std::setprecision(2);
|
||||||
auto numKBytes = (double) bytes / 1024;
|
auto numKBytes = (double) bytes / 1024;
|
||||||
if (numKBytes < 1024)
|
if (numKBytes < 1024)
|
||||||
s << numKBytes << " " << tr("KiB");
|
s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB");
|
||||||
else if (numKBytes < 1024 * 1024)
|
else if (numKBytes < 1024 * 1024)
|
||||||
s << numKBytes / 1024 << " " << tr("MiB");
|
s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB");
|
||||||
else
|
else
|
||||||
s << numKBytes / 1024 / 1024 << " " << tr("GiB");
|
s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
|
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
|
||||||
@ -185,7 +191,7 @@ namespace http {
|
|||||||
else stateText = tr("unknown");
|
else stateText = tr("unknown");
|
||||||
|
|
||||||
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
|
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
|
||||||
s << " " << (int) (bytes / 1024) << " " << tr("KiB") << "\r\n";
|
s << " " << (int) (bytes / 1024) << " " << tr(/* tr: Kibibit */ "KiB") << "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetLogLevel (const std::string& level)
|
static void SetLogLevel (const std::string& level)
|
||||||
@ -223,18 +229,18 @@ namespace http {
|
|||||||
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
|
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
|
||||||
"<div class=\"wrapper\">\r\n"
|
"<div class=\"wrapper\">\r\n"
|
||||||
"<div class=\"menu\">\r\n"
|
"<div class=\"menu\">\r\n"
|
||||||
" <a href=\"" << webroot << "\">" << tr("Main page") << "</a><br>\r\n"
|
" <a href=\"" << webroot << "\">" << tr("Main page") << "</a><br><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">" << tr("Router commands") << "</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">" << tr("Router commands") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">" << tr("Local destinations") << "</a>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">" << tr("Local Destinations") << "</a><br>\r\n";
|
||||||
if (i2p::context.IsFloodfill ())
|
if (i2p::context.IsFloodfill ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">" << tr("LeaseSets") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">" << tr("LeaseSets") << "</a><br>\r\n";
|
||||||
s <<
|
s <<
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">" << tr("Tunnels") << "</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">" << tr("Tunnels") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit tunnels") << "</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit Tunnels") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
|
||||||
if (i2p::client::context.GetSAMBridge ())
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
|
||||||
s <<
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=\"content\">";
|
"<div class=\"content\">";
|
||||||
@ -319,13 +325,13 @@ namespace http {
|
|||||||
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
||||||
s << "<b>" << tr("Received") << ":</b> ";
|
s << "<b>" << tr("Received") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>" << tr("Sent") << ":</b> ";
|
s << "<b>" << tr("Sent") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>" << tr("Transit") << ":</b> ";
|
s << "<b>" << tr("Transit") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
|
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
|
||||||
s << "<div class='slide'>";
|
s << "<div class='slide'>";
|
||||||
if((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
|
if((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
|
||||||
@ -476,7 +482,7 @@ namespace http {
|
|||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
|
s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )";
|
||||||
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
@ -534,7 +540,8 @@ namespace http {
|
|||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
ShowLeaseSetDestination (s, dest, token);
|
ShowLeaseSetDestination (s, dest, token);
|
||||||
// show streams
|
|
||||||
|
// Print table with streams information
|
||||||
s << "<table>\r\n<caption>" << tr("Streams") << "</caption>\r\n<thead>\r\n<tr>";
|
s << "<table>\r\n<caption>" << tr("Streams") << "</caption>\r\n<thead>\r\n<tr>";
|
||||||
s << "<th style=\"width:25px;\">StreamID</th>";
|
s << "<th style=\"width:25px;\">StreamID</th>";
|
||||||
s << "<th style=\"width:5px;\" \\>"; // Stream closing button column
|
s << "<th style=\"width:5px;\" \\>"; // Stream closing button column
|
||||||
@ -679,25 +686,29 @@ namespace http {
|
|||||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
/* commands */
|
|
||||||
s << "<b>" << tr("Router commands") << "</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
|
s << "<b>" << tr("Router commands") << "</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">" << tr("Run peer test") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">" << tr("Run peer test") << "</a><br>\r\n";
|
||||||
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
|
||||||
|
// s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
|
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">" << tr("Decline transit tunnels") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">" << tr("Decline transit tunnels") << "</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">" << tr("Accept transit tunnels") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">" << tr("Accept transit tunnels") << "</a><br>\r\n";
|
||||||
|
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (Daemon.gracefulShutdownInterval)
|
if (Daemon.gracefulShutdownInterval)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
||||||
#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a>\r\n";
|
||||||
s << "</div>";
|
s << "</div>";
|
||||||
|
|
||||||
@ -718,13 +729,26 @@ namespace http {
|
|||||||
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
|
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
|
||||||
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
|
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
|
||||||
s << "</form>\r\n<br>\r\n";
|
s << "</form>\r\n<br>\r\n";
|
||||||
|
|
||||||
|
std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language
|
||||||
|
s << "<b>" << tr("Change language") << "</b><br>\r\n";
|
||||||
|
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
|
||||||
|
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_SETLANGUAGE << "\">\r\n";
|
||||||
|
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
|
||||||
|
s << " <select name=\"lang\" id=\"lang\">\r\n";
|
||||||
|
for (const auto& it: i2p::i18n::languages)
|
||||||
|
s << " <option value=\"" << it.first << "\"" << ((it.first.compare(currLang) == 0) ? " selected" : "") << ">" << it.second.LocaleName << "</option>\r\n";
|
||||||
|
s << " </select>\r\n";
|
||||||
|
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
|
||||||
|
s << "</form>\r\n<br>\r\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowTransitTunnels (std::stringstream& s)
|
void ShowTransitTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
||||||
{
|
{
|
||||||
s << "<b>" << tr("Transit tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||||
{
|
{
|
||||||
s << "<div class=\"listitem\">\r\n";
|
s << "<div class=\"listitem\">\r\n";
|
||||||
@ -740,7 +764,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s << "<b>" << tr("Transit tunnels") << ":</b> " << tr("no transit tunnels currently built") << ".<br>\r\n";
|
s << "<b>" << tr("Transit Tunnels") << ":</b> " << tr("no transit tunnels currently built") << ".<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,7 +1284,7 @@ namespace http {
|
|||||||
s << "<b>" << tr("ERROR") << "</b>: " << tr("StreamID can't be null") << "<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("StreamID can't be null") << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
|
||||||
s << "<p>" << tr("You will be redirected back in 5 seconds") << "</b>";
|
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
|
||||||
redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
|
redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
return;
|
return;
|
||||||
@ -1273,7 +1297,7 @@ namespace http {
|
|||||||
else {
|
else {
|
||||||
s << "<b>" << tr("ERROR") << "</b>: " << tr("Transit tunnels count must not exceed 65535") << "\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Transit tunnels count must not exceed 65535") << "\r\n<br>\r\n<br>\r\n";
|
||||||
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n";
|
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n";
|
||||||
s << "<p>" << tr("You will be redirected back in 5 seconds") << "</b>";
|
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1281,7 +1305,7 @@ namespace http {
|
|||||||
else if (cmd == HTTP_COMMAND_GET_REG_STRING)
|
else if (cmd == HTTP_COMMAND_GET_REG_STRING)
|
||||||
{
|
{
|
||||||
std::string b32 = params["b32"];
|
std::string b32 = params["b32"];
|
||||||
std::string name = params["name"];
|
std::string name = i2p::http::UrlDecode(params["name"]);
|
||||||
|
|
||||||
i2p::data::IdentHash ident;
|
i2p::data::IdentHash ident;
|
||||||
ident.FromBase32 (b32);
|
ident.FromBase32 (b32);
|
||||||
@ -1327,6 +1351,14 @@ namespace http {
|
|||||||
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a>\r\n";
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a>\r\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (cmd == HTTP_COMMAND_SETLANGUAGE)
|
||||||
|
{
|
||||||
|
std::string lang = params["lang"];
|
||||||
|
std::string currLang = i2p::context.GetLanguage ()->GetLanguage();
|
||||||
|
|
||||||
|
if (currLang.compare(lang) != 0)
|
||||||
|
i2p::i18n::SetLanguage(lang);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res.code = 400;
|
res.code = 400;
|
||||||
|
@ -406,7 +406,7 @@ 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", std::to_string (i2p::context.GetUptime ()*1000LL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::VersionHandler (std::ostringstream& results)
|
void I2PControlService::VersionHandler (std::ostringstream& results)
|
||||||
|
@ -18,8 +18,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace i18n
|
namespace i18n
|
||||||
{
|
{
|
||||||
namespace afrikaans // language
|
namespace afrikaans // language namespace
|
||||||
{
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "afrikaans";
|
||||||
|
|
||||||
// See for language plural forms here:
|
// See for language plural forms here:
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
static int plural (int n) {
|
static int plural (int n) {
|
||||||
@ -65,7 +68,7 @@ namespace afrikaans // language
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
{
|
{
|
||||||
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // language
|
} // language
|
||||||
|
@ -19,8 +19,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace i18n
|
namespace i18n
|
||||||
{
|
{
|
||||||
namespace english // language
|
namespace english // language namespace
|
||||||
{
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "english";
|
||||||
|
|
||||||
// See for language plural forms here:
|
// See for language plural forms here:
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
static int plural (int n) {
|
static int plural (int n) {
|
||||||
@ -39,7 +42,7 @@ namespace english // language
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
{
|
{
|
||||||
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // language
|
} // language
|
||||||
|
13
i18n/I18N.h
13
i18n/I18N.h
@ -17,16 +17,11 @@ namespace i18n
|
|||||||
{
|
{
|
||||||
inline void SetLanguage(const std::string &lang)
|
inline void SetLanguage(const std::string &lang)
|
||||||
{
|
{
|
||||||
if (!lang.compare("afrikaans"))
|
const auto it = i2p::i18n::languages.find(lang);
|
||||||
i2p::context.SetLanguage (i2p::i18n::afrikaans::GetLocale());
|
if (it == i2p::i18n::languages.end()) // fallback
|
||||||
else if (!lang.compare("russian"))
|
|
||||||
i2p::context.SetLanguage (i2p::i18n::russian::GetLocale());
|
|
||||||
else if (!lang.compare("turkmen"))
|
|
||||||
i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale());
|
|
||||||
else if (!lang.compare("ukrainian"))
|
|
||||||
i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale());
|
|
||||||
else // fallback
|
|
||||||
i2p::context.SetLanguage (i2p::i18n::english::GetLocale());
|
i2p::context.SetLanguage (i2p::i18n::english::GetLocale());
|
||||||
|
else
|
||||||
|
i2p::context.SetLanguage (it->second.LocaleFunc());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string translate (const std::string& arg)
|
inline std::string translate (const std::string& arg)
|
||||||
|
@ -17,10 +17,17 @@ namespace i18n
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Locale (
|
Locale (
|
||||||
|
const std::string& language,
|
||||||
const std::map<std::string, std::string>& strings,
|
const std::map<std::string, std::string>& strings,
|
||||||
const std::map<std::string, std::vector<std::string>>& plurals,
|
const std::map<std::string, std::vector<std::string>>& plurals,
|
||||||
std::function<int(int)> formula
|
std::function<int(int)> formula
|
||||||
): m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
|
): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
|
||||||
|
|
||||||
|
// Get activated language name for webconsole
|
||||||
|
std::string GetLanguage() const
|
||||||
|
{
|
||||||
|
return m_Language;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetString (const std::string& arg) const
|
std::string GetString (const std::string& arg) const
|
||||||
{
|
{
|
||||||
@ -50,11 +57,18 @@ namespace i18n
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const std::string m_Language;
|
||||||
const std::map<std::string, std::string> m_Strings;
|
const std::map<std::string, std::string> m_Strings;
|
||||||
const std::map<std::string, std::vector<std::string>> m_Plurals;
|
const std::map<std::string, std::vector<std::string>> m_Plurals;
|
||||||
std::function<int(int)> m_Formula;
|
std::function<int(int)> m_Formula;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct langData
|
||||||
|
{
|
||||||
|
std::string LocaleName; //localized name
|
||||||
|
std::function<std::shared_ptr<const i2p::i18n::Locale> (void)> LocaleFunc;
|
||||||
|
};
|
||||||
|
|
||||||
// Add localization here with language name as namespace
|
// Add localization here with language name as namespace
|
||||||
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
@ -62,6 +76,18 @@ namespace i18n
|
|||||||
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* That map contains international language name lower-case and name in it's language
|
||||||
|
*/
|
||||||
|
static std::map<std::string, langData> languages
|
||||||
|
{
|
||||||
|
{ "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} },
|
||||||
|
{ "english", {"English", i2p::i18n::english::GetLocale} },
|
||||||
|
{ "russian", {"русский язык", i2p::i18n::russian::GetLocale} },
|
||||||
|
{ "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} },
|
||||||
|
{ "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} },
|
||||||
|
};
|
||||||
|
|
||||||
} // i18n
|
} // i18n
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
|
310
i18n/Russian.cpp
310
i18n/Russian.cpp
@ -18,8 +18,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace i18n
|
namespace i18n
|
||||||
{
|
{
|
||||||
namespace russian // language
|
namespace russian // language namespace
|
||||||
{
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "russian";
|
||||||
|
|
||||||
// See for language plural forms here:
|
// See for language plural forms here:
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
static int plural (int n) {
|
static int plural (int n) {
|
||||||
@ -28,23 +31,152 @@ namespace russian // language
|
|||||||
|
|
||||||
static std::map<std::string, std::string> strings
|
static std::map<std::string, std::string> strings
|
||||||
{
|
{
|
||||||
// HTTP Proxy
|
{"Disabled", "Выключено"},
|
||||||
|
{"Enabled", "Включено"},
|
||||||
|
{"KiB", "КиБ"},
|
||||||
|
{"MiB", "МиБ"},
|
||||||
|
{"GiB", "ГиБ"},
|
||||||
|
{"building", "строится"},
|
||||||
|
{"failed", "неудачный"},
|
||||||
|
{"expiring", "истекает"},
|
||||||
|
{"established", "работает"},
|
||||||
|
{"unknown", "неизвестно"},
|
||||||
|
{"exploratory", "исследовательский"},
|
||||||
|
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
|
||||||
|
{"Main page", "Главная"},
|
||||||
|
{"Router commands", "Команды роутера"},
|
||||||
|
{"Local destinations", "Локальные назначения"},
|
||||||
|
{"LeaseSets", "Лизсеты"},
|
||||||
|
{"Tunnels", "Туннели"},
|
||||||
|
{"Transit tunnels", "Транзитные туннели"},
|
||||||
|
{"Transports", "Транспорты"},
|
||||||
|
{"I2P tunnels", "I2P туннели"},
|
||||||
|
{"SAM sessions", "SAM сессии"},
|
||||||
|
{"ERROR", "ОШИБКА"},
|
||||||
|
{"OK", "OK"},
|
||||||
|
{"Testing", "Тестирование"},
|
||||||
|
{"Firewalled", "Заблокировано извне"},
|
||||||
|
{"Unknown", "Неизвестно"},
|
||||||
|
{"Proxy", "Прокси"},
|
||||||
|
{"Mesh", "MESH-сеть"},
|
||||||
|
{"Error", "Ошибка"},
|
||||||
|
{"Clock skew", "Не точное время"},
|
||||||
|
{"Offline", "Оффлайн"},
|
||||||
|
{"Symmetric NAT", "Симметричный NAT"},
|
||||||
|
{"Uptime", "В сети"},
|
||||||
|
{"Network status", "Сетевой статус"},
|
||||||
|
{"Network status v6", "Сетевой статус v6"},
|
||||||
|
{"Stopping in", "Остановка через"},
|
||||||
|
{"Family", "Семейство"},
|
||||||
|
{"Tunnel creation success rate", "Успешно построенных туннелей"},
|
||||||
|
{"Received", "Получено"},
|
||||||
|
{"KiB/s", "КиБ/с"},
|
||||||
|
{"Sent", "Отправлено"},
|
||||||
|
{"Transit", "Транзит"},
|
||||||
|
{"Data path", "Путь к данным"},
|
||||||
|
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
|
||||||
|
{"Router Ident", "Идентификатор роутера"},
|
||||||
|
{"Router Family", "Семейство роутера"},
|
||||||
|
{"Router Caps", "Флаги роутера"},
|
||||||
|
{"Version", "Версия"},
|
||||||
|
{"Our external address", "Наш внешний адрес"},
|
||||||
|
{"supported", "поддерживается"},
|
||||||
|
{"Routers", "Роутеры"},
|
||||||
|
{"Floodfills", "Флудфилы"},
|
||||||
|
{"Client Tunnels", "Клиентские туннели"},
|
||||||
|
{"Transit Tunnels", "Транзитные туннели"},
|
||||||
|
{"Services", "Сервисы"},
|
||||||
|
{"Local Destinations", "Локальные назначения"},
|
||||||
|
{"Encrypted B33 address", "Шифрованные B33 адреса"},
|
||||||
|
{"Address registration line", "Строка регистрации адреса"},
|
||||||
|
{"Domain", "Домен"},
|
||||||
|
{"Generate", "Сгенерировать"},
|
||||||
|
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Примечание:</b> полученная строка может быть использована только для регистрации доменов второго уровня (example.i2p). Для регистрации поддоменов используйте i2pd-tools."},
|
||||||
|
{"Address", "Адрес"},
|
||||||
|
{"Type", "Тип"},
|
||||||
|
{"EncType", "ТипШифр"},
|
||||||
|
{"Inbound tunnels", "Входящие туннели"},
|
||||||
|
{"ms", "мс"},
|
||||||
|
{"Outbound tunnels", "Исходящие туннели"},
|
||||||
|
{"Tags", "Теги"},
|
||||||
|
{"Incoming", "Входящие"},
|
||||||
|
{"Outgoing", "Исходящие"},
|
||||||
|
{"Destination", "Назначение"},
|
||||||
|
{"Amount", "Количество"},
|
||||||
|
{"Incoming Tags", "Входящие Теги"},
|
||||||
|
{"Tags sessions", "Сессии Тегов"},
|
||||||
|
{"Status", "Статус"},
|
||||||
|
{"Local Destination", "Локальное назначение"},
|
||||||
|
{"Streams", "Стримы"},
|
||||||
|
{"Close stream", "Закрыть стрим"},
|
||||||
|
{"I2CP session not found", "I2CP сессия не найдена"},
|
||||||
|
{"I2CP is not enabled", "I2CP не включен"},
|
||||||
|
{"Invalid", "Некорректный"},
|
||||||
|
{"Store type", "Тип хранилища"},
|
||||||
|
{"Expires", "Истекает"},
|
||||||
|
{"Non Expired Leases", "Не истекшие Lease-ы"},
|
||||||
|
{"Gateway", "Шлюз"},
|
||||||
|
{"TunnelID", "ID туннеля"},
|
||||||
|
{"EndDate", "Заканчивается"},
|
||||||
|
{"not floodfill", "не флудфил"},
|
||||||
|
{"Queue size", "Размер очереди"},
|
||||||
|
{"Run peer test", "Запустить тестирование"},
|
||||||
|
{"Decline transit tunnels", "Отклонять транзитные туннели"},
|
||||||
|
{"Accept transit tunnels", "Принимать транзитные туннели"},
|
||||||
|
{"Cancel graceful shutdown", "Отменить плавную остановку"},
|
||||||
|
{"Start graceful shutdown", "Запустить плавную остановку"},
|
||||||
|
{"Force shutdown", "Принудительная остановка"},
|
||||||
|
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
|
||||||
|
{"Logging level", "Уровень логирования"},
|
||||||
|
{"Transit tunnels limit", "Лимит транзитных туннелей"},
|
||||||
|
{"Change", "Изменить"},
|
||||||
|
{"Change language", "Изменение языка"},
|
||||||
|
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
|
||||||
|
{"SAM disabled", "SAM выключен"},
|
||||||
|
{"no sessions currently running", "нет запущенных сессий"},
|
||||||
|
{"SAM session not found", "SAM сессия не найдена"},
|
||||||
|
{"SAM Session", "SAM сессия"},
|
||||||
|
{"Server Tunnels", "Серверные туннели"},
|
||||||
|
{"Client Forwards", "Клиентские перенаправления"},
|
||||||
|
{"Server Forwards", "Серверные перенаправления"},
|
||||||
|
{"Unknown page", "Неизвестная страница"},
|
||||||
|
{"Invalid token", "Неверный токен"},
|
||||||
|
{"SUCCESS", "УСПЕШНО"},
|
||||||
|
{"Stream closed", "Стрим закрыт"},
|
||||||
|
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
|
||||||
|
{"Destination not found", "Точка назначения не найдена"},
|
||||||
|
{"StreamID can't be null", "StreamID не может быть пустым"},
|
||||||
|
{"Return to destination page", "Вернуться на страницу точки назначения"},
|
||||||
|
{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
|
||||||
|
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
|
||||||
|
{"Back to commands list", "Вернуться к списку команд"},
|
||||||
|
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
|
||||||
|
{"Description", "Описание"},
|
||||||
|
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
|
||||||
|
{"Submit", "Отправить"},
|
||||||
|
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
|
||||||
|
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
|
||||||
|
{"Such destination is not found", "Такая точка назначения не найдена"},
|
||||||
|
{"Unknown command", "Неизвестная команда"},
|
||||||
|
{"Command accepted", "Команда принята"},
|
||||||
|
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
|
||||||
{"Proxy error", "Ошибка прокси"},
|
{"Proxy error", "Ошибка прокси"},
|
||||||
{"Proxy info", "Информация прокси"},
|
{"Proxy info", "Информация прокси"},
|
||||||
{"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"},
|
{"Proxy error: Host not found", "Ошибка прокси: Узел не найден"},
|
||||||
{"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"},
|
{"Remote host not found in router's addressbook", "Запрошенный узел не найден в адресной книге роутера"},
|
||||||
{"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"},
|
{"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"},
|
||||||
{"Invalid request", "Некорректный запрос"},
|
{"Invalid request", "Некорректный запрос"},
|
||||||
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
|
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
|
||||||
{"addresshelper is not supported", "addresshelper не поддерживается"},
|
{"addresshelper is not supported", "addresshelper не поддерживается"},
|
||||||
{"Host", "Адрес"},
|
{"Host", "Узел"},
|
||||||
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
|
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
|
||||||
{"already in router's addressbook", "уже в адресной книге роутера"},
|
|
||||||
{"Click", "Нажмите"},
|
{"Click", "Нажмите"},
|
||||||
{"here", "здесь"},
|
{"here", "здесь"},
|
||||||
{"to proceed", "чтобы продолжить"},
|
{"to proceed", "чтобы продолжить"},
|
||||||
{"to update record", "чтобы обновить запись"},
|
|
||||||
{"Addresshelper found", "Найден addresshelper"},
|
{"Addresshelper found", "Найден addresshelper"},
|
||||||
|
{"already in router's addressbook", "уже в адресной книге роутера"},
|
||||||
|
{"to update record", "чтобы обновить запись"},
|
||||||
|
{"Invalid Request", "неверный запрос"},
|
||||||
{"invalid request uri", "некорректный URI запроса"},
|
{"invalid request uri", "некорректный URI запроса"},
|
||||||
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
|
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
|
||||||
{"Outproxy failure", "Ошибка внешнего прокси"},
|
{"Outproxy failure", "Ошибка внешнего прокси"},
|
||||||
@ -63,169 +195,13 @@ namespace russian // language
|
|||||||
{"cannot connect", "не удалось подключиться"},
|
{"cannot connect", "не удалось подключиться"},
|
||||||
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
|
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
|
||||||
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
|
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
|
||||||
{"Host is down", "Адрес недоступен"},
|
{"Host is down", "Узел недоступен"},
|
||||||
{"Can't create connection to requested host, it may be down. Please try again later.",
|
{"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
|
||||||
"Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."},
|
|
||||||
|
|
||||||
// Webconsole //
|
|
||||||
// cssStyles
|
|
||||||
{"Disabled", "Выключено"},
|
|
||||||
{"Enabled", "Включено"},
|
|
||||||
// ShowTraffic
|
|
||||||
{"KiB", "КиБ"},
|
|
||||||
{"MiB", "МиБ"},
|
|
||||||
{"GiB", "ГиБ"},
|
|
||||||
// ShowTunnelDetails
|
|
||||||
{"building", "строится"},
|
|
||||||
{"failed", "неудачный"},
|
|
||||||
{"expiring", "истекает"},
|
|
||||||
{"established", "работает"},
|
|
||||||
{"exploratory", "исследовательский"},
|
|
||||||
{"unknown", "неизвестно"},
|
|
||||||
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
|
|
||||||
// ShowPageHead
|
|
||||||
{"Main page", "Главная"},
|
|
||||||
{"Router commands", "Команды роутера"},
|
|
||||||
{"Local destinations", "Локальные назнач."},
|
|
||||||
{"LeaseSets", "Лизсеты"},
|
|
||||||
{"Tunnels", "Туннели"},
|
|
||||||
{"Transit tunnels", "Транзит. туннели"},
|
|
||||||
{"Transports", "Транспорты"},
|
|
||||||
{"I2P tunnels", "I2P туннели"},
|
|
||||||
{"SAM sessions", "SAM сессии"},
|
|
||||||
// Network Status
|
|
||||||
{"OK", "OK"},
|
|
||||||
{"Testing", "Тестирование"},
|
|
||||||
{"Firewalled", "Заблокировано извне"},
|
|
||||||
{"Unknown", "Неизвестно"},
|
|
||||||
{"Proxy", "Прокси"},
|
|
||||||
{"Mesh", "MESH-сеть"},
|
|
||||||
{"Error", "Ошибка"},
|
|
||||||
{"Clock skew", "Не точное время"},
|
|
||||||
{"Offline", "Оффлайн"},
|
|
||||||
{"Symmetric NAT", "Симметричный NAT"},
|
|
||||||
// Status
|
|
||||||
{"Uptime", "В сети"},
|
|
||||||
{"Network status", "Сетевой статус"},
|
|
||||||
{"Network status v6", "Сетевой статус v6"},
|
|
||||||
{"Stopping in", "Остановка через"},
|
|
||||||
{"Family", "Семейство"},
|
|
||||||
{"Tunnel creation success rate", "Успешно построенных туннелей"},
|
|
||||||
{"Received", "Получено"},
|
|
||||||
{"Sent", "Отправлено"},
|
|
||||||
{"Transit", "Транзит"},
|
|
||||||
{"KiB/s", "КиБ/с"},
|
|
||||||
{"Data path", "Путь к данным"},
|
|
||||||
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
|
|
||||||
{"Router Ident", "Идентификатор роутера"},
|
|
||||||
{"Router Family", "Семейство роутера"},
|
|
||||||
{"Router Caps", "Флаги роутера"},
|
|
||||||
{"Version", "Версия"},
|
|
||||||
{"Our external address", "Наш внешний адрес"},
|
|
||||||
{"supported", "поддерживается"},
|
|
||||||
{"Routers", "Роутеры"},
|
|
||||||
{"Floodfills", "Флудфилы"},
|
|
||||||
{"LeaseSets", "Лизсеты"},
|
|
||||||
{"Client Tunnels", "Клиентские туннели"},
|
|
||||||
{"Transit Tunnels", "Транзитные туннели"},
|
|
||||||
{"Services", "Сервисы"},
|
|
||||||
// ShowLocalDestinations
|
|
||||||
{"Local Destinations", "Локальные назначения"},
|
|
||||||
// ShowLeaseSetDestination
|
|
||||||
{"Encrypted B33 address", "Шифрованные B33 адреса"},
|
|
||||||
{"Address registration line", "Строка регистрации адреса"},
|
|
||||||
{"Domain", "Домен"},
|
|
||||||
{"Generate", "Сгенерировать"},
|
|
||||||
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.",
|
|
||||||
"<b>Примечание:</b> полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."},
|
|
||||||
{"Address", "Адрес"},
|
|
||||||
{"Type", "Тип"},
|
|
||||||
{"EncType", "ТипШифр"},
|
|
||||||
{"Inbound tunnels", "Входящие туннели"},
|
|
||||||
{"Outbound tunnels", "Исходящие туннели"},
|
|
||||||
{"ms", "мс"}, // milliseconds
|
|
||||||
{"Tags", "Теги"},
|
|
||||||
{"Incoming", "Входящие"},
|
|
||||||
{"Outgoing", "Исходящие"},
|
|
||||||
{"Destination", "Назначение"},
|
|
||||||
{"Amount", "Количество"},
|
|
||||||
{"Incoming Tags", "Входящие Теги"},
|
|
||||||
{"Tags sessions", "Сессии Тегов"},
|
|
||||||
{"Status", "Статус"},
|
|
||||||
// ShowLocalDestination
|
|
||||||
{"Local Destination", "Локальное назначение"},
|
|
||||||
{"Streams", "Стримы"},
|
|
||||||
{"Close stream", "Закрыть стрим"},
|
|
||||||
// ShowI2CPLocalDestination
|
|
||||||
{"I2CP session not found", "I2CP сессия не найдена"},
|
|
||||||
{"I2CP is not enabled", "I2CP не включен"},
|
|
||||||
// ShowLeasesSets
|
|
||||||
{"Invalid", "Некорректный"},
|
|
||||||
{"Store type", "Тип хранилища"},
|
|
||||||
{"Expires", "Истекает"},
|
|
||||||
{"Non Expired Leases", "Не истекшие Lease-ы"},
|
|
||||||
{"Gateway", "Шлюз"},
|
|
||||||
{"TunnelID", "ID туннеля"},
|
|
||||||
{"EndDate", "Заканчивается"},
|
|
||||||
{"not floodfill", "не флудфил"},
|
|
||||||
// ShowTunnels
|
|
||||||
{"Queue size", "Размер очереди"},
|
|
||||||
// ShowCommands
|
|
||||||
{"Run peer test", "Запустить тестирование"},
|
|
||||||
{"Decline transit tunnels", "Отклонять транзитные туннели"},
|
|
||||||
{"Accept transit tunnels", "Принимать транзитные туннели"},
|
|
||||||
{"Cancel graceful shutdown", "Отменить плавную остановку"},
|
|
||||||
{"Start graceful shutdown", "Запустить плавную остановку"},
|
|
||||||
{"Force shutdown", "Принудительная остановка"},
|
|
||||||
{"<b>Note:</b> any action done here are not persistent and not changes your config files.",
|
|
||||||
"<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
|
|
||||||
{"Logging level", "Уровень логирования"},
|
|
||||||
{"Transit tunnels limit", "Лимит транзитных туннелей"},
|
|
||||||
{"Change", "Изменить"},
|
|
||||||
// ShowTransitTunnels
|
|
||||||
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
|
|
||||||
// ShowSAMSessions/ShowSAMSession
|
|
||||||
{"SAM disabled", "SAM выключен"},
|
|
||||||
{"SAM session not found", "SAM сессия не найдена"},
|
|
||||||
{"no sessions currently running", "нет запущенных сессий"},
|
|
||||||
{"SAM Session", "SAM сессия"},
|
|
||||||
// ShowI2PTunnels
|
|
||||||
{"Server Tunnels", "Серверные туннели"},
|
|
||||||
{"Client Forwards", "Клиентские перенаправления"},
|
|
||||||
{"Server Forwards", "Серверные перенаправления"},
|
|
||||||
// HandlePage
|
|
||||||
{"Unknown page", "Неизвестная страница"},
|
|
||||||
// HandleCommand, ShowError
|
|
||||||
{"Invalid token", "Неверный токен"},
|
|
||||||
{"SUCCESS", "УСПЕШНО"},
|
|
||||||
{"ERROR", "ОШИБКА"},
|
|
||||||
{"Unknown command", "Неизвестная команда"},
|
|
||||||
{"Command accepted", "Команда принята"},
|
|
||||||
{"Back to commands list", "Вернуться к списку команд"},
|
|
||||||
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
|
|
||||||
// HTTP_COMMAND_KILLSTREAM
|
|
||||||
{"Stream closed", "Стрим закрыт"},
|
|
||||||
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
|
|
||||||
{"Destination not found", "Точка назначения не найдена"},
|
|
||||||
{"StreamID can't be null", "StreamID не может быть пустым"},
|
|
||||||
{"Return to destination page", "Вернуться на страницу точки назначения"},
|
|
||||||
{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
|
|
||||||
// HTTP_COMMAND_LIMITTRANSIT
|
|
||||||
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
|
|
||||||
// HTTP_COMMAND_GET_REG_STRING
|
|
||||||
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
|
|
||||||
{"Description", "Описание"},
|
|
||||||
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
|
|
||||||
{"Submit", "Отправить"},
|
|
||||||
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
|
|
||||||
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
|
|
||||||
{"Such destination is not found", "Такая точка назначения не найдена"},
|
|
||||||
{"", ""},
|
{"", ""},
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::map<std::string, std::vector<std::string>> plurals
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
{
|
{
|
||||||
// ShowUptime
|
|
||||||
{"days", {"день", "дня", "дней"}},
|
{"days", {"день", "дня", "дней"}},
|
||||||
{"hours", {"час", "часа", "часов"}},
|
{"hours", {"час", "часа", "часов"}},
|
||||||
{"minutes", {"минуту", "минуты", "минут"}},
|
{"minutes", {"минуту", "минуты", "минут"}},
|
||||||
@ -235,7 +211,7 @@ namespace russian // language
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
{
|
{
|
||||||
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // language
|
} // language
|
||||||
|
@ -18,8 +18,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace i18n
|
namespace i18n
|
||||||
{
|
{
|
||||||
namespace turkmen // language
|
namespace turkmen // language namespace
|
||||||
{
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "turkmen";
|
||||||
|
|
||||||
// See for language plural forms here:
|
// See for language plural forms here:
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
static int plural (int n) {
|
static int plural (int n) {
|
||||||
@ -234,7 +237,7 @@ namespace turkmen // language
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
{
|
{
|
||||||
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // language
|
} // language
|
||||||
|
@ -18,8 +18,11 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace i18n
|
namespace i18n
|
||||||
{
|
{
|
||||||
namespace ukrainian // language
|
namespace ukrainian // language namespace
|
||||||
{
|
{
|
||||||
|
// language name in lowercase
|
||||||
|
static std::string language = "ukrainian";
|
||||||
|
|
||||||
// See for language plural forms here:
|
// See for language plural forms here:
|
||||||
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
static int plural (int n) {
|
static int plural (int n) {
|
||||||
@ -28,23 +31,151 @@ namespace ukrainian // language
|
|||||||
|
|
||||||
static std::map<std::string, std::string> strings
|
static std::map<std::string, std::string> strings
|
||||||
{
|
{
|
||||||
// HTTP Proxy
|
{"Disabled", "Вимкнуто"},
|
||||||
|
{"Enabled", "Увімкнуто"},
|
||||||
|
{"KiB", "КіБ"},
|
||||||
|
{"MiB", "МіБ"},
|
||||||
|
{"GiB", "ГіБ"},
|
||||||
|
{"building", "будується"},
|
||||||
|
{"failed", "невдалий"},
|
||||||
|
{"expiring", "завершується"},
|
||||||
|
{"established", "працює"},
|
||||||
|
{"unknown", "невідомо"},
|
||||||
|
{"exploratory", "дослідницький"},
|
||||||
|
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
|
||||||
|
{"Main page", "Головна"},
|
||||||
|
{"Router commands", "Команди маршрутизатора"},
|
||||||
|
{"Local destinations", "Локальні призначення"},
|
||||||
|
{"LeaseSets", "Лізсети"},
|
||||||
|
{"Tunnels", "Тунелі"},
|
||||||
|
{"Transit tunnels", "Транзитні тунелі"},
|
||||||
|
{"Transports", "Транспорти"},
|
||||||
|
{"I2P tunnels", "I2P тунелі"},
|
||||||
|
{"SAM sessions", "SAM сесії"},
|
||||||
|
{"ERROR", "ПОМИЛКА"},
|
||||||
|
{"OK", "OK"},
|
||||||
|
{"Testing", "Тестування"},
|
||||||
|
{"Firewalled", "Заблоковано ззовні"},
|
||||||
|
{"Unknown", "Невідомо"},
|
||||||
|
{"Proxy", "Проксі"},
|
||||||
|
{"Mesh", "MESH-мережа"},
|
||||||
|
{"Error", "Помилка"},
|
||||||
|
{"Clock skew", "Неточний час"},
|
||||||
|
{"Offline", "Офлайн"},
|
||||||
|
{"Symmetric NAT", "Симетричний NAT"},
|
||||||
|
{"Uptime", "У мережі"},
|
||||||
|
{"Network status", "Мережевий статус"},
|
||||||
|
{"Network status v6", "Мережевий статус v6"},
|
||||||
|
{"Stopping in", "Зупинка через"},
|
||||||
|
{"Family", "Сімейство"},
|
||||||
|
{"Tunnel creation success rate", "Успішно побудованих тунелів"},
|
||||||
|
{"Received", "Отримано"},
|
||||||
|
{"KiB/s", "КіБ/с"},
|
||||||
|
{"Sent", "Відправлено"},
|
||||||
|
{"Transit", "Транзит"},
|
||||||
|
{"Data path", "Шлях до даних"},
|
||||||
|
{"Hidden content. Press on text to see.", "Прихований вміст. Щоб відобразити, натисніть на текст."},
|
||||||
|
{"Router Ident", "Ідентифікатор маршрутизатора"},
|
||||||
|
{"Router Family", "Сімейство маршрутизатора"},
|
||||||
|
{"Router Caps", "Прапорці маршрутизатора"},
|
||||||
|
{"Version", "Версія"},
|
||||||
|
{"Our external address", "Наша зовнішня адреса"},
|
||||||
|
{"supported", "підтримується"},
|
||||||
|
{"Routers", "Маршрутизатори"},
|
||||||
|
{"Floodfills", "Флудфіли"},
|
||||||
|
{"Client Tunnels", "Клієнтські Тунелі"},
|
||||||
|
{"Transit Tunnels", "Транзитні Тунелі"},
|
||||||
|
{"Services", "Сервіси"},
|
||||||
|
{"Local Destinations", "Локальні Призначення"},
|
||||||
|
{"Encrypted B33 address", "Шифровані B33 адреси"},
|
||||||
|
{"Address registration line", "Рядок реєстрації адреси"},
|
||||||
|
{"Domain", "Домен"},
|
||||||
|
{"Generate", "Згенерувати"},
|
||||||
|
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Примітка:</b> отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня (example.i2p). Для реєстрації піддоменів використовуйте i2pd-tools."},
|
||||||
|
{"Address", "Адреса"},
|
||||||
|
{"Type", "Тип"},
|
||||||
|
{"EncType", "ТипШифр"},
|
||||||
|
{"Inbound tunnels", "Вхідні тунелі"},
|
||||||
|
{"ms", "мс"},
|
||||||
|
{"Outbound tunnels", "Вихідні тунелі"},
|
||||||
|
{"Tags", "Теги"},
|
||||||
|
{"Incoming", "Вхідні"},
|
||||||
|
{"Outgoing", "Вихідні"},
|
||||||
|
{"Destination", "Призначення"},
|
||||||
|
{"Amount", "Кількість"},
|
||||||
|
{"Incoming Tags", "Вхідні Теги"},
|
||||||
|
{"Tags sessions", "Сесії Тегів"},
|
||||||
|
{"Status", "Статус"},
|
||||||
|
{"Local Destination", "Локальні Призначення"},
|
||||||
|
{"Streams", "Потоки"},
|
||||||
|
{"Close stream", "Закрити потік"},
|
||||||
|
{"I2CP session not found", "I2CP сесія не знайдена"},
|
||||||
|
{"I2CP is not enabled", "I2CP не увікнуто"},
|
||||||
|
{"Invalid", "Некоректний"},
|
||||||
|
{"Store type", "Тип сховища"},
|
||||||
|
{"Expires", "Завершується"},
|
||||||
|
{"Non Expired Leases", "Не завершені Lease-и"},
|
||||||
|
{"Gateway", "Шлюз"},
|
||||||
|
{"TunnelID", "ID тунеля"},
|
||||||
|
{"EndDate", "Закінчується"},
|
||||||
|
{"not floodfill", "не флудфіл"},
|
||||||
|
{"Queue size", "Розмір черги"},
|
||||||
|
{"Run peer test", "Запустити тестування"},
|
||||||
|
{"Decline transit tunnels", "Відхиляти транзитні тунелі"},
|
||||||
|
{"Accept transit tunnels", "Ухвалювати транзитні тунелі"},
|
||||||
|
{"Cancel graceful shutdown", "Скасувати плавну зупинку"},
|
||||||
|
{"Start graceful shutdown", "Запустити плавну зупинку"},
|
||||||
|
{"Force shutdown", "Примусова зупинка"},
|
||||||
|
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Примітка:</b> будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."},
|
||||||
|
{"Logging level", "Рівень логування"},
|
||||||
|
{"Transit tunnels limit", "Обмеження транзитних тунелів"},
|
||||||
|
{"Change", "Змінити"},
|
||||||
|
{"no transit tunnels currently built", "немає побудованих транзитних тунелів"},
|
||||||
|
{"SAM disabled", "SAM вимкнуто"},
|
||||||
|
{"no sessions currently running", "немає запущених сесій"},
|
||||||
|
{"SAM session not found", "SAM сесія не знайдена"},
|
||||||
|
{"SAM Session", "SAM сесія"},
|
||||||
|
{"Server Tunnels", "Серверні Тунелі"},
|
||||||
|
{"Client Forwards", "Клієнтські Переспрямування"},
|
||||||
|
{"Server Forwards", "Серверні Переспрямування"},
|
||||||
|
{"Unknown page", "Невідома сторінка"},
|
||||||
|
{"Invalid token", "Невірний токен"},
|
||||||
|
{"SUCCESS", "УСПІШНО"},
|
||||||
|
{"Stream closed", "Потік зачинений"},
|
||||||
|
{"Stream not found or already was closed", "Потік не знайдений або вже зачинений"},
|
||||||
|
{"Destination not found", "Точка призначення не знайдена"},
|
||||||
|
{"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"},
|
||||||
|
{"Return to destination page", "Повернутися на сторінку точки призначення"},
|
||||||
|
{"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"},
|
||||||
|
{"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"},
|
||||||
|
{"Back to commands list", "Повернутися до списку команд"},
|
||||||
|
{"Register at reg.i2p", "Зареєструвати на reg.i2p"},
|
||||||
|
{"Description", "Опис"},
|
||||||
|
{"A bit information about service on domain", "Трохи інформації про сервіс на домені"},
|
||||||
|
{"Submit", "Надіслати"},
|
||||||
|
{"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"},
|
||||||
|
{"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"},
|
||||||
|
{"Such destination is not found", "Така точка призначення не знайдена"},
|
||||||
|
{"Unknown command", "Невідома команда"},
|
||||||
|
{"Command accepted", "Команда прийнята"},
|
||||||
|
{"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"},
|
||||||
{"Proxy error", "Помилка проксі"},
|
{"Proxy error", "Помилка проксі"},
|
||||||
{"Proxy info", "Інформація проксі"},
|
{"Proxy info", "Інформація проксі"},
|
||||||
{"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"},
|
{"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"},
|
||||||
{"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі роутера"},
|
{"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі маршрутизатора"},
|
||||||
{"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"},
|
{"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"},
|
||||||
{"Invalid request", "Некоректний запит"},
|
{"Invalid request", "Некоректний запит"},
|
||||||
{"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"},
|
{"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"},
|
||||||
{"addresshelper is not supported", "addresshelper не підтримується"},
|
{"addresshelper is not supported", "addresshelper не підтримується"},
|
||||||
{"Host", "Адреса"},
|
{"Host", "Адреса"},
|
||||||
{"added to router's addressbook from helper", "доданий в адресну книгу роутера через хелпер"},
|
{"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"},
|
||||||
{"already in router's addressbook", "вже в адресній книзі роутера"},
|
|
||||||
{"Click", "Натисніть"},
|
{"Click", "Натисніть"},
|
||||||
{"here", "тут"},
|
{"here", "тут"},
|
||||||
{"to proceed", "щоб продовжити"},
|
{"to proceed", "щоб продовжити"},
|
||||||
{"to update record", "щоб оновити запис"},
|
|
||||||
{"Addresshelper found", "Знайдено addresshelper"},
|
{"Addresshelper found", "Знайдено addresshelper"},
|
||||||
|
{"already in router's addressbook", "вже в адресній книзі маршрутизатора"},
|
||||||
|
{"to update record", "щоб оновити запис"},
|
||||||
|
{"Invalid Request", "Некоректний Запит"},
|
||||||
{"invalid request uri", "некоректний URI запиту"},
|
{"invalid request uri", "некоректний URI запиту"},
|
||||||
{"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"},
|
{"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"},
|
||||||
{"Outproxy failure", "Помилка зовнішнього проксі"},
|
{"Outproxy failure", "Помилка зовнішнього проксі"},
|
||||||
@ -64,169 +195,14 @@ namespace ukrainian // language
|
|||||||
{"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"},
|
{"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"},
|
||||||
{"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"},
|
{"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"},
|
||||||
{"Host is down", "Вузол недоступний"},
|
{"Host is down", "Вузол недоступний"},
|
||||||
{"Can't create connection to requested host, it may be down. Please try again later.",
|
{"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."},
|
||||||
"Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."},
|
|
||||||
|
|
||||||
// Webconsole //
|
|
||||||
// cssStyles
|
|
||||||
{"Disabled", "Вимкнуто"},
|
|
||||||
{"Enabled", "Увімкнуто"},
|
|
||||||
// ShowTraffic
|
|
||||||
{"KiB", "КіБ"},
|
|
||||||
{"MiB", "МіБ"},
|
|
||||||
{"GiB", "ГіБ"},
|
|
||||||
// ShowTunnelDetails
|
|
||||||
{"building", "будується"},
|
|
||||||
{"failed", "невдалий"},
|
|
||||||
{"expiring", "завершується"},
|
|
||||||
{"established", "працює"},
|
|
||||||
{"exploratory", "дослідницький"},
|
|
||||||
{"unknown", "невідомо"},
|
|
||||||
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
|
|
||||||
// ShowPageHead
|
|
||||||
{"Main page", "Головна"},
|
|
||||||
{"Router commands", "Команди роутера"},
|
|
||||||
{"Local destinations", "Локальні призначення"},
|
|
||||||
{"LeaseSets", "Лізсети"},
|
|
||||||
{"Tunnels", "Тунелі"},
|
|
||||||
{"Transit tunnels", "Транзитні тунелі"},
|
|
||||||
{"Transports", "Транспорти"},
|
|
||||||
{"I2P tunnels", "I2P тунелі"},
|
|
||||||
{"SAM sessions", "SAM сесії"},
|
|
||||||
// Network Status
|
|
||||||
{"OK", "OK"},
|
|
||||||
{"Testing", "Тестування"},
|
|
||||||
{"Firewalled", "Заблоковано ззовні"},
|
|
||||||
{"Unknown", "Невідомо"},
|
|
||||||
{"Proxy", "Проксі"},
|
|
||||||
{"Mesh", "MESH-мережа"},
|
|
||||||
{"Error", "Помилка"},
|
|
||||||
{"Clock skew", "Неточний час"},
|
|
||||||
{"Offline", "Офлайн"},
|
|
||||||
{"Symmetric NAT", "Симетричний NAT"},
|
|
||||||
// Status
|
|
||||||
{"Uptime", "В мережі"},
|
|
||||||
{"Network status", "Мережевий статус"},
|
|
||||||
{"Network status v6", "Мережевий статус v6"},
|
|
||||||
{"Stopping in", "Зупинка через"},
|
|
||||||
{"Family", "Сімейство"},
|
|
||||||
{"Tunnel creation success rate", "Успішно побудованих тунелів"},
|
|
||||||
{"Received", "Отримано"},
|
|
||||||
{"Sent", "Відправлено"},
|
|
||||||
{"Transit", "Транзит"},
|
|
||||||
{"KiB/s", "КіБ/с"},
|
|
||||||
{"Data path", "Шлях до даних"},
|
|
||||||
{"Hidden content. Press on text to see.", "Прихований вміст. Натисніть на текст щоб відобразити."},
|
|
||||||
{"Router Ident", "Ідентифікатор Роутера"},
|
|
||||||
{"Router Family", "Сімейство Роутера"},
|
|
||||||
{"Router Caps", "Прапорці Роутера"},
|
|
||||||
{"Version", "Версія"},
|
|
||||||
{"Our external address", "Наша зовнішня адреса"},
|
|
||||||
{"supported", "підтримується"},
|
|
||||||
{"Routers", "Роутери"},
|
|
||||||
{"Floodfills", "Флудфіли"},
|
|
||||||
{"Client Tunnels", "Клієнтські Тунелі"},
|
|
||||||
{"Transit Tunnels", "Транзитні Тунелі"},
|
|
||||||
{"Services", "Сервіси"},
|
|
||||||
// ShowLocalDestinations
|
|
||||||
{"Local Destinations", "Локальні Призначення"},
|
|
||||||
// ShowLeaseSetDestination
|
|
||||||
{"Encrypted B33 address", "Шифровані B33 адреси"},
|
|
||||||
{"Address registration line", "Рядок реєстрації адреси"},
|
|
||||||
{"Domain", "Домен"},
|
|
||||||
{"Generate", "Згенерувати"},
|
|
||||||
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.",
|
|
||||||
"<b>Примітка:</b> отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня. Для реєстрації піддоменів використовуйте i2pd-tools."},
|
|
||||||
{"Address", "Адреса"},
|
|
||||||
{"Type", "Тип"},
|
|
||||||
{"EncType", "ТипШифр"},
|
|
||||||
{"Inbound tunnels", "Вхідні тунелі"},
|
|
||||||
{"Outbound tunnels", "Вихідні тунелі"},
|
|
||||||
{"ms", "мс"}, // milliseconds
|
|
||||||
{"Tags", "Теги"},
|
|
||||||
{"Incoming", "Вхідні"},
|
|
||||||
{"Outgoing", "Вихідні"},
|
|
||||||
{"Destination", "Призначення"},
|
|
||||||
{"Amount", "Кількість"},
|
|
||||||
{"Incoming Tags", "Вхідні Теги"},
|
|
||||||
{"Tags sessions", "Сесії тегів"},
|
|
||||||
{"Status", "Статус"},
|
|
||||||
// ShowLocalDestination
|
|
||||||
{"Local Destination", "Локальні Призначення"},
|
|
||||||
{"Streams", "Потоки"},
|
|
||||||
{"Close stream", "Закрити потік"},
|
|
||||||
// ShowI2CPLocalDestination
|
|
||||||
{"I2CP session not found", "I2CP сесія не знайдена"},
|
|
||||||
{"I2CP is not enabled", "I2CP не увікнуто"},
|
|
||||||
// ShowLeasesSets
|
|
||||||
{"Invalid", "Некоректний"},
|
|
||||||
{"Store type", "Тип сховища"},
|
|
||||||
{"Expires", "Завершується"},
|
|
||||||
{"Non Expired Leases", "Не завершені Lease-и"},
|
|
||||||
{"Gateway", "Шлюз"},
|
|
||||||
{"TunnelID", "ID тунеля"},
|
|
||||||
{"EndDate", "Закінчується"},
|
|
||||||
{"not floodfill", "не флудфіл"},
|
|
||||||
// ShowTunnels
|
|
||||||
{"Queue size", "Розмір черги"},
|
|
||||||
// ShowCommands
|
|
||||||
{"Run peer test", "Запустити тестування"},
|
|
||||||
{"Decline transit tunnels", "Відхиляти транзитні тунелі"},
|
|
||||||
{"Accept transit tunnels", "Ухвалювати транзитні тунелі"},
|
|
||||||
{"Cancel graceful shutdown", "Скасувати плавну зупинку"},
|
|
||||||
{"Start graceful shutdown", "Запустити плавну зупинку"},
|
|
||||||
{"Force shutdown", "Примусова зупинка"},
|
|
||||||
{"<b>Note:</b> any action done here are not persistent and not changes your config files.",
|
|
||||||
"<b>Примітка:</b> будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."},
|
|
||||||
{"Logging level", "Рівень логування"},
|
|
||||||
{"Transit tunnels limit", "Обмеження транзитних тунелів"},
|
|
||||||
{"Change", "Змінити"},
|
|
||||||
// ShowTransitTunnels
|
|
||||||
{"no transit tunnels currently built", "немає побудованих транзитних тунелів"},
|
|
||||||
// ShowSAMSessions/ShowSAMSession
|
|
||||||
{"SAM disabled", "SAM вимкнуто"},
|
|
||||||
{"SAM session not found", "SAM сесія не знайдена"},
|
|
||||||
{"no sessions currently running", "немає запущених сесій"},
|
|
||||||
{"SAM Session", "SAM сесія"},
|
|
||||||
// ShowI2PTunnels
|
|
||||||
{"Server Tunnels", "Серверні Тунелі"},
|
|
||||||
{"Client Forwards", "Клієнтські Переспрямування"},
|
|
||||||
{"Server Forwards", "Серверні Переспрямування"},
|
|
||||||
// HandlePage
|
|
||||||
{"Unknown page", "Невідома сторінка"},
|
|
||||||
// HandleCommand, ShowError
|
|
||||||
{"Invalid token", "Невірний токен"},
|
|
||||||
{"SUCCESS", "УСПІШНО"},
|
|
||||||
{"ERROR", "ПОМИЛКА"},
|
|
||||||
{"Unknown command", "Невідома команда"},
|
|
||||||
{"Command accepted", "Команда прийнята"},
|
|
||||||
{"Back to commands list", "Повернутися до списку команд"},
|
|
||||||
{"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"},
|
|
||||||
// HTTP_COMMAND_KILLSTREAM
|
|
||||||
{"Stream closed", "Потік зачинений"},
|
|
||||||
{"Stream not found or already was closed", "Потік не знайдений або вже зачинений"},
|
|
||||||
{"Destination not found", "Точка призначення не знайдена"},
|
|
||||||
{"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"},
|
|
||||||
{"Return to destination page", "Повернутися на сторінку точки призначення"},
|
|
||||||
{"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"},
|
|
||||||
// HTTP_COMMAND_LIMITTRANSIT
|
|
||||||
{"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"},
|
|
||||||
// HTTP_COMMAND_GET_REG_STRING
|
|
||||||
{"Register at reg.i2p", "Зареєструвати на reg.i2p"},
|
|
||||||
{"Description", "Опис"},
|
|
||||||
{"A bit information about service on domain", "Трохи інформації про сервіс на домені"},
|
|
||||||
{"Submit", "Надіслати"},
|
|
||||||
{"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"},
|
|
||||||
{"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"},
|
|
||||||
{"Such destination is not found", "Така точка призначення не знайдена"},
|
|
||||||
{"", ""},
|
{"", ""},
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::map<std::string, std::vector<std::string>> plurals
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
{
|
{
|
||||||
// ShowUptime
|
{"days", {"день", "дня", "днів"}},
|
||||||
{"days", {"день", "дня", "днів"}},
|
{"hours", {"годину", "години", "годин"}},
|
||||||
{"hours", {"годину", "години", "годин"}},
|
|
||||||
{"minutes", {"хвилину", "хвилини", "хвилин"}},
|
{"minutes", {"хвилину", "хвилини", "хвилин"}},
|
||||||
{"seconds", {"секунду", "секунди", "секунд"}},
|
{"seconds", {"секунду", "секунди", "секунд"}},
|
||||||
{"", {"", "", ""}},
|
{"", {"", "", ""}},
|
||||||
@ -234,7 +210,7 @@ namespace ukrainian // language
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
|
||||||
{
|
{
|
||||||
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
|
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // language
|
} // language
|
||||||
|
@ -37,6 +37,7 @@ namespace config {
|
|||||||
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
|
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
|
||||||
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
|
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
|
||||||
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
|
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
|
||||||
|
("certsdir", value<std::string>()->default_value(""), "Path to certificates used for verifying .su3, families (default: ~/.i2pd/certificates or /var/lib/i2pd/certificates")
|
||||||
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
|
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
|
||||||
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
|
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
|
||||||
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
||||||
@ -284,7 +285,7 @@ namespace config {
|
|||||||
|
|
||||||
options_description meshnets("Meshnet transports options");
|
options_description meshnets("Meshnet transports options");
|
||||||
meshnets.add_options()
|
meshnets.add_options()
|
||||||
("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)")
|
("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)")
|
||||||
("meshnets.yggaddress", value<std::string>()->default_value(""), "Yggdrasil address to publish")
|
("meshnets.yggaddress", value<std::string>()->default_value(""), "Yggdrasil address to publish")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ namespace i2p {
|
|||||||
namespace fs {
|
namespace fs {
|
||||||
std::string appName = "i2pd";
|
std::string appName = "i2pd";
|
||||||
std::string dataDir = "";
|
std::string dataDir = "";
|
||||||
|
std::string certsDir = "";
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::string dirSep = "\\";
|
std::string dirSep = "\\";
|
||||||
#else
|
#else
|
||||||
@ -42,6 +43,10 @@ namespace fs {
|
|||||||
return dataDir;
|
return dataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string & GetCertsDir () {
|
||||||
|
return certsDir;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string GetUTF8DataDir () {
|
const std::string GetUTF8DataDir () {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
boost::filesystem::wpath path (dataDir);
|
boost::filesystem::wpath path (dataDir);
|
||||||
@ -126,6 +131,21 @@ namespace fs {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetCertsDir(const std::string & cmdline_certsdir) {
|
||||||
|
if (cmdline_certsdir != "")
|
||||||
|
{
|
||||||
|
if (cmdline_certsdir[cmdline_certsdir.length()-1] == '/')
|
||||||
|
certsDir = cmdline_certsdir.substr(0, cmdline_certsdir.size()-1); // strip trailing slash
|
||||||
|
else
|
||||||
|
certsDir = cmdline_certsdir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
certsDir = i2p::fs::DataDirPath("certificates");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool Init() {
|
bool Init() {
|
||||||
if (!boost::filesystem::exists(dataDir))
|
if (!boost::filesystem::exists(dataDir))
|
||||||
boost::filesystem::create_directory(dataDir);
|
boost::filesystem::create_directory(dataDir);
|
||||||
|
18
libi2pd/FS.h
18
libi2pd/FS.h
@ -75,6 +75,9 @@ namespace fs {
|
|||||||
/** @brief Returns datadir path */
|
/** @brief Returns datadir path */
|
||||||
const std::string & GetDataDir();
|
const std::string & GetDataDir();
|
||||||
|
|
||||||
|
/** @brief Returns certsdir path */
|
||||||
|
const std::string & GetCertsDir();
|
||||||
|
|
||||||
/** @brief Returns datadir path in UTF-8 encoding */
|
/** @brief Returns datadir path in UTF-8 encoding */
|
||||||
const std::string GetUTF8DataDir();
|
const std::string GetUTF8DataDir();
|
||||||
|
|
||||||
@ -90,7 +93,20 @@ namespace fs {
|
|||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||||
*/
|
*/
|
||||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set certsdir either from cmdline option or using autodetection
|
||||||
|
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
|
||||||
|
*
|
||||||
|
* Examples of autodetected paths:
|
||||||
|
*
|
||||||
|
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\certificates
|
||||||
|
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\certificates
|
||||||
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
|
||||||
|
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
|
||||||
|
*/
|
||||||
|
void SetCertsDir(const std::string & cmdline_certsdir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create subdirectories inside datadir
|
* @brief Create subdirectories inside datadir
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Family.h"
|
#include "Family.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -98,7 +99,8 @@ namespace data
|
|||||||
|
|
||||||
void Families::LoadCertificates ()
|
void Families::LoadCertificates ()
|
||||||
{
|
{
|
||||||
std::string certDir = i2p::fs::DataDirPath("certificates", "family");
|
std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "family";
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
int numCertificates = 0;
|
int numCertificates = 0;
|
||||||
|
|
||||||
|
@ -36,10 +36,21 @@ namespace i2p
|
|||||||
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
return std::make_shared<I2NPMessageBuffer<I2NP_MAX_SHORT_MESSAGE_SIZE> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage ()
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint)
|
||||||
{
|
{
|
||||||
auto msg = new I2NPMessageBuffer<i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12
|
I2NPMessage * msg = nullptr;
|
||||||
msg->Align (12);
|
if (endpoint)
|
||||||
|
{
|
||||||
|
// should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet
|
||||||
|
msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6
|
||||||
|
msg->Align (6);
|
||||||
|
msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = new I2NPMessageBuffer<i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12
|
||||||
|
msg->Align (12);
|
||||||
|
}
|
||||||
return std::shared_ptr<I2NPMessage>(msg);
|
return std::shared_ptr<I2NPMessage>(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,7 +702,7 @@ 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 (false);
|
||||||
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;
|
||||||
@ -699,7 +710,7 @@ namespace i2p
|
|||||||
|
|
||||||
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 (false);
|
||||||
htobe32buf (msg->GetPayload (), tunnelID);
|
htobe32buf (msg->GetPayload (), tunnelID);
|
||||||
msg->len += 4; // tunnelID
|
msg->len += 4; // tunnelID
|
||||||
msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4);
|
msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4);
|
||||||
@ -707,9 +718,9 @@ namespace i2p
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg ()
|
std::shared_ptr<I2NPMessage> CreateEmptyTunnelDataMsg (bool endpoint)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPTunnelMessage ();
|
auto msg = NewI2NPTunnelMessage (endpoint);
|
||||||
msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE;
|
msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE;
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace i2p
|
|||||||
|
|
||||||
// TunnelBuild
|
// TunnelBuild
|
||||||
const size_t TUNNEL_BUILD_RECORD_SIZE = 528;
|
const size_t TUNNEL_BUILD_RECORD_SIZE = 528;
|
||||||
const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 236;
|
const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218;
|
||||||
|
|
||||||
//BuildRequestRecordClearText
|
//BuildRequestRecordClearText
|
||||||
const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0;
|
const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0;
|
||||||
@ -113,7 +113,7 @@ namespace i2p
|
|||||||
const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1;
|
const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1;
|
||||||
const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4;
|
const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4;
|
||||||
const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4;
|
const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4;
|
||||||
const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172;
|
const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154;
|
||||||
|
|
||||||
enum I2NPMessageType
|
enum I2NPMessageType
|
||||||
{
|
{
|
||||||
@ -278,7 +278,7 @@ namespace tunnel
|
|||||||
|
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPShortMessage ();
|
||||||
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage ();
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
||||||
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);
|
||||||
@ -307,7 +307,7 @@ namespace tunnel
|
|||||||
|
|
||||||
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 (bool endpoint);
|
||||||
|
|
||||||
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,
|
||||||
|
@ -497,7 +497,8 @@ namespace data
|
|||||||
|
|
||||||
void Reseeder::LoadCertificates ()
|
void Reseeder::LoadCertificates ()
|
||||||
{
|
{
|
||||||
std::string certDir = i2p::fs::DataDirPath("certificates", "reseed");
|
std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "reseed";
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
int numCertificates = 0;
|
int numCertificates = 0;
|
||||||
|
|
||||||
|
@ -470,7 +470,8 @@ namespace i2p
|
|||||||
uint8_t caps = m_RouterInfo.GetCaps ();
|
uint8_t caps = m_RouterInfo.GetCaps ();
|
||||||
caps &= ~i2p::data::RouterInfo::eReachable;
|
caps &= ~i2p::data::RouterInfo::eReachable;
|
||||||
caps |= i2p::data::RouterInfo::eUnreachable;
|
caps |= i2p::data::RouterInfo::eUnreachable;
|
||||||
caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill
|
if (v6 || !SupportsV6 ())
|
||||||
|
caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill
|
||||||
m_RouterInfo.SetCaps (caps);
|
m_RouterInfo.SetCaps (caps);
|
||||||
}
|
}
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
@ -568,16 +569,21 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published);
|
bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published);
|
||||||
if (ntcp2 && ntcp2Published)
|
if (ntcp2)
|
||||||
{
|
{
|
||||||
std::string ntcp2Host;
|
if (ntcp2Published)
|
||||||
if (!i2p::config::IsDefault ("ntcp2.addressv6"))
|
{
|
||||||
i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
|
std::string ntcp2Host;
|
||||||
|
if (!i2p::config::IsDefault ("ntcp2.addressv6"))
|
||||||
|
i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
|
||||||
|
else
|
||||||
|
ntcp2Host = "::1";
|
||||||
|
uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
|
||||||
|
if (!ntcp2Port) ntcp2Port = port;
|
||||||
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ntcp2Host = "::1";
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6);
|
||||||
uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
|
|
||||||
if (!ntcp2Port) ntcp2Port = port;
|
|
||||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_RouterInfo.EnableV6 ();
|
m_RouterInfo.EnableV6 ();
|
||||||
@ -632,7 +638,7 @@ namespace i2p
|
|||||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port);
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
|
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_RouterInfo.EnableV4 ();
|
m_RouterInfo.EnableV4 ();
|
||||||
|
@ -840,21 +840,33 @@ namespace data
|
|||||||
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;
|
||||||
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
||||||
|
m_ReachableTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
||||||
m_Addresses->push_back(std::move(addr));
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port)
|
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||||
|
const boost::asio::ip::address& host, int port, uint8_t caps)
|
||||||
{
|
{
|
||||||
auto addr = std::make_shared<Address>();
|
auto addr = std::make_shared<Address>();
|
||||||
addr->host = host;
|
addr->host = host;
|
||||||
addr->port = port;
|
addr->port = port;
|
||||||
addr->transportStyle = eTransportNTCP;
|
addr->transportStyle = eTransportNTCP;
|
||||||
addr->caps = 0;
|
addr->caps = caps;
|
||||||
addr->date = 0;
|
addr->date = 0;
|
||||||
addr->ntcp2.reset (new NTCP2Ext ());
|
addr->ntcp2.reset (new NTCP2Ext ());
|
||||||
if (port) addr->published = true;
|
if (port) addr->published = true;
|
||||||
memcpy (addr->ntcp2->staticKey, staticKey, 32);
|
memcpy (addr->ntcp2->staticKey, staticKey, 32);
|
||||||
memcpy (addr->ntcp2->iv, iv, 16);
|
memcpy (addr->ntcp2->iv, iv, 16);
|
||||||
|
if (addr->IsV4 ())
|
||||||
|
{
|
||||||
|
m_SupportedTransports |= eNTCP2V4;
|
||||||
|
if (addr->published) m_ReachableTransports |= eNTCP2V4;
|
||||||
|
}
|
||||||
|
if (addr->IsV6 ())
|
||||||
|
{
|
||||||
|
m_SupportedTransports |= eNTCP2V6;
|
||||||
|
if (addr->published) m_ReachableTransports |= eNTCP2V6;
|
||||||
|
}
|
||||||
m_Addresses->push_back(std::move(addr));
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,8 @@ namespace data
|
|||||||
std::shared_ptr<const Address> GetYggdrasilAddress () const;
|
std::shared_ptr<const Address> GetYggdrasilAddress () const;
|
||||||
|
|
||||||
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);
|
||||||
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0);
|
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||||
|
const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0);
|
||||||
bool AddIntroducer (const Introducer& introducer);
|
bool AddIntroducer (const Introducer& introducer);
|
||||||
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||||
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
|
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
|
||||||
|
@ -1050,6 +1050,7 @@ namespace stream
|
|||||||
it.second->Terminate (false); // we delete here
|
it.second->Terminate (false); // we delete here
|
||||||
m_Streams.clear ();
|
m_Streams.clear ();
|
||||||
m_IncomingStreams.clear ();
|
m_IncomingStreams.clear ();
|
||||||
|
m_LastStream = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1058,9 +1059,16 @@ namespace stream
|
|||||||
uint32_t sendStreamID = packet->GetSendStreamID ();
|
uint32_t sendStreamID = packet->GetSendStreamID ();
|
||||||
if (sendStreamID)
|
if (sendStreamID)
|
||||||
{
|
{
|
||||||
auto it = m_Streams.find (sendStreamID);
|
if (!m_LastStream || sendStreamID != m_LastStream->GetRecvStreamID ())
|
||||||
if (it != m_Streams.end ())
|
{
|
||||||
it->second->HandleNextPacket (packet);
|
auto it = m_Streams.find (sendStreamID);
|
||||||
|
if (it != m_Streams.end ())
|
||||||
|
m_LastStream = it->second;
|
||||||
|
else
|
||||||
|
m_LastStream = nullptr;
|
||||||
|
}
|
||||||
|
if (m_LastStream)
|
||||||
|
m_LastStream->HandleNextPacket (packet);
|
||||||
else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ())
|
else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ())
|
||||||
{
|
{
|
||||||
// ping
|
// ping
|
||||||
@ -1166,7 +1174,7 @@ namespace stream
|
|||||||
{
|
{
|
||||||
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, port);
|
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, port);
|
||||||
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
||||||
m_Streams[s->GetRecvStreamID ()] = s;
|
m_Streams.emplace (s->GetRecvStreamID (), s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,8 +1182,8 @@ namespace stream
|
|||||||
{
|
{
|
||||||
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this);
|
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this);
|
||||||
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
||||||
m_Streams[s->GetRecvStreamID ()] = s;
|
m_Streams.emplace (s->GetRecvStreamID (), s);
|
||||||
m_IncomingStreams[receiveStreamID] = s;
|
m_IncomingStreams.emplace (receiveStreamID, s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1186,6 +1194,7 @@ namespace stream
|
|||||||
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
std::unique_lock<std::mutex> l(m_StreamsMutex);
|
||||||
m_Streams.erase (stream->GetRecvStreamID ());
|
m_Streams.erase (stream->GetRecvStreamID ());
|
||||||
m_IncomingStreams.erase (stream->GetSendStreamID ());
|
m_IncomingStreams.erase (stream->GetSendStreamID ());
|
||||||
|
if (m_LastStream == stream) m_LastStream = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2021, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -297,12 +297,13 @@ namespace stream
|
|||||||
uint16_t m_LocalPort;
|
uint16_t m_LocalPort;
|
||||||
bool m_Gzip; // gzip compression of data messages
|
bool m_Gzip; // gzip compression of data messages
|
||||||
std::mutex m_StreamsMutex;
|
std::mutex m_StreamsMutex;
|
||||||
std::map<uint32_t, std::shared_ptr<Stream> > m_Streams; // sendStreamID->stream
|
std::unordered_map<uint32_t, std::shared_ptr<Stream> > m_Streams; // sendStreamID->stream
|
||||||
std::map<uint32_t, std::shared_ptr<Stream> > m_IncomingStreams; // receiveStreamID->stream
|
std::unordered_map<uint32_t, std::shared_ptr<Stream> > m_IncomingStreams; // receiveStreamID->stream
|
||||||
|
std::shared_ptr<Stream> m_LastStream;
|
||||||
Acceptor m_Acceptor;
|
Acceptor m_Acceptor;
|
||||||
std::list<std::shared_ptr<Stream> > m_PendingIncomingStreams;
|
std::list<std::shared_ptr<Stream> > m_PendingIncomingStreams;
|
||||||
boost::asio::deadline_timer m_PendingIncomingTimer;
|
boost::asio::deadline_timer m_PendingIncomingTimer;
|
||||||
std::map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
|
std::unordered_map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
|
||||||
|
|
||||||
i2p::util::MemoryPool<Packet> m_PacketsPool;
|
i2p::util::MemoryPool<Packet> m_PacketsPool;
|
||||||
i2p::util::MemoryPool<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> > m_I2NPMsgsPool;
|
i2p::util::MemoryPool<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> > m_I2NPMsgsPool;
|
||||||
|
@ -39,7 +39,7 @@ namespace tunnel
|
|||||||
|
|
||||||
void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg)
|
void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg)
|
||||||
{
|
{
|
||||||
auto newMsg = CreateEmptyTunnelDataMsg ();
|
auto newMsg = CreateEmptyTunnelDataMsg (false);
|
||||||
EncryptTunnelMsg (tunnelMsg, newMsg);
|
EncryptTunnelMsg (tunnelMsg, newMsg);
|
||||||
|
|
||||||
m_NumTransmittedBytes += tunnelMsg->GetLength ();
|
m_NumTransmittedBytes += tunnelMsg->GetLength ();
|
||||||
@ -87,7 +87,7 @@ namespace tunnel
|
|||||||
|
|
||||||
void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg)
|
void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg)
|
||||||
{
|
{
|
||||||
auto newMsg = CreateEmptyTunnelDataMsg ();
|
auto newMsg = CreateEmptyTunnelDataMsg (true);
|
||||||
EncryptTunnelMsg (tunnelMsg, newMsg);
|
EncryptTunnelMsg (tunnelMsg, newMsg);
|
||||||
|
|
||||||
LogPrint (eLogDebug, "TransitTunnel: handle msg for endpoint ", GetTunnelID ());
|
LogPrint (eLogDebug, "TransitTunnel: handle msg for endpoint ", GetTunnelID ());
|
||||||
|
@ -401,7 +401,7 @@ namespace transport
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto r = netdb.FindRouter (ident);
|
auto r = netdb.FindRouter (ident);
|
||||||
if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return;
|
if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
||||||
|
@ -234,7 +234,7 @@ namespace tunnel
|
|||||||
void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg)
|
void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive
|
if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive
|
||||||
auto newMsg = CreateEmptyTunnelDataMsg ();
|
auto newMsg = CreateEmptyTunnelDataMsg (true);
|
||||||
EncryptTunnelMsg (msg, newMsg);
|
EncryptTunnelMsg (msg, newMsg);
|
||||||
newMsg->from = shared_from_this ();
|
newMsg->from = shared_from_this ();
|
||||||
m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg);
|
m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg);
|
||||||
|
@ -52,24 +52,25 @@ namespace tunnel
|
|||||||
bool isFollowOnFragment = flag & 0x80, isLastFragment = true;
|
bool isFollowOnFragment = flag & 0x80, isLastFragment = true;
|
||||||
uint32_t msgID = 0;
|
uint32_t msgID = 0;
|
||||||
int fragmentNum = 0;
|
int fragmentNum = 0;
|
||||||
TunnelMessageBlockEx m;
|
|
||||||
if (!isFollowOnFragment)
|
if (!isFollowOnFragment)
|
||||||
{
|
{
|
||||||
// first fragment
|
// first fragment
|
||||||
|
if (m_CurrentMsgID)
|
||||||
m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03);
|
AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete
|
||||||
switch (m.deliveryType)
|
|
||||||
|
m_CurrentMessage.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03);
|
||||||
|
switch (m_CurrentMessage.deliveryType)
|
||||||
{
|
{
|
||||||
case eDeliveryTypeLocal: // 0
|
case eDeliveryTypeLocal: // 0
|
||||||
break;
|
break;
|
||||||
case eDeliveryTypeTunnel: // 1
|
case eDeliveryTypeTunnel: // 1
|
||||||
m.tunnelID = bufbe32toh (fragment);
|
m_CurrentMessage.tunnelID = bufbe32toh (fragment);
|
||||||
fragment += 4; // tunnelID
|
fragment += 4; // tunnelID
|
||||||
m.hash = i2p::data::IdentHash (fragment);
|
m_CurrentMessage.hash = i2p::data::IdentHash (fragment);
|
||||||
fragment += 32; // hash
|
fragment += 32; // hash
|
||||||
break;
|
break;
|
||||||
case eDeliveryTypeRouter: // 2
|
case eDeliveryTypeRouter: // 2
|
||||||
m.hash = i2p::data::IdentHash (fragment);
|
m_CurrentMessage.hash = i2p::data::IdentHash (fragment);
|
||||||
fragment += 32; // to hash
|
fragment += 32; // to hash
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
@ -81,6 +82,7 @@ namespace tunnel
|
|||||||
// Message ID
|
// Message ID
|
||||||
msgID = bufbe32toh (fragment);
|
msgID = bufbe32toh (fragment);
|
||||||
fragment += 4;
|
fragment += 4;
|
||||||
|
m_CurrentMsgID = msgID;
|
||||||
isLastFragment = false;
|
isLastFragment = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,50 +98,60 @@ namespace tunnel
|
|||||||
uint16_t size = bufbe16toh (fragment);
|
uint16_t size = bufbe16toh (fragment);
|
||||||
fragment += 2;
|
fragment += 2;
|
||||||
|
|
||||||
msg->offset = fragment - msg->buf;
|
// handle fragment
|
||||||
msg->len = msg->offset + size;
|
if (isFollowOnFragment)
|
||||||
if (msg->len > msg->maxLen)
|
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size);
|
// existing message
|
||||||
return;
|
if (m_CurrentMsgID && m_CurrentMsgID == msgID && m_CurrentMessage.nextFragmentNum == fragmentNum)
|
||||||
}
|
HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); // previous
|
||||||
if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE)
|
else
|
||||||
{
|
|
||||||
// this is not last message. we have to copy it
|
|
||||||
m.data = NewI2NPTunnelMessage ();
|
|
||||||
m.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header
|
|
||||||
m.data->len += TUNNEL_GATEWAY_HEADER_SIZE;
|
|
||||||
*(m.data) = *msg;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m.data = msg;
|
|
||||||
|
|
||||||
if (!isFollowOnFragment && isLastFragment)
|
|
||||||
HandleNextMessage (m);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (msgID) // msgID is presented, assume message is fragmented
|
|
||||||
{
|
{
|
||||||
if (!isFollowOnFragment) // create new incomlete message
|
HandleFollowOnFragment (msgID, isLastFragment, fragmentNum, fragment, size); // another
|
||||||
{
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
m.nextFragmentNum = 1;
|
}
|
||||||
m.receiveTime = i2p::util::GetMillisecondsSinceEpoch ();
|
}
|
||||||
auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m));
|
else
|
||||||
if (ret.second)
|
{
|
||||||
HandleOutOfSequenceFragments (msgID, ret.first->second);
|
// new message
|
||||||
else
|
msg->offset = fragment - msg->buf;
|
||||||
LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists");
|
msg->len = msg->offset + size;
|
||||||
}
|
// check message size
|
||||||
else
|
if (msg->len > msg->maxLen)
|
||||||
{
|
{
|
||||||
m.nextFragmentNum = fragmentNum;
|
LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size);
|
||||||
HandleFollowOnFragment (msgID, isLastFragment, m);
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
// create new or assign I2NP message
|
||||||
|
if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE)
|
||||||
|
{
|
||||||
|
// this is not last message. we have to copy it
|
||||||
|
m_CurrentMessage.data = NewI2NPTunnelMessage (true);
|
||||||
|
*(m_CurrentMessage.data) = *msg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
m_CurrentMessage.data = msg;
|
||||||
|
|
||||||
|
if (isLastFragment)
|
||||||
|
{
|
||||||
|
// single message
|
||||||
|
HandleNextMessage (m_CurrentMessage);
|
||||||
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
|
}
|
||||||
|
else if (msgID)
|
||||||
|
{
|
||||||
|
// first fragment of a new message
|
||||||
|
m_CurrentMessage.nextFragmentNum = 1;
|
||||||
|
m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
|
HandleOutOfSequenceFragments (msgID, m_CurrentMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented");
|
LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented");
|
||||||
}
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fragment += size;
|
fragment += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,27 +159,17 @@ namespace tunnel
|
|||||||
LogPrint (eLogError, "TunnelMessage: zero not found");
|
LogPrint (eLogError, "TunnelMessage: zero not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m)
|
void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment,
|
||||||
|
uint8_t fragmentNum, const uint8_t * fragment, size_t size)
|
||||||
{
|
{
|
||||||
auto fragment = m.data->GetBuffer ();
|
|
||||||
auto size = m.data->GetLength ();
|
|
||||||
auto it = m_IncompleteMessages.find (msgID);
|
auto it = m_IncompleteMessages.find (msgID);
|
||||||
if (it != m_IncompleteMessages.end())
|
if (it != m_IncompleteMessages.end())
|
||||||
{
|
{
|
||||||
auto& msg = it->second;
|
auto& msg = it->second;
|
||||||
if (m.nextFragmentNum == msg.nextFragmentNum)
|
if (fragmentNum == msg.nextFragmentNum)
|
||||||
{
|
{
|
||||||
if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long
|
if (ConcatFollowOnFragment (msg, fragment, size))
|
||||||
{
|
{
|
||||||
if (msg.data->len + size > msg.data->maxLen)
|
|
||||||
{
|
|
||||||
// LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough");
|
|
||||||
auto newMsg = NewI2NPMessage ();
|
|
||||||
*newMsg = *(msg.data);
|
|
||||||
msg.data = newMsg;
|
|
||||||
}
|
|
||||||
if (msg.data->Concat (fragment, size) < size) // concatenate fragment
|
|
||||||
LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen);
|
|
||||||
if (isLastFragment)
|
if (isLastFragment)
|
||||||
{
|
{
|
||||||
// message complete
|
// message complete
|
||||||
@ -182,26 +184,86 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "TunnelMessage: Fragment ", m.nextFragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped");
|
LogPrint (eLogError, "TunnelMessage: Fragment ", fragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped");
|
||||||
m_IncompleteMessages.erase (it);
|
m_IncompleteMessages.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)m.nextFragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved");
|
LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)fragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved");
|
||||||
AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data);
|
AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "TunnelMessage: First fragment of message ", msgID, " not found, saved");
|
LogPrint (eLogDebug, "TunnelMessage: First fragment of message ", msgID, " not found, saved");
|
||||||
AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data);
|
AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data)
|
bool TunnelEndpoint::ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const
|
||||||
{
|
{
|
||||||
if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second)
|
if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long
|
||||||
|
{
|
||||||
|
if (msg.data->len + size > msg.data->maxLen)
|
||||||
|
{
|
||||||
|
// LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough");
|
||||||
|
auto newMsg = NewI2NPMessage ();
|
||||||
|
*newMsg = *(msg.data);
|
||||||
|
msg.data = newMsg;
|
||||||
|
}
|
||||||
|
if (msg.data->Concat (fragment, size) < size) // concatenate fragment
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TunnelEndpoint::HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment)
|
||||||
|
{
|
||||||
|
if (ConcatFollowOnFragment (m_CurrentMessage, fragment, size))
|
||||||
|
{
|
||||||
|
if (isLastFragment)
|
||||||
|
{
|
||||||
|
// message complete
|
||||||
|
HandleNextMessage (m_CurrentMessage);
|
||||||
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_CurrentMessage.nextFragmentNum++;
|
||||||
|
HandleOutOfSequenceFragments (m_CurrentMsgID, m_CurrentMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "TunnelMessage: Fragment ", m_CurrentMessage.nextFragmentNum, " of message ", m_CurrentMsgID, " exceeds max I2NP message size, message dropped");
|
||||||
|
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TunnelEndpoint::AddIncompleteCurrentMessage ()
|
||||||
|
{
|
||||||
|
if (m_CurrentMsgID)
|
||||||
|
{
|
||||||
|
auto ret = m_IncompleteMessages.emplace (m_CurrentMsgID, m_CurrentMessage);
|
||||||
|
if (!ret.second)
|
||||||
|
LogPrint (eLogError, "TunnelMessage: Incomplete message ", m_CurrentMsgID, " already exists");
|
||||||
|
m_CurrentMessage.data = nullptr;
|
||||||
|
m_CurrentMsgID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum,
|
||||||
|
bool isLastFragment, const uint8_t * fragment, size_t size)
|
||||||
|
{
|
||||||
|
std::unique_ptr<Fragment> f(new Fragment (isLastFragment, i2p::util::GetMillisecondsSinceEpoch (), size));
|
||||||
|
memcpy (f->data.data (), fragment, size);
|
||||||
|
if (!m_OutOfSequenceFragments.emplace ((uint64_t)msgID << 32 | fragmentNum, std::move (f)).second)
|
||||||
LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
|
LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +274,14 @@ namespace tunnel
|
|||||||
if (!msg.nextFragmentNum) // message complete
|
if (!msg.nextFragmentNum) // message complete
|
||||||
{
|
{
|
||||||
HandleNextMessage (msg);
|
HandleNextMessage (msg);
|
||||||
m_IncompleteMessages.erase (msgID);
|
if (&msg == &m_CurrentMessage)
|
||||||
|
{
|
||||||
|
m_CurrentMsgID = 0;
|
||||||
|
m_CurrentMessage.data = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_IncompleteMessages.erase (msgID);
|
||||||
|
LogPrint (eLogDebug, "TunnelMessage: All fragments of message ", msgID, " found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,11 +289,11 @@ namespace tunnel
|
|||||||
|
|
||||||
bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
|
bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
|
||||||
{
|
{
|
||||||
auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum});
|
auto it = m_OutOfSequenceFragments.find ((uint64_t)msgID << 32 | msg.nextFragmentNum);
|
||||||
if (it != m_OutOfSequenceFragments.end ())
|
if (it != m_OutOfSequenceFragments.end ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found");
|
LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found");
|
||||||
size_t size = it->second.data->GetLength ();
|
size_t size = it->second->data.size ();
|
||||||
if (msg.data->len + size > msg.data->maxLen)
|
if (msg.data->len + size > msg.data->maxLen)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
|
LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
|
||||||
@ -232,9 +301,9 @@ namespace tunnel
|
|||||||
*newMsg = *(msg.data);
|
*newMsg = *(msg.data);
|
||||||
msg.data = newMsg;
|
msg.data = newMsg;
|
||||||
}
|
}
|
||||||
if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment
|
if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment
|
||||||
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
||||||
if (it->second.isLastFragment)
|
if (it->second->isLastFragment)
|
||||||
// message complete
|
// message complete
|
||||||
msg.nextFragmentNum = 0;
|
msg.nextFragmentNum = 0;
|
||||||
else
|
else
|
||||||
@ -287,7 +356,7 @@ namespace tunnel
|
|||||||
// out-of-sequence fragments
|
// out-of-sequence fragments
|
||||||
for (auto it = m_OutOfSequenceFragments.begin (); it != m_OutOfSequenceFragments.end ();)
|
for (auto it = m_OutOfSequenceFragments.begin (); it != m_OutOfSequenceFragments.end ();)
|
||||||
{
|
{
|
||||||
if (ts > it->second.receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT)
|
if (ts > it->second->receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT)
|
||||||
it = m_OutOfSequenceFragments.erase (it);
|
it = m_OutOfSequenceFragments.erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2021, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -10,7 +10,8 @@
|
|||||||
#define TUNNEL_ENDPOINT_H__
|
#define TUNNEL_ENDPOINT_H__
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
#include "TunnelBase.h"
|
#include "TunnelBase.h"
|
||||||
@ -29,14 +30,15 @@ namespace tunnel
|
|||||||
|
|
||||||
struct Fragment
|
struct Fragment
|
||||||
{
|
{
|
||||||
|
Fragment (bool last, uint64_t t, size_t size): isLastFragment (last), receiveTime (t), data (size) {};
|
||||||
bool isLastFragment;
|
bool isLastFragment;
|
||||||
std::shared_ptr<I2NPMessage> data;
|
|
||||||
uint64_t receiveTime; // milliseconds since epoch
|
uint64_t receiveTime; // milliseconds since epoch
|
||||||
|
std::vector<uint8_t> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0) {};
|
TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0), m_CurrentMsgID (0) {};
|
||||||
~TunnelEndpoint ();
|
~TunnelEndpoint ();
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||||
void Cleanup ();
|
void Cleanup ();
|
||||||
@ -45,19 +47,24 @@ namespace tunnel
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m);
|
void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, uint8_t fragmentNum, const uint8_t * fragment, size_t size);
|
||||||
|
bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success
|
||||||
|
void HandleCurrenMessageFollowOnFragment (const uint8_t * frgament, size_t size, bool isLastFragment);
|
||||||
void HandleNextMessage (const TunnelMessageBlock& msg);
|
void HandleNextMessage (const TunnelMessageBlock& msg);
|
||||||
|
|
||||||
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data);
|
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, const uint8_t * fragment, size_t size);
|
||||||
bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
|
bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
|
||||||
void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg);
|
void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg);
|
||||||
|
void AddIncompleteCurrentMessage ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
|
std::unordered_map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
|
||||||
std::map<std::pair<uint32_t, uint8_t>, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment
|
std::unordered_map<uint64_t, std::unique_ptr<Fragment> > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment
|
||||||
bool m_IsInbound;
|
bool m_IsInbound;
|
||||||
size_t m_NumReceivedBytes;
|
size_t m_NumReceivedBytes;
|
||||||
|
TunnelMessageBlockEx m_CurrentMessage;
|
||||||
|
uint32_t m_CurrentMsgID;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ namespace tunnel
|
|||||||
const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs ();
|
const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs ();
|
||||||
for (auto& tunnelMsg : tunnelDataMsgs)
|
for (auto& tunnelMsg : tunnelDataMsgs)
|
||||||
{
|
{
|
||||||
auto newMsg = CreateEmptyTunnelDataMsg ();
|
auto newMsg = CreateEmptyTunnelDataMsg (false);
|
||||||
m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg);
|
m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg);
|
||||||
htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ());
|
htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ());
|
||||||
newMsg->FillI2NPMessageHeader (eI2NPTunnelData);
|
newMsg->FillI2NPMessageHeader (eI2NPTunnelData);
|
||||||
|
@ -319,7 +319,7 @@ namespace proxy {
|
|||||||
auto pos = uri.find(":");
|
auto pos = uri.find(":");
|
||||||
if(pos == std::string::npos || pos == uri.size() - 1)
|
if(pos == std::string::npos || pos == uri.size() - 1)
|
||||||
{
|
{
|
||||||
GenericProxyError(tr("Invalid Request"), tr("invalid request uri"));
|
GenericProxyError(tr("Invalid request"), tr("invalid request uri"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user