From 2c9fa2f738a87ba2dd4e0355805e27232e596d8d Mon Sep 17 00:00:00 2001 From: Zetok Zalbavar Date: Wed, 24 Jul 2019 11:15:31 +0100 Subject: [PATCH 001/189] Fix and update i2pd.service - /var/run on distros with systemd is a symlink to /run , hence the path changes. - Remove unnecessary runtime dependency on `/bin/kill` which is provided by `procps` and might not be available on minimal installs (e.g. containers). Instead use `/bin/sh` which has a built-in `kill`. - `PrivateDevices=yes` causes i2pd to fail to start on latest Debian unstable. Service exits with the following: ``` i2pd.service: Failed to execute command: Operation not permitted i2pd.service: Failed at step EXEC spawning /usr/sbin/i2pd: Operation not permitted i2pd.service: Control process exited, code=exited, status=203/EXEC i2pd.service: Failed with result 'exit-code'. Failed to start I2P Router written in C++. ``` According to `man systemd.exec` exit code 203 corresponds to the `execve(2)` system call failing. So it looks like i2pd tries to do something it shouldn't be doing. The proper fix would be in i2pd, but who knows how long that would actually take, so to allow people to actually launch i2pd in meanwhile the line has been removed from the service file. Also, surprisingly, right after installing i2pd it started without any problems, and only after restarting the box i2pd started to fail for no apparent reason. --- contrib/i2pd.service | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contrib/i2pd.service b/contrib/i2pd.service index a8eeb8d3..8ce851b0 100644 --- a/contrib/i2pd.service +++ b/contrib/i2pd.service @@ -11,9 +11,9 @@ RuntimeDirectoryMode=0700 LogsDirectory=i2pd LogsDirectoryMode=0700 Type=forking -ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service -ExecReload=/bin/kill -HUP $MAINPID -PIDFile=/var/run/i2pd/i2pd.pid +ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service +ExecReload=/bin/sh -c "kill -HUP $MAINPID" +PIDFile=/run/i2pd/i2pd.pid ### Uncomment, if auto restart needed #Restart=on-failure @@ -27,7 +27,6 @@ KillSignal=SIGQUIT LimitNOFILE=4096 # To enable write of coredump uncomment this #LimitCORE=infinity -PrivateDevices=yes [Install] WantedBy=multi-user.target From 35d62686754a2d959964cf4c52f6fe3689eb6bbb Mon Sep 17 00:00:00 2001 From: Alexandre ZANNI <16578570+noraj@users.noreply.github.com> Date: Sat, 23 Nov 2019 22:52:31 +0100 Subject: [PATCH 002/189] README: explicit linux distro supported close #1440 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b5fb8f7e..25e6c3e5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![GitHub release](https://img.shields.io/github/release/PurpleI2P/i2pd.svg?label=latest%20release)](https://github.com/PurpleI2P/i2pd/releases/latest) [![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE) +[![Packaging status](https://repology.org/badge/tiny-repos/i2pd.svg)](https://repology.org/project/i2pd/versions) i2pd ==== @@ -63,9 +64,10 @@ Build instructions: **Supported systems:** * GNU/Linux - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) + * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) + * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. * Windows - [![Build status](https://ci.appveyor.com/api/projects/status/1908qe4p48ff1x23?svg=true)](https://ci.appveyor.com/project/PurpleI2P/i2pd) * Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) -* CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) * Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/) * Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap) * FreeBSD From 5cfc574f9adeaa78fde582ea2706b1bad08275d8 Mon Sep 17 00:00:00 2001 From: donarrock <35000066+donarrock@users.noreply.github.com> Date: Sun, 12 Jan 2020 16:24:21 +0100 Subject: [PATCH 003/189] Update Dockerfile Fixes dependencies, re-adds `boost-python` as `boost-python2` which was removed in #1408 . --- contrib/docker/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 322261b8..6b6250d0 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -36,9 +36,9 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib && cd /usr/local/bin \ && strip i2pd \ && rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \ - boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \ - boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \ - libtool g++ gcc pkgconfig + boost-python3 python3 gdbm boost-unit_test_framework boost-python2 linux-headers boost-prg_exec_monitor \ + boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \ + libtool g++ gcc # 2. Adding required libraries to run i2pd to ensure it will run. RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl musl-utils libstdc++ From 00db527377cfbbee1767766828daf46b81593ae0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 27 Feb 2020 14:58:06 +0300 Subject: [PATCH 004/189] drop websockets support Signed-off-by: R4SAS --- Makefile | 4 - build/CMakeLists.txt | 11 - daemon/Daemon.cpp | 87 ++--- libi2pd/Config.cpp | 8 - libi2pd/Event.cpp | 19 -- libi2pd/Event.h | 33 +- libi2pd/NTCPSession.cpp | 6 - libi2pd/SSUData.cpp | 6 - libi2pd/Transports.cpp | 16 - libi2pd/Tunnel.cpp | 21 -- libi2pd/Tunnel.h | 38 +-- libi2pd/TunnelPool.cpp | 15 - libi2pd_client/ClientContext.h | 2 +- libi2pd_client/WebSocks.cpp | 488 +--------------------------- libi2pd_client/Websocket.cpp | 195 ----------- libi2pd_client/Websocket.h | 28 -- qt/i2pd_qt/generalsettingswidget.ui | 115 ------- qt/i2pd_qt/i2pd_qt.pro | 2 - qt/i2pd_qt/mainwindow.cpp | 4 - 19 files changed, 57 insertions(+), 1041 deletions(-) delete mode 100644 libi2pd_client/Websocket.cpp delete mode 100644 libi2pd_client/Websocket.h diff --git a/Makefile b/Makefile index 3dfaaade..a814aecf 100644 --- a/Makefile +++ b/Makefile @@ -27,10 +27,6 @@ else LD_DEBUG = -s endif -ifeq ($(WEBSOCKETS),1) - NEEDED_CXXFLAGS += -DWITH_EVENTS -endif - ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2577fb1b..324ac468 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -20,7 +20,6 @@ option(WITH_MESHNET "Build for cjdns test network" OFF) option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) option(WITH_I2LUA "Build for i2lua" OFF) -option(WITH_WEBSOCKETS "Build with websocket ui" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -86,11 +85,6 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" ) -if (WITH_WEBSOCKETS) - add_definitions(-DWITH_EVENTS) - find_package(websocketpp REQUIRED) -endif () - if (WIN32 OR MSYS) list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") endif () @@ -127,10 +121,6 @@ set (CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp" ) -if(WITH_WEBSOCKETS) - list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp") -endif () - add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") @@ -427,7 +417,6 @@ message(STATUS " MESHNET : ${WITH_MESHNET}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS " I2LUA : ${WITH_I2LUA}") -message(STATUS " WEBSOCKETS : ${WITH_WEBSOCKETS}") message(STATUS "---------------------------------------") #Handle paths nicely diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 0ea45bb7..2c6b34d7 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -26,9 +26,6 @@ #include "Timestamp.h" #include "util.h" -#include "Event.h" -#include "Websocket.h" - namespace i2p { namespace util @@ -43,9 +40,6 @@ namespace i2p std::unique_ptr m_I2PControlService; std::unique_ptr UPnP; std::unique_ptr m_NTPSync; -#ifdef WITH_EVENTS - std::unique_ptr m_WebsocketServer; -#endif }; Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} @@ -62,12 +56,12 @@ namespace i2p return service; } - bool Daemon_Singleton::init(int argc, char* argv[]) { - return init(argc, argv, nullptr); - } + bool Daemon_Singleton::init(int argc, char* argv[]) { + return init(argc, argv, nullptr); + } - bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) - { + bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) + { i2p::config::Init(); i2p::config::ParseCmdline(argc, argv); @@ -110,10 +104,10 @@ namespace i2p logs = "file"; i2p::log::Logger().SetLogLevel(loglevel); - if (logstream) { - LogPrint(eLogInfo, "Log: will send messages to std::ostream"); - i2p::log::Logger().SendTo (logstream); - } else if (logs == "file") { + if (logstream) { + LogPrint(eLogInfo, "Log: will send messages to std::ostream"); + i2p::log::Logger().SendTo (logstream); + } else if (logs == "file") { if (logfile == "") logfile = i2p::fs::DataDirPath("i2pd.log"); LogPrint(eLogInfo, "Log: will send messages to ", logfile); @@ -127,7 +121,7 @@ namespace i2p // use stdout -- default } - LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); + LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); @@ -151,8 +145,8 @@ namespace i2p LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port); i2p::context.UpdatePort (port); } - i2p::context.SetSupportsV6 (ipv6); - i2p::context.SetSupportsV4 (ipv4); + i2p::context.SetSupportsV6 (ipv6); + i2p::context.SetSupportsV4 (ipv4); bool ntcp; i2p::config::GetOption("ntcp", ntcp); i2p::context.PublishNTCPAddress (ntcp, !ipv6); @@ -233,15 +227,15 @@ namespace i2p if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); - bool trust; i2p::config::GetOption("trust.enabled", trust); - if (trust) - { - LogPrint(eLogInfo, "Daemon: explicit trust enabled"); - std::string fam; i2p::config::GetOption("trust.family", fam); + bool trust; i2p::config::GetOption("trust.enabled", trust); + if (trust) + { + LogPrint(eLogInfo, "Daemon: explicit trust enabled"); + std::string fam; i2p::config::GetOption("trust.family", fam); std::string routers; i2p::config::GetOption("trust.routers", routers); bool restricted = false; - if (fam.length() > 0) - { + if (fam.length() > 0) + { std::set fams; size_t pos = 0, comma; do @@ -253,7 +247,7 @@ namespace i2p while (comma != std::string::npos); i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; - } + } if (routers.length() > 0) { std::set idents; size_t pos = 0, comma; @@ -272,14 +266,15 @@ namespace i2p } if(!restricted) LogPrint(eLogError, "Daemon: no trusted routers of families specififed"); - } - bool hidden; i2p::config::GetOption("trust.hidden", hidden); - if (hidden) - { - LogPrint(eLogInfo, "Daemon: using hidden mode"); - i2p::data::netdb.SetHidden(true); - } - return true; + } + + bool hidden; i2p::config::GetOption("trust.hidden", hidden); + if (hidden) + { + LogPrint(eLogInfo, "Daemon: using hidden mode"); + i2p::data::netdb.SetHidden(true); + } + return true; } bool Daemon_Singleton::start() @@ -322,7 +317,7 @@ namespace i2p bool http; i2p::config::GetOption("http.enabled", http); if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); @@ -344,26 +339,11 @@ namespace i2p d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); } -#ifdef WITH_EVENTS - - bool websocket; i2p::config::GetOption("websockets.enabled", websocket); - if(websocket) { - std::string websocketAddr; i2p::config::GetOption("websockets.address", websocketAddr); - uint16_t websocketPort; i2p::config::GetOption("websockets.port", websocketPort); - LogPrint(eLogInfo, "Daemon: starting Websocket server at ", websocketAddr, ":", websocketPort); - d.m_WebsocketServer = std::unique_ptr(new i2p::event::WebsocketServer (websocketAddr, websocketPort)); - d.m_WebsocketServer->Start(); - i2p::event::core.SetListener(d.m_WebsocketServer->ToListener()); - } -#endif return true; } bool Daemon_Singleton::stop() { -#ifdef WITH_EVENTS - i2p::event::core.SetListener(nullptr); -#endif LogPrint(eLogInfo, "Daemon: shutting down"); LogPrint(eLogInfo, "Daemon: stopping Client"); i2p::client::context.Stop(); @@ -397,13 +377,6 @@ namespace i2p d.m_I2PControlService->Stop (); d.m_I2PControlService = nullptr; } -#ifdef WITH_EVENTS - if (d.m_WebsocketServer) { - LogPrint(eLogInfo, "Daemon: stopping Websocket server"); - d.m_WebsocketServer->Stop(); - d.m_WebsocketServer = nullptr; - } -#endif i2p::crypto::TerminateCrypto (); i2p::log::Logger().Stop(); diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b0f7572d..13cd772d 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -218,13 +218,6 @@ namespace config { ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?") ; - options_description websocket("Websocket Options"); - websocket.add_options() - ("websockets.enabled", value()->default_value(false), "Enable websocket server") - ("websockets.address", value()->default_value("127.0.0.1"), "Address to bind websocket server on") - ("websockets.port", value()->default_value(7666), "Port to bind websocket server on") - ; - options_description exploratory("Exploratory Options"); exploratory.add_options() ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") @@ -274,7 +267,6 @@ namespace config { .add(reseed) .add(addressbook) .add(trust) - .add(websocket) .add(exploratory) .add(ntcp2) .add(nettime) diff --git a/libi2pd/Event.cpp b/libi2pd/Event.cpp index 9c75f95b..90c5ed97 100644 --- a/libi2pd/Event.cpp +++ b/libi2pd/Event.cpp @@ -5,10 +5,6 @@ namespace i2p { namespace event { -#ifdef WITH_EVENTS - EventCore core; -#endif - void EventCore::SetListener(EventListener * l) { m_listener = l; @@ -44,18 +40,3 @@ namespace i2p } } } - -void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val) -{ -#ifdef WITH_EVENTS - i2p::event::core.CollectEvent(type, ident, val); -#endif -} - -void EmitEvent(const EventType & e) -{ -#if WITH_EVENTS - i2p::event::core.QueueEvent(e); -#endif -} - diff --git a/libi2pd/Event.h b/libi2pd/Event.h index a8b46a4b..74eed1db 100644 --- a/libi2pd/Event.h +++ b/libi2pd/Event.h @@ -14,40 +14,33 @@ namespace i2p { namespace event { - class EventListener { + class EventListener { public: virtual ~EventListener() {}; virtual void HandleEvent(const EventType & ev) = 0; - /** @brief handle collected event when pumped */ - virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; + /** @brief handle collected event when pumped */ + virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; }; class EventCore { public: void QueueEvent(const EventType & ev); - void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); + void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); void SetListener(EventListener * l); - void PumpCollected(EventListener * l); + void PumpCollected(EventListener * l); private: - std::mutex m_collect_mutex; - struct CollectedEvent - { - std::string Key; - std::string Ident; - uint64_t Val; - }; - std::map m_collected; + std::mutex m_collect_mutex; + struct CollectedEvent + { + std::string Key; + std::string Ident; + uint64_t Val; + }; + std::map m_collected; EventListener * m_listener = nullptr; }; -#ifdef WITH_EVENTS - extern EventCore core; -#endif } } - -void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val); -void EmitEvent(const EventType & ev); - #endif diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 7e8ecd15..9711ffb0 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -14,9 +14,6 @@ #include "NTCPSession.h" #include "HTTP.h" #include "util.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif using namespace i2p::crypto; @@ -649,9 +646,6 @@ namespace transport { if (!m_NextMessage->IsExpired ()) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.recvmsg", GetIdentHashBase64(), 1); -#endif m_Handler.PutNextMessage (m_NextMessage); } else diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 3ad5e769..add58739 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -5,9 +5,6 @@ #include "NetDb.hpp" #include "SSU.h" #include "SSUData.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -241,9 +238,6 @@ namespace transport m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); if (!msg->IsExpired ()) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.recvmsg", m_Session.GetIdentHashBase64(), 1); -#endif m_Handler.PutNextMessage (msg); } else diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 42a605a4..ee99acf7 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -6,10 +6,6 @@ #include "Transports.h" #include "Config.h" #include "HTTP.h" -#ifdef WITH_EVENTS -#include "Event.h" -#include "util.h" -#endif using namespace i2p::data; @@ -346,9 +342,6 @@ namespace transport void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.send", ident.ToBase64(), msgs.size()); -#endif m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs)); } @@ -597,9 +590,6 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "false"}}); -#endif bool sendDatabaseStore = true; if (it->second.delayedMessages.size () > 0) { @@ -625,9 +615,6 @@ namespace transport session->Done(); return; } -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "true"}}); -#endif session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore std::unique_lock l(m_PeersMutex); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); @@ -642,9 +629,6 @@ namespace transport auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.disconnected"}, {"ident", ident.ToBase64()}}); -#endif auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 00b0a12c..9dacddac 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -14,9 +14,6 @@ #include "Config.h" #include "Tunnel.h" #include "TunnelPool.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -35,9 +32,6 @@ namespace tunnel void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { -#ifdef WITH_EVENTS - std::string peers = i2p::context.GetIdentity()->GetIdentHash().ToBase64(); -#endif auto numHops = m_Config->GetNumHops (); int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops; auto msg = NewI2NPShortMessage (); @@ -64,15 +58,9 @@ namespace tunnel hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx); hop->recordIndex = idx; i++; -#ifdef WITH_EVENTS - peers += ":" + hop->ident->GetIdentHash().ToBase64(); -#endif hop = hop->next; } BN_CTX_free (ctx); -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.build", this, peers); -#endif // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { @@ -207,9 +195,6 @@ namespace tunnel void Tunnel::SetState(TunnelState state) { m_State = state; -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", this, state); -#endif } @@ -614,9 +599,6 @@ namespace tunnel hop = hop->next; } } -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); -#endif // for i2lua if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout); // delete @@ -628,9 +610,6 @@ namespace tunnel break; case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted"); -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); -#endif // for i2lua if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected); diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 3244faad..66b620b8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -25,42 +25,28 @@ namespace i2p { namespace tunnel { - - template - static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) + { (void) ev; (void) t; -#endif - } + } - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", std::to_string(val)}, {"inbound", std::to_string(t->IsInbound())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) + { (void) ev; (void) t; (void) val; -#endif - } + } - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", val}, {"inbound", std::to_string(t->IsInbound())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) + { (void) ev; (void) t; (void) val; -#endif - } - + } const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7a1325fe..b3e3c7d2 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -11,9 +11,6 @@ #include "Tunnel.h" #include "TunnelPool.h" #include "Destination.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -86,9 +83,6 @@ namespace tunnel { if (!m_IsActive) return; { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.created", createdTunnel); -#endif std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.insert (createdTunnel); } @@ -102,9 +96,6 @@ namespace tunnel { if (expiredTunnel) { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.expired", expiredTunnel); -#endif expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; @@ -118,9 +109,6 @@ namespace tunnel { if (!m_IsActive) return; { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.created", createdTunnel); -#endif std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } @@ -133,9 +121,6 @@ namespace tunnel { if (expiredTunnel) { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.expired", expiredTunnel); -#endif expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index a239035f..610914bf 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -37,7 +37,7 @@ namespace client const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels"; - const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; + const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_PORT[] = "port"; diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp index c80feac8..95abf455 100644 --- a/libi2pd_client/WebSocks.cpp +++ b/libi2pd_client/WebSocks.cpp @@ -2,491 +2,6 @@ #include "Log.h" #include -#ifdef WITH_EVENTS -#include "ClientContext.h" -#include "Identity.h" -#include "Destination.h" -#include "Streaming.h" -#include - -#include -#include - -#include -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 -#include -#endif - -namespace i2p -{ -namespace client -{ - typedef websocketpp::server WebSocksServerImpl; - - typedef std::function)> StreamConnectFunc; - - - struct IWebSocksConn : public I2PServiceHandler - { - IWebSocksConn(I2PService * parent) : I2PServiceHandler(parent) {} - virtual void Close() = 0; - virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) = 0; - }; - - typedef std::shared_ptr WebSocksConn_ptr; - - WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent); - - class WebSocksImpl - { - - typedef std::mutex mutex_t; - typedef std::unique_lock lock_t; - - typedef std::shared_ptr Destination_t; - public: - - typedef WebSocksServerImpl ServerImpl; - typedef ServerImpl::message_ptr MessagePtr; - - WebSocksImpl(const std::string & addr, int port) : - Parent(nullptr), - m_Run(false), - m_Addr(addr), - m_Port(port), - m_Thread(nullptr) - { - m_Server.init_asio(); - m_Server.set_open_handler(std::bind(&WebSocksImpl::ConnOpened, this, std::placeholders::_1)); - } - - void InitializeDestination(WebSocks * parent) - { - Parent = parent; - m_Dest = Parent->GetLocalDestination(); - } - - ServerImpl::connection_ptr GetConn(const websocketpp::connection_hdl & conn) - { - return m_Server.get_con_from_hdl(conn); - } - - void CloseConn(const websocketpp::connection_hdl & conn) - { - auto c = GetConn(conn); - if(c) c->close(websocketpp::close::status::normal, "closed"); - } - - void CreateStreamTo(const std::string & addr, int port, StreamConnectFunc complete) - { - auto & addressbook = i2p::client::context.GetAddressBook(); - auto a = addressbook.GetAddress (addr); - if (a && a->IsIdentHash ()) - { - // address found - m_Dest->CreateStream(complete, a->identHash, port); - } - else - { - // not found - complete(nullptr); - } - } - - void ConnOpened(websocketpp::connection_hdl conn) - { - auto ptr = CreateWebSocksConn(conn, this); - Parent->AddHandler(ptr); - m_Conns.push_back(ptr); - } - - void Start() - { - if(m_Run) return; // already started - m_Server.listen(boost::asio::ip::address::from_string(m_Addr), m_Port); - m_Server.start_accept(); - m_Run = true; - m_Thread = new std::thread([&] (){ - while(m_Run) { - try { - m_Server.run(); - } catch( std::exception & ex) { - LogPrint(eLogError, "Websocks runtime exception: ", ex.what()); - } - } - }); - m_Dest->Start(); - } - - void Stop() - { - for(const auto & conn : m_Conns) - conn->Close(); - - m_Dest->Stop(); - m_Run = false; - m_Server.stop(); - if(m_Thread) { - m_Thread->join(); - delete m_Thread; - } - m_Thread = nullptr; - } - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() - { - return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port); - } - - i2p::datagram::DatagramDestination * GetDatagramDest() const - { - auto dgram = m_Dest->GetDatagramDestination(); - if(!dgram) dgram = m_Dest->CreateDatagramDestination(); - return dgram; - } - - WebSocks * Parent; - - private: - std::vector m_Conns; - bool m_Run; - ServerImpl m_Server; - std::string m_Addr; - int m_Port; - std::thread * m_Thread; - Destination_t m_Dest; - }; - - struct WebSocksConn : public IWebSocksConn , public std::enable_shared_from_this - { - enum ConnState - { - eWSCInitial, - eWSCTryConnect, - eWSCFailConnect, - eWSCOkayConnect, - eWSCDatagram, - eWSCClose, - eWSCEnd - }; - - typedef WebSocksServerImpl ServerImpl; - typedef ServerImpl::message_ptr Message_t; - typedef websocketpp::connection_hdl ServerConn; - typedef std::shared_ptr Destination_t; - typedef std::shared_ptr StreamDest_t; - typedef std::shared_ptr Stream_t; - - ServerConn m_Conn; - Stream_t m_Stream; - ConnState m_State; - WebSocksImpl * m_Parent; - std::string m_RemoteAddr; - int m_RemotePort; - uint8_t m_RecvBuf[2048]; - bool m_IsDatagram; - i2p::datagram::DatagramDestination * m_Datagram; - - WebSocksConn(const ServerConn & conn, WebSocksImpl * parent) : - IWebSocksConn(parent->Parent), - m_Conn(conn), - m_Stream(nullptr), - m_State(eWSCInitial), - m_Parent(parent), - m_IsDatagram(false), - m_Datagram(nullptr) - { - - } - - ~WebSocksConn() - { - Close(); - } - - void HandleDatagram(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) - { - auto conn = m_Parent->GetConn(m_Conn); - if(conn) - { - std::stringstream ss; - ss << from.GetIdentHash().ToBase32(); - ss << ".b32.i2p:"; - ss << std::to_string(fromPort); - ss << "\n"; - ss.write((char *)buf, len); - conn->send(ss.str()); - } - } - - void BeginDatagram() - { - m_Datagram = m_Parent->GetDatagramDest(); - m_Datagram->SetReceiver( - std::bind( - &WebSocksConn::HandleDatagram, - this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3, - std::placeholders::_4, - std::placeholders::_5), m_RemotePort); - } - - void EnterState(ConnState state) - { - LogPrint(eLogDebug, "websocks: state ", m_State, " -> ", state); - switch(m_State) - { - case eWSCInitial: - if (state == eWSCClose) { - m_State = eWSCClose; - // connection was opened but never used - LogPrint(eLogInfo, "websocks: connection closed but never used"); - Close(); - return; - } else if (state == eWSCTryConnect) { - // we will try to connect - m_State = eWSCTryConnect; - m_Parent->CreateStreamTo(m_RemoteAddr, m_RemotePort, std::bind(&WebSocksConn::ConnectResult, this, std::placeholders::_1)); - } else if (state == eWSCDatagram) { - if (m_RemotePort >= 0 && m_RemotePort <= 65535) - { - LogPrint(eLogDebug, "websocks: datagram mode initiated"); - m_State = eWSCDatagram; - BeginDatagram(); - SendResponse(""); - } - else - SendResponse("invalid port"); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCTryConnect: - if(state == eWSCOkayConnect) { - // we connected okay - LogPrint(eLogDebug, "websocks: connected to ", m_RemoteAddr, ":", m_RemotePort); - SendResponse(""); - m_State = eWSCOkayConnect; - } else if(state == eWSCFailConnect) { - // we did not connect okay - LogPrint(eLogDebug, "websocks: failed to connect to ", m_RemoteAddr, ":", m_RemotePort); - SendResponse("failed to connect"); - m_State = eWSCFailConnect; - EnterState(eWSCInitial); - } else if(state == eWSCClose) { - // premature close - LogPrint(eLogWarning, "websocks: websocket connection closed prematurely"); - m_State = eWSCClose; - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCFailConnect: - if (state == eWSCInitial) { - // reset to initial state so we can try connecting again - m_RemoteAddr = ""; - m_RemotePort = 0; - LogPrint(eLogDebug, "websocks: reset websocket conn to initial state"); - m_State = eWSCInitial; - } else if (state == eWSCClose) { - // we are going to close the connection - m_State = eWSCClose; - Close(); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCDatagram: - if(state != eWSCClose) { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - m_State = eWSCClose; - Close(); - return; - case eWSCOkayConnect: - if(state == eWSCClose) { - // graceful close - m_State = eWSCClose; - Close(); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCClose: - if(state == eWSCEnd) { - LogPrint(eLogDebug, "websocks: socket ended"); - Kill(); - auto me = shared_from_this(); - Done(me); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - default: - LogPrint(eLogError, "websocks: bad state ", m_State); - } - } - - void StartForwarding() - { - LogPrint(eLogDebug, "websocks: begin forwarding data"); - uint8_t b[1]; - m_Stream->Send(b, 0); - AsyncRecv(); - } - - void HandleAsyncRecv(const boost::system::error_code &ec, std::size_t n) - { - if(ec) { - // error - LogPrint(eLogWarning, "websocks: connection error ", ec.message()); - EnterState(eWSCClose); - } else { - // forward data - LogPrint(eLogDebug, "websocks recv ", n); - - std::string str((char*)m_RecvBuf, n); - auto conn = m_Parent->GetConn(m_Conn); - if(!conn) { - LogPrint(eLogWarning, "websocks: connection is gone"); - EnterState(eWSCClose); - return; - } - conn->send(str); - AsyncRecv(); - - } - } - - void AsyncRecv() - { - m_Stream->AsyncReceive( - boost::asio::buffer(m_RecvBuf, sizeof(m_RecvBuf)), - std::bind(&WebSocksConn::HandleAsyncRecv, this, std::placeholders::_1, std::placeholders::_2), 60); - } - - /** @brief send error message or empty string for success */ - void SendResponse(const std::string & errormsg) - { - boost::property_tree::ptree resp; - if(errormsg.size()) { - resp.put("error", errormsg); - resp.put("success", 0); - } else { - resp.put("success", 1); - } - std::ostringstream ss; - write_json(ss, resp); - auto conn = m_Parent->GetConn(m_Conn); - if(conn) conn->send(ss.str()); - } - - void ConnectResult(Stream_t stream) - { - m_Stream = stream; - if(m_State == eWSCClose) { - // premature close of websocket - Close(); - return; - } - if(m_Stream) { - // connect good - EnterState(eWSCOkayConnect); - StartForwarding(); - } else { - // connect failed - EnterState(eWSCFailConnect); - } - } - - virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) - { - (void) conn; - std::string payload = msg->get_payload(); - if(m_State == eWSCOkayConnect) - { - // forward to server - LogPrint(eLogDebug, "websocks: forward ", payload.size()); - m_Stream->Send((uint8_t*)payload.c_str(), payload.size()); - } else if (m_State == eWSCInitial) { - // recv connect request - auto itr = payload.find(":"); - if(itr == std::string::npos) { - // no port - m_RemotePort = 0; - m_RemoteAddr = payload; - } else { - // includes port - m_RemotePort = std::stoi(payload.substr(itr+1)); - m_RemoteAddr = payload.substr(0, itr); - } - m_IsDatagram = m_RemoteAddr == "DATAGRAM"; - if(m_IsDatagram) - EnterState(eWSCDatagram); - else - EnterState(eWSCTryConnect); - } else if (m_State == eWSCDatagram) { - // send datagram - // format is "host:port\npayload" - auto idx = payload.find("\n"); - std::string line = payload.substr(0, idx); - auto itr = line.find(":"); - auto & addressbook = i2p::client::context.GetAddressBook(); - std::string addr; - int port = 0; - if (itr == std::string::npos) - { - addr = line; - } - else - { - addr = line.substr(0, itr); - port = std::atoi(line.substr(itr+1).c_str()); - } - auto a = addressbook.GetAddress (addr); - if (a && a->IsIdentHash ()) - { - const char * data = payload.c_str() + idx + 1; - size_t len = payload.size() - (1 + line.size()); - m_Datagram->SendDatagramTo((const uint8_t*)data, len, a->identHash, m_RemotePort, port); - } - } else { - // wtf? - LogPrint(eLogWarning, "websocks: got message in invalid state ", m_State); - } - } - - virtual void Close() - { - if(m_State == eWSCClose) { - LogPrint(eLogDebug, "websocks: closing connection"); - if(m_Stream) m_Stream->Close(); - if(m_Datagram) m_Datagram->ResetReceiver(m_RemotePort); - m_Parent->CloseConn(m_Conn); - EnterState(eWSCEnd); - } else { - EnterState(eWSCClose); - } - } - }; - - WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent) - { - auto ptr = std::make_shared(conn, parent); - auto c = parent->GetConn(conn); - c->set_message_handler(std::bind(&WebSocksConn::GotMessage, ptr.get(), std::placeholders::_1, std::placeholders::_2)); - return ptr; - } - -} -} -#else - -// no websocket support - namespace i2p { namespace client @@ -504,7 +19,7 @@ namespace client void Start() { - LogPrint(eLogInfo, "WebSockets not enabled on compile time"); + LogPrint(eLogInfo, "[Tunnels] starting websocks tunnel at %s:%d is rejected: WebSockets is deprecated", m_Addr, m_Port); } void Stop() @@ -527,7 +42,6 @@ namespace client } } -#endif namespace i2p { namespace client diff --git a/libi2pd_client/Websocket.cpp b/libi2pd_client/Websocket.cpp deleted file mode 100644 index 3d456655..00000000 --- a/libi2pd_client/Websocket.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#ifdef WITH_EVENTS -#include "Websocket.h" -#include "Log.h" - -#include -#include - -#include -#include -#include -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 -#include -#endif - -#include - -namespace i2p -{ - namespace event - { - - typedef websocketpp::server ServerImpl; - typedef websocketpp::connection_hdl ServerConn; - - class WebsocketServerImpl : public EventListener - { - private: - typedef ServerImpl::message_ptr MessagePtr; - public: - - WebsocketServerImpl(const std::string & addr, int port) : - m_run(false), - m_ws_thread(nullptr), - m_ev_thread(nullptr), - m_WebsocketTicker(m_Service) - { - m_server.init_asio(); - m_server.set_open_handler(std::bind(&WebsocketServerImpl::ConnOpened, this, std::placeholders::_1)); - m_server.set_close_handler(std::bind(&WebsocketServerImpl::ConnClosed, this, std::placeholders::_1)); - m_server.set_message_handler(std::bind(&WebsocketServerImpl::OnConnMessage, this, std::placeholders::_1, std::placeholders::_2)); - - m_server.listen(boost::asio::ip::address::from_string(addr), port); - } - - ~WebsocketServerImpl() - { - } - - void Start() { - m_run = true; - m_server.start_accept(); - m_ws_thread = new std::thread([&] () { - while(m_run) { - try { - m_server.run(); - } catch (std::exception & e ) { - LogPrint(eLogError, "Websocket server: ", e.what()); - } - } - }); - m_ev_thread = new std::thread([&] () { - while(m_run) { - try { - m_Service.run(); - break; - } catch (std::exception & e ) { - LogPrint(eLogError, "Websocket service: ", e.what()); - } - } - }); - ScheduleTick(); - } - - void Stop() { - m_run = false; - m_Service.stop(); - m_server.stop(); - - if(m_ev_thread) { - m_ev_thread->join(); - delete m_ev_thread; - } - m_ev_thread = nullptr; - - if(m_ws_thread) { - m_ws_thread->join(); - delete m_ws_thread; - } - m_ws_thread = nullptr; - } - - void ConnOpened(ServerConn c) - { - std::lock_guard lock(m_connsMutex); - m_conns.insert(c); - } - - void ConnClosed(ServerConn c) - { - std::lock_guard lock(m_connsMutex); - m_conns.erase(c); - } - - void OnConnMessage(ServerConn conn, ServerImpl::message_ptr msg) - { - (void) conn; - (void) msg; - } - - void HandleTick(const boost::system::error_code & ec) - { - - if(ec != boost::asio::error::operation_aborted) - LogPrint(eLogError, "Websocket ticker: ", ec.message()); - // pump collected events to us - i2p::event::core.PumpCollected(this); - ScheduleTick(); - } - - void ScheduleTick() - { - LogPrint(eLogDebug, "Websocket schedule tick"); - boost::posix_time::seconds dlt(1); - m_WebsocketTicker.expires_from_now(dlt); - m_WebsocketTicker.async_wait(std::bind(&WebsocketServerImpl::HandleTick, this, std::placeholders::_1)); - } - - /** @brief called from m_ev_thread */ - void HandlePumpEvent(const EventType & ev, const uint64_t & val) - { - EventType e; - for (const auto & i : ev) - e[i.first] = i.second; - - e["number"] = std::to_string(val); - HandleEvent(e); - } - - /** @brief called from m_ws_thread */ - void HandleEvent(const EventType & ev) - { - std::lock_guard lock(m_connsMutex); - boost::property_tree::ptree event; - for (const auto & item : ev) { - event.put(item.first, item.second); - } - std::ostringstream ss; - write_json(ss, event); - std::string s = ss.str(); - - ConnList::iterator it; - for (it = m_conns.begin(); it != m_conns.end(); ++it) { - ServerImpl::connection_ptr con = m_server.get_con_from_hdl(*it); - con->send(s); - } - } - - private: - typedef std::set > ConnList; - bool m_run; - std::thread * m_ws_thread; - std::thread * m_ev_thread; - std::mutex m_connsMutex; - ConnList m_conns; - ServerImpl m_server; - boost::asio::io_service m_Service; - boost::asio::deadline_timer m_WebsocketTicker; - }; - - - WebsocketServer::WebsocketServer(const std::string & addr, int port) : m_impl(new WebsocketServerImpl(addr, port)) {} - WebsocketServer::~WebsocketServer() - { - delete m_impl; - } - - - void WebsocketServer::Start() - { - m_impl->Start(); - } - - void WebsocketServer::Stop() - { - m_impl->Stop(); - } - - EventListener * WebsocketServer::ToListener() - { - return m_impl; - } - } -} -#endif diff --git a/libi2pd_client/Websocket.h b/libi2pd_client/Websocket.h deleted file mode 100644 index 3a754e49..00000000 --- a/libi2pd_client/Websocket.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef WEBSOCKET_H__ -#define WEBSOCKET_H__ -#include "Event.h" -namespace i2p -{ - namespace event - { - - class WebsocketServerImpl; - - class WebsocketServer - { - public: - WebsocketServer(const std::string & addr, int port); - ~WebsocketServer(); - - void Start(); - void Stop(); - - EventListener * ToListener(); - - private: - WebsocketServerImpl * m_impl; - }; - - } -} -#endif diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index a7f07e5d..9e59132f 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -2135,121 +2135,6 @@ Comma separated list of base64 identities: - - - - - 0 - 0 - - - - - 0 - 105 - - - - - 16777215 - 105 - - - - Websockets server - - - - - 0 - 20 - 85 - 21 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Address to bind websocket server on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to bind websocket server on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index caa0bd50..1f01cb4b 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -74,7 +74,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd_client/MatchedDestination.cpp \ ../../libi2pd_client/SAM.cpp \ ../../libi2pd_client/SOCKS.cpp \ - ../../libi2pd_client/Websocket.cpp \ ../../libi2pd_client/WebSocks.cpp \ ../../daemon/Daemon.cpp \ ../../daemon/HTTPServer.cpp \ @@ -161,7 +160,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd_client/MatchedDestination.h \ ../../libi2pd_client/SAM.h \ ../../libi2pd_client/SOCKS.h \ - ../../libi2pd_client/Websocket.h \ ../../libi2pd_client/WebSocks.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e4c9f2a7..76a6fda8 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -258,10 +258,6 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters); initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden); - initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable); - initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->lineEdit_webSock_addr, tr("Websocket server -> IP address")); - initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->lineEdit_webSock_port, tr("Websocket server -> Port")); - # undef OPTION //widgetlocks.add(new widgetlock(widget,lockbtn)); From bca0809918a2843b3d5b853a129a3068b0d9882a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 Feb 2020 18:48:43 +0300 Subject: [PATCH 005/189] cleanup removed websockets funtions Signed-off-by: R4SAS --- build/CMakeLists.txt | 1 - filelist.mk | 2 +- libi2pd/Event.cpp | 42 --------------------------------- libi2pd/Event.h | 46 ------------------------------------- libi2pd/Tunnel.h | 24 ------------------- libi2pd_client/WebSocks.cpp | 1 - qt/i2pd_qt/i2pd_qt.pro | 2 -- 7 files changed, 1 insertion(+), 117 deletions(-) delete mode 100644 libi2pd/Event.cpp delete mode 100644 libi2pd/Event.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 324ac468..d39dd113 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -74,7 +74,6 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/Signature.cpp" "${LIBI2PD_SRC_DIR}/Timestamp.cpp" "${LIBI2PD_SRC_DIR}/api.cpp" - "${LIBI2PD_SRC_DIR}/Event.cpp" "${LIBI2PD_SRC_DIR}/Gost.cpp" "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" "${LIBI2PD_SRC_DIR}/Poly1305.cpp" diff --git a/filelist.mk b/filelist.mk index 8d451dc9..72773975 100644 --- a/filelist.mk +++ b/filelist.mk @@ -5,7 +5,7 @@ # SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ # Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ # Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ -# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp Gost.cpp +# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Gost.cpp LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp) diff --git a/libi2pd/Event.cpp b/libi2pd/Event.cpp deleted file mode 100644 index 90c5ed97..00000000 --- a/libi2pd/Event.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "Event.h" -#include "Log.h" - -namespace i2p -{ - namespace event - { - void EventCore::SetListener(EventListener * l) - { - m_listener = l; - LogPrint(eLogInfo, "Event: listener set"); - } - - void EventCore::QueueEvent(const EventType & ev) - { - if(m_listener) m_listener->HandleEvent(ev); - } - - void EventCore::CollectEvent(const std::string & type, const std::string & ident, uint64_t val) - { - std::unique_lock lock(m_collect_mutex); - std::string key = type + "." + ident; - if (m_collected.find(key) == m_collected.end()) - { - m_collected[key] = {type, key, 0}; - } - m_collected[key].Val += val; - } - - void EventCore::PumpCollected(EventListener * listener) - { - std::unique_lock lock(m_collect_mutex); - if(listener) - { - for(const auto & ev : m_collected) { - listener->HandlePumpEvent({{"type", ev.second.Key}, {"ident", ev.second.Ident}}, ev.second.Val); - } - } - m_collected.clear(); - } - } -} diff --git a/libi2pd/Event.h b/libi2pd/Event.h deleted file mode 100644 index 74eed1db..00000000 --- a/libi2pd/Event.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef EVENT_H__ -#define EVENT_H__ -#include -#include -#include -#include -#include - -#include - -typedef std::map EventType; - -namespace i2p -{ - namespace event - { - class EventListener { - public: - virtual ~EventListener() {}; - virtual void HandleEvent(const EventType & ev) = 0; - /** @brief handle collected event when pumped */ - virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; - }; - - class EventCore - { - public: - void QueueEvent(const EventType & ev); - void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); - void SetListener(EventListener * l); - void PumpCollected(EventListener * l); - - private: - std::mutex m_collect_mutex; - struct CollectedEvent - { - std::string Key; - std::string Ident; - uint64_t Val; - }; - std::map m_collected; - EventListener * m_listener = nullptr; - }; - } -} -#endif diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 66b620b8..f97bcc63 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -19,35 +19,11 @@ #include "TunnelGateway.h" #include "TunnelBase.h" #include "I2NPProtocol.h" -#include "Event.h" namespace i2p { namespace tunnel { - template - static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) - { - (void) ev; - (void) t; - } - - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) - { - (void) ev; - (void) t; - (void) val; - } - - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) - { - (void) ev; - (void) t; - (void) val; - } - const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp index 95abf455..a3e8c1bf 100644 --- a/libi2pd_client/WebSocks.cpp +++ b/libi2pd_client/WebSocks.cpp @@ -70,4 +70,3 @@ namespace client } } } - diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 1f01cb4b..ce3ec1ca 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -28,7 +28,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/Datagram.cpp \ ../../libi2pd/Destination.cpp \ ../../libi2pd/Ed25519.cpp \ - ../../libi2pd/Event.cpp \ ../../libi2pd/Family.cpp \ ../../libi2pd/FS.cpp \ ../../libi2pd/Garlic.cpp \ @@ -106,7 +105,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/Datagram.h \ ../../libi2pd/Destination.h \ ../../libi2pd/Ed25519.h \ - ../../libi2pd/Event.h \ ../../libi2pd/Family.h \ ../../libi2pd/FS.h \ ../../libi2pd/Garlic.h \ From e969d58689a6a5f57e896ef6b8e0dab649904c8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Mar 2020 15:11:54 -0500 Subject: [PATCH 006/189] handle ntcp2.proxy parameter --- libi2pd/Config.cpp | 4 +- libi2pd/NTCP2.cpp | 139 +++++++++++++++++++++-------------------- libi2pd/Transports.cpp | 12 ++-- 3 files changed, 80 insertions(+), 75 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 4050f769..521ebf65 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -60,8 +60,7 @@ namespace config { ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") - ("ntcp2proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") + ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") @@ -240,6 +239,7 @@ namespace config { ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") + ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") ; options_description nettime("Time sync options"); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 10cc3d89..c46dbd81 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1189,46 +1189,48 @@ namespace transport case eSocksProxy: { // TODO: support username/password auth etc - uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); - } - }); - uint8_t readbuff[2]; - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), - [=](const boost::system::error_code & ec, std::size_t transferred) - { - LogPrint(eLogError, "NTCP2: ", transferred); - if(ec) - { - LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if(readbuff[1] == 0xba) + static const uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; + LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); } - else if (readbuff[1] == 0xff) + }); + auto readbuff = std::make_shared >(); + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(*readbuff, 2), + [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) + { + LogPrint(eLogError, "NTCP2: ", transferred); + if(ec) { - LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); timer->cancel(); conn->Terminate(); return; } - LogPrint(eLogError, "NTCP2:", readbuff[1]); - } - LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); + else if(transferred == 2) + { + if((*readbuff)[1] == 0xba) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if ((*readbuff)[1] == 0xff) + { + LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + LogPrint(eLogError, "NTCP2:", (*readbuff)[1]); + } + LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); break; } case eHTTPProxy: @@ -1245,47 +1247,47 @@ namespace transport std::ostream out(&writebuff); out << req.to_string(); - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); - }); + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); boost::asio::streambuf * readbuff = new boost::asio::streambuf; boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [=] (const boost::system::error_code & ec, std::size_t transferred) - { - if(ec) + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) { - LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + if(ec) { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - { - LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); - } + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); } else - LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); break; } default: @@ -1304,7 +1306,8 @@ namespace transport auto timeout = NTCP_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 34ec25f4..8a36c5aa 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -157,7 +157,7 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); - std::string ntcp2proxy; i2p::config::GetOption("ntcp2proxy", ntcp2proxy); + std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); i2p::http::URL proxyurl; uint16_t softLimit, hardLimit, threads; i2p::config::GetOption("limits.ntcpsoft", softLimit); @@ -201,7 +201,7 @@ namespace transport bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { - if(ntcp2proxy.size()) + if(!ntcp2proxy.empty()) { if(proxyurl.parse(ntcp2proxy)) { @@ -223,9 +223,11 @@ namespace transport LogPrint(eLogError, "Transports: invalid NTCP2 proxy url ", ntcp2proxy); return; } - - // m_NTCP2Server = new NTCP2Server (); - // m_NTCP2Server->Start (); + else + { + m_NTCP2Server = new NTCP2Server (); + m_NTCP2Server->Start (); + } } // create acceptors From 2d3fad2cdbf01f2fa19e4a9fb708db80ca432902 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 2 Mar 2020 16:24:00 -0500 Subject: [PATCH 007/189] correct proxy buffers --- libi2pd/NTCP2.cpp | 450 +++++++++++++++++++++++----------------------- 1 file changed, 226 insertions(+), 224 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index c46dbd81..3dfd6250 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -377,78 +377,6 @@ namespace transport } } - void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - - // build request - size_t sz = 0; - uint8_t buff[256]; - uint8_t readbuff[256]; - buff[0] = 0x05; - buff[1] = 0x01; - buff[2] = 0x00; - - if(addrtype == eIP4Address) - { - buff[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eIP6Address) - { - buff[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eHostname) - { - buff[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > sizeof(buff)) - { - // too big - return; - } - buff[4] = (uint8_t) addrsize; - memcpy(buff+5, host.c_str(), addrsize); - } - htobe16buf(buff+sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { - if(ec) - { - LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); - return; - } - }); - - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) { - if(e) - { - LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); - } - else if(transferred == sz) - { - if( readbuff[1] == 0x00) - { - timer->cancel(); - conn->ClientLogin(); - return; - } - } - if(!e) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - timer->cancel(); - conn->Terminate(); - }); - } - - NTCP2Session::~NTCP2Session () { delete[] m_NextReceivedBuffer; @@ -1168,158 +1096,6 @@ namespace transport EncryptAndSendNextBuffer (payloadLen); } - void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) - { - m_ProxyType = proxytype; - m_ProxyAddress = addr; - m_ProxyPort = port; - } - - void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - if (ecode) - { - LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); - timer->cancel(); - conn->Terminate(); - return; - } - switch (m_ProxyType) - { - case eSocksProxy: - { - // TODO: support username/password auth etc - static const uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), - [] (const boost::system::error_code & ec, std::size_t transferred) - { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); - } - }); - auto readbuff = std::make_shared >(); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(*readbuff, 2), - [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) - { - LogPrint(eLogError, "NTCP2: ", transferred); - if(ec) - { - LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if((*readbuff)[1] == 0xba) - { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; - } - else if ((*readbuff)[1] == 0xff) - { - LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); - timer->cancel(); - conn->Terminate(); - return; - } - LogPrint(eLogError, "NTCP2:", (*readbuff)[1]); - } - LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); - break; - } - case eHTTPProxy: - { - i2p::http::HTTPReq req; - req.method = "CONNECT"; - req.version ="HTTP/1.1"; - if(addrtype == eIP6Address) - req.uri = "[" + host + "]:" + std::to_string(port); - else - req.uri = host + ":" + std::to_string(port); - - boost::asio::streambuf writebuff; - std::ostream out(&writebuff); - out << req.to_string(); - - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) - { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); - }); - - boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) - { - if(ec) - { - LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) - { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); - } - else - LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); - break; - } - default: - LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); - } - } - - void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(!m_ProxyEndpoint) return - GetService().post([=]() { - if (this->AddNTCP2Session (conn)) - { - - auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { if (!m_SendKey || !m_SendSipKey) return; @@ -1640,5 +1416,231 @@ namespace transport ScheduleTermination (); } } + + void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) + { + m_ProxyType = proxytype; + m_ProxyAddress = addr; + m_ProxyPort = port; + } + + void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + if (ecode) + { + LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); + timer->cancel(); + conn->Terminate(); + return; + } + switch (m_ProxyType) + { + case eSocksProxy: + { + // TODO: support username/password auth etc + static const uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + { + LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); + } + }); + auto readbuff = std::make_shared >(2); + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), + [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + return; + } + else if(transferred == 2) + { + if((*readbuff)[1] == 0x00) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if ((*readbuff)[1] == 0xff) + { + LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + LogPrint(eLogError, "NTCP2:", (int)(*readbuff)[1]); + } + LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); + break; + } + case eHTTPProxy: + { + i2p::http::HTTPReq req; + req.method = "CONNECT"; + req.version ="HTTP/1.1"; + if(addrtype == eIP6Address) + req.uri = "[" + host + "]:" + std::to_string(port); + else + req.uri = host + ":" + std::to_string(port); + + boost::asio::streambuf writebuff; + std::ostream out(&writebuff); + out << req.to_string(); + + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); + + boost::asio::streambuf * readbuff = new boost::asio::streambuf; + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + } + else + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); + break; + } + default: + LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); + } + } + + void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(!m_ProxyEndpoint) return; + GetService().post([this, host, port, addrtype, conn]() { + if (this->AddNTCP2Session (conn)) + { + + auto timer = std::make_shared(GetService()); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); + } + + void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + // build request + size_t sz = 0; + auto buff = std::make_shared >(256); + auto readbuff = std::make_shared >(256); + (*buff)[0] = 0x05; + (*buff)[1] = 0x01; + (*buff)[2] = 0x00; + + if(addrtype == eIP4Address) + { + (*buff)[3] = 0x01; + auto addr = boost::asio::ip::address::from_string(host).to_v4(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff->data () + 4, addrbytes.data(), addrsize); + } + else if (addrtype == eIP6Address) + { + (*buff)[3] = 0x04; + auto addr = boost::asio::ip::address::from_string(host).to_v6(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff->data () + 4, addrbytes.data(), addrsize); + } + else if (addrtype == eHostname) + { + (*buff)[3] = 0x03; + size_t addrsize = host.size(); + sz = addrsize + 1 + 4; + if (2 + sz > buff->size ()) + { + // too big + return; + } + (*buff)[4] = (uint8_t) addrsize; + memcpy(buff->data() + 5, host.c_str(), addrsize); + } + htobe16buf(buff->data () + sz, port); + sz += 2; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t written) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); + return; + } + }); + + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), + [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) + { + if(e) + { + LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); + } + else if(transferred == sz) + { + if((*readbuff)[1] == 0x00) + { + timer->cancel(); + conn->ClientLogin(); + return; + } + } + if(!e) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + timer->cancel(); + conn->Terminate(); + }); + } + } } From 1e9a53da3fead5b1caaea7145ef90eb411bc2ff7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Mar 2020 15:54:09 -0500 Subject: [PATCH 008/189] delete stream by id for HTTP interface --- libi2pd/Destination.cpp | 10 ++++++++++ libi2pd/Destination.h | 1 + libi2pd/Streaming.cpp | 9 +++++++++ libi2pd/Streaming.h | 1 + 4 files changed, 21 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6544d120..d4620ed9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1191,6 +1191,16 @@ namespace client } } + bool ClientDestination::DeleteStream (uint32_t recvStreamID) + { + if (m_StreamingDestination->DeleteStream (recvStreamID)) + return true; + for (auto it: m_StreamingDestinationsByPorts) + if (it.second->DeleteStream (recvStreamID)) + return true; + return false; + } + RunnableClientDestination::RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): RunnableService ("Destination"), ClientDestination (GetIOService (), keys, isPublic, params) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index ed3abdfb..23ed5188 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -281,6 +281,7 @@ namespace client // for HTTP only std::vector > GetAllStreams () const; + bool DeleteStream (uint32_t recvStreamID); }; class RunnableClientDestination: private i2p::util::RunnableService, public ClientDestination diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index b5f935fe..97a653f5 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1128,6 +1128,15 @@ namespace stream } } + bool StreamingDestination::DeleteStream (uint32_t recvStreamID) + { + auto it = m_Streams.find (recvStreamID); + if (it == m_Streams.end ()) + return false; + DeleteStream (it->second); + return true; + } + void StreamingDestination::SetAcceptor (const Acceptor& acceptor) { m_Acceptor = acceptor; // we must set it immediately for IsAcceptorSet diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 3424bb2d..9962ad8d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -250,6 +250,7 @@ namespace stream std::shared_ptr CreateNewOutgoingStream (std::shared_ptr remote, int port = 0); void DeleteStream (std::shared_ptr stream); + bool DeleteStream (uint32_t recvStreamID); void SetAcceptor (const Acceptor& acceptor); void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; From 5eec580727df7d2865f6478ccb21498fafa2556f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Mar 2020 18:31:22 -0500 Subject: [PATCH 009/189] delete strem from destination upon termination --- libi2pd/Streaming.cpp | 7 ++++--- libi2pd/Streaming.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 97a653f5..3efcfb99 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -86,13 +86,14 @@ namespace stream LogPrint (eLogDebug, "Streaming: Stream deleted"); } - void Stream::Terminate () // shoudl be called from StreamingDestination::Stop only + void Stream::Terminate (bool deleteFromDestination) // shoudl be called from StreamingDestination::Stop only { m_AckSendTimer.cancel (); m_ReceiveTimer.cancel (); m_ResendTimer.cancel (); //CleanUp (); /* Need to recheck - broke working on windows */ - //m_LocalDestination.DeleteStream (shared_from_this ()); + if (deleteFromDestination) + m_LocalDestination.DeleteStream (shared_from_this ()); } void Stream::CleanUp () @@ -993,7 +994,7 @@ namespace stream { std::unique_lock l(m_StreamsMutex); for (auto it: m_Streams) - it.second->Terminate (); + it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 9962ad8d..985a7eca 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -180,7 +180,7 @@ namespace stream int GetWindowSize () const { return m_WindowSize; }; int GetRTT () const { return m_RTT; }; - void Terminate (); + void Terminate (bool deleteFromDestination = true); private: From 51d018acc61c84aca55d669a2157fdcf3e8cd4c3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 5 Mar 2020 04:14:39 +0300 Subject: [PATCH 010/189] webconsole: add stream closing Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 180 ++++++++++++++++++++++++++++-------------- daemon/HTTPServer.h | 1 + 2 files changed, 121 insertions(+), 60 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7dc6a9d2..36e26785 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -54,6 +54,7 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " a, .slide label { text-decoration: none; color: #894C84; }\r\n" " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n" + " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial;}\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" " .left { float: left; position: absolute; }\r\n" @@ -64,10 +65,11 @@ namespace http { " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" - " .slide p, .slide [type='checkbox']{ display:none; }\r\n" - " .slide [type='checkbox']:checked ~ p { display:block; margin-top: 0; padding: 0; }\r\n" + " .slide p, .slide [type='checkbox'] { display: none; }\r\n" + " .slide [type='checkbox']:checked ~ p { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" + " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -89,10 +91,12 @@ namespace http { const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; const char HTTP_COMMAND_LOGLEVEL[] = "set_loglevel"; + const char HTTP_COMMAND_KILLSTREAM[] = "closestream"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; static std::string ConvertTime (uint64_t time); + std::map HTTPConnection::m_Tokens; static void ShowUptime (std::stringstream& s, int seconds) { @@ -203,10 +207,7 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - void ShowStatus ( - std::stringstream& s, - bool includeHiddenContent, - i2p::http::OutputFormatEnum outputFormat) + void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) { s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); @@ -253,12 +254,12 @@ namespace http { ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; - s << "
"; - if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n

\r\n"; - } - if(includeHiddenContent) { - s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; + s << "

"; + if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { + s << "\r\n\r\n

\r\n"; + } + if(includeHiddenContent) { + s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; s << "Our external address:" << "
\r\n" ; @@ -292,12 +293,12 @@ namespace http { } s << address->host.to_string() << ":" << address->port << "
\r\n"; } - } + } s << "

\r\n
\r\n"; - if(outputFormat==OutputFormatEnum::forQtUi) { - s << "
"; - } - s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; + if(outputFormat==OutputFormatEnum::forQtUi) { + s << "
"; + } + s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; @@ -308,17 +309,17 @@ namespace http { s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; - if(outputFormat==OutputFormatEnum::forWebConsole) { - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - s << "\r\n"; - s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; - } + if(outputFormat==OutputFormatEnum::forWebConsole) { + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); + s << "\r\n"; + s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; + } } void ShowLocalDestinations (std::stringstream& s) @@ -352,7 +353,7 @@ namespace http { static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest) { - s << "Base64:
\r\n
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { @@ -403,19 +404,21 @@ namespace http { s << "
\r\n"; } - void ShowLocalDestination (std::stringstream& s, const std::string& b32) + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token) { s << "Local Destination:
\r\n
\r\n"; i2p::data::IdentHash ident; ident.FromBase32 (b32); auto dest = i2p::client::context.FindLocalDestination (ident); + if (dest) { ShowLeaseSetDestination (s, dest); // show streams - s << "\r\n"; - s << ""; - s << ""; + s << "
Streams
StreamIDDestination
\r\n\r\n\r\n"; + s << ""; + s << ""; s << ""; s << ""; s << ""; @@ -424,13 +427,20 @@ namespace http { s << ""; s << ""; s << ""; - s << "\r\n"; + s << "\r\n\r\n\r\n"; for (const auto& it: dest->GetAllStreams ()) { + auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()); s << ""; - s << ""; - s << ""; + s << ""; + if (it->GetRecvStreamID ()) { + s << ""; + } else { + s << ""; s << ""; s << ""; s << ""; @@ -441,7 +451,7 @@ namespace http { s << ""; s << "\r\n"; } - s << "
Streams
StreamID"; // Stream closing button column + s << "DestinationSentReceivedOutRTTWindowStatus
" << it->GetSendStreamID () << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << "" << it->GetRecvStreamID () << ""; + } + s << "" << streamDest << "" << it->GetNumSentBytes () << "" << it->GetNumReceivedBytes () << "" << it->GetSendQueueSize () << "" << (int)it->GetStatus () << "
"; + s << "\r\n"; } } @@ -858,7 +868,8 @@ namespace http { m_Socket->close (); } - bool HTTPConnection::CheckAuth (const HTTPReq & req) { + bool HTTPConnection::CheckAuth (const HTTPReq & req) + { /* method #1: http://user:pass@127.0.0.1:7070/ */ if (req.uri.find('@') != std::string::npos) { URL url; @@ -920,7 +931,7 @@ namespace http { } else if (req.uri.find("cmd=") != std::string::npos) { HandleCommand (req, res, s); } else { - ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole); + ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole); res.add_header("Refresh", "10"); } ShowPageTail (s); @@ -930,7 +941,23 @@ namespace http { SendReply (res, content); } - std::map HTTPConnection::m_Tokens; + uint32_t HTTPConnection::CreateToken () + { + uint32_t token; + RAND_bytes ((uint8_t *)&token, 4); + token &= 0x7FFFFFFF; // clear first bit + auto ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) + { + if (ts > it->second + TOKEN_EXPIRATION_TIMEOUT) + it = m_Tokens.erase (it); + else + ++it; + } + m_Tokens[token] = ts; + return token; + } + void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; @@ -947,18 +974,7 @@ namespace http { ShowTunnels (s); else if (page == HTTP_PAGE_COMMANDS) { - uint32_t token; - RAND_bytes ((uint8_t *)&token, 4); - token &= 0x7FFFFFFF; // clear first bit - auto ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) - { - if (ts > it->second + TOKEN_EXPIRATION_TIMEOUT) - it = m_Tokens.erase (it); - else - ++it; - } - m_Tokens[token] = ts; + uint32_t token = CreateToken (); ShowCommands (s, token); } else if (page == HTTP_PAGE_TRANSIT_TUNNELS) @@ -966,7 +982,10 @@ namespace http { else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) ShowLocalDestinations (s); else if (page == HTTP_PAGE_LOCAL_DESTINATION) - ShowLocalDestination (s, params["b32"]); + { + uint32_t token = CreateToken (); + ShowLocalDestination (s, params["b32"], token); + } else if (page == HTTP_PAGE_I2CP_LOCAL_DESTINATION) ShowI2CPLocalDestination (s, params["i2cp_id"]); else if (page == HTTP_PAGE_SAM_SESSIONS) @@ -992,7 +1011,10 @@ namespace http { url.parse(req.uri); url.parse_query(params); + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + std::string redirect = "5; url=" + webroot + "?page=commands"; std::string token = params["token"]; + if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) { ShowError(s, "Invalid token"); @@ -1008,36 +1030,74 @@ namespace http { i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_DISABLE_TRANSIT) i2p::context.SetAcceptsTunnels (false); - else if (cmd == HTTP_COMMAND_SHUTDOWN_START) { + else if (cmd == HTTP_COMMAND_SHUTDOWN_START) + { i2p::context.SetAcceptsTunnels (false); #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) Daemon.gracefulShutdownInterval = 10*60; #elif defined(WIN32_APP) i2p::win32::GracefulShutdown (); #endif - } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { + } + else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) + { i2p::context.SetAcceptsTunnels (true); #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) Daemon.gracefulShutdownInterval = 0; #elif defined(WIN32_APP) i2p::win32::StopGracefulShutdown (); #endif - } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { + } + else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) + { #ifndef WIN32_APP Daemon.running = false; #else i2p::win32::StopWin32App (); #endif - } else if (cmd == HTTP_COMMAND_LOGLEVEL){ + } + else if (cmd == HTTP_COMMAND_LOGLEVEL) + { std::string level = params["level"]; SetLogLevel (level); - } else { + } + else if (cmd == HTTP_COMMAND_KILLSTREAM) + { + std::string b32 = params["b32"]; + uint32_t streamID = std::stoul(params["streamID"], nullptr); + + i2p::data::IdentHash ident; + ident.FromBase32 (b32); + auto dest = i2p::client::context.FindLocalDestination (ident); + + if (streamID) + { + if (dest) + { + if(dest->DeleteStream (streamID)) + s << "SUCCESS: Stream closed

\r\n"; + else + s << "ERROR: Stream not found or already was closed

\r\n"; + } + else + s << "ERROR: Destination not found

\r\n"; + } + else + s << "ERROR: StreamID can be null

\r\n"; + + s << "Return to destination page
\r\n"; + s << "

You will be redirected back in 5 seconds"; + redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32; + res.add_header("Refresh", redirect.c_str()); + return; + } + else + { res.code = 400; ShowError(s, "Unknown command: " + cmd); return; } - std::string webroot; i2p::config::GetOption("http.webroot", webroot); - std::string redirect = "5; url=" + webroot + "?page=commands"; + s << "SUCCESS: Command accepted

\r\n"; s << "Back to commands list
\r\n"; s << "

You will be redirected in 5 seconds"; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 3d32ed2b..f5ac95fc 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -35,6 +35,7 @@ namespace http void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void SendReply (HTTPRes & res, std::string & content); + uint32_t CreateToken (); private: From dd9b5faa5c072c24aadf4ca6c31d6ac00be992e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Mar 2020 18:44:15 -0500 Subject: [PATCH 011/189] fixed crash on termination --- libi2pd_client/I2CP.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index a14588a8..c09b7f4d 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -814,8 +814,11 @@ namespace client { m_IsRunning = false; m_Acceptor.cancel (); - for (auto& it: m_Sessions) - it.second->Stop (); + { + auto sessions = m_Sessions; + for (auto& it: sessions) + it.second->Stop (); + } m_Sessions.clear (); m_Service.stop (); if (m_Thread) From 64da62dbe69be040215babad89fc481f0e429c00 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Mar 2020 18:46:40 -0500 Subject: [PATCH 012/189] alsways store latest symmkey --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 33 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 +-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d2d07343..a066dc17 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -39,25 +39,28 @@ namespace garlic return m_KeyData.GetTag (); } - const uint8_t * RatchetTagSet::GetSymmKey (int index) + void RatchetTagSet::GetSymmKey (int index, uint8_t * key) { - // TODO: store intermediate keys - if (m_NextSymmKeyIndex > 0 && index == m_NextSymmKeyIndex) + if (m_NextSymmKeyIndex > 0 && index >= m_NextSymmKeyIndex) { - i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); - m_NextSymmKeyIndex++; + auto num = index + 1 - m_NextSymmKeyIndex; + for (int i = 0; i < num; i++) + i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); + m_NextSymmKeyIndex += num; + memcpy (key, m_CurrentSymmKeyCK + 32, 32); } else - CalculateSymmKeyCK (index); - return m_CurrentSymmKeyCK + 32; + CalculateSymmKeyCK (index, key); } - void RatchetTagSet::CalculateSymmKeyCK (int index) + void RatchetTagSet::CalculateSymmKeyCK (int index, uint8_t * key) { - i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + // TODO: store intermediate keys + uint8_t currentSymmKeyCK[64]; + i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", currentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) for (int i = 0; i < index; i++) - i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_n = HKDF(symmKey_chainKey_(n-1), SYMMKEY_CONSTANT, "SymmetricRatchet", 64) - m_NextSymmKeyIndex = index + 1; + i2p::crypto::HKDF (currentSymmKeyCK, nullptr, 0, "SymmetricRatchet", currentSymmKeyCK); // keydata_n = HKDF(symmKey_chainKey_(n-1), SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + memcpy (key, currentSymmKeyCK + 32, 32); } ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): @@ -373,7 +376,9 @@ namespace garlic memcpy (out, &tag, 8); // ad = The session tag, 8 bytes // ciphertext = ENCRYPT(k, n, payload, ad) - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, m_SendTagset.GetSymmKey (index), nonce, out + 8, outLen - 8, true)) // encrypt + uint8_t key[32]; + m_SendTagset.GetSymmKey (index, key); + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, key, nonce, out + 8, outLen - 8, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; @@ -387,7 +392,9 @@ namespace garlic CreateNonce (index, nonce); // tag's index len -= 8; // tag std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveTagset.GetSymmKey (index), nonce, payload.data (), len - 16, false)) // decrypt + uint8_t key[32]; + m_ReceiveTagset.GetSymmKey (index, key); + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, key, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index e5836cd4..f23c569c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -22,11 +22,11 @@ namespace garlic void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); int GetNextIndex () const { return m_NextIndex; }; - const uint8_t * GetSymmKey (int index); + void GetSymmKey (int index, uint8_t * key); private: - void CalculateSymmKeyCK (int index); + void CalculateSymmKeyCK (int index, uint8_t * key); private: From 4adc741de319ee2afc6f51f180fff33db63869b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 8 Mar 2020 18:13:41 -0400 Subject: [PATCH 013/189] send DeliveryStatusMsg for LeaseSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 53 ++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + libi2pd/Garlic.cpp | 60 ++++++++++++++--------- libi2pd/Garlic.h | 11 +++-- 4 files changed, 96 insertions(+), 29 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a066dc17..5f2eb5c8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -6,6 +6,8 @@ #include "Tag.h" #include "I2PEndian.h" #include "Timestamp.h" +#include "Tunnel.h" +#include "TunnelPool.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -460,12 +462,22 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { + uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 7; // datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); - if (leaseSet) + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()) : nullptr; + std::shared_ptr deliveryStatus; + if (leaseSet) + { payloadLen += leaseSet->GetPayloadLength () + 13; + deliveryStatus = CreateEncryptedDeliveryStatusMsg (leaseSet->GetMsgID ()); + payloadLen += deliveryStatus->GetPayloadLength () + 49; + if (GetLeaseSetUpdateMsgID ()) GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); // remove previous + SetLeaseSetUpdateStatus (eLeaseSetSubmitted); + SetLeaseSetUpdateMsgID (leaseSet->GetMsgID ()); + SetLeaseSetSubmissionTime (ts); + } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -475,10 +487,13 @@ namespace garlic // DateTime v[offset] = eECIESx25519BlkDateTime; offset++; htobe16buf (v.data () + offset, 4); offset += 2; - htobe32buf (v.data () + offset, i2p::util::GetSecondsSinceEpoch ()); offset += 4; + htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds // LeaseSet if (leaseSet) offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + // DeliveryStatus + if (deliveryStatus) + offset += CreateDeliveryStatusClove (deliveryStatus, v.data () + offset, payloadLen - offset); // msg if (msg && m_Destination) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); @@ -513,6 +528,38 @@ namespace garlic return cloveSize + 3; } + size_t ECIESX25519AEADRatchetSession::CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len) + { + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 37 /* delivery instruction */; + if ((int)len < cloveSize + 3) return 0; + buf[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (buf + 1, cloveSize); // size + buf += 3; + if (GetOwner ()) + { + auto inboundTunnel = GetOwner ()->GetTunnelPool ()->GetNextInboundTunnel (); + if (inboundTunnel) + { + // delivery instructions + *buf = eGarlicDeliveryTypeTunnel << 5; buf++; // delivery instructions flag tunnel + // hash and tunnelID sequence is reversed for Garlic + memcpy (buf, inboundTunnel->GetNextIdentHash (), 32); buf += 32;// To Hash + htobe32buf (buf, inboundTunnel->GetNextTunnelID ()); buf += 4;// tunnelID + } + else + { + LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); + return 0; + } + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); + } + else + return 0; + return cloveSize + 3; + } + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (int numTags) { for (int i = 0; i < numTags; i++) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index f23c569c..4d273c13 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -107,6 +107,7 @@ namespace garlic std::vector CreatePayload (std::shared_ptr msg); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + size_t CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len); void GenerateMoreReceiveTags (int numTags); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 45c97172..dd63572c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -58,6 +58,34 @@ namespace garlic m_SharedRoutingPath = path; } + bool GarlicRoutingSession::MessageConfirmed (uint32_t msgID) + { + if (msgID == GetLeaseSetUpdateMsgID ()) + { + SetLeaseSetUpdateStatus (eLeaseSetUpToDate); + SetLeaseSetUpdateMsgID (0); + LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); + return true; + } + return false; + } + + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) + { + auto msg = CreateDeliveryStatusMsg (msgID); + if (GetOwner ()) + { + //encrypt + uint8_t key[32], tag[32]; + RAND_bytes (key, 32); // random session key + RAND_bytes (tag, 32); // random session tag + GetOwner ()->SubmitSessionKey (key, tag); + ElGamalAESSession garlic (key, tag); + msg = garlic.WrapSingleMessage (msg); + } + return msg; + } + ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, int numTags, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet), @@ -289,19 +317,12 @@ namespace garlic htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID size += 4; // create msg - auto msg = CreateDeliveryStatusMsg (msgID); - if (GetOwner ()) - { - //encrypt - uint8_t key[32], tag[32]; - RAND_bytes (key, 32); // random session key - RAND_bytes (tag, 32); // random session tag - GetOwner ()->SubmitSessionKey (key, tag); - ElGamalAESSession garlic (key, tag); - msg = garlic.WrapSingleMessage (msg); - } - memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); - size += msg->GetLength (); + auto msg = CreateEncryptedDeliveryStatusMsg (msgID); + if (msg) + { + memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); + size += msg->GetLength (); + } // fill clove uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 8000; // 8 sec uint32_t cloveID; @@ -334,17 +355,12 @@ namespace garlic return tags; } - void ElGamalAESSession::MessageConfirmed (uint32_t msgID) + bool ElGamalAESSession::MessageConfirmed (uint32_t msgID) { TagsConfirmed (msgID); - if (msgID == GetLeaseSetUpdateMsgID ()) - { - SetLeaseSetUpdateStatus (eLeaseSetUpToDate); - SetLeaseSetUpdateMsgID (0); - LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); - } - else + if (!GarlicRoutingSession::MessageConfirmed (msgID)) CleanupExpiredTags (); + return true; } void ElGamalAESSession::TagsConfirmed (uint32_t msgID) @@ -775,7 +791,7 @@ namespace garlic void GarlicDestination::HandleDeliveryStatusMessage (uint32_t msgID) { - ElGamalAESSessionPtr session; + GarlicRoutingSessionPtr session; { std::unique_lock l(m_DeliveryStatusSessionsMutex); auto it = m_DeliveryStatusSessions.find (msgID); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 9c256b48..be0ac117 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -104,7 +104,8 @@ namespace garlic virtual ~GarlicRoutingSession (); virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession - + virtual bool MessageConfirmed (uint32_t msgID); + void SetLeaseSetUpdated () { if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated; @@ -118,7 +119,7 @@ namespace garlic GarlicDestination * GetOwner () const { return m_Owner; } void SetOwner (GarlicDestination * owner) { m_Owner = owner; } - + protected: LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } @@ -127,6 +128,8 @@ namespace garlic void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } + std::shared_ptr CreateEncryptedDeliveryStatusMsg (uint32_t msgID); + private: GarlicDestination * m_Owner; @@ -165,7 +168,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - void MessageConfirmed (uint32_t msgID); + bool MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left bool CleanupUnconfirmedTags (); // returns true if something has been deleted @@ -267,7 +270,7 @@ namespace garlic std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; - std::unordered_map m_DeliveryStatusSessions; // msgID -> session + std::unordered_map m_DeliveryStatusSessions; // msgID -> session public: From 3c534798643d9b0e7f7a529b24beacd679732281 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 8 Mar 2020 20:58:59 -0400 Subject: [PATCH 014/189] update LeaseSet for ECIESX25519AEADRatchet sessions --- libi2pd/Garlic.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index dd63572c..9ac5540f 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -810,8 +810,12 @@ namespace garlic void GarlicDestination::SetLeaseSetUpdated () { - std::unique_lock l(m_SessionsMutex); - for (auto& it: m_Sessions) + { + std::unique_lock l(m_SessionsMutex); + for (auto& it: m_Sessions) + it.second->SetLeaseSetUpdated (); + } + for (auto& it: m_ECIESx25519Sessions) it.second->SetLeaseSetUpdated (); } From ee73ee365f5d02a4fc29832745f70a381b085aa1 Mon Sep 17 00:00:00 2001 From: user Date: Tue, 10 Mar 2020 21:49:04 +0800 Subject: [PATCH 015/189] some work on qt --- .gitignore | 4 + qt/i2pd_qt/DelayedSaveManager.cpp | 3 + qt/i2pd_qt/DelayedSaveManager.h | 24 +++++ qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 140 ++++++++++++++++++++++++++ qt/i2pd_qt/DelayedSaveManagerImpl.h | 82 +++++++++++++++ qt/i2pd_qt/Saver.cpp | 6 ++ qt/i2pd_qt/Saver.h | 22 ++++ qt/i2pd_qt/SaverImpl.cpp | 79 +++++++++++++++ qt/i2pd_qt/SaverImpl.h | 33 ++++++ qt/i2pd_qt/TunnelPane.cpp | 2 +- qt/i2pd_qt/i2pd_qt.pro | 14 ++- qt/i2pd_qt/mainwindow.cpp | 103 ++++++++----------- qt/i2pd_qt/mainwindow.h | 29 ++++-- 13 files changed, 466 insertions(+), 75 deletions(-) create mode 100644 qt/i2pd_qt/DelayedSaveManager.cpp create mode 100644 qt/i2pd_qt/DelayedSaveManager.h create mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.cpp create mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.h create mode 100644 qt/i2pd_qt/Saver.cpp create mode 100644 qt/i2pd_qt/Saver.h create mode 100644 qt/i2pd_qt/SaverImpl.cpp create mode 100644 qt/i2pd_qt/SaverImpl.h diff --git a/.gitignore b/.gitignore index c2db70e0..68aea504 100644 --- a/.gitignore +++ b/.gitignore @@ -264,3 +264,7 @@ qt/i2pd_qt/*.ui_* #unknown android stuff android/libs/ + +#various logs +*LOGS/ + diff --git a/qt/i2pd_qt/DelayedSaveManager.cpp b/qt/i2pd_qt/DelayedSaveManager.cpp new file mode 100644 index 00000000..8e17d111 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManager.cpp @@ -0,0 +1,3 @@ +#include "DelayedSaveManager.h" + +DelayedSaveManager::DelayedSaveManager(){} diff --git a/qt/i2pd_qt/DelayedSaveManager.h b/qt/i2pd_qt/DelayedSaveManager.h new file mode 100644 index 00000000..9a9a997b --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManager.h @@ -0,0 +1,24 @@ +#ifndef DELAYEDSAVEMANAGER_H +#define DELAYEDSAVEMANAGER_H + +#include "Saver.h" + +class DelayedSaveManager +{ +public: + DelayedSaveManager(); + + virtual void setSaver(Saver* saver)=0; + + typedef unsigned int DATA_SERIAL_TYPE; + + virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool needsTunnelFocus, std::string tunnelNameToFocus)=0; + + //returns false iff save failed + virtual bool appExiting()=0; + + virtual bool needsFocusOnTunnel()=0; + virtual std::string getTunnelNameToFocus()=0; +}; + +#endif // DELAYEDSAVEMANAGER_H diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp new file mode 100644 index 00000000..5588d7e9 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -0,0 +1,140 @@ +#include "DelayedSaveManagerImpl.h" + +DelayedSaveManagerImpl::DelayedSaveManagerImpl() : + saver(nullptr), + lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL), + lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP), + exiting(false), + thread(new DelayedSaveThread(this)) +{ +} + +void DelayedSaveManagerImpl::setSaver(Saver* saver) { + this->saver = saver; +} + +void DelayedSaveManagerImpl::start() { + thread->start(); +} + +bool DelayedSaveManagerImpl::isSaverValid() { + return saver != nullptr; +} + +void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus) { + if(lastDataSerialSeen==dataSerial)return; + this->focusOnTunnel = focusOnTunnel; + this->tunnelNameToFocus = tunnelNameToFocus; + lastDataSerialSeen=dataSerial; + assert(isSaverValid()); + TIMESTAMP_TYPE now = getTime(); + TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS; + if(now < wakeTime) { + //defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS + thread->deferSaveUntil(wakeTime); + return; + } + lastSaveStartedTimestamp = now; + thread->startSavingNow(); +} + +bool DelayedSaveManagerImpl::appExiting() { + exiting=true; + thread->wakeThreadAndJoinThread(); + assert(isSaverValid()); + saver->save(false, ""); + return true; +} + +DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_): + delayedSaveManagerImpl(delayedSaveManagerImpl_), + mutex(new QMutex()), + waitCondition(new QWaitCondition()), + saveNow(false), + defer(false) +{ + mutex->lock(); +} + +DelayedSaveThread::~DelayedSaveThread(){ + mutex->unlock(); + delete mutex; + delete waitCondition; +} + +void DelayedSaveThread::run() { + forever { + if(delayedSaveManagerImpl->isExiting())return; + waitCondition->wait(mutex, WAIT_TIME_MILLIS); + if(delayedSaveManagerImpl->isExiting())return; + Saver* saver = delayedSaveManagerImpl->getSaver(); + assert(saver!=nullptr); + if(saveNow) { + saveNow = false; + const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); + saver->save(focusOnTunnel, tunnelNameToFocus); + continue; + } + if(defer) { + defer=false; +#define max(a,b) (((a)>(b))?(a):(b)) + forever { + TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime(); + TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0); + if(millisToWait>0) { + waitCondition->wait(mutex, millisToWait); + if(delayedSaveManagerImpl->isExiting())return; + continue; + } + const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); + saver->save(focusOnTunnel, tunnelNameToFocus); + break; //break inner loop + } + } + } +} + +void DelayedSaveThread::wakeThreadAndJoinThread() { + waitCondition->wakeAll(); + quit(); + wait();//join //"similar to the POSIX pthread_join()" +} + +DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() { + return QDateTime::currentMSecsSinceEpoch(); +} + +void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) { + wakeTime = wakeTime_; + defer = true; + waitCondition->wakeAll(); +} + +void DelayedSaveThread::startSavingNow() { + //mutex->lock(); + saveNow=true; + waitCondition->wakeAll(); + //mutex->unlock(); +} + +DelayedSaveManagerImpl::~DelayedSaveManagerImpl() { + thread->wakeThreadAndJoinThread(); + delete thread; +} + +bool DelayedSaveManagerImpl::isExiting() { + return exiting; +} +Saver* DelayedSaveManagerImpl::getSaver() { + return saver; +} + +bool DelayedSaveManagerImpl::needsFocusOnTunnel() { + return focusOnTunnel; +} + +std::string DelayedSaveManagerImpl::getTunnelNameToFocus() { + return tunnelNameToFocus; +} diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.h b/qt/i2pd_qt/DelayedSaveManagerImpl.h new file mode 100644 index 00000000..0d8c7592 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.h @@ -0,0 +1,82 @@ +#ifndef DELAYEDSAVEMANAGERIMPL_H +#define DELAYEDSAVEMANAGERIMPL_H + +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "DelayedSaveManager.h" +#include "Saver.h" + +class DelayedSaveManagerImpl; + +class DelayedSaveThread : public QThread +{ + Q_OBJECT + +public: + static constexpr unsigned long WAIT_TIME_MILLIS = 1000L; + + typedef qint64 TIMESTAMP_TYPE; + static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0; + + DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl); + virtual ~DelayedSaveThread(); + + void run() override; + + void deferSaveUntil(TIMESTAMP_TYPE wakeTime); + void startSavingNow(); + + void wakeThreadAndJoinThread(); + +private: + DelayedSaveManagerImpl* delayedSaveManagerImpl; + QMutex* mutex; + QWaitCondition* waitCondition; + volatile bool saveNow; + volatile bool defer; + volatile TIMESTAMP_TYPE wakeTime; +}; + +class DelayedSaveManagerImpl : public DelayedSaveManager +{ +public: + DelayedSaveManagerImpl(); + virtual ~DelayedSaveManagerImpl(); + virtual void setSaver(Saver* saver); + virtual void start(); + virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus); + virtual bool appExiting(); + + typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE; + + static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0; + bool isExiting(); + Saver* getSaver(); + static TIMESTAMP_TYPE getTime(); + + bool needsFocusOnTunnel(); + std::string getTunnelNameToFocus(); + +private: + Saver* saver; + bool isSaverValid(); + + volatile DATA_SERIAL_TYPE lastDataSerialSeen; + + static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; + TIMESTAMP_TYPE lastSaveStartedTimestamp; + + volatile bool exiting; + DelayedSaveThread* thread; + void wakeThreadAndJoinThread(); + + volatile bool focusOnTunnel; + std::string tunnelNameToFocus; +}; + +#endif // DELAYEDSAVEMANAGERIMPL_H diff --git a/qt/i2pd_qt/Saver.cpp b/qt/i2pd_qt/Saver.cpp new file mode 100644 index 00000000..4841acb0 --- /dev/null +++ b/qt/i2pd_qt/Saver.cpp @@ -0,0 +1,6 @@ +#include "Saver.h" + +Saver::Saver() +{ + +} diff --git a/qt/i2pd_qt/Saver.h b/qt/i2pd_qt/Saver.h new file mode 100644 index 00000000..cefe0220 --- /dev/null +++ b/qt/i2pd_qt/Saver.h @@ -0,0 +1,22 @@ +#ifndef SAVER_H +#define SAVER_H + +#include +#include +#include + +class Saver : public QObject +{ + Q_OBJECT + +public: + Saver(); + //false iff failures + virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus)=0; + +signals: + void reloadTunnelsConfigAndUISignal(const QString); + +}; + +#endif // SAVER_H diff --git a/qt/i2pd_qt/SaverImpl.cpp b/qt/i2pd_qt/SaverImpl.cpp new file mode 100644 index 00000000..f35ef5b7 --- /dev/null +++ b/qt/i2pd_qt/SaverImpl.cpp @@ -0,0 +1,79 @@ +#include "SaverImpl.h" + +#include +#include +#include + +#include "QList" +#include "QString" + +#include "mainwindow.h" + +SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList * configItems_, std::map* tunnelConfigs_) : + configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_) +{} + +SaverImpl::~SaverImpl() {} + +bool SaverImpl::save(const bool focusOnTunnel, const std::string& tunnelNameToFocus) { + //save main config + { + std::stringstream out; + for(QList::iterator it = configItems->begin(); it!= configItems->end(); ++it) { + MainWindowItem* item = *it; + item->saveToStringStream(out); + } + + using namespace std; + + + QString backup=confpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(confpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + } + + //save tunnels config + { + std::stringstream out; + + for (std::map::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) { + //const std::string& name = it->first; + TunnelConfig* tunconf = it->second; + tunconf->saveHeaderToStringStream(out); + tunconf->saveToStringStream(out); + tunconf->saveI2CPParametersToStringStream(out); + } + + using namespace std; + + QString backup=tunconfpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(tunconfpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + } + + //reload saved configs +#if 0 + i2p::client::context.ReloadConfig(); +#endif + + if(focusOnTunnel) emit reloadTunnelsConfigAndUISignal(QString::fromStdString(tunnelNameToFocus)); + + return true; +} + +void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; } + +void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; } + +/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) { + this->focusOnTunnel=focusOnTunnel; + this->tunnelNameToFocus=tunnelNameToFocus; +}*/ diff --git a/qt/i2pd_qt/SaverImpl.h b/qt/i2pd_qt/SaverImpl.h new file mode 100644 index 00000000..c44877a2 --- /dev/null +++ b/qt/i2pd_qt/SaverImpl.h @@ -0,0 +1,33 @@ +#ifndef SAVERIMPL_H +#define SAVERIMPL_H + +#include +#include + +#include +#include "QList" + +#include "mainwindow.h" +#include "TunnelConfig.h" +#include "Saver.h" + +class MainWindowItem; +class TunnelConfig; + +class SaverImpl : public Saver +{ +public: + SaverImpl(MainWindow *mainWindowPtr_, QList * configItems_, std::map* tunnelConfigs_); + virtual ~SaverImpl(); + virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus); + void setConfPath(QString& confpath_); + void setTunnelsConfPath(QString& tunconfpath_); +private: + QList * configItems; + std::map* tunnelConfigs; + QString confpath; + QString tunconfpath; + MainWindow* mainWindowPtr; +}; + +#endif // SAVERIMPL_H diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index fb840276..3813eafc 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -64,7 +64,7 @@ void TunnelPane::setupTunnelPane( //type { - const QString& type = tunnelConfig->getType(); + //const QString& type = tunnelConfig->getType(); QHBoxLayout * horizontalLayout_ = new QHBoxLayout(); horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_")); typeLabel = new QLabel(gridLayoutWidget_2); diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 15565c5c..0cb73a2f 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -62,6 +62,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ ../../libi2pd/util.cpp \ + ../../libi2pd/Elligator.cpp \ ../../libi2pd_client/AddressBook.cpp \ ../../libi2pd_client/BOB.cpp \ ../../libi2pd_client/ClientContext.cpp \ @@ -89,7 +90,11 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ pagewithbackbutton.cpp \ widgetlock.cpp \ widgetlockregistry.cpp \ - logviewermanager.cpp + logviewermanager.cpp \ + DelayedSaveManager.cpp \ + Saver.cpp \ + DelayedSaveManagerImpl.cpp \ + SaverImpl.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/api.h \ @@ -147,6 +152,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/TunnelPool.h \ ../../libi2pd/util.h \ ../../libi2pd/version.h \ + ../../libi2pd/Elligator.h \ ../../libi2pd_client/AddressBook.h \ ../../libi2pd_client/BOB.h \ ../../libi2pd_client/ClientContext.h \ @@ -175,7 +181,11 @@ HEADERS += DaemonQT.h mainwindow.h \ widgetlock.h \ widgetlockregistry.h \ i2pd.rc \ - logviewermanager.h + logviewermanager.h \ + DelayedSaveManager.h \ + Saver.h \ + DelayedSaveManagerImpl.h \ + SaverImpl.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e4c9f2a7..3b1890c4 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,11 +1,8 @@ -#include -#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" #include "ui_routercommandswidget.h" #include "ui_generalsettingswidget.h" -#include #include #include #include @@ -29,17 +26,22 @@ #include "logviewermanager.h" +#include "DelayedSaveManagerImpl.h" +#include "SaverImpl.h" + std::string programOptionsWriterCurrentSection; MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *parent) : QMainWindow(parent) ,logStream(logStream_) -#ifndef ANDROID - ,quitting(false) -#endif + ,delayedSaveManagerPtr(new DelayedSaveManagerImpl()) + ,dataSerial(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL) ,wasSelectingAtStatusMainPage(false) ,showHiddenInfoStatusMainPage(false) ,logViewerManagerPtr(nullptr) +#ifndef ANDROID + ,quitting(false) +#endif ,ui(new Ui::MainWindow) ,statusButtonsUI(new Ui::StatusButtonsForm) ,routerCommandsUI(new Ui::routerCommandsWidget) @@ -51,9 +53,14 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ,datadir() ,confpath() ,tunconfpath() + ,tunnelConfigs() ,tunnelsPageUpdateListener(this) + ,saverPtr(new SaverImpl(this, &configItems, &tunnelConfigs)) { + assert(delayedSaveManagerPtr!=nullptr); + assert(saverPtr!=nullptr); + ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); routerCommandsUI->setupUi(routerCommandsParent); @@ -75,7 +82,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ui->stackedWidget->setCurrentIndex(0); ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380); - QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); + //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); int w = 683; int h = 3060; ui->settingsContents->setFixedSize(w, h); @@ -270,7 +277,13 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton)); widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton)); - loadAllConfigs(); + loadAllConfigs(saverPtr); + + QObject::connect(saverPtr, SIGNAL(reloadTunnelsConfigAndUISignal(const QString)), + this, SLOT(reloadTunnelsConfigAndUI_QString(const QString))); + + delayedSaveManagerPtr->setSaver(saverPtr); + delayedSaveManagerPtr->start(); QObject::connect(uiSettings->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(logDestinationComboBoxValueChanged(const QString &))); @@ -292,7 +305,6 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren QObject::connect(uiSettings->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(reloadTunnelsConfigAndUI())); - QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased())); QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased())); @@ -307,7 +319,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren logViewerManagerPtr=new LogViewerManager(logStream_,ui->logViewerTextEdit,this); assert(logViewerManagerPtr!=nullptr); - onLoggingOptionsChange(); + //onLoggingOptionsChange(); //QMetaObject::connectSlotsByName(this); } @@ -500,6 +512,8 @@ void MainWindow::handleQuitButton() { quitting=true; #endif close(); + delayedSaveManagerPtr->appExiting(); + qDebug("Performing quit"); QApplication::instance()->quit(); } @@ -526,6 +540,7 @@ void MainWindow::handleGracefulQuitTimerEvent() { quitting=true; #endif close(); + delayedSaveManagerPtr->appExiting(); qDebug("Performing quit"); QApplication::instance()->quit(); } @@ -534,6 +549,8 @@ MainWindow::~MainWindow() { qDebug("Destroying main window"); delete statusPageUpdateTimer; + delete delayedSaveManagerPtr; + delete saverPtr; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->deleteLater(); @@ -594,7 +611,7 @@ NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { return retValue; } -void MainWindow::loadAllConfigs(){ +void MainWindow::loadAllConfigs(SaverImpl* saverPtr){ //BORROWED FROM ??? //TODO move this code into single location std::string config; i2p::config::GetOption("conf", config); @@ -635,6 +652,9 @@ void MainWindow::loadAllConfigs(){ this->datadir = datadir.c_str(); this->tunconfpath = tunConf.c_str(); + saverPtr->setConfPath(this->confpath); + saverPtr->setTunnelsConfPath(this->tunconfpath); + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->loadFromConfigOption(); @@ -642,10 +662,10 @@ void MainWindow::loadAllConfigs(){ ReadTunnelsConfig(); - onLoggingOptionsChange(); + //onLoggingOptionsChange(); } /** returns false iff not valid items present and save was aborted */ -bool MainWindow::saveAllConfigs(){ +bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); @@ -653,7 +673,6 @@ bool MainWindow::saveAllConfigs(){ daemonOption->optionValue=boost::any(false); serviceOption->optionValue=boost::any(false); - std::stringstream out; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; if(!item->isValid()){ @@ -661,27 +680,8 @@ bool MainWindow::saveAllConfigs(){ return false; } } - - for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { - MainWindowItem* item = *it; - item->saveToStringStream(out); - } - - using namespace std; - - - QString backup=confpath+"~"; - if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors - ofstream outfile; - outfile.open(confpath.toStdString());//TODO handle errors - outfile << out.str().c_str(); - outfile.close(); - - SaveTunnelsConfig(); - - onLoggingOptionsChange(); - + delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus); + //onLoggingOptionsChange(); return true; } @@ -711,7 +711,7 @@ void MainWindow::updated() { adjustSizesAccordingToWrongLabel(); applyTunnelsUiToConfigs(); - saveAllConfigs(); + saveAllConfigs(false); } void MainWindowItem::installListeners(MainWindow *mainWindow) {} @@ -784,6 +784,10 @@ bool MainWindow::applyTunnelsUiToConfigs() { return true; } +void MainWindow::reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus) { + reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString()); +} + void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { deleteTunnelForms(); for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { @@ -795,31 +799,6 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { appendTunnelForms(tunnelNameToFocus); } -void MainWindow::SaveTunnelsConfig() { - std::stringstream out; - - for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { - const std::string& name = it->first; - TunnelConfig* tunconf = it->second; - tunconf->saveHeaderToStringStream(out); - tunconf->saveToStringStream(out); - tunconf->saveI2CPParametersToStringStream(out); - } - - using namespace std; - - QString backup=tunconfpath+"~"; - if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors - ofstream outfile; - outfile.open(tunconfpath.toStdString());//TODO handle errors - outfile << out.str().c_str(); - outfile.close(); - - i2p::client::context.ReloadConfig(); - -} - void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) { if(oldName!=tunConf->getName()) { //name has changed @@ -827,7 +806,7 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; } - mainWindow->saveAllConfigs(); + mainWindow->saveAllConfigs(true, tunConf->getName()); } void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 048f44af..bfbc527f 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -62,6 +62,12 @@ #include "widgetlockregistry.h" #include "widgetlock.h" +#include "DelayedSaveManager.h" +#include "DelayedSaveManagerImpl.h" +#include "SaverImpl.h" + +class SaverImpl; + class LogViewerManager; template @@ -373,10 +379,14 @@ using namespace i2p::qt; class Controller; +class DelayedSaveManagerImpl; + class MainWindow : public QMainWindow { Q_OBJECT private: std::shared_ptr logStream; + DelayedSaveManagerImpl* delayedSaveManagerPtr; + DelayedSaveManager::DATA_SERIAL_TYPE dataSerial; public: explicit MainWindow(std::shared_ptr logStream_, QWidget *parent=nullptr); ~MainWindow(); @@ -502,16 +512,16 @@ protected: void initStringBox(ConfigOption option, QLineEdit* lineEdit); NonGUIOptionItem* initNonGUIOption(ConfigOption option); - void loadAllConfigs(); + void loadAllConfigs(SaverImpl* saverPtr); public slots: /** returns false iff not valid items present and save was aborted */ - bool saveAllConfigs(); - void SaveTunnelsConfig(); + bool saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus=""); void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus); //focus none void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); } + void reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus); void addServerTunnelPushButtonReleased(); void addClientTunnelPushButtonReleased(); @@ -578,8 +588,7 @@ private: tunnelConfigs.erase(it); delete tc; } - saveAllConfigs(); - reloadTunnelsConfigAndUI(""); + saveAllConfigs(false); } std::string GenerateNewTunnelName() { @@ -614,8 +623,7 @@ private: destinationPort, sigType); - saveAllConfigs(); - reloadTunnelsConfigAndUI(name); + saveAllConfigs(true, name); } void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () @@ -651,8 +659,7 @@ private: isUniqueLocal); - saveAllConfigs(); - reloadTunnelsConfigAndUI(name); + saveAllConfigs(true, name); } void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () @@ -793,7 +800,9 @@ private: TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener; - void onLoggingOptionsChange() {} + //void onLoggingOptionsChange() {} + + SaverImpl* saverPtr; }; #endif // MAINWINDOW_H From 0e38e43315836d1797caba87e82d5fc0340bf090 Mon Sep 17 00:00:00 2001 From: user Date: Tue, 10 Mar 2020 23:22:49 +0800 Subject: [PATCH 016/189] some qt work. fixed on slow computers; now faster as delayed save is implemented --- .gitignore | 4 ++- daemon/HTTPServer.h | 2 +- qt/i2pd_qt/DelayedSaveManager.h | 2 +- qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 6 ++--- qt/i2pd_qt/DelayedSaveManagerImpl.h | 8 +++--- qt/i2pd_qt/TunnelConfig.h | 7 +++++- qt/i2pd_qt/TunnelPane.cpp | 5 ++++ qt/i2pd_qt/TunnelPane.h | 2 ++ qt/i2pd_qt/mainwindow.cpp | 36 ++++++++++++++++++++++++++- qt/i2pd_qt/mainwindow.h | 3 +++ 10 files changed, 63 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 68aea504..3319fa10 100644 --- a/.gitignore +++ b/.gitignore @@ -258,7 +258,7 @@ build/Makefile # qt -qt/i2pd_qt/*.ui.autosave +qt/i2pd_qt/*.autosave qt/i2pd_qt/*.ui.bk* qt/i2pd_qt/*.ui_* @@ -268,3 +268,5 @@ android/libs/ #various logs *LOGS/ +qt/build-*.sh* + diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index f5ac95fc..abc4fea5 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -89,7 +89,7 @@ namespace http void ShowTransports (std::stringstream& s); void ShowSAMSessions (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32); + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); } // http } // i2p diff --git a/qt/i2pd_qt/DelayedSaveManager.h b/qt/i2pd_qt/DelayedSaveManager.h index 9a9a997b..b09aa28f 100644 --- a/qt/i2pd_qt/DelayedSaveManager.h +++ b/qt/i2pd_qt/DelayedSaveManager.h @@ -18,7 +18,7 @@ public: virtual bool appExiting()=0; virtual bool needsFocusOnTunnel()=0; - virtual std::string getTunnelNameToFocus()=0; + virtual std::string& getTunnelNameToFocus()=0; }; #endif // DELAYEDSAVEMANAGER_H diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp index 5588d7e9..f6704c17 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -21,10 +21,10 @@ bool DelayedSaveManagerImpl::isSaverValid() { return saver != nullptr; } -void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus) { +void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus_) { if(lastDataSerialSeen==dataSerial)return; this->focusOnTunnel = focusOnTunnel; - this->tunnelNameToFocus = tunnelNameToFocus; + tunnelNameToFocus = tunnelNameToFocus_; lastDataSerialSeen=dataSerial; assert(isSaverValid()); TIMESTAMP_TYPE now = getTime(); @@ -135,6 +135,6 @@ bool DelayedSaveManagerImpl::needsFocusOnTunnel() { return focusOnTunnel; } -std::string DelayedSaveManagerImpl::getTunnelNameToFocus() { +std::string& DelayedSaveManagerImpl::getTunnelNameToFocus() { return tunnelNameToFocus; } diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.h b/qt/i2pd_qt/DelayedSaveManagerImpl.h index 0d8c7592..cb1f7568 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.h +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.h @@ -60,22 +60,22 @@ public: static TIMESTAMP_TYPE getTime(); bool needsFocusOnTunnel(); - std::string getTunnelNameToFocus(); + std::string& getTunnelNameToFocus(); private: Saver* saver; bool isSaverValid(); - volatile DATA_SERIAL_TYPE lastDataSerialSeen; + DATA_SERIAL_TYPE lastDataSerialSeen; static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; TIMESTAMP_TYPE lastSaveStartedTimestamp; - volatile bool exiting; + bool exiting; DelayedSaveThread* thread; void wakeThreadAndJoinThread(); - volatile bool focusOnTunnel; + bool focusOnTunnel; std::string tunnelNameToFocus; }; diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 58a1fa0b..059d48b5 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -40,6 +40,9 @@ public: class ClientTunnelConfig; class ServerTunnelConfig; + +class TunnelPane; + class TunnelConfig { /* const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; @@ -54,6 +57,7 @@ class TunnelConfig { */ QString type; std::string name; + TunnelPane* tunnelPane; public: TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} @@ -68,7 +72,8 @@ public: virtual void saveToStringStream(std::stringstream& out)=0; virtual ClientTunnelConfig* asClientTunnelConfig()=0; virtual ServerTunnelConfig* asServerTunnelConfig()=0; - + void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;} + TunnelPane* getTunnelPane() {return tunnelPane;} private: I2CPParameters i2cpParameters; }; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 3813eafc..c64b37ab 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -83,6 +83,11 @@ void TunnelPane::setupTunnelPane( retranslateTunnelForm(*this); } +void TunnelPane::deleteWidget() { + //gridLayoutWidget_2->deleteLater(); + tunnelGroupBox->deleteLater(); +} + void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) { { //number of hops of an inbound tunnel diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index a7012810..71331b4e 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -41,6 +41,8 @@ public: virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; + void deleteWidget(); + protected: MainWindow* mainWindow; QWidget * wrongInputPane; diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 3b1890c4..97a4ee69 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -664,6 +664,36 @@ void MainWindow::loadAllConfigs(SaverImpl* saverPtr){ //onLoggingOptionsChange(); } + +void MainWindow::layoutTunnels() { + + int height=0; + ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0); + for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + const std::string& name=it->first; + TunnelConfig* tunconf = it->second; + TunnelPane * tunnelPane=tunconf->getTunnelPane(); + if(!tunnelPane)continue; + int h=tunnelPane->height(); + height+=h; + //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); + //int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + } + //qDebug() << "tun.setting height:" << height; + ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); + /*QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren(); + foreach(QWidget* widget, childWidgets) + widget->show();*/ +} + +void MainWindow::deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf) { + TunnelPane* tp = cnf->getTunnelPane(); + if(!tp)return; + tunnelPanes.remove(tp); + tp->deleteWidget(); + layoutTunnels(); +} + /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); @@ -681,6 +711,7 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu } } delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus); + //onLoggingOptionsChange(); return true; } @@ -725,6 +756,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel, this); + tunconf->setTunnelPane(tunnelPane); int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); @@ -738,6 +770,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel, this); + tunconf->setTunnelPane(tunnelPane); int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); @@ -854,7 +887,8 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { pageWithBackButton->show(); textBrowser->hide(); std::stringstream s; - i2p::http::ShowLocalDestination(s,str.toStdString()); + std::string strstd = str.toStdString(); + i2p::http::ShowLocalDestination(s,strstd,0); childTextBrowser->setHtml(QString::fromStdString(s.str())); } } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index bfbc527f..91c99122 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -513,6 +513,7 @@ protected: NonGUIOptionItem* initNonGUIOption(ConfigOption option); void loadAllConfigs(SaverImpl* saverPtr); + void layoutTunnels(); public slots: /** returns false iff not valid items present and save was aborted */ @@ -540,6 +541,7 @@ private: void appendTunnelForms(std::string tunnelNameToFocus); void deleteTunnelForms(); + void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf); template std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const @@ -585,6 +587,7 @@ private: std::map::const_iterator it=tunnelConfigs.find(name); if(it!=tunnelConfigs.end()){ TunnelConfig* tc=it->second; + deleteTunnelFromUI(name, tc); tunnelConfigs.erase(it); delete tc; } From dd8200e8b0a9f2f7bf56a95db2ccacace81eb572 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 12 Mar 2020 03:50:21 +0300 Subject: [PATCH 017/189] cleanup websocks Signed-off-by: R4SAS --- build/CMakeLists.txt | 1 - filelist.mk | 2 +- libi2pd_client/ClientContext.cpp | 7 +--- libi2pd_client/WebSocks.cpp | 72 -------------------------------- libi2pd_client/WebSocks.h | 34 --------------- qt/i2pd_qt/i2pd_qt.pro | 2 - 6 files changed, 3 insertions(+), 115 deletions(-) delete mode 100644 libi2pd_client/WebSocks.cpp delete mode 100644 libi2pd_client/WebSocks.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 8b3553d2..2bdfb396 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -117,7 +117,6 @@ set (CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp" ) add_library(libi2pdclient ${CLIENT_SRC}) diff --git a/filelist.mk b/filelist.mk index 72773975..7d13fb2f 100644 --- a/filelist.mk +++ b/filelist.mk @@ -11,7 +11,7 @@ LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp) #LIB_CLIENT_SRC = \ # AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \ -# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp WebSocks.cpp +# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index d72f40a8..722fb242 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -9,7 +9,6 @@ #include "util.h" #include "ClientContext.h" #include "SOCKS.h" -#include "WebSocks.h" #include "MatchedDestination.h" namespace i2p @@ -598,10 +597,8 @@ namespace client } else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { - // websocks proxy - auto tun = std::make_shared(address, port, localDestination); - clientTunnel = tun; - clientEndpoint = tun->GetLocalEndpoint(); + LogPrint(eLogError, "Clients: I2P Client tunnel websocks is deprecated"); + continue; } else { diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp deleted file mode 100644 index a3e8c1bf..00000000 --- a/libi2pd_client/WebSocks.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "WebSocks.h" -#include "Log.h" -#include - -namespace i2p -{ -namespace client -{ - class WebSocksImpl - { - public: - WebSocksImpl(const std::string & addr, int port) : m_Addr(addr), m_Port(port) - { - } - - ~WebSocksImpl() - { - } - - void Start() - { - LogPrint(eLogInfo, "[Tunnels] starting websocks tunnel at %s:%d is rejected: WebSockets is deprecated", m_Addr, m_Port); - } - - void Stop() - { - } - - void InitializeDestination(WebSocks * parent) - { - } - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() - { - return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port); - } - - std::string m_Addr; - int m_Port; - - }; -} -} - -namespace i2p -{ -namespace client -{ - WebSocks::WebSocks(const std::string & addr, int port, std::shared_ptr localDestination) : m_Impl(new WebSocksImpl(addr, port)) - { - m_Impl->InitializeDestination(this); - } - WebSocks::~WebSocks() { delete m_Impl; } - - void WebSocks::Start() - { - m_Impl->Start(); - GetLocalDestination()->Start(); - } - - boost::asio::ip::tcp::endpoint WebSocks::GetLocalEndpoint() const - { - return m_Impl->GetLocalEndpoint(); - } - - void WebSocks::Stop() - { - m_Impl->Stop(); - GetLocalDestination()->Stop(); - } -} -} diff --git a/libi2pd_client/WebSocks.h b/libi2pd_client/WebSocks.h deleted file mode 100644 index 2314659f..00000000 --- a/libi2pd_client/WebSocks.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef WEBSOCKS_H_ -#define WEBSOCKS_H_ -#include -#include -#include "I2PService.h" -#include "Destination.h" - -namespace i2p -{ -namespace client -{ - - class WebSocksImpl; - - /** @brief websocket socks proxy server */ - class WebSocks : public i2p::client::I2PService - { - public: - WebSocks(const std::string & addr, int port, std::shared_ptr localDestination); - ~WebSocks(); - - void Start(); - void Stop(); - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() const; - - const char * GetName() { return "WebSOCKS Proxy"; } - - private: - WebSocksImpl * m_Impl; - }; -} -} -#endif diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index aa87a765..6eec3a16 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -73,7 +73,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd_client/MatchedDestination.cpp \ ../../libi2pd_client/SAM.cpp \ ../../libi2pd_client/SOCKS.cpp \ - ../../libi2pd_client/WebSocks.cpp \ ../../daemon/Daemon.cpp \ ../../daemon/HTTPServer.cpp \ ../../daemon/I2PControl.cpp \ @@ -162,7 +161,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd_client/MatchedDestination.h \ ../../libi2pd_client/SAM.h \ ../../libi2pd_client/SOCKS.h \ - ../../libi2pd_client/WebSocks.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ ../../daemon/I2PControl.h \ From 45145fa50af40a5270223930cd92d33df452db82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Mar 2020 09:33:48 -0400 Subject: [PATCH 018/189] add ECIESX25519AEADRatchet session to delivery status --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + libi2pd/Garlic.cpp | 2 +- libi2pd/Garlic.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5f2eb5c8..4705c708 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -477,6 +477,7 @@ namespace garlic SetLeaseSetUpdateStatus (eLeaseSetSubmitted); SetLeaseSetUpdateMsgID (leaseSet->GetMsgID ()); SetLeaseSetSubmissionTime (ts); + GetOwner ()->DeliveryStatusSent (shared_from_this (), leaseSet->GetMsgID ()); } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 9ac5540f..99b737b1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -783,7 +783,7 @@ namespace garlic m_DeliveryStatusSessions.erase (msgID); } - void GarlicDestination::DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID) + void GarlicDestination::DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID) { std::unique_lock l(m_DeliveryStatusSessionsMutex); m_DeliveryStatusSessions[msgID] = session; diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index be0ac117..396a38fe 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -226,7 +226,7 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread - void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); + void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); void AddECIESx25519SessionTag (int index, uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); From b5bc05ac2b2ed9375d689207190af89b5344c37d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Mar 2020 16:35:34 -0400 Subject: [PATCH 019/189] delete unconfirmed LeaseSet and DeliveryStatus --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 6 ++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 19 ++++++++++++------- libi2pd/Garlic.h | 3 ++- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4705c708..8c293f15 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -571,6 +571,12 @@ namespace garlic } m_NumReceiveTags += numTags; } + + bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) + { + CleanupUnconfirmedLeaseSet (ts); + return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 4d273c13..db9807a5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -85,7 +85,7 @@ namespace garlic if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - bool IsExpired (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } + bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 99b737b1..97f80b41 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -70,6 +70,16 @@ namespace garlic return false; } + void GarlicRoutingSession::CleanupUnconfirmedLeaseSet (uint64_t ts) + { + if (m_LeaseSetUpdateMsgID && ts*1000LL > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) + { + if (GetOwner ()) + GetOwner ()->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); + m_LeaseSetUpdateMsgID = 0; + } + } + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) { auto msg = CreateDeliveryStatusMsg (msgID); @@ -390,12 +400,7 @@ namespace garlic ++it; } CleanupUnconfirmedTags (); - if (GetLeaseSetUpdateMsgID () && ts*1000LL > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT) - { - if (GetOwner ()) - GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); - SetLeaseSetUpdateMsgID (0); - } + CleanupUnconfirmedLeaseSet (ts); return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); } @@ -767,7 +772,7 @@ namespace garlic for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) { - if (it->second->IsExpired (ts)) + if (it->second->CheckExpired (ts)) { it->second->SetOwner (nullptr); it = m_ECIESx25519Sessions.erase (it); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 396a38fe..06da679d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -113,7 +113,8 @@ namespace garlic bool IsLeaseSetNonConfirmed () const { return m_LeaseSetUpdateStatus == eLeaseSetSubmitted; }; bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; }; uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; } - + void CleanupUnconfirmedLeaseSet (uint64_t ts); + std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); From 5da92437a136cf5938062c5ec4ceaf28832c5aff Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Mar 2020 16:41:07 -0400 Subject: [PATCH 020/189] set msg type for deliverystatus --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8c293f15..8d300a16 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -552,6 +552,7 @@ namespace garlic LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); return 0; } + *buf = msg->GetTypeID (); // I2NP msg type htobe32buf (buf + 1, msg->GetMsgID ()); // msgID htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); From f3b0e57a5440586c3f7de2ed97b5b742f52c995c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Mar 2020 18:03:03 -0400 Subject: [PATCH 021/189] publish multiple encryption keys --- libi2pd/Destination.cpp | 5 +++-- libi2pd/LeaseSet.cpp | 18 ++++++++++++------ libi2pd/LeaseSet.h | 9 ++++++++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d4620ed9..60f5062c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1149,10 +1149,11 @@ namespace client else { // standard LS2 (type 3) first - auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; + uint16_t keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, - m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted); + m_Keys, i2p::data::LocalLeaseSet2::KeySections { {m_EncryptionKeyType, keyLen, m_EncryptionPublicKey} }, + tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 ls2 = std::make_shared (ls2, m_Keys, GetAuthType (), m_AuthKeys); leaseSet = ls2; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8d1b9524..e2da1d21 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -748,7 +748,7 @@ namespace data } LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, + const KeySections& encryptionKeys, std::vector > tunnels, bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) @@ -757,8 +757,11 @@ namespace data // assume standard LS2 int num = tunnels.size (); if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES; + size_t keySectionsLen = 0; + for (const auto& it: encryptionKeys) + keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; m_BufferLen = identity->GetFullLen () + 4/*published*/ + 2/*expires*/ + 2/*flag*/ + 2/*properties len*/ + - 1/*num keys*/ + 2/*key type*/ + 2/*key len*/ + keyLen/*key*/ + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); + 1/*num keys*/ + keySectionsLen + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); uint16_t flags = 0; if (keys.IsOfflineSignature ()) { @@ -789,10 +792,13 @@ namespace data } htobe16buf (m_Buffer + offset, 0); offset += 2; // properties len // keys - m_Buffer[offset] = 1; offset++; // 1 key - htobe16buf (m_Buffer + offset, keyType); offset += 2; // key type - htobe16buf (m_Buffer + offset, keyLen); offset += 2; // key len - memcpy (m_Buffer + offset, encryptionPublicKey, keyLen); offset += keyLen; // key + m_Buffer[offset] = encryptionKeys.size (); offset++; // 1 key + for (const auto& it: encryptionKeys) + { + htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type + htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len + memcpy (m_Buffer + offset, it.encryptionPublicKey, it.keyLen); offset += it.keyLen; // key + } // leases uint32_t expirationTime = 0; // in seconds m_Buffer[offset] = num; offset++; // num leases diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index a51570f7..791d77e3 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -231,8 +231,15 @@ namespace data { public: + struct KeySection + { + uint16_t keyType, keyLen; + const uint8_t * encryptionPublicKey; + }; + typedef std::vector KeySections; + LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, + const KeySections& encryptionKeys, std::vector > tunnels, bool isPublic, bool isPublishedEncrypted = false); LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP From 2fcaa7d260fa9b657e9e1e24f00a03f964c7febf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Mar 2020 02:26:55 +0300 Subject: [PATCH 022/189] [webconsole] rework spoilers; print tags, leases, router info in table Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 240 ++++++++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 103 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 36e26785..a7bd693f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -54,7 +54,7 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " a, .slide label { text-decoration: none; color: #894C84; }\r\n" " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n" - " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial;}\r\n" + " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial; width: 1.5em;}\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" " .left { float: left; position: absolute; }\r\n" @@ -64,12 +64,13 @@ namespace http { " .tunnel.failed { color: #D33F3F; }\r\n" " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" - " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" - " .slide p, .slide [type='checkbox'] { display: none; }\r\n" - " .slide [type='checkbox']:checked ~ p { display: block; margin-top: 0; padding: 0; }\r\n" + " table { display: table; border-collapse: collapse; text-align: center; }\r\n" + " table.extaddr { text-align: left; }\r\n table.services { width: 100%; }" + " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" + " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" + " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" - " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -181,8 +182,10 @@ namespace http { "

\r\n" " Main page
\r\n
\r\n" " Router commands
\r\n" - " Local destinations
\r\n" - " LeaseSets
\r\n" + " Local destinations
\r\n"; + if (i2p::context.IsFloodfill ()) + s << " LeaseSets
\r\n"; + s << " Tunnels
\r\n" " Transit tunnels
\r\n" " Transports
\r\n" @@ -234,11 +237,8 @@ namespace http { } s << "
\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) - if (auto remains = Daemon.gracefulShutdownInterval) { - s << "Stopping in: "; - s << remains << " seconds"; - s << "
\r\n"; - } + if (auto remains = Daemon.gracefulShutdownInterval) + s << "Stopping in: " << remains << " seconds
\r\n"; #endif auto family = i2p::context.GetFamily (); if (family.length () > 0) @@ -256,45 +256,50 @@ namespace http { s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n

\r\n"; + s << "\r\n\r\n

\r\n"; } if(includeHiddenContent) { s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; - s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; + if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) + s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; - s << "Our external address:" << "
\r\n" ; + s << "Our external address:" << "
\r\n\r\n"; for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) { + s << "\r\n"; if (address->IsNTCP2 () && !address->IsPublishedNTCP2 ()) { - s << "NTCP2"; + s << "\r\n\r\n"; continue; } switch (address->transportStyle) { case i2p::data::RouterInfo::eTransportNTCP: { - s << "NTCP"; + s << "\r\n"; break; } case i2p::data::RouterInfo::eTransportSSU: + { + s << "\r\n"; + break; + } default: - s << "Unknown  "; + s << "\r\n"; } - s << address->host.to_string() << ":" << address->port << "
\r\n"; + s << "\r\n\r\n"; } + s << "
NTCP2"; if (address->host.is_v6 ()) s << "v6"; - s << "   supported
\r\n"; + s << "
supported
NTCP"; if (address->IsPublishedNTCP2 ()) s << "2"; if (address->host.is_v6 ()) s << "v6"; - s << "  "; + s << "SSU"; if (address->host.is_v6 ()) - s << "SSUv6     "; - else - s << "SSU     "; - break; + s << "v6"; + s << "Unknown" << address->host.to_string() << ":" << address->port << "
\r\n"; } - s << "

\r\n
\r\n"; + s << "\r\n
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forQtUi) { s << "
"; } @@ -310,15 +315,15 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forWebConsole) { - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - s << "\r\n"; - s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "
Services
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; } } @@ -358,19 +363,20 @@ namespace http { if (dest->IsEncryptedLeaseSet ()) { i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); - s << "
\r\n\r\n

\r\n"; + s << "

\r\n\r\n
\r\n"; s << blinded.ToB33 () << ".b32.i2p
\r\n"; - s << "

\r\n
\r\n"; + s << "
\r\n
\r\n"; } if(dest->GetNumRemoteLeaseSets()) { - s << "
\r\n\r\n

\r\n"; + s << "

\r\n\r\n
\r\n"; for(auto& it: dest->GetLeaseSets ()) - s << it.first.ToBase32 () << " " << (int)it.second->GetStoreType () << "
\r\n"; - s << "

\r\n\r\n"; + s << "\r\n"; + s << "
AddressTypeEncType
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n
\r\n
\r\n
\r\n"; } else - s << "LeaseSets: 0
\r\n"; + s << "LeaseSets: 0
\r\n
\r\n"; auto pool = dest->GetTunnelPool (); if (pool) { @@ -395,10 +401,11 @@ namespace http { if (!dest->GetSessions ().empty ()) { std::stringstream tmp_s; uint32_t out_tags = 0; for (const auto& it: dest->GetSessions ()) { - tmp_s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " " << it.second->GetNumOutgoingTags () << "
\r\n"; + tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; out_tags = out_tags + it.second->GetNumOutgoingTags (); } - s << "
\r\n\r\n

\r\n" << tmp_s.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -473,46 +480,57 @@ namespace http { void ShowLeasesSets(std::stringstream& s) { - s << "LeaseSets:
\r\n
\r\n"; - int counter = 1; - // for each lease set - i2p::data::netdb.VisitLeaseSets( - [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) - { - // create copy of lease set so we extract leases - auto storeType = leaseSet->GetStoreType (); - std::unique_ptr ls; - if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) - ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); - else - ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); - if (!ls) return; - s << "
\r\n"; - if (!ls->IsValid()) - s << "
!! Invalid !!
\r\n"; - s << "
\r\n"; - s << "\r\n

\r\n"; - s << "Store type: " << (int)storeType << "
\r\n"; - s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; - if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) - { - // leases information is available - auto leases = ls->GetNonExpiredLeases(); - s << "Non Expired Leases: " << leases.size() << "
\r\n"; - for ( auto & l : leases ) + if (i2p::data::netdb.GetNumLeaseSets ()) + { + s << "LeaseSets:
\r\n
\r\n"; + int counter = 1; + // for each lease set + i2p::data::netdb.VisitLeaseSets( + [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) + { + // create copy of lease set so we extract leases + auto storeType = leaseSet->GetStoreType (); + std::unique_ptr ls; + if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) + ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); + else + ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); + if (!ls) return; + s << "

\r\n"; + if (!ls->IsValid()) + s << "
!! Invalid !!
\r\n"; + s << "
\r\n"; + s << "\r\n
\r\n"; + s << "Store type: " << (int)storeType << "
\r\n"; + s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; + if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) { - s << "Gateway: " << l->tunnelGateway.ToBase64() << "
\r\n"; - s << "TunnelID: " << l->tunnelID << "
\r\n"; - s << "EndDate: " << ConvertTime(l->endDate) << "
\r\n"; + // leases information is available + auto leases = ls->GetNonExpiredLeases(); + s << "Non Expired Leases: " << leases.size() << "
\r\n"; + for ( auto & l : leases ) + { + s << "Gateway: " << l->tunnelGateway.ToBase64() << "
\r\n"; + s << "TunnelID: " << l->tunnelID << "
\r\n"; + s << "EndDate: " << ConvertTime(l->endDate) << "
\r\n"; + } } - } - s << "

\r\n
\r\n
\r\n"; - } - ); - // end for each lease set + s << "
\r\n
\r\n
\r\n"; + } + ); + // end for each lease set + } + else if (!i2p::context.IsFloodfill ()) + { + s << "LeaseSets: not floodfill.
\r\n"; + } + else + { + s << "LeaseSets: 0
\r\n"; + } } void ShowTunnels (std::stringstream& s) @@ -574,16 +592,23 @@ namespace http { void ShowTransitTunnels (std::stringstream& s) { - s << "Transit tunnels:
\r\n
\r\n"; - for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) + if(i2p::tunnel::tunnels.CountTransitTunnels()) { - if (std::dynamic_pointer_cast(it)) - s << it->GetTunnelID () << " ⇒ "; - else if (std::dynamic_pointer_cast(it)) - s << " ⇒ " << it->GetTunnelID (); - else - s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + s << "Transit tunnels:
\r\n
\r\n"; + for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) + { + if (std::dynamic_pointer_cast(it)) + s << it->GetTunnelID () << " ⇒ "; + else if (std::dynamic_pointer_cast(it)) + s << " ⇒ " << it->GetTunnelID (); + else + s << " ⇒ " << it->GetTunnelID () << " ⇒ "; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + } + } + else + { + s << "Transit tunnels: no transit tunnels currently built.
\r\n"; } } @@ -617,13 +642,15 @@ namespace http { } if (!tmp_s.str ().empty ()) { - s << "
\r\n\r\n

"; - s << tmp_s.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n
" + << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { - s << "
\r\n\r\n

"; - s << tmp_s6.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n
" + << tmp_s6.str () << "
\r\n
\r\n"; } } @@ -650,7 +677,7 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n

"; + s << "

\r\n\r\n
"; for (const auto& it: sessions) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -662,12 +689,12 @@ namespace http { s << " [itag:" << it.second->GetRelayTag () << "]"; s << "
\r\n" << std::endl; } - s << "

\r\n
\r\n"; + s << "
\r\n
\r\n"; } auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n

"; + s << "

\r\n\r\n
"; for (const auto& it: sessions6) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -679,7 +706,7 @@ namespace http { s << " [itag:" << it.second->GetRelayTag () << "]"; s << "
\r\n" << std::endl; } - s << "

\r\n
\r\n"; + s << "
\r\n
\r\n"; } } } @@ -688,17 +715,24 @@ namespace http { { std::string webroot; i2p::config::GetOption("http.webroot", webroot); auto sam = i2p::client::context.GetSAMBridge (); - if (!sam) { + if (!sam) + { ShowError(s, "SAM disabled"); return; } - s << "SAM Sessions:
\r\n
\r\n"; - for (auto& it: sam->GetSessions ()) + + if(sam->GetSessions ().size ()) { - auto& name = it.second->localDestination->GetNickname (); - s << ""; - s << name << " (" << it.first << ")
\r\n" << std::endl; + s << "SAM Sessions:
\r\n
\r\n"; + for (auto& it: sam->GetSessions ()) + { + auto& name = it.second->localDestination->GetNickname (); + s << ""; + s << name << " (" << it.first << ")
\r\n" << std::endl; + } } + else + s << "SAM Sessions: no sessions currently running.
\r\n"; } static void ShowSAMSession (std::stringstream& s, const std::string& id) From 22497080973e25e8b9b5fd93b86af44f795a18e3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Mar 2020 02:34:45 +0300 Subject: [PATCH 023/189] [webconsole] remove excess tag Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a7bd693f..5eac08a9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -299,7 +299,7 @@ namespace http { } s << "\r\n"; } - s << "\r\n
\r\n
\r\n"; + s << "\r\n\r\n"; if(outputFormat==OutputFormatEnum::forQtUi) { s << "
"; } From 3ca17fdc039f46996038d5bb501539a728e06f8a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Mar 2020 18:33:42 -0400 Subject: [PATCH 024/189] support multiple encryption keys --- libi2pd/Destination.cpp | 11 +++++++++-- libi2pd/Destination.h | 9 +++++---- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 ++-- libi2pd/Garlic.cpp | 4 ++-- libi2pd/Identity.h | 4 ++-- libi2pd_client/I2CP.h | 3 ++- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 60f5062c..46d3fc57 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -388,7 +388,7 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else - leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetEncryptionType ()); // LeaseSet2 + leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2 if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { if (leaseSet->GetIdentHash () != GetIdentHash ()) @@ -412,7 +412,7 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetEncryptionType ()); + auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key @@ -822,6 +822,13 @@ namespace client } } + i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const + { + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET; + return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; + } + ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (service, isPublic, params), diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 23ed5188..f26200a0 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -161,6 +161,7 @@ namespace client void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); + i2p::data::CryptoKeyType GetPreferredCryptoType () const; private: @@ -232,14 +233,14 @@ namespace client int GetStreamingAckDelay () const { return m_StreamingAckDelay; } // datagram - i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (); + i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; + i2p::datagram::DatagramDestination * CreateDatagramDestination (); // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; - const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; + const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; }; protected: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8d300a16..2cea2172 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -126,7 +126,7 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32); // h = SHA256(h || bpk) if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { @@ -235,7 +235,7 @@ namespace garlic // encrypt static key section uint8_t nonce[12]; CreateNonce (0, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 97f80b41..629e0d76 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -488,7 +488,7 @@ namespace garlic else { // tag not found. Handle depending on encryption type - if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) { HandleECIESx25519 (buf, length); return; @@ -680,7 +680,7 @@ namespace garlic std::shared_ptr destination, bool attachLeaseSet) { if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET && - GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index f217f3c5..9c78f552 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -228,8 +228,8 @@ namespace data virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; - virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override for LeaseSet - virtual const uint8_t * GetEncryptionPublicKey () const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet + virtual bool SupportsEncryptionType (CryptoKeyType keyType) const { return GetIdentity ()->GetCryptoKeyType () == keyType; }; // override for LeaseSet + virtual const uint8_t * GetEncryptionPublicKey (CryptoKeyType keyType) const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet }; } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 68b4415a..848378e0 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -80,7 +80,8 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; - i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; + // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; protected: From b6b25dc9f3c6d57c11f8fd8c2980e64133f4a682 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 20 Mar 2020 17:44:53 +0300 Subject: [PATCH 025/189] update log messages Signed-off-by: R4SAS --- libi2pd/Garlic.cpp | 2 +- libi2pd/LeaseSet.cpp | 2 +- libi2pd/SSUData.cpp | 6 +++--- libi2pd/Transports.cpp | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 629e0d76..02d1cd83 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -890,7 +890,7 @@ namespace garlic m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption)); } if (!m_Tags.empty ()) - LogPrint (eLogInfo, m_Tags.size (), " loaded for ", ident); + LogPrint (eLogInfo, "Garlic: " m_Tags.size (), " tags loaded for ", ident); } } i2p::fs::Remove (path); diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index e2da1d21..bcfede33 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -159,7 +159,7 @@ namespace data } } else - LogPrint (eLogWarning, "LeaseSet: Lease is expired already "); + LogPrint (eLogWarning, "LeaseSet: Lease is expired already"); } uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index add58739..866da277 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -442,7 +442,7 @@ namespace transport } catch (boost::system::system_error& ec) { - LogPrint (eLogWarning, "SSU: Can't resend data fragment ", ec.what ()); + LogPrint (eLogWarning, "SSU: Can't resend message ", it->first, " data fragment: ", ec.what ()); } } @@ -452,7 +452,7 @@ namespace transport } else { - LogPrint (eLogInfo, "SSU: message has not been ACKed after ", MAX_NUM_RESENDS, " attempts, deleted"); + LogPrint (eLogInfo, "SSU: message ", it->first, " has not been ACKed after ", MAX_NUM_RESENDS, " attempts, deleted"); it = m_SentMessages.erase (it); } } @@ -488,7 +488,7 @@ namespace transport { if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) { - LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); + LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); it = m_IncompleteMessages.erase (it); } else diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 97c29c70..804f26cb 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -271,11 +271,11 @@ namespace transport m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); - if (m_IsNAT) - { - m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); - m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); - } + if (m_IsNAT) + { + m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); + m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); + } } void Transports::Stop () @@ -589,6 +589,7 @@ namespace transport if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; if (m_SSUServer) { + LogPrint (eLogInfo, "Transports: Started peer test"); bool statusChanged = false; for (int i = 0; i < 5; i++) { @@ -604,7 +605,7 @@ namespace transport } } if (!statusChanged) - LogPrint (eLogWarning, "Can't find routers for peer test"); + LogPrint (eLogWarning, "Transports: Can't find routers for peer test"); } } From 168da33d8bc5689ee0ecb01e4c05ca785e3662ba Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 20 Mar 2020 18:43:54 +0300 Subject: [PATCH 026/189] add comma Signed-off-by: R4SAS --- libi2pd/Garlic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 02d1cd83..ae6599fc 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -890,7 +890,7 @@ namespace garlic m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption)); } if (!m_Tags.empty ()) - LogPrint (eLogInfo, "Garlic: " m_Tags.size (), " tags loaded for ", ident); + LogPrint (eLogInfo, "Garlic: ", m_Tags.size (), " tags loaded for ", ident); } } i2p::fs::Remove (path); From 962c2160c77cce4460950fb6a231725235daf89d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Mar 2020 17:43:37 -0400 Subject: [PATCH 027/189] set actual LeaseSet2 buffer size --- libi2pd/LeaseSet.cpp | 15 +++++++++++++++ libi2pd/LeaseSet.h | 1 + 2 files changed, 16 insertions(+) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index bcfede33..b411ca0e 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -251,6 +251,13 @@ namespace data memcpy (m_Buffer, buf, len); } + void LeaseSet::SetBufferLen (size_t len) + { + if (len <= m_BufferLen) m_BufferLen = len; + else + LogPrint (eLogError, "LeaseSet2: actual buffer size ", len , " exceeds full buffer size ", m_BufferLen); + } + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto): LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) { @@ -331,6 +338,8 @@ namespace data VerifySignature (identity, buf, len, offset); SetIsValid (verified); } + offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen (); + SetBufferLen (offset); } template @@ -537,6 +546,12 @@ namespace data else LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); } + else + { + // we set actual length of encrypted buffer + offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : blindedVerifier->GetSignatureLen (); + SetBufferLen (offset); + } } // helper for ExtractClientAuthData diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 791d77e3..0d255644 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -97,6 +97,7 @@ namespace data // called from LeaseSet2 LeaseSet (bool storeLeases); void SetBuffer (const uint8_t * buf, size_t len); + void SetBufferLen (size_t len); void SetIdentity (std::shared_ptr identity) { m_Identity = identity; }; void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; }; void SetIsValid (bool isValid) { m_IsValid = isValid; }; From ff19bab80087947c7f364d60edfd8af63478b9c7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 21 Mar 2020 16:21:51 -0400 Subject: [PATCH 028/189] set only key correctly --- libi2pd_client/I2CP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index c09b7f4d..ccd94e46 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -572,7 +572,7 @@ namespace client uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length if (offset + keyLen > len) return; - if (keyType > currentKeyType) + if (!currentKey || keyType > currentKeyType) { currentKeyType = keyType; currentKey = buf + offset; From 6fb80f226acd76c50e4f615111a8ba01e279c4d5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Mar 2020 08:14:20 -0400 Subject: [PATCH 029/189] reopen socked and restart receiver on exception --- libi2pd/SSU.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index daf7e1e9..4eb958de 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -160,6 +160,13 @@ namespace transport catch (std::exception& ex) { LogPrint (eLogError, "SSU: receivers runtime exception: ", ex.what ()); + if (m_IsRunning) + { + // restart socket + m_Socket.close (); + OpenSocket (); + Receive (); + } } } } @@ -175,6 +182,12 @@ namespace transport catch (std::exception& ex) { LogPrint (eLogError, "SSU: v6 receivers runtime exception: ", ex.what ()); + if (m_IsRunning) + { + m_SocketV6.close (); + OpenSocketV6 (); + ReceiveV6 (); + } } } } From fe9ac10f02da049c7966c0ecb2cd84c8e94698c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Mar 2020 21:21:12 -0400 Subject: [PATCH 030/189] generate new tags based on last received index --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +--- libi2pd/ECIESX25519AEADRatchetSession.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2cea2172..5dd78747 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -402,8 +402,7 @@ namespace garlic return false; } HandlePayload (payload.data (), len - 16); - if (m_NumReceiveTags > 0)m_NumReceiveTags--; - if (m_NumReceiveTags <= GetOwner ()->GetNumTags ()*2/3) + if (m_ReceiveTagset.GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; } @@ -570,7 +569,6 @@ namespace garlic uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); } - m_NumReceiveTags += numTags; } bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index db9807a5..95875013 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -119,7 +119,6 @@ namespace garlic SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; - int m_NumReceiveTags = 0; std::unique_ptr m_Destination;// TODO: might not need it }; } From 744e893dcef13db3d47aea1d877cf97032fa0c03 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Mar 2020 18:09:57 -0400 Subject: [PATCH 031/189] check message length --- libi2pd_client/I2CP.cpp | 12 ++++++++++-- libi2pd_client/I2CP.h | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index ccd94e46..eec21f06 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -246,8 +246,16 @@ namespace client m_PayloadLen = bufbe32toh (m_Header + I2CP_HEADER_LENGTH_OFFSET); if (m_PayloadLen > 0) { - m_Payload = new uint8_t[m_PayloadLen]; - ReceivePayload (); + if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH) + { + m_Payload = new uint8_t[m_PayloadLen]; + ReceivePayload (); + } + else + { + LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); + Terminate (); + } } else // no following payload { diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 848378e0..f675318f 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -24,7 +24,8 @@ namespace client { const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; - + const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; From 869d0156ce38de301e32c5a35a698059c4a0d5d9 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Mar 2020 19:03:38 -0400 Subject: [PATCH 032/189] handle Ack request --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 25 +++++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 6 +++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5dd78747..c57553d4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,6 +38,7 @@ namespace garlic { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; + if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset return m_KeyData.GetTag (); } @@ -178,7 +179,7 @@ namespace garlic return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, int index) { size_t offset = 0; while (offset < len) @@ -207,6 +208,12 @@ namespace garlic case eECIESx25519BlkPadding: LogPrint (eLogDebug, "Garlic: padding"); break; + case eECIESx25519BlkAckRequest: + { + LogPrint (eLogDebug, "Garlic: ack request"); + m_AckRequests.push_back ( {bufbe16toh (buf + offset), index}); + break; + } default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } @@ -401,7 +408,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - HandlePayload (payload.data (), len - 16); + HandlePayload (payload.data (), len - 16, index); if (m_ReceiveTagset.GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; @@ -478,6 +485,8 @@ namespace garlic SetLeaseSetSubmissionTime (ts); GetOwner ()->DeliveryStatusSent (shared_from_this (), leaseSet->GetMsgID ()); } + if (m_AckRequests.size () > 0) + payloadLen += m_AckRequests.size ()*4 + 3; uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -497,6 +506,18 @@ namespace garlic // msg if (msg && m_Destination) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + // ack + if (m_AckRequests.size () > 0) + { + v[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (v.data () + offset, m_AckRequests.size ()*4); offset += 2; + for (auto& it: m_AckRequests) + { + htobe16buf (v.data () + offset, it.first); offset += 2; + htobe16buf (v.data () + offset, it.second); offset += 2; + } + m_AckRequests.clear (); + } // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 95875013..56fb48cf 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "Garlic.h" @@ -51,6 +52,8 @@ namespace garlic eECIESx25519BlkTermination = 4, eECIESx25519BlkOptions = 5, eECIESx25519BlkNextSessionKey = 7, + eECIESx25519BlkAck = 8, + eECIESx25519BlkAckRequest = 9, eECIESx25519BlkGalicClove = 11, eECIESx25519BlkPadding = 254 }; @@ -99,7 +102,7 @@ namespace garlic bool HandleNewIncomingSession (const uint8_t * buf, size_t len); bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index); - void HandlePayload (const uint8_t * buf, size_t len); + void HandlePayload (const uint8_t * buf, size_t len, int index = 0); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); @@ -120,6 +123,7 @@ namespace garlic uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; std::unique_ptr m_Destination;// TODO: might not need it + std::list > m_AckRequests; // (key_id, indeX) }; } } From f4ca6bbb52d8d2029662be8e72305fb21c29acba Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Mar 2020 19:27:10 -0400 Subject: [PATCH 033/189] fixed race with identity verifier --- libi2pd/Identity.cpp | 49 ++++++++++++++++++++------------------------ libi2pd/Identity.h | 5 +++-- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 3f9633ed..1026eb02 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -34,12 +34,11 @@ namespace data } IdentityEx::IdentityEx (): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { } - IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType): - m_IsVerifierCreated (false) + IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType) { memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of if (type != SIGNING_KEY_TYPE_DSA_SHA1) @@ -141,19 +140,19 @@ namespace data } IdentityEx::IdentityEx (const uint8_t * buf, size_t len): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { FromBuffer (buf, len); } IdentityEx::IdentityEx (const IdentityEx& other): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { *this = other; } IdentityEx::IdentityEx (const Identity& standard): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { *this = standard; } @@ -161,6 +160,7 @@ namespace data IdentityEx::~IdentityEx () { delete[] m_ExtendedBuffer; + delete m_Verifier; } IdentityEx& IdentityEx::operator=(const IdentityEx& other) @@ -178,8 +178,8 @@ namespace data else m_ExtendedBuffer = nullptr; + delete m_Verifier; m_Verifier = nullptr; - m_IsVerifierCreated = false; return *this; } @@ -193,8 +193,8 @@ namespace data m_ExtendedBuffer = nullptr; m_ExtendedLen = 0; + delete m_Verifier; m_Verifier = nullptr; - m_IsVerifierCreated = false; return *this; } @@ -233,6 +233,7 @@ namespace data } SHA256(buf, GetFullLen (), m_IdentHash); + delete m_Verifier; m_Verifier = nullptr; return GetFullLen (); @@ -381,33 +382,27 @@ namespace data void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const { - if (!m_Verifier) + bool del = false; { - auto created = m_IsVerifierCreated.exchange (true); - if (!created) - m_Verifier.reset (verifier); + std::lock_guard l(m_VerifierMutex); + if (!m_Verifier) + m_Verifier = verifier; else - { - delete verifier; - int count = 0; - while (!m_Verifier && count < 500) // 5 seconds - { - std::this_thread::sleep_for (std::chrono::milliseconds(10)); - count++; - } - if (!m_Verifier) - LogPrint (eLogError, "Identity: couldn't get verifier in 5 seconds"); - } + del = true; } - else + if (del) delete verifier; } void IdentityEx::DropVerifier () const { - // TODO: potential race condition with Verify - m_IsVerifierCreated = false; - m_Verifier = nullptr; + i2p::crypto::Verifier * verifier; + { + std::lock_guard l(m_VerifierMutex); + verifier = m_Verifier; + m_Verifier = nullptr; + } + delete verifier; } std::shared_ptr IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 9c78f552..0ee87beb 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "Base.h" #include "Signature.h" #include "CryptoKey.h" @@ -125,8 +126,8 @@ namespace data Identity m_StandardIdentity; IdentHash m_IdentHash; - mutable std::unique_ptr m_Verifier; - mutable std::atomic_bool m_IsVerifierCreated; // make sure we don't create twice + mutable i2p::crypto::Verifier * m_Verifier = nullptr; + mutable std::mutex m_VerifierMutex; size_t m_ExtendedLen; uint8_t * m_ExtendedBuffer; }; From f21af4068fd1c9890eb467d94af718e717bd8b21 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Mar 2020 17:35:51 -0400 Subject: [PATCH 034/189] preferred crypto type for Decrypt --- libi2pd/Destination.cpp | 2 +- libi2pd/Destination.h | 2 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 2 +- libi2pd/Identity.h | 2 +- libi2pd/RouterContext.cpp | 2 +- libi2pd/RouterContext.h | 2 +- libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 46d3fc57..fb0add02 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1173,7 +1173,7 @@ namespace client if (m_DatagramDestination) m_DatagramDestination->CleanUp (); } - bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f26200a0..c5c2c16f 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -237,7 +237,7 @@ namespace client i2p::datagram::DatagramDestination * CreateDatagramDestination (); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; }; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c57553d4..1523d775 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -138,7 +138,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr); // x25519(bsk, aepk) + GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // decrypt flags/static @@ -160,7 +160,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) + GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags @@ -211,7 +211,7 @@ namespace garlic case eECIESx25519BlkAckRequest: { LogPrint (eLogDebug, "Garlic: ack request"); - m_AckRequests.push_back ( {bufbe16toh (buf + offset), index}); + m_AckRequests.push_back ({0, index}); // TODO: use actual tagsetid break; } default: @@ -250,7 +250,7 @@ namespace garlic MixHash (out + offset, 48); // h = SHA256(h || ciphertext) offset += 48; // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt @@ -339,7 +339,7 @@ namespace garlic uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 56fb48cf..ed1fa17d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -123,7 +123,7 @@ namespace garlic uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; std::unique_ptr m_Destination;// TODO: might not need it - std::list > m_AckRequests; // (key_id, indeX) + std::list > m_AckRequests; // (tagsetid, index) }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index ae6599fc..fd6e8fee 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -495,7 +495,7 @@ namespace garlic } // otherwise assume ElGamal/AES ElGamalBlock elGamal; - if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx)) + if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) { auto decryption = std::make_shared(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 0ee87beb..663f46b5 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -225,7 +225,7 @@ namespace data public: virtual ~LocalDestination() {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6c63ef79..b86ed8f2 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -724,7 +724,7 @@ namespace i2p return std::chrono::duration_cast (std::chrono::steady_clock::now() - m_StartupTime).count (); } - bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index dfc05fe7..28c324c4 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -108,7 +108,7 @@ namespace i2p // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; void SetLeaseSetUpdated () {}; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index eec21f06..f4c8a91e 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -59,7 +59,7 @@ namespace client m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey); } - bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index f675318f..7f590555 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -80,7 +80,7 @@ namespace client void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; From 8872d1f389a63cf2823d9562396eb34b01bd3e63 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Apr 2020 09:54:10 -0400 Subject: [PATCH 035/189] mutex for m_RemoteIdentity --- libi2pd/TransportSession.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 49067ce2..55c39c7a 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "RouterInfo.h" @@ -67,8 +68,16 @@ namespace transport std::string GetIdentHashBase64() const { return m_RemoteIdentity ? m_RemoteIdentity->GetIdentHash().ToBase64() : ""; } - std::shared_ptr GetRemoteIdentity () { return m_RemoteIdentity; }; - void SetRemoteIdentity (std::shared_ptr ident) { m_RemoteIdentity = ident; }; + std::shared_ptr GetRemoteIdentity () + { + std::lock_guard l(m_RemoteIdentityMutex); + return m_RemoteIdentity; + } + void SetRemoteIdentity (std::shared_ptr ident) + { + std::lock_guard l(m_RemoteIdentityMutex); + m_RemoteIdentity = ident; + } size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; @@ -85,6 +94,7 @@ namespace transport protected: std::shared_ptr m_RemoteIdentity; + mutable std::mutex m_RemoteIdentityMutex; std::shared_ptr m_DHKeysPair; // X - for client and Y - for server size_t m_NumSentBytes, m_NumReceivedBytes; bool m_IsOutgoing; From aa7750bfd345aa04aefa4b08e4fedf97d6997c04 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Apr 2020 21:48:39 -0400 Subject: [PATCH 036/189] keep sending new session reply until first established session message received --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 36 +++++++++++++++++++---- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 1523d775..c3f7320d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -298,7 +298,8 @@ namespace garlic return false; } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) - out += 16; + offset += 16; + memcpy (m_NSRHeader, out, 56); // for possible next NSR // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) @@ -308,18 +309,33 @@ namespace garlic m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset.NextSessionTagRatchet (); GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt { - LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); + LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); return false; } - m_State = eSessionStateEstablished; + m_State = eSessionStateNewSessionReplySent; return true; } + bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Bob and sent NSR already + memcpy (out, m_NSRHeader, 56); + uint8_t nonce[12]; + CreateNonce (0, nonce); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); + return false; + } + return true; + } + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len) { // we are Alice @@ -419,6 +435,11 @@ namespace garlic m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); switch (m_State) { + case eSessionStateNewSessionReplySent: + m_State = eSessionStateEstablished; +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif case eSessionStateEstablished: return HandleExistingSessionMessage (buf, len, index); case eSessionStateNew: @@ -456,6 +477,11 @@ namespace garlic return nullptr; len += 72; break; + case eSessionStateNewSessionReplySent: + if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 72; + break; default: return nullptr; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index ed1fa17d..82675331 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -69,6 +69,7 @@ namespace garlic eSessionStateNew =0, eSessionStateNewSessionReceived, eSessionStateNewSessionSent, + eSessionStateNewSessionReplySent, eSessionStateEstablished }; @@ -106,6 +107,7 @@ namespace garlic bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); std::vector CreatePayload (std::shared_ptr msg); @@ -117,7 +119,8 @@ namespace garlic private: uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; - uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only + uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only + uint8_t m_NSRHeader[56], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming From d503f0756470ec1d27228295fd906cf47f97fe3e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 26 Mar 2020 09:54:51 +0300 Subject: [PATCH 037/189] suppress GCC 7 (bug 77728) psabi note Suppresses messages like that: note: parameter passing for argument of type <...> will change in GCC 7.1 Signed-off-by: R4SAS --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 9db660c2..fa2f2fdf 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,5 +1,5 @@ # set defaults instead redefine -CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation +CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation -Wno-psabi LDFLAGS ?= ${LD_DEBUG} ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time From a9436aa9af5a97daef899f352c9b774d4ce40e6d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 3 Apr 2020 14:31:18 +0300 Subject: [PATCH 038/189] drop i2lua Signed-off-by: R4SAS --- build/CMakeLists.txt | 6 ------ libi2pd/Destination.cpp | 26 -------------------------- libi2pd/Destination.h | 20 +++----------------- libi2pd/Tunnel.cpp | 6 ------ libi2pd/TunnelPool.cpp | 10 ---------- libi2pd/TunnelPool.h | 10 ---------- libi2pd_client/MatchedDestination.cpp | 5 ----- libi2pd_client/MatchedDestination.h | 1 - 8 files changed, 3 insertions(+), 81 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2bdfb396..1a459bf8 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -19,7 +19,6 @@ option(WITH_GUI "Include GUI (currently MS Windows only)" ON) option(WITH_MESHNET "Build for cjdns test network" OFF) option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) -option(WITH_I2LUA "Build for i2lua" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -88,10 +87,6 @@ if (WIN32 OR MSYS) list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") endif () -if (WITH_I2LUA) - add_definitions(-DI2LUA) -endif() - add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") @@ -414,7 +409,6 @@ message(STATUS " PCH : ${WITH_PCH}") message(STATUS " MESHNET : ${WITH_MESHNET}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") -message(STATUS " I2LUA : ${WITH_I2LUA}") message(STATUS "---------------------------------------") #Handle paths nicely diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index fb0add02..98c4b323 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -931,32 +931,6 @@ namespace client } } -#ifdef I2LUA - void ClientDestination::Ready(ReadyPromise & p) - { - ScheduleCheckForReady(&p); - } - - void ClientDestination::ScheduleCheckForReady(ReadyPromise * p) - { - // tick every 100ms - m_ReadyChecker.expires_from_now(boost::posix_time::milliseconds(100)); - m_ReadyChecker.async_wait([&, p] (const boost::system::error_code & ecode) { - HandleCheckForReady(ecode, p); - }); - } - - void ClientDestination::HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p) - { - if(ecode) // error happened - p->set_value(nullptr); - else if(IsReady()) // we are ready - p->set_value(std::shared_ptr(this)); - else // we are not ready - ScheduleCheckForReady(p); - } -#endif - void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index c5c2c16f..83a38816 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -8,9 +8,6 @@ #include #include #include -#ifdef I2LUA -#include -#endif #include #include "Identity.h" #include "TunnelPool.h" @@ -196,13 +193,6 @@ namespace client class ClientDestination: public LeaseSetDestination { public: -#ifdef I2LUA - // type for informing that a client destination is ready - typedef std::promise > ReadyPromise; - // informs promise with shared_from_this() when this destination is ready to use - // if cancelled before ready, informs promise with nullptr - void Ready(ReadyPromise & p); -#endif ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); @@ -251,14 +241,10 @@ namespace client private: - std::shared_ptr GetSharedFromThis () - { return std::static_pointer_cast(shared_from_this ()); } + std::shared_ptr GetSharedFromThis () { + return std::static_pointer_cast(shared_from_this ()); + } void PersistTemporaryKeys (); -#ifdef I2LUA - void ScheduleCheckForReady(ReadyPromise * p); - void HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p); -#endif - void ReadAuthKey (const std::string& group, const std::map * params); private: diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 9dacddac..879ee2d3 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -576,7 +576,6 @@ namespace tunnel for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) { auto tunnel = it->second; - auto pool = tunnel->GetTunnelPool(); switch (tunnel->GetState ()) { case eTunnelStatePending: @@ -599,8 +598,6 @@ namespace tunnel hop = hop->next; } } - // for i2lua - if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout); // delete it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; @@ -610,9 +607,6 @@ namespace tunnel break; case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted"); - // for i2lua - if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected); - it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; break; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b3e3c7d2..7256b2db 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -88,8 +88,6 @@ namespace tunnel } if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); - - OnTunnelBuildResult(createdTunnel, eBuildResultOkay); } void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) @@ -112,8 +110,6 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } - OnTunnelBuildResult(createdTunnel, eBuildResultOkay); - //CreatePairedInboundTunnel (createdTunnel); } @@ -596,11 +592,5 @@ namespace tunnel } return tun; } - - void TunnelPool::OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result) - { - auto peers = tunnel->GetPeers(); - if(m_CustomPeerSelector) m_CustomPeerSelector->OnBuildResult(peers, tunnel->IsInbound(), result); - } } } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index fc46930c..d6fb91cc 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -23,13 +23,6 @@ namespace tunnel class InboundTunnel; class OutboundTunnel; - - enum TunnelBuildResult { - eBuildResultOkay, // tunnel was built okay - eBuildResultRejected, // tunnel build was explicitly rejected - eBuildResultTimeout // tunnel build timed out - }; - typedef std::shared_ptr Peer; typedef std::vector Path; @@ -38,7 +31,6 @@ namespace tunnel { virtual ~ITunnelPeerSelector() {}; virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0; - virtual bool OnBuildResult(const Path & peers, bool isInbound, TunnelBuildResult result) = 0; }; @@ -98,8 +90,6 @@ namespace tunnel std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude=nullptr) const; std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude=nullptr) const; - void OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result); - // for overriding tunnel peer selection std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 3d75a3ca..5cec178f 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -94,10 +94,5 @@ namespace client } return true; } - - bool MatchedTunnelDestination::OnBuildResult(const i2p::tunnel::Path & path, bool inbound, i2p::tunnel::TunnelBuildResult result) - { - return true; - } } } diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 67b874e6..9d61799a 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -18,7 +18,6 @@ namespace client void Stop(); bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); - bool OnBuildResult(const i2p::tunnel::Path & peers, bool inbound, i2p::tunnel::TunnelBuildResult result); private: void ResolveCurrentLeaseSet(); From 4e1319d874ca788672dba47a942efa8f849dc675 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Apr 2020 11:40:18 -0400 Subject: [PATCH 039/189] handle ECIESFlag in DatabaseLookup at floodfill --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 35 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 2 ++ libi2pd/I2NPProtocol.h | 1 + libi2pd/NetDb.cpp | 21 ++++++++++---- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c3f7320d..4371124e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -623,6 +623,41 @@ namespace garlic CleanupUnconfirmedLeaseSet (ts); return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } + + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + size_t len = cloveSize + 3; + payload[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (payload + 1, cloveSize); // size + payload += 3; + *payload = 0; payload++; // flag and delivery instructions + *payload = msg->GetTypeID (); // I2NP msg type + htobe32buf (payload + 1, msg->GetMsgID ()); // msgID + htobe32buf (payload + 5, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); + + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); + return nullptr; + } + offset += len + 16; + + htobe32buf (m->GetPayload (), offset); + m->len += offset + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; + } + } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 82675331..3185a7fc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -128,6 +128,8 @@ namespace garlic std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) }; + + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); } } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index ca074aed..5714afce 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -95,6 +95,7 @@ namespace i2p // DatabaseLookup flags const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01; const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02; + const uint8_t DATABASE_LOOKUP_ECIES_FLAG = 0x10; const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C; const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0; const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100 diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 6d69f131..5d452d1d 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -15,8 +15,9 @@ #include "NTCP2.h" #include "RouterContext.h" #include "Garlic.h" -#include "NetDb.hpp" +#include "ECIESX25519AEADRatchetSession.h" #include "Config.h" +#include "NetDb.hpp" using namespace i2p::transport; @@ -949,10 +950,20 @@ namespace data const uint8_t numTags = excluded[32]; if (numTags) { - const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag - i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); - replyMsg = garlic.WrapSingleMessage (replyMsg); - if(replyMsg == nullptr) LogPrint(eLogError, "NetDb: failed to wrap message"); + if (flag & DATABASE_LOOKUP_ECIES_FLAG) + { + uint64_t tag; + memcpy (&tag, excluded + 33, 8); + replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); + } + else + { + const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag + i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); + replyMsg = garlic.WrapSingleMessage (replyMsg); + } + if (!replyMsg) + LogPrint (eLogError, "NetDb: failed to wrap message"); } else LogPrint(eLogWarning, "NetDb: encrypted reply requested but no tags provided"); From 49c1e477369cc08a94ea6eb57d19b4e91f81fc42 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 8 Apr 2020 18:02:12 -0400 Subject: [PATCH 040/189] correct termination if session already exists --- libi2pd/NTCP2.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 3dfd6250..a92c77ce 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -706,9 +706,13 @@ namespace transport // ready to communicate auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); - m_Server.AddNTCP2Session (shared_from_this (), true); - Established (); - ReceiveLength (); + if (m_Server.AddNTCP2Session (shared_from_this (), true)) + { + Established (); + ReceiveLength (); + } + else + Terminate (); } else Terminate (); @@ -1258,7 +1262,6 @@ namespace transport if (it != m_NTCP2Sessions.end ()) { LogPrint (eLogWarning, "NTCP2: session to ", ident.ToBase64 (), " already exists"); - session->Terminate(); return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); @@ -1301,6 +1304,8 @@ namespace transport }); conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), std::bind (&NTCP2Server::HandleConnect, this, std::placeholders::_1, conn, timer)); } + else + conn->Terminate (); }); } From b7c206c44bacaf611b06855f9d6292d88b196978 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Apr 2020 15:00:38 -0400 Subject: [PATCH 041/189] replace by new incoming session --- libi2pd/NTCP2.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index a92c77ce..85d83bf0 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1262,7 +1262,11 @@ namespace transport if (it != m_NTCP2Sessions.end ()) { LogPrint (eLogWarning, "NTCP2: session to ", ident.ToBase64 (), " already exists"); - return false; + if (incoming) + // replace by new session + it->second->Terminate (); + else + return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); return true; From b3974cb52a2eb5bf2201af6b5e82410024b643e9 Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 10 Apr 2020 02:34:47 +0000 Subject: [PATCH 042/189] [webconsole] security hardening headers (closes #1464) Signed-off-by: r4sas --- daemon/HTTPServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 5eac08a9..f93c3531 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1141,6 +1141,8 @@ namespace http { void HTTPConnection::SendReply (HTTPRes& reply, std::string& content) { reply.add_header("X-Frame-Options", "SAMEORIGIN"); + reply.add_header("X-Content-Type-Options", "nosniff"); + reply.add_header("X-XSS-Protection", "1; mode=block"); reply.add_header("Content-Type", "text/html"); reply.body = content; From 5e606573b1b0ea640a6ed21fd9a0707541587854 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Apr 2020 12:57:47 -0400 Subject: [PATCH 043/189] 2.31.0 --- ChangeLog | 19 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 39 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 293764a6..39d62f21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,25 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.31.0] - 2020-04-10 +### Added +- NTCP2 HTTP proxy +- Publish LeaseSet2 for I2CP destinations +- Show status page on main activity for android +- Handle ECIESFlag in DatabaseLookup at floodfill +- C++17 features for eligible compilers +### Changed +- Droped Websockets and Lua support +- Send DeliveryStatusMsg for LeaseSet for ECIES-X25519-AEAD-Ratchet +- Keep sending new session reply until established for ECIES-X25519-AEAD-Ratchet +- Updated SSU log messages +- Security hardening headers in web console +- Various QT changes +### Fixed +- NTCP2 socket descriptors leak +- Race condition with router's identity in transport sessions +- Not terminated streams remain forever + ## [2.30.0] - 2020-02-25 ### Added - Single threaded SAM diff --git a/Win32/installer.iss b/Win32/installer.iss index d4f6f247..8e66c17a 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.30.0" +#define I2Pd_ver "2.31.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 6fcb4521..d3c5c16b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2300 - versionName "2.30.0" + versionCode 2310 + versionName "2.31.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index 8c4a1a9d..d6dcf060 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.30.0.{build} +version: 2.31.0.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index f9571ca0..b182dca4 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.30.0 +Version: 2.31.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -118,6 +118,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Apr 10 2020 orignal - 2.31.0 +- update to 2.31.0 + * Tue Feb 25 2020 orignal - 2.30.0 - update to 2.30.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index b3cca8ab..5ece769c 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.30.0 +Version: 2.31.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -116,6 +116,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Apr 10 2020 orignal - 2.31.0 +- update to 2.31.0 + * Tue Feb 25 2020 orignal - 2.30.0 - update to 2.30.0 diff --git a/debian/changelog b/debian/changelog index da177cbd..3824d4f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.31.0-1) unstable; urgency=medium + + * updated to version 2.31.0 + + -- orignal Fri, 10 Apr 2020 16:00:00 +0000 + i2pd (2.30.0-1) unstable; urgency=medium * updated to version 2.30.0/0.9.45 diff --git a/libi2pd/version.h b/libi2pd/version.h index 36fbe2ca..4ad1a546 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 30 +#define I2PD_VERSION_MINOR 31 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 00b6974a..4c027bc0 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 4e37df26a3ba285ebd9c1918472d59dfb530f2cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Apr 2020 20:33:54 +0300 Subject: [PATCH 044/189] 2.31.0 Signed-off-by: R4SAS --- ChangeLog | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 39d62f21..930be261 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ ## [2.31.0] - 2020-04-10 ### Added -- NTCP2 HTTP proxy +- NTCP2 through HTTP proxy - Publish LeaseSet2 for I2CP destinations - Show status page on main activity for android - Handle ECIESFlag in DatabaseLookup at floodfill @@ -13,7 +13,9 @@ - Send DeliveryStatusMsg for LeaseSet for ECIES-X25519-AEAD-Ratchet - Keep sending new session reply until established for ECIES-X25519-AEAD-Ratchet - Updated SSU log messages +- Reopen SSU socket on exception - Security hardening headers in web console +- Various web console changes - Various QT changes ### Fixed - NTCP2 socket descriptors leak From 95fa835191d052feee915cfa047230a05176e646 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Apr 2020 23:28:45 +0300 Subject: [PATCH 045/189] [android] update strings, menus, add reloading tunnels item Signed-off-by: R4SAS --- android/.gitignore | 2 + android/AndroidManifest.xml | 5 +- android/jni/i2pd_android.cpp | 6 + android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 3 + android/res/layout/activity_perms_asker.xml | 7 +- .../res/layout/activity_perms_explanation.xml | 6 +- android/res/layout/webview.xml | 11 +- android/res/menu/options_main.xml | 30 +- android/res/values-ru/strings.xml | 18 +- android/res/values/strings.xml | 20 +- .../org/purplei2p/i2pd/DaemonSingleton.java | 76 +++- .../src/org/purplei2p/i2pd/I2PDActivity.java | 382 +++++++++--------- android/src/org/purplei2p/i2pd/I2PD_JNI.java | 2 + 13 files changed, 326 insertions(+), 242 deletions(-) diff --git a/android/.gitignore b/android/.gitignore index 666c6694..57a0a6cd 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -4,6 +4,7 @@ bin libs log* obj +.cxx .gradle .idea .externalNativeBuild @@ -14,3 +15,4 @@ android.iml build *.iml *.local +*.jks diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index a95e3773..88985138 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -17,8 +17,9 @@ android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:requestLegacyExternalStorage="true" - android:usesCleartextTraffic="true" + android:usesCleartextTraffic="true" > + @@ -30,10 +31,10 @@ android:label="@string/app_name"> - + diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index da908648..bb058b5d 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -2,6 +2,7 @@ #include "org_purplei2p_i2pd_I2PD_JNI.h" #include "DaemonAndroid.h" #include "RouterContext.h" +#include "ClientContext.h" #include "Transports.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith @@ -61,6 +62,11 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels i2p::context.SetAcceptsTunnels (true); } +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs + (JNIEnv *env, jclass clazz) { + i2p::client::context.ReloadConfig(); +} + JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged (JNIEnv *env, jclass clazz, jboolean isConnected) { bool isConnectedBool = (bool) isConnected; diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index 6939a153..6d809e63 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -27,6 +27,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels (JNIEnv *, jclass); +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs + (JNIEnv *, jclass); + JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged (JNIEnv * env, jclass clazz, jboolean isConnected); diff --git a/android/res/layout/activity_perms_asker.xml b/android/res/layout/activity_perms_asker.xml index d2d12cb6..778c9ef5 100644 --- a/android/res/layout/activity_perms_asker.xml +++ b/android/res/layout/activity_perms_asker.xml @@ -15,13 +15,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/horizontal_page_margin" - android:visibility="gone" - /> + android:visibility="gone" /> \r\n"; + s << "\r\n
\r\n"; } void ShowTransitTunnels (std::stringstream& s) @@ -1125,6 +1137,19 @@ namespace http { res.add_header("Refresh", redirect.c_str()); return; } + else if (cmd == HTTP_COMMAND_LIMITTRANSIT) + { + uint32_t limit = std::stoul(params["limit"], nullptr); + if (limit > 0 && limit <= 65535) + SetMaxNumTransitTunnels (limit); + else { + s << "ERROR: Transit tunnels count must not exceed 65535

\r\n"; + s << "Back to commands list
\r\n"; + s << "

You will be redirected back in 5 seconds"; + res.add_header("Refresh", redirect.c_str()); + return; + } + } else { res.code = 400; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b0233901..275aa69d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -316,13 +316,23 @@ namespace i2p static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO: void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) { - if (maxNumTransitTunnels > 0 && maxNumTransitTunnels <= 10000 && g_MaxNumTransitTunnels != maxNumTransitTunnels) + if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels) { - LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + if (maxNumTransitTunnels <= 65535) { + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + } else { + LogPrint (eLogWarning, "I2NP: Requested number of transit tunnels exceeds 65535, limited"); + maxNumTransitTunnels = 65535; + } g_MaxNumTransitTunnels = maxNumTransitTunnels; } } + uint16_t GetMaxNumTransitTunnels () + { + return g_MaxNumTransitTunnels; + } + bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 5714afce..2fca1538 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -285,6 +285,7 @@ namespace tunnel const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500; void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); + uint16_t GetMaxNumTransitTunnels (); } #endif From 51e3d5f7bc122d81eb0c0466e3fb3b7511ea4ecd Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Apr 2020 19:27:31 -0400 Subject: [PATCH 062/189] create next tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 70 ++++++++++++++++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 9 +-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2a30713e..8d820eb6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,7 +38,11 @@ namespace garlic { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; - if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset + if (m_NextIndex >= 65535) + { + LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); + return 0; + } return m_KeyData.GetTag (); } @@ -251,7 +255,26 @@ namespace garlic uint8_t flag = buf[0]; buf++; // flag if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG) { - // TODO: implement + if (!m_NextSendRatchet) return; + uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID + if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || + (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) + { + if (flag & ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG) + memcpy (m_NextSendRatchet->remote, buf, 32); + uint8_t sharedSecret[32], tagsetKey[32]; + m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); + i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) + auto newTagset = std::make_shared (shared_from_this ()); + newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); + newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); + newTagset->NextSessionTagRatchet (); + m_SendTagset = newTagset; + m_SendForwardKey = false; + LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created"); + } + else + LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID); } else { @@ -292,6 +315,26 @@ namespace garlic LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } + + void ECIESX25519AEADRatchetSession::NewNextSendRatchet () + { + auto newTagset = new DHRatchet (); + if (m_NextSendRatchet) + { + newTagset->keyID = m_NextSendRatchet->keyID; + if (!newTagset->newKey || !newTagset->keyID) + { + newTagset->keyID++; + newTagset->newKey = true; + } + else + newTagset->newKey = false; + } + if (newTagset->newKey) + newTagset->key.GenerateKeys (); + m_NextSendRatchet.reset (newTagset); + m_SendForwardKey = true; + } bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { @@ -487,7 +530,9 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; - } + } + if (index >= ECIESX25519_TAGSET_MAX_NUM_TAGS && !m_SendForwardKey) + NewNextSendRatchet (); return true; } @@ -601,6 +646,11 @@ namespace garlic payloadLen += 6; if (m_NextReceiveRatchet->newKey) payloadLen += 32; } + if (m_SendForwardKey) + { + payloadLen += 6; + if (m_NextSendRatchet->newKey) payloadLen += 32; + } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -662,6 +712,20 @@ namespace garlic } m_SendReverseKey = false; } + if (m_SendForwardKey) + { + v[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; + v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; + if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only + offset++; // flag + htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid + if (m_NextSendRatchet->newKey) + { + memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + offset += 32; // public key + } + } // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 963429ed..0a051810 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -73,6 +73,7 @@ namespace garlic const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after const int ECIESX25519_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 60000; // number of tags we request new tagset after class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { @@ -90,7 +91,7 @@ namespace garlic int keyID = 0; i2p::crypto::X25519Keys key; uint8_t remote[32]; // last remote public key - bool newKey; + bool newKey = true; }; public: @@ -136,6 +137,7 @@ namespace garlic size_t CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len); void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); + void NewNextSendRatchet (); private: @@ -148,9 +150,8 @@ namespace garlic std::shared_ptr m_SendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) - int m_SendKeyID = 0, m_ReceiveKeyID = 0; - bool m_SendReverseKey = false; - std::unique_ptr m_NextReceiveRatchet; + bool m_SendReverseKey = false, m_SendForwardKey = false; + std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); From 50a77fedca2c6d9119b8a10237e3bcc54367f8c1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Apr 2020 19:37:00 -0400 Subject: [PATCH 063/189] removed trivial check --- libi2pd/I2NPProtocol.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 275aa69d..0e7c245e 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -318,12 +318,7 @@ namespace i2p { if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels) { - if (maxNumTransitTunnels <= 65535) { - LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); - } else { - LogPrint (eLogWarning, "I2NP: Requested number of transit tunnels exceeds 65535, limited"); - maxNumTransitTunnels = 65535; - } + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); g_MaxNumTransitTunnels = maxNumTransitTunnels; } } From 5700e18257993a7f18e69629f92a53d111292c5e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 27 Apr 2020 13:23:29 +0300 Subject: [PATCH 064/189] [FS] read tunnels configs which ends with .conf only Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 722fb242..fa0532c3 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -490,6 +490,7 @@ namespace client { for (auto& it: files) { + if (it.substr(it.size() - 5) != ".conf") continue; // skip files which not ends with ".conf" LogPrint(eLogDebug, "Clients: tunnels extra config file: ", it); ReadTunnels (it, numClientTunnels, numServerTunnels); } From e6fdf5ad8da59072f431268e27cb9b736441fd15 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 27 Apr 2020 13:59:00 +0300 Subject: [PATCH 065/189] [Log] create logfile even if loglevel is "none" Signed-off-by: R4SAS --- libi2pd/Log.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 79b4a511..7d77aaf8 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -199,7 +199,6 @@ namespace log { void Log::SendTo (const std::string& path) { if (m_LogStream) m_LogStream = nullptr; // close previous - if (m_MinLevel == eLogNone) return; auto flags = std::ofstream::out | std::ofstream::app; auto os = std::make_shared (path, flags); if (os->is_open ()) From 142a138cfceb96c35d05217606525a8f21255018 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Apr 2020 09:35:02 -0400 Subject: [PATCH 066/189] store previous reverse key --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8d820eb6..b02e49f8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -255,12 +255,12 @@ namespace garlic uint8_t flag = buf[0]; buf++; // flag if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG) { - if (!m_NextSendRatchet) return; + if (!m_SendForwardKey || !m_NextSendRatchet) return; uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) { - if (flag & ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG) + if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); @@ -318,22 +318,23 @@ namespace garlic void ECIESX25519AEADRatchetSession::NewNextSendRatchet () { - auto newTagset = new DHRatchet (); if (m_NextSendRatchet) { - newTagset->keyID = m_NextSendRatchet->keyID; - if (!newTagset->newKey || !newTagset->keyID) + if (!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) { - newTagset->keyID++; - newTagset->newKey = true; + m_NextSendRatchet->keyID++; + m_NextSendRatchet->newKey = true; } else - newTagset->newKey = false; + m_NextSendRatchet->newKey = false; } - if (newTagset->newKey) - newTagset->key.GenerateKeys (); - m_NextSendRatchet.reset (newTagset); + else + m_NextSendRatchet.reset (new DHRatchet ()); + if (m_NextSendRatchet->newKey) + m_NextSendRatchet->key.GenerateKeys (); + m_SendForwardKey = true; + LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); } bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) From f77a58b2dc03ef3478d8b8a13da3b13ea315109a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Apr 2020 18:53:02 -0400 Subject: [PATCH 067/189] set some ECIESx25519 params --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 13 ++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 9 ++++++--- libi2pd/Garlic.cpp | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b02e49f8..4dba003d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -311,7 +311,7 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } @@ -426,7 +426,7 @@ namespace garlic m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt @@ -495,7 +495,7 @@ namespace garlic auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -552,8 +552,11 @@ namespace garlic return false; } HandlePayload (payload.data (), len - 16, receiveTagset, index); - if (receiveTagset->GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 + if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; + moreTags -= (receiveTagset->GetNextIndex () - index); + if (moreTags > 0) + GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 0a051810..5cba8868 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -72,9 +72,12 @@ namespace garlic const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after - const int ECIESX25519_EXPIRATION_TIMEOUT = 600; // in seconds - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 60000; // number of tags we request new tagset after - + const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; + const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index f0e3c10e..fe5e8d69 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -788,7 +788,7 @@ namespace garlic // ECIESx25519 for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { - if (ts > it->second.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT) + if (ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else ++it; From 7b22ef4270de78e2bd013edff6fd9795bb5b6c2c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 14:47:53 -0400 Subject: [PATCH 068/189] create incoming NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4dba003d..06f6c84e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -378,7 +378,7 @@ namespace garlic m_State = eSessionStateNewSessionSent; if (GetOwner ()) - GetOwner ()->AddECIESx25519SessionNextTag (CreateNewSessionTagset ()); + GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 5cba8868..20676405 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -77,6 +77,7 @@ namespace garlic const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { From 0a431594f89a2e57f12f5bc9c29fd5905b44a726 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 00:56:43 +0300 Subject: [PATCH 069/189] [Log] Change default loglevel (closes #1230) Signed-off-by: R4SAS --- contrib/i2pd.conf | 10 +++++----- libi2pd/Config.cpp | 30 +++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 1ef725bb..f8786a33 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -13,10 +13,10 @@ ## Tunnels config files path ## Use that path to store separated tunnels in different config files. ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d -# tunnelsdir = /var/lib/i2pd/tunnels.conf.d +# tunnelsdir = /var/lib/i2pd/tunnels.d ## Where to write pidfile (don't write by default) -# pidfile = /var/run/i2pd.pid +# pidfile = /run/i2pd.pid ## Logging configuration section ## By default logs go to stdout with level 'info' and higher @@ -27,10 +27,10 @@ ## * syslog - use syslog, see man 3 syslog # log = file ## Path to logfile (default - autodetect) -# logfile = /var/log/i2pd.log -## Log messages above this level (debug, *info, warn, error, none) +# logfile = /var/log/i2pd/i2pd.log +## Log messages above this level (debug, info, *warn, error, none) ## If you set it to none, logging will be disabled -# loglevel = info +# loglevel = warn ## Write full CLF-formatted date and time to log (default: write only time) # logclftime = true diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 975a027e..cd17660a 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -35,11 +35,11 @@ namespace config { ("version", "Show i2pd version") ("conf", value()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)") ("tunconf", value()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)") - ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") + ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") ("pidfile", value()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)") ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") - ("loglevel", value()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error, none)") + ("loglevel", value()->default_value("warn"), "Set the minimal level of log messages (debug, info, warn, error, none)") ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") @@ -88,7 +88,7 @@ namespace config { ("http.pass", value()->default_value(""), "Password for basic auth (default: random, see logs)") ("http.strictheaders", value()->default_value(true), "Enable strict host checking on WebUI") ("http.hostname", value()->default_value("localhost"), "Expected hostname for WebUI") - ("http.webroot", value()->default_value("/"), "WebUI root path (default: / )") + ("http.webroot", value()->default_value("/"), "WebUI root path (default: / )") ; options_description httpproxy("HTTP Proxy options"); @@ -131,7 +131,7 @@ namespace config { ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") ("sam.port", value()->default_value(7656), "SAM listen port") - ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") + ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") ; options_description bob("BOB options"); @@ -191,15 +191,15 @@ namespace config { "https://reseed.i2p-projekt.de/," "https://i2p.mooo.com/netDb/," "https://netdb.i2p2.no/," - "https://reseed.i2p2.no/," - "https://reseed2.i2p2.no/," + "https://reseed.i2p2.no/," + "https://reseed2.i2p2.no/," // "https://us.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," - "https://i2p.novg.net/" + "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; @@ -228,29 +228,29 @@ namespace config { options_description ntcp2("NTCP2 Options"); ntcp2.add_options() - ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") - ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") - ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") + ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") + ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") + ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") - ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") + ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") ; options_description nettime("Time sync options"); nettime.add_options() - ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") + ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") ("nettime.ntpservers", value()->default_value( "0.pool.ntp.org," "1.pool.ntp.org," "2.pool.ntp.org," "3.pool.ntp.org" ), "Comma separated list of NTCP servers") - ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") + ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") ; options_description persist("Network information persisting options"); persist.add_options() - ("persist.profiles", value()->default_value(true), "Persist peer profiles (default: true)") - ("persist.addressbook", value()->default_value(true), "Persist full addresses (default: true)") + ("persist.profiles", value()->default_value(true), "Persist peer profiles (default: true)") + ("persist.addressbook", value()->default_value(true), "Persist full addresses (default: true)") ; m_OptionsDesc From 65e1871cd73adc07f9c0fb6180b63764c7bbf781 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 18:23:13 -0400 Subject: [PATCH 070/189] new tag for each NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 25 ++++++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 06f6c84e..43049d56 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -386,7 +386,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - uint64_t tag = CreateNewSessionTagset ()->GetNextSessionTag (); + m_NSRTagset = CreateNewSessionTagset (); + uint64_t tag = m_NSRTagset->GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, &tag, 8); @@ -396,6 +397,8 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; } + memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR + memcpy (m_NSRH, m_H, 32); offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) @@ -408,14 +411,13 @@ namespace garlic uint8_t nonce[12]; CreateNonce (0, nonce); // calulate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) offset += 16; - memcpy (m_NSRHeader, out, 56); // for possible next NSR // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) @@ -442,9 +444,21 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob and sent NSR already - memcpy (out, m_NSRHeader, 56); + uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + memcpy (out, &tag, 8); + memcpy (out + 8, m_NSREncodedKey, 32); + // recalculte h with new tag + memcpy (m_H, m_NSRH, 32); + MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; - CreateNonce (0, nonce); + CreateNonce (0, nonce); + if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + { + LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); + return false; + } + MixHash (out + 40, 16); // h = SHA256(h || ciphertext) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt { @@ -568,6 +582,7 @@ namespace garlic { case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; + m_NSRTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 20676405..995bbe4a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -147,11 +147,11 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only - uint8_t m_NSRHeader[56], m_NSRKey[32]; // new session reply, for incoming only + uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset; + std::shared_ptr m_SendTagset, m_NSRTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; From c0de9455bbda0d18e7db75aa382a9bfa166a36a8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 02:11:35 +0300 Subject: [PATCH 071/189] [android] stop immediatly if no transit tunnels available while graceful shutdown Signed-off-by: R4SAS --- android/jni/i2pd_android.cpp | 6 ++++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 3 +++ android/src/org/purplei2p/i2pd/DaemonSingleton.java | 4 ++++ android/src/org/purplei2p/i2pd/I2PDActivity.java | 11 ++++++++--- android/src/org/purplei2p/i2pd/I2PD_JNI.java | 2 ++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index bb058b5d..177bfd7c 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -4,6 +4,7 @@ #include "RouterContext.h" #include "ClientContext.h" #include "Transports.h" +#include "Tunnel.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith (JNIEnv *env, jclass clazz) { @@ -98,3 +99,8 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir // Set DataDir i2p::android::SetDataDir(dataDir); } + +JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount + (JNIEnv *env, jclass clazz) { + return i2p::tunnel::tunnels.CountTransitTunnels(); +} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index 6d809e63..d5c2f15f 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -36,6 +36,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir (JNIEnv *env, jclass clazz, jstring jdataDir); +JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index 49a323ae..e9e4fc06 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -65,6 +65,10 @@ public class DaemonSingleton { } } + public synchronized int GetTransitTunnelsCount() { + return I2PD_JNI.GetTransitTunnelsCount(); + } + private volatile boolean startedOkay; public enum State { diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 5303a4da..8295e9f1 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -74,7 +74,7 @@ public class I2PDActivity extends Activity { processAssets(); runOnUiThread(() -> { try { - if (textView==null) + if (textView == null) return; Throwable tr = daemon.getLastThrowable(); if (tr!=null) { @@ -128,7 +128,7 @@ public class I2PDActivity extends Activity { doBindService(); final Timer gracefulQuitTimer = getGracefulQuitTimer(); - if (gracefulQuitTimer!=null) { + if (gracefulQuitTimer != null) { long gracefulStopAtMillis; synchronized (graceStartedMillis_LOCK) { gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; @@ -373,6 +373,11 @@ public class I2PDActivity extends Activity { if (gracefulQuitTimerOld != null) gracefulQuitTimerOld.cancel(); + if(daemon.GetTransitTunnelsCount() <= 0) { // no tunnels left + Log.d(TAG, "no transit tunnels left, stopping"); + i2pdStop(); + } + final Timer gracefulQuitTimer = new Timer(true); setGracefulQuitTimer(gracefulQuitTimer); gracefulQuitTimer.schedule(new TimerTask() { @@ -480,7 +485,7 @@ public class I2PDActivity extends Activity { private void deleteRecursive(File fileOrDirectory) { if (fileOrDirectory.isDirectory()) { File[] files = fileOrDirectory.listFiles(); - if (files!=null) { + if (files != null) { for (File child : files) { deleteRecursive(child); } diff --git a/android/src/org/purplei2p/i2pd/I2PD_JNI.java b/android/src/org/purplei2p/i2pd/I2PD_JNI.java index deb7d6b9..582b102b 100644 --- a/android/src/org/purplei2p/i2pd/I2PD_JNI.java +++ b/android/src/org/purplei2p/i2pd/I2PD_JNI.java @@ -22,6 +22,8 @@ public class I2PD_JNI { public static native void setDataDir(String jdataDir); + public static native int GetTransitTunnelsCount(); + public static void loadLibraries() { //System.loadLibrary("c++_shared"); System.loadLibrary("i2pd"); From 3d9c844dca41d464920077cd73d46a374175f0b5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 22:03:13 -0400 Subject: [PATCH 072/189] handle out of order NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 52 ++++++++++++++++------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 43049d56..025340c8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -482,13 +482,18 @@ namespace garlic } buf += 32; len -= 32; // KDF for Reply Key Section + uint8_t h[32]; memcpy (h, m_H, 32); // save m_H MixHash (tag, 8); // h = SHA256(h || tag) MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + if (m_State == eSessionStateNewSessionSent) + { + // only fist time, we assume ephemeral keys the same + m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + } uint8_t nonce[12]; CreateNonce (0, nonce); // calulate hash for zero length @@ -502,14 +507,17 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - // k_ab = keydata[0:31], k_ba = keydata[32:63] - m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) - m_SendTagset->NextSessionTagRatchet (); - auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) - receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + if (m_State == eSessionStateNewSessionSent) + { + // k_ab = keydata[0:31], k_ba = keydata[32:63] + m_SendTagset = std::make_shared(shared_from_this ()); + m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_SendTagset->NextSessionTagRatchet (); + auto receiveTagset = std::make_shared(shared_from_this ()); + receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + receiveTagset->NextSessionTagRatchet (); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -518,9 +526,13 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - - m_State = eSessionStateEstablished; - GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + + if (m_State == eSessionStateNewSessionSent) + { + m_State = eSessionStateEstablished; + GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + } + memcpy (m_H, h, 32); // restore m_H HandlePayload (payload.data (), len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it @@ -587,7 +599,15 @@ namespace garlic [[fallthrough]]; #endif case eSessionStateEstablished: - return HandleExistingSessionMessage (buf, len, receiveTagset, index); + if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; + if (index < ECIESX25519_NSR_NUM_GENERATED_TAGS) + { + // check NSR just in case + LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); + return HandleNewOutgoingSessionReply (buf, len); + } + else + return false; case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: From 16b992d7055fdd1258572674cc8b5f9391af9867 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 16:55:25 +0300 Subject: [PATCH 073/189] update info about pidfile defaults (closes #1136) Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- daemon/UnixDaemon.cpp | 3 +-- daemon/i2pd.cpp | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index f8786a33..2174abe8 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -15,7 +15,7 @@ ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d # tunnelsdir = /var/lib/i2pd/tunnels.d -## Where to write pidfile (don't write by default) +## Where to write pidfile (default: i2pd.pid, not used in Windows) # pidfile = /run/i2pd.pid ## Logging configuration section diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index 3dd38fba..b7af779c 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -167,7 +167,7 @@ namespace i2p sigaction(SIGABRT, &sa, 0); sigaction(SIGTERM, &sa, 0); sigaction(SIGINT, &sa, 0); - sigaction(SIGPIPE, &sa, 0); + sigaction(SIGPIPE, &sa, 0); return Daemon_Singleton::start(); } @@ -175,7 +175,6 @@ namespace i2p bool DaemonLinux::stop() { i2p::fs::Remove(pidfile); - return Daemon_Singleton::stop(); } diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 8718ad0c..425c2560 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -7,18 +7,18 @@ namespace i2p { namespace qt { - int RunQT (int argc, char* argv[]); + int RunQT (int argc, char* argv[]); } } int main( int argc, char* argv[] ) { - return i2p::qt::RunQT (argc, argv); + return i2p::qt::RunQT (argc, argv); } #else int main( int argc, char* argv[] ) { - if (Daemon.init(argc, argv)) + if (Daemon.init(argc, argv)) { if (Daemon.start()) Daemon.run (); From 627d8cfe6965c26b0907a7b8574ada7bcf1a73a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Apr 2020 17:11:48 -0400 Subject: [PATCH 074/189] correct timestamp check for LeaseSet2 --- libi2pd/LeaseSet.cpp | 36 ++++++++++++++++++++++-------------- libi2pd/LeaseSet.h | 10 ++++++---- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index b411ca0e..6ce77792 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -149,20 +149,13 @@ namespace data auto ret = m_Leases.insert (std::make_shared(lease)); if (!ret.second) (*ret.first)->endDate = lease.endDate; // update existing (*ret.first)->isUpdated = true; - // check if lease's gateway is in our netDb - if (!netdb.FindRouter (lease.tunnelGateway)) - { - // if not found request it - LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting"); - netdb.RequestDestination (lease.tunnelGateway); - } } } else LogPrint (eLogWarning, "LeaseSet: Lease is expired already"); } - uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const + uint64_t LeaseSet::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const { if (!m_Identity) return 0; size_t size = m_Identity->GetFullLen (); @@ -187,7 +180,7 @@ namespace data bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const { - return ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen); + return ExtractExpirationTimestamp (buf, len) > (m_ExpirationTime ? m_ExpirationTime : ExtractExpirationTimestamp (m_Buffer, m_BufferLen)); } bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const @@ -282,6 +275,12 @@ namespace data ReadFromBuffer (buf, len, false, verifySignature); // TODO: implement encrypted } + + bool LeaseSet2::IsNewer (const uint8_t * buf, size_t len) const + { + uint64_t expiration; + return ExtractPublishedTimestamp (buf, len, expiration) > m_PublishedTimestamp; + } void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity, bool verifySignature) { @@ -640,7 +639,14 @@ namespace data encryptor->Encrypt (data, encrypted, ctx, true); } - uint64_t LeaseSet2::ExtractTimestamp (const uint8_t * buf, size_t len) const + uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const + { + uint64_t expiration = 0; + ExtractPublishedTimestamp (buf, len, expiration); + return expiration; + } + + uint64_t LeaseSet2::ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const { if (len < 8) return 0; if (m_StoreType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) @@ -655,7 +661,8 @@ namespace data offset += blindedKeyLen; uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; uint16_t expires = bufbe16toh (buf + offset); offset += 2; - return (timestamp + expires)* 1000LL; + expiration = (timestamp + expires)* 1000LL; + return timestamp; } else { @@ -665,10 +672,11 @@ namespace data if (offset + 6 >= len) return 0; uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; uint16_t expires = bufbe16toh (buf + offset); offset += 2; - return (timestamp + expires)* 1000LL; + expiration = (timestamp + expires)* 1000LL; + return timestamp; } - } - + } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): m_ExpirationTime (0), m_Identity (identity) { diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 0d255644..4d084da3 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -63,14 +63,14 @@ namespace data LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true); virtual ~LeaseSet () { delete[] m_EncryptionKey; delete[] m_Buffer; }; virtual void Update (const uint8_t * buf, size_t len, bool verifySignature = true); - bool IsNewer (const uint8_t * buf, size_t len) const; + virtual bool IsNewer (const uint8_t * buf, size_t len) const; void PopulateLeases (); // from buffer const uint8_t * GetBuffer () const { return m_Buffer; }; size_t GetBufferLen () const { return m_BufferLen; }; bool IsValid () const { return m_IsValid; }; const std::vector > GetNonExpiredLeases (bool withThreshold = true) const; - const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; + const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; bool HasExpiredLeases () const; bool IsExpired () const; bool IsEmpty () const { return m_Leases.empty (); }; @@ -106,7 +106,7 @@ namespace data private: void ReadFromBuffer (bool readIdentity = true, bool verifySignature = true); - virtual uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time + virtual uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time private: @@ -145,6 +145,7 @@ namespace data bool IsPublishedEncrypted () const { return m_IsPublishedEncrypted; }; std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; }; void Update (const uint8_t * buf, size_t len, bool verifySignature); + bool IsNewer (const uint8_t * buf, size_t len) const; // implements RoutingDestination void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; @@ -160,7 +161,8 @@ namespace data template bool VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset); - uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; + uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const; + uint64_t ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const; size_t ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const; // subcredential is subcredential + timestamp, return length of autData without flag private: From 7133a07f389de35e273d65e24b066ec1396f2d26 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 01:52:44 +0300 Subject: [PATCH 075/189] [SOCKS] wrap DNS type requests response as IPv4 (fixes netcat usage, closes #1336) Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 69 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 8742d4c5..9cb69590 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -135,9 +135,9 @@ namespace proxy void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamConnected(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; @@ -184,8 +184,8 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async sock read"); if (m_sock) { m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), - std::bind(&SOCKSHandler::HandleSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError,"SOCKS: no socket for read"); } @@ -219,8 +219,8 @@ namespace proxy assert(error >= SOCKS4_OK); m_response[0] = '\x00'; //Version m_response[1] = error; //Response code - htobe16buf(m_response+2,port); //Port - htobe32buf(m_response+4,ip); //IP + htobe16buf(m_response + 2, port); //Port + htobe32buf(m_response + 4, ip); //IP return boost::asio::const_buffers_1(m_response,8); } @@ -236,20 +236,23 @@ namespace proxy { case ADDR_IPV4: size = 10; - htobe32buf(m_response+4,addr.ip); + htobe32buf(m_response + 4, addr.ip); break; case ADDR_IPV6: size = 22; - memcpy(m_response+4,addr.ipv6, 16); + memcpy(m_response + 4, addr.ipv6, 16); break; case ADDR_DNS: - size = 7+addr.dns.size; + size = 7 + addr.dns.size; m_response[4] = addr.dns.size; - memcpy(m_response+5,addr.dns.value, addr.dns.size); + memcpy(m_response + 5, addr.dns.value, addr.dns.size); + // replace type to IPv4 for support socks5 clients + // without domain name resolving support (like netcat) + m_response[3] = ADDR_IPV4; break; } - htobe16buf(m_response+size-2,port); //Port - return boost::asio::const_buffers_1(m_response,size); + htobe16buf(m_response + size - 2, port); //Port + return boost::asio::const_buffers_1(m_response, size); } boost::asio::const_buffers_1 SOCKSHandler::GenerateUpstreamRequest() @@ -259,7 +262,7 @@ namespace proxy // SOCKS 4a m_upstream_request[0] = '\x04'; //version m_upstream_request[1] = m_cmd; - htobe16buf(m_upstream_request+2, m_port); + htobe16buf(m_upstream_request + 2, m_port); m_upstream_request[4] = 0; m_upstream_request[5] = 0; m_upstream_request[6] = 0; @@ -270,7 +273,7 @@ namespace proxy m_upstream_request[10] = 'p'; m_upstream_request[11] = 'd'; m_upstream_request[12] = 0; - upstreamRequestSize += 13; + upstreamRequestSize += 13; if (m_address.dns.size <= max_socks_hostname_size - ( upstreamRequestSize + 1) ) { // bounds check okay memcpy(m_upstream_request + upstreamRequestSize, m_address.dns.value, m_address.dns.size); @@ -285,21 +288,19 @@ namespace proxy bool SOCKSHandler::Socks5ChooseAuth() { - m_response[0] = '\x05'; //Version - m_response[1] = m_authchosen; //Response code - boost::asio::const_buffers_1 response(m_response,2); + m_response[0] = '\x05'; // Version + m_response[1] = m_authchosen; // Response code + boost::asio::const_buffers_1 response(m_response, 2); if (m_authchosen == AUTH_UNACCEPTABLE) { LogPrint(eLogWarning, "SOCKS: v5 authentication negotiation failed"); - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, shared_from_this(), std::placeholders::_1)); return false; } else { LogPrint(eLogDebug, "SOCKS: v5 choosing authentication method: ", m_authchosen); - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1)); return true; } } @@ -313,7 +314,7 @@ namespace proxy { case SOCKS4: LogPrint(eLogWarning, "SOCKS: v4 request failed: ", error); - if (error < SOCKS4_OK) error = SOCKS4_FAIL; //Transparently map SOCKS5 errors + if (error < SOCKS4_OK) error = SOCKS4_FAIL; // Transparently map SOCKS5 errors response = GenerateSOCKS4Response(error, m_4aip, m_port); break; case SOCKS5: @@ -322,13 +323,13 @@ namespace proxy break; } boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, - shared_from_this(), std::placeholders::_1)); + shared_from_this(), std::placeholders::_1)); } void SOCKSHandler::SocksRequestSuccess() { boost::asio::const_buffers_1 response(nullptr,0); - //TODO: this should depend on things like the command type and callbacks may change + // TODO: this should depend on things like the command type and callbacks may change switch (m_socksv) { case SOCKS4: @@ -339,12 +340,11 @@ namespace proxy LogPrint(eLogInfo, "SOCKS: v5 connection success"); auto s = i2p::client::context.GetAddressBook().ToAddress(GetOwner()->GetLocalDestination()->GetIdentHash()); address ad; ad.dns.FromString(s); - //HACK only 16 bits passed in port as SOCKS5 doesn't allow for more + // HACK only 16 bits passed in port as SOCKS5 doesn't allow for more response = GenerateSOCKS5Response(SOCKS5_OK, ADDR_DNS, ad, m_stream->GetRecvStreamID()); break; } - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone, shared_from_this(), std::placeholders::_1)); } void SOCKSHandler::EnterState(SOCKSHandler::state nstate, uint8_t parseleft) { @@ -366,12 +366,12 @@ namespace proxy { if ( m_cmd != CMD_CONNECT ) { - //TODO: we need to support binds and other shit! + // TODO: we need to support binds and other shit! LogPrint(eLogError, "SOCKS: unsupported command: ", m_cmd); SocksRequestFailed(SOCKS5_CMD_UNSUP); return false; } - //TODO: we may want to support other address types! + // TODO: we may want to support other address types! if ( m_addrtype != ADDR_DNS ) { switch (m_socksv) @@ -433,9 +433,9 @@ namespace proxy break; case CMD_UDP: if (m_socksv == SOCKS5) break; -#if (__cplusplus >= 201703L) // C++ 17 or higher +#if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; -#endif +#endif default: LogPrint(eLogError, "SOCKS: invalid command: ", ((int)*sock_buff)); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -652,8 +652,8 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async upstream sock read"); if (m_upstreamSock) { m_upstreamSock->async_read_some(boost::asio::buffer(m_upstream_response, SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE), - std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError, "SOCKS: no upstream socket for read"); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -735,8 +735,7 @@ namespace proxy LogPrint(eLogInfo, "SOCKS: negotiating with upstream proxy"); EnterState(UPSTREAM_HANDSHAKE); if (m_upstreamSock) { - boost::asio::write(*m_upstreamSock, - GenerateUpstreamRequest()); + boost::asio::write(*m_upstreamSock, GenerateUpstreamRequest()); AsyncUpstreamSockRead(); } else { LogPrint(eLogError, "SOCKS: no upstream socket to send handshake to"); From 27d69894d474092f97990b726d787cd5245ddda5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Apr 2020 20:50:31 -0400 Subject: [PATCH 076/189] show ECIESx25519 session and tag on the web console --- daemon/HTTPServer.cpp | 11 +++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 9 +++++++++ libi2pd/Garlic.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ef1e0716..bc1eccd5 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -22,6 +22,7 @@ #include "HTTPServer.h" #include "Daemon.h" #include "util.h" +#include "ECIESX25519AEADRatchetSession.h" #ifdef WIN32_APP #include "Win32/Win32App.h" #endif @@ -409,6 +410,16 @@ namespace http { << "

\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n\r\n"; } else s << "Outgoing: 0
\r\n"; + auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); + if (numECIESx25519Tags > 0) + s << "Incoming ECIESx25519: " << numECIESx25519Tags << "
"; + if (!dest->GetECIESx25519Sessions ().empty ()) + { + s << "
\r\nECIESx25519Tags sessions
"; + for (const auto& it: dest->GetECIESx25519Sessions ()) + s << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) + << " " << it.second->GetState () << "
\r\n"; + } s << "
\r\n"; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 995bbe4a..6dd842e4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -156,6 +156,15 @@ namespace garlic std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; + + public: + + // for HTTP only + int GetState () const { return (int)m_State; } + i2p::data::IdentHash GetDestination () const + { + return m_Destination ? *m_Destination : i2p::data::IdentHash (); + } }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index ffb66245..2c71abe8 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -276,7 +276,9 @@ namespace garlic // for HTTP only size_t GetNumIncomingTags () const { return m_Tags.size (); } + size_t GetNumIncomingECIESx25519Tags () const { return m_ECIESx25519Tags.size (); } const decltype(m_Sessions)& GetSessions () const { return m_Sessions; }; + const decltype(m_ECIESx25519Sessions)& GetECIESx25519Sessions () const { return m_ECIESx25519Sessions; } }; void CleanUpTagsFiles (); From 1aa0da33820eb091c76e7b95553cace3416245eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 04:44:13 +0300 Subject: [PATCH 077/189] [NTCP2] fix socks proxy support Signed-off-by: R4SAS --- libi2pd/Config.cpp | 10 ++-- libi2pd/NTCP2.cpp | 119 +++++++++++++++++---------------------- libi2pd/NTCP2.h | 2 +- libi2pd/NTCPSession.cpp | 1 - libi2pd/Transports.cpp | 56 +++++++++--------- libi2pd_client/SOCKS.cpp | 42 +++++++------- 6 files changed, 109 insertions(+), 121 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index cd17660a..580e9156 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -58,9 +58,9 @@ namespace config { ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") - ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") + ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") @@ -97,7 +97,8 @@ namespace config { ("httpproxy.address", value()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.port", value()->default_value(4444), "HTTP Proxy listen port") ("httpproxy.keys", value()->default_value(""), "File to persist HTTP Proxy keys") - ("httpproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("httpproxy.signaturetype", value()-> + default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") ("httpproxy.outbound.length", value()->default_value("3"), "HTTP proxy outbound tunnel length") ("httpproxy.inbound.quantity", value()->default_value("5"), "HTTP proxy inbound tunnels quantity") @@ -114,7 +115,8 @@ namespace config { ("socksproxy.address", value()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.port", value()->default_value(4447), "SOCKS Proxy listen port") ("socksproxy.keys", value()->default_value(""), "File to persist SOCKS Proxy keys") - ("socksproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("socksproxy.signaturetype", value()-> + default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") ("socksproxy.outbound.length", value()->default_value("3"), "SOCKS proxy outbound tunnel length") ("socksproxy.inbound.quantity", value()->default_value("5"), "SOCKS proxy inbound tunnels quantity") diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 85d83bf0..e7c37fdd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()) + m_Resolver(GetService ()), m_ProxyType(eNoProxy), m_ProxyEndpoint(nullptr) { } @@ -1164,25 +1164,23 @@ namespace transport StartIOService (); if(UsingProxy()) { - LogPrint(eLogError, "NTCP2: USING PROXY "); + LogPrint(eLogInfo, "NTCP2: Using proxy to connect to peers"); // TODO: resolve proxy until it is resolved boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); boost::system::error_code e; auto itr = m_Resolver.resolve(q, e); if(e) - { LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message()); - } else { m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr)); if (m_ProxyEndpoint) - LogPrint(eLogError, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); + LogPrint(eLogDebug, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); } } else { - LogPrint(eLogError, "NTCP2: NOTUSING PROXY "); + LogPrint(eLogInfo, "NTCP2: Proxy is not used"); auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address: addresses) { @@ -1426,6 +1424,31 @@ namespace transport } } + void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(!m_ProxyEndpoint) return; + GetService().post([this, host, port, addrtype, conn]() { + if (this->AddNTCP2Session (conn)) + { + + auto timer = std::make_shared(GetService()); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); + } + void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) { m_ProxyType = proxytype; @@ -1443,14 +1466,14 @@ namespace transport return; } switch (m_ProxyType) - { + { case eSocksProxy: { // TODO: support username/password auth etc static const uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), - [] (const boost::system::error_code & ec, std::size_t transferred) - { + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { (void) transferred; if(ec) { @@ -1505,8 +1528,8 @@ namespace transport out << req.to_string(); boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) - { + [](const boost::system::error_code & ec, std::size_t transferred) + { (void) transferred; if(ec) LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); @@ -1549,38 +1572,13 @@ namespace transport } default: LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); - } + } } - void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(!m_ProxyEndpoint) return; - GetService().post([this, host, port, addrtype, conn]() { - if (this->AddNTCP2Session (conn)) - { - - auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) { // build request - size_t sz = 0; + size_t sz = 6; // header + port auto buff = std::make_shared >(256); auto readbuff = std::make_shared >(256); (*buff)[0] = 0x05; @@ -1590,37 +1588,27 @@ namespace transport if(addrtype == eIP4Address) { (*buff)[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff->data () + 4, addrbytes.data(), addrsize); + auto addrbytes = boost::asio::ip::address::from_string(host).to_v4().to_bytes(); + sz += 4; + memcpy(buff->data () + 4, addrbytes.data(), 4); } else if (addrtype == eIP6Address) { (*buff)[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff->data () + 4, addrbytes.data(), addrsize); + auto addrbytes = boost::asio::ip::address::from_string(host).to_v6().to_bytes(); + sz += 16; + memcpy(buff->data () + 4, addrbytes.data(), 16); } else if (addrtype == eHostname) { - (*buff)[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > buff->size ()) - { - // too big - return; - } - (*buff)[4] = (uint8_t) addrsize; - memcpy(buff->data() + 5, host.c_str(), addrsize); + // We mustn't really fall here because all connections are made to IP addresses + LogPrint(eLogError, "NTCP2: Tried to connect to domain name via socks proxy"); + return; } - htobe16buf(buff->data () + sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t written) - { + htobe16buf(buff->data () + sz - 2, port); + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), + [buff](const boost::system::error_code & ec, std::size_t written) + { if(ec) { LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); @@ -1628,9 +1616,9 @@ namespace transport } }); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), - [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) - { + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), + [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) + { if(e) { LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); @@ -1650,6 +1638,5 @@ namespace transport conn->Terminate(); }); } - } } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 11ae5995..10170fda 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -274,7 +274,7 @@ namespace transport std::map > m_NTCP2Sessions; std::list > m_PendingIncomingSessions; - ProxyType m_ProxyType =eNoProxy; + ProxyType m_ProxyType; std::string m_ProxyAddress; uint16_t m_ProxyPort; boost::asio::ip::tcp::resolver m_Resolver; diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 9711ffb0..ae94553c 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -1193,7 +1193,6 @@ namespace transport void NTCPServer::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) { - // build request size_t sz = 0; uint8_t buff[256]; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 804f26cb..bb74e2ad 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -176,7 +176,7 @@ namespace transport if (proxyurl.schema == "http") proxytype = NTCPServer::eHTTPProxy; - m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port); m_NTCPServer->Start(); if(!m_NTCPServer->NetworkIsReady()) { @@ -194,7 +194,7 @@ namespace transport return; } // create NTCP2. TODO: move to acceptor - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { if(!ntcp2proxy.empty()) @@ -209,7 +209,7 @@ namespace transport if (proxyurl.schema == "http") proxytype = NTCP2Server::eHTTPProxy; - m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port); m_NTCP2Server->Start(); } else @@ -424,36 +424,36 @@ namespace transport { if (peer.router) // we have RI already { - if (!peer.numAttempts) // NTCP2 - { - peer.numAttempts++; - if (m_NTCP2Server) // we support NTCP2 - { - // NTCP2 have priority over NTCP - auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address) - { - auto s = std::make_shared (*m_NTCP2Server, peer.router); + if (!peer.numAttempts) // NTCP2 + { + peer.numAttempts++; + if (m_NTCP2Server) // we support NTCP2 + { + // NTCP2 have priority over NTCP + auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only + if (address) + { + auto s = std::make_shared (*m_NTCP2Server, peer.router); - if(m_NTCP2Server->UsingProxy()) - { - NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; - std::string addr = address->host.to_string(); + if(m_NTCP2Server->UsingProxy()) + { + NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; + std::string addr = address->host.to_string(); - if(address->host.is_v6()) - remote = NTCP2Server::eIP6Address; + if(address->host.is_v6()) + remote = NTCP2Server::eIP6Address; - m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); - } - else - m_NTCP2Server->Connect (address->host, address->port, s); - return true; - } - } - } + m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); + } + else + m_NTCP2Server->Connect (address->host, address->port, s); + return true; + } + } + } if (peer.numAttempts == 1) // NTCP1 { - peer.numAttempts++; + peer.numAttempts++; auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); if (address && m_NTCPServer) { diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 9cb69590..a70ac2b7 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -118,7 +118,7 @@ namespace proxy boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method); boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); - boost::asio::const_buffers_1 GenerateUpstreamRequest(); + boost::asio::const_buffers_1 GenerateUpstreamRequest(); bool Socks5ChooseAuth(); void SocksRequestFailed(errTypes error); void SocksRequestSuccess(); @@ -128,27 +128,27 @@ namespace proxy void HandleStreamRequestComplete (std::shared_ptr stream); void ForwardSOCKS(); - void SocksUpstreamSuccess(); - void AsyncUpstreamSockRead(); - void SendUpstreamRequest(); + void SocksUpstreamSuccess(); + void AsyncUpstreamSockRead(); + void SendUpstreamRequest(); void HandleUpstreamData(uint8_t * buff, std::size_t len); - void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); - void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); - void HandleUpstreamConnected(const boost::system::error_code & ecode, + void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); + void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); + void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); - void HandleUpstreamResolved(const boost::system::error_code & ecode, + void HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); - boost::asio::ip::tcp::resolver m_proxy_resolver; - uint8_t m_sock_buff[socks_buffer_size]; - std::shared_ptr m_sock, m_upstreamSock; + boost::asio::ip::tcp::resolver m_proxy_resolver; + uint8_t m_sock_buff[socks_buffer_size]; + std::shared_ptr m_sock, m_upstreamSock; std::shared_ptr m_stream; uint8_t *m_remaining_data; //Data left to be sent uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded uint8_t m_response[7+max_socks_hostname_size]; - uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; - uint8_t m_upstream_request[14+max_socks_hostname_size]; - std::size_t m_upstream_response_len; + uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; + uint8_t m_upstream_request[14+max_socks_hostname_size]; + std::size_t m_upstream_response_len; address m_address; //Address std::size_t m_remaining_data_len; //Size of the data left to be sent uint32_t m_4aip; //Used in 4a requests @@ -161,11 +161,11 @@ namespace proxy cmdTypes m_cmd; // Command requested state m_state; const bool m_UseUpstreamProxy; // do we want to use the upstream proxy for non i2p addresses? - const std::string m_UpstreamProxyAddress; - const uint16_t m_UpstreamProxyPort; + const std::string m_UpstreamProxyAddress; + const uint16_t m_UpstreamProxyPort; public: - SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : + SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : I2PServiceHandler(parent), m_proxy_resolver(parent->GetService()), m_sock(sock), m_stream(nullptr), @@ -226,7 +226,7 @@ namespace proxy boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) { - size_t size = 6; + size_t size = 6; // header + port assert(error <= SOCKS5_ADDR_UNSUP); m_response[0] = '\x05'; //Version m_response[1] = error; //Response code @@ -235,15 +235,15 @@ namespace proxy switch (type) { case ADDR_IPV4: - size = 10; + size += 4; htobe32buf(m_response + 4, addr.ip); break; case ADDR_IPV6: - size = 22; + size += 16; memcpy(m_response + 4, addr.ipv6, 16); break; case ADDR_DNS: - size = 7 + addr.dns.size; + size += (1 + addr.dns.size); /* name length + domain name */ m_response[4] = addr.dns.size; memcpy(m_response + 5, addr.dns.value, addr.dns.size); // replace type to IPv4 for support socks5 clients From f5712c419848bd9c4ea27dfe66253ad8a6c61a1f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 04:59:05 +0300 Subject: [PATCH 078/189] remove not needed initialization for pointer Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e7c37fdd..4efcc92f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()), m_ProxyType(eNoProxy), m_ProxyEndpoint(nullptr) + m_Resolver(GetService ()), m_ProxyType(eNoProxy) { } @@ -1412,7 +1412,7 @@ namespace transport if ((*it)->IsEstablished () || (*it)->IsTerminationTimeoutExpired (ts)) { (*it)->Terminate (); - it = m_PendingIncomingSessions.erase (it); // etsablished of expired + it = m_PendingIncomingSessions.erase (it); // established of expired } else if ((*it)->IsTerminated ()) it = m_PendingIncomingSessions.erase (it); // already terminated From c36747603681f3919a7ee26a2cb68a2adecbd968 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 16:21:49 +0300 Subject: [PATCH 079/189] [webconsole] fix printing information about ECIESx25519 tags/sessions Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index bc1eccd5..8b0323ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -399,28 +399,36 @@ namespace http { } } s << "
\r\n"; - s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
"; + + s << "Tags
\r\nIncoming: " << dest->GetNumIncomingTags () << "
\r\n"; if (!dest->GetSessions ().empty ()) { std::stringstream tmp_s; uint32_t out_tags = 0; for (const auto& it: dest->GetSessions ()) { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; - out_tags = out_tags + it.second->GetNumOutgoingTags (); + out_tags += it.second->GetNumOutgoingTags (); } s << "
\r\n\r\n" << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; - auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); - if (numECIESx25519Tags > 0) - s << "Incoming ECIESx25519: " << numECIESx25519Tags << "
"; - if (!dest->GetECIESx25519Sessions ().empty ()) - { - s << "
\r\nECIESx25519Tags sessions
"; - for (const auto& it: dest->GetECIESx25519Sessions ()) - s << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) - << " " << it.second->GetState () << "
\r\n"; - } s << "
\r\n"; + + auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); + if (numECIESx25519Tags > 0) { + s << "ECIESx25519
\r\nIncoming Tags: " << numECIESx25519Tags << "
\r\n"; + if (!dest->GetECIESx25519Sessions ().empty ()) + { + std::stringstream tmp_s; uint32_t ecies_sessions = 0; + for (const auto& it: dest->GetECIESx25519Sessions ()) { + tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "" << it.second->GetState () << "\r\n"; + ecies_sessions++; + } + s << "
\r\n\r\n" + << "
\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + } else + s << "Tags sessions: 0
\r\n"; + s << "
\r\n"; + } } void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token) From c4f9f7da06123b678b40271d528697a78baf1e23 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 13:45:26 -0400 Subject: [PATCH 080/189] fixed warning --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 4efcc92f..2091b373 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()), m_ProxyType(eNoProxy) + m_ProxyType(eNoProxy), m_Resolver(GetService ()) { } From 17e69e67b1391705e44348599524632ba44cf4d9 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 15:38:15 -0400 Subject: [PATCH 081/189] create additional tags for NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 025340c8..56fc5948 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -600,14 +600,11 @@ namespace garlic #endif case eSessionStateEstablished: if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; - if (index < ECIESX25519_NSR_NUM_GENERATED_TAGS) - { - // check NSR just in case - LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); - return HandleNewOutgoingSessionReply (buf, len); - } - else - return false; + // check NSR just in case + LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); + if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2) + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS); + return HandleNewOutgoingSessionReply (buf, len); case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: @@ -620,12 +617,12 @@ namespace garlic std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); size_t len = payload.size (); - + auto m = NewI2NPMessage (len + 100); // 96 + 4 + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + switch (m_State) { case eSessionStateEstablished: From ec4e17f75c0109bcb3a0d70ff67b98e10ef2368f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 21:27:35 -0400 Subject: [PATCH 082/189] cleanup previous tagsets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 21 +++++++++++++-------- libi2pd/Garlic.cpp | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 56fc5948..788d4d6d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -78,6 +78,12 @@ namespace garlic LogPrint (eLogError, "Garlic: Missing symmetric key for index ", index); } } + + void RatchetTagSet::Expire () + { + if (!m_ExpirationTimestamp) + m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; + } ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) @@ -311,7 +317,8 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } @@ -608,6 +615,7 @@ namespace garlic case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: + receiveTagset->Expire (); // NSR tagset return HandleNewOutgoingSessionReply (buf, len); default: return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 6dd842e4..cf4eb3d7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -17,6 +17,15 @@ namespace i2p { namespace garlic { + const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after + const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; + const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; + class ECIESX25519AEADRatchetSession; class RatchetTagSet { @@ -34,6 +43,9 @@ namespace garlic std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; + + void Expire (); + bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; private: @@ -52,6 +64,7 @@ namespace garlic std::unordered_map > m_ItermediateSymmKeys; std::weak_ptr m_Session; int m_TagSetID = 0; + uint64_t m_ExpirationTimestamp = 0; }; enum ECIESx25519BlockType @@ -71,14 +84,6 @@ namespace garlic const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02; const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; - const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after - const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds - const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after - const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; - const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; - const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fe5e8d69..fb3451d0 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -788,7 +788,7 @@ namespace garlic // ECIESx25519 for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { - if (ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) + if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else ++it; From d48db501e03a81685e3419186f7831107df8e716 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 May 2020 07:33:05 -0400 Subject: [PATCH 083/189] max payload is always 1730 --- libi2pd/Streaming.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3efcfb99..3214e81b 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -505,7 +505,7 @@ namespace stream memset (signature, 0, signatureLen); // zeroes for now size += signatureLen; // signature htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size - size += m_SendBuffer.Get (packet + size, STREAMING_MTU - size); // payload + size += m_SendBuffer.Get (packet + size, STREAMING_MTU); // payload m_LocalDestination.GetOwner ()->Sign (packet, size, signature); } else @@ -515,7 +515,7 @@ namespace stream size += 2; // flags htobuf16 (packet + size, 0); // no options size += 2; // options size - size += m_SendBuffer.Get(packet + size, STREAMING_MTU - size); // payload + size += m_SendBuffer.Get(packet + size, STREAMING_MTU); // payload } p->len = size; packets.push_back (p); From c49e544781fc615879fd51d68bb338e9ec6afcab Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 May 2020 14:30:56 -0400 Subject: [PATCH 084/189] allow longer families --- libi2pd/Family.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index b7cbf7d4..bc99bb52 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -113,9 +113,9 @@ namespace data bool Families::VerifyFamily (const std::string& family, const IdentHash& ident, const char * signature, const char * key) { - uint8_t buf[50], signatureBuf[64]; + uint8_t buf[100], signatureBuf[64]; size_t len = family.length (), signatureLen = strlen (signature); - if (len + 32 > 50) + if (len + 32 > 100) { LogPrint (eLogError, "Family: ", family, " is too long"); return false; From e301387896cec0f8a30753adc7ab86d248879f79 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 May 2020 11:13:40 -0400 Subject: [PATCH 085/189] don't calculate checsum for Data message send through ECIESX25519AEADRatchet session --- libi2pd/ECIESX25519AEADRatchetSession.h | 2 ++ libi2pd/Garlic.h | 1 + libi2pd/I2NPProtocol.cpp | 4 ++-- libi2pd/I2NPProtocol.h | 2 +- libi2pd/Streaming.cpp | 10 ++++++---- libi2pd/Streaming.h | 7 +++---- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cf4eb3d7..79e920b5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -122,6 +122,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + bool IsRatchets () const { return true; }; + private: void ResetKeys (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 2c71abe8..6c81dabf 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -105,6 +105,7 @@ namespace garlic virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); + virtual bool IsRatchets () const { return false; }; void SetLeaseSetUpdated () { diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 0e7c245e..933fa707 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -39,14 +39,14 @@ namespace i2p return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); } - void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) + void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) { SetTypeID (msgType); if (!replyMsgID) RAND_bytes ((uint8_t *)&replyMsgID, 4); SetMsgID (replyMsgID); SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT); UpdateSize (); - UpdateChks (); + if (checksum) UpdateChks (); } void I2NPMessage::RenewI2NPMessageHeader () diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 2fca1538..c8957b5f 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -218,7 +218,7 @@ namespace tunnel memcpy (ntcp2 + I2NP_HEADER_TYPEID_OFFSET, GetHeader () + I2NP_HEADER_TYPEID_OFFSET, 5); // typeid + msgid } - void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0); + void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0, bool checksum = true); void RenewI2NPMessageHeader (); bool IsExpired () const; }; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3214e81b..6b547170 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -756,7 +756,8 @@ namespace stream std::vector msgs; for (auto it: packets) { - auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage (it->GetBuffer (), it->GetLength (), m_Port)); + auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage ( + it->GetBuffer (), it->GetLength (), m_Port, !m_RoutingSession->IsRatchets ())); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, @@ -1207,9 +1208,10 @@ namespace stream DeletePacket (uncompressed); } - std::shared_ptr StreamingDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort) + std::shared_ptr StreamingDestination::CreateDataMessage ( + const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { - auto msg = NewI2NPShortMessage (); + auto msg = m_I2NPMsgsPool.AcquireShared (); if (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION); else @@ -1225,7 +1227,7 @@ namespace stream htobe16buf (buf + 6, toPort); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol msg->len += size; - msg->FillI2NPMessageHeader (eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } else msg = nullptr; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 985a7eca..64e4c18d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -255,20 +255,18 @@ namespace stream void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; void AcceptOnce (const Acceptor& acceptor); + void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); std::shared_ptr GetOwner () const { return m_Owner; }; void SetOwner (std::shared_ptr owner) { m_Owner = owner; }; uint16_t GetLocalPort () const { return m_LocalPort; }; void HandleDataMessagePayload (const uint8_t * buf, size_t len); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort); + std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true); Packet * NewPacket () { return m_PacketsPool.Acquire(); } void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); } - - void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); - private: void HandleNextPacket (Packet * packet); @@ -289,6 +287,7 @@ namespace stream std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; + i2p::util::MemoryPool > m_I2NPMsgsPool; public: From 1eead0e885d2fbeaa4f60aea1682eab895c85dff Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 May 2020 21:18:44 -0400 Subject: [PATCH 086/189] GzipNoCompression witout zlib calls --- libi2pd/Gzip.cpp | 15 +++++++++++++++ libi2pd/Gzip.h | 9 +++++++-- libi2pd/Streaming.cpp | 8 +++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 1c06e941..a03640a7 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -10,6 +10,7 @@ #include /* memset */ #include #include "Log.h" +#include "I2PEndian.h" #include "Gzip.h" namespace i2p @@ -111,5 +112,19 @@ namespace data LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; } + + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) + { + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x01 }; + if (outLen < (size_t)inLen + 23) return 0; + memcpy (out, gzipHeader, 11); + htole16buf (out + 11, inLen); + htole16buf (out + 13, 0xffff - inLen); + memcpy (out + 15, in, inLen); + htole32buf (out + inLen + 15, crc32 (0, in, inLen)); + htole32buf (out + inLen + 19, inLen); + return inLen + 23; + } + } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 35661abe..cf08d920 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -3,8 +3,10 @@ #include -namespace i2p { -namespace data { +namespace i2p +{ +namespace data +{ class GzipInflator { public: @@ -38,6 +40,9 @@ namespace data { z_stream m_Deflator; bool m_IsDirty; }; + + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K + } // data } // i2p diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 6b547170..2a4175f4 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1212,14 +1212,12 @@ namespace stream const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { auto msg = m_I2NPMsgsPool.AcquireShared (); - if (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) - m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION); - else - m_Deflator.SetCompressionLevel (Z_DEFAULT_COMPRESSION); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for lengthlength msg->len += 4; - size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + size_t size = (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE)? + i2p::data::GzipNoCompression (payload, len, buf, msg->maxLen - msg->len): + m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length From dff510c181469f4bd6d4d0063ea3f3cc376d8cf2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 3 May 2020 09:27:17 -0400 Subject: [PATCH 087/189] set best compression for RouterInfo --- libi2pd/Gzip.cpp | 5 ++++- libi2pd/I2NPProtocol.cpp | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index a03640a7..2ca711b0 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -107,7 +107,10 @@ namespace data m_Deflator.avail_out = outLen; int err; if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) + { + out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; @@ -115,7 +118,7 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { - static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x01 }; + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; if (outLen < (size_t)inLen + 23) return 0; memcpy (out, gzipHeader, 11); htole16buf (out + 11, inLen); diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 933fa707..a16ce580 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -250,6 +250,7 @@ namespace i2p buf += 2; m->len += (buf - payload); // payload size i2p::data::GzipDeflator deflator; + deflator.SetCompressionLevel (Z_BEST_COMPRESSION); size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); if (size) { From b7ba8f8e93a58dadf9eadfba3824149e5435bc82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 3 May 2020 13:23:08 -0400 Subject: [PATCH 088/189] precalculate initial h and ck --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 788d4d6d..7fdf351e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -97,11 +97,18 @@ namespace garlic void ECIESX25519AEADRatchetSession::ResetKeys () { - // TODO : use precalculated hashes - static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes - SHA256 ((const uint8_t *)protocolName, 40, m_H); - memcpy (m_CK, m_H, 32); - SHA256 (m_H, 32, m_H); + static const uint8_t protocolNameHash[32] = + { + 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, + 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c + }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes + static const uint8_t hh[32] = + { + 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, + 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c + }; // SHA256 (protocolNameHash) + memcpy (m_CK, protocolNameHash, 32); + memcpy (m_H, hh, 32); } void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) From 4d48d35ad7901346a3a2936d3d6f5294bb69995f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 May 2019 10:28:58 +0300 Subject: [PATCH 089/189] [SSU] handle socket binding errors Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 8 ++++---- libi2pd/NTCPSession.cpp | 7 ++++--- libi2pd/SSU.cpp | 28 +++++++++++++++++++--------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 2091b373..195f664f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1195,11 +1195,11 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to ip4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ",address->port, ex.what()); continue; } - LogPrint (eLogInfo, "NTCP2: Start listening TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared(*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } @@ -1214,11 +1214,11 @@ namespace transport m_NTCP2V6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); m_NTCP2V6Acceptor->listen (); - LogPrint (eLogInfo, "NTCP2: Start listening V6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port); continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index ae94553c..9fe5d415 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -820,9 +820,10 @@ namespace transport try { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); + LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); } catch ( std::exception & ex ) { /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to ip4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP: Failed to bind to v4 port ",address->port, ex.what()); continue; } @@ -841,11 +842,11 @@ namespace transport m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); m_NTCPV6Acceptor->listen (); - LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port); continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 4eb958de..f101443f 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,19 +45,29 @@ namespace transport void SSUServer::OpenSocket () { - m_Socket.open (boost::asio::ip::udp::v4()); - m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); - m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); - m_Socket.bind (m_Endpoint); + try { + m_Socket.open (boost::asio::ip::udp::v4()); + m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); + m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); + m_Socket.bind (m_Endpoint); + LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); + } catch ( std::exception & ex ) { + LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); + } } void SSUServer::OpenSocketV6 () { - m_SocketV6.open (boost::asio::ip::udp::v6()); - m_SocketV6.set_option (boost::asio::ip::v6_only (true)); - m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); - m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); - m_SocketV6.bind (m_EndpointV6); + try { + m_SocketV6.open (boost::asio::ip::udp::v6()); + m_SocketV6.set_option (boost::asio::ip::v6_only (true)); + m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); + m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); + m_SocketV6.bind (m_EndpointV6); + LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); + } catch ( std::exception & ex ) { + LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); + } } void SSUServer::Start () From d991cc3b96b2560bacaa27f6c55b8db17057a85c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 May 2019 11:04:44 +0300 Subject: [PATCH 090/189] [services] handle binding errors in tunnels, webconsole Signed-off-by: R4SAS --- daemon/Daemon.cpp | 2 +- daemon/HTTPServer.cpp | 13 +++++++++---- libi2pd_client/I2PService.cpp | 10 +++++++--- libi2pd_client/I2PTunnel.cpp | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 2c6b34d7..b0596634 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -317,7 +317,7 @@ namespace i2p bool http; i2p::config::GetOption("http.enabled", http); if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8b0323ce..3104dba8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1226,10 +1226,15 @@ namespace http { i2p::config::SetOption("http.pass", pass); LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - m_IsRunning = true; - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); - m_Acceptor.listen (); - Accept (); + + try { + m_IsRunning = true; + m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_Acceptor.listen (); + Accept (); + } catch (std::exception& ex) { + LogPrint (eLogError, "HTTPServer: failed to start webconsole: ", ex.what ()); + } } void HTTPServer::Stop () diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 7157020f..c795fc5f 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -283,10 +283,14 @@ namespace client void TCPIPAcceptor::Start () { m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); - //update the local end point in case port has been set zero and got updated now + // update the local end point in case port has been set zero and got updated now m_LocalEndpoint = m_Acceptor->local_endpoint(); - m_Acceptor->listen (); - Accept (); + try { + m_Acceptor->listen (); + Accept (); + } catch (std::exception& ex) { + LogPrint (eLogError, "I2PService: failed to start ", GetName(), " acceptor: ", ex.what ()); + } } void TCPIPAcceptor::Stop () diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 290ce11e..b7487441 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -389,7 +389,7 @@ namespace client } - /* This handler tries to stablish a connection with the desired server and dies if it fails to do so */ + /* This handler tries to establish a connection with the desired server and dies if it fails to do so */ class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this { public: From 42d4781a9685266f489c6e509d614caf5352db77 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 5 May 2020 02:36:34 +0300 Subject: [PATCH 091/189] [windows] add binding exceptions messagebox notifications, update exceptions handling code Signed-off-by: R4SAS --- Win32/Win32App.cpp | 3 +- daemon/Daemon.cpp | 41 +++++++----- daemon/HTTPServer.cpp | 12 ++-- libi2pd/Log.h | 43 ++++++++++++ libi2pd/NTCP2.cpp | 10 ++- libi2pd/NTCPSession.cpp | 10 ++- libi2pd/SSU.cpp | 14 ++-- libi2pd_client/ClientContext.cpp | 108 ++++++++++++++++--------------- libi2pd_client/I2PService.cpp | 16 ++--- 9 files changed, 160 insertions(+), 97 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index dd614df2..7ae4e419 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -432,7 +432,7 @@ namespace win32 HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); if (hWnd) PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); - UnSubscribeFromEvents(); + // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); } @@ -451,6 +451,5 @@ namespace win32 PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); return hWnd; } - } } diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index b0596634..75829ef6 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -71,18 +71,13 @@ namespace i2p i2p::fs::Init(); datadir = i2p::fs::GetDataDir(); - // TODO: drop old name detection in v2.8.0 + if (config == "") { - config = i2p::fs::DataDirPath("i2p.conf"); - if (i2p::fs::Exists (config)) { - LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config); - } else { - config = i2p::fs::DataDirPath("i2pd.conf"); - if (!i2p::fs::Exists (config)) { - // use i2pd.conf only if exists - config = ""; /* reset */ - } + config = i2p::fs::DataDirPath("i2pd.conf"); + if (!i2p::fs::Exists (config)) { + // use i2pd.conf only if exists + config = ""; /* reset */ } } @@ -265,7 +260,7 @@ namespace i2p restricted = idents.size() > 0; } if(!restricted) - LogPrint(eLogError, "Daemon: no trusted routers of families specififed"); + LogPrint(eLogError, "Daemon: no trusted routers of families specified"); } bool hidden; i2p::config::GetOption("trust.hidden", hidden); @@ -318,9 +313,16 @@ namespace i2p if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); - d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); - d.httpServer->Start(); + LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); + try { + d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); + d.httpServer->Start(); + } catch (std::exception& ex) { + LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); +#endif + } } @@ -336,8 +338,15 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); - d.m_I2PControlService->Start (); + try { + d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); + d.m_I2PControlService->Start (); + } catch (std::exception& ex) { + LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); +#endif + } } return true; } diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 3104dba8..a1cba3ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1227,14 +1227,10 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - try { - m_IsRunning = true; - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); - m_Acceptor.listen (); - Accept (); - } catch (std::exception& ex) { - LogPrint (eLogError, "HTTPServer: failed to start webconsole: ", ex.what ()); - } + m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_Acceptor.listen (); + Accept (); + m_IsRunning = true; } void HTTPServer::Stop () diff --git a/libi2pd/Log.h b/libi2pd/Log.h index ba10b5e9..8343e3b3 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -23,6 +23,11 @@ #include #endif +#ifdef WIN32_APP +#include +#include "Win32/Win32App.h" +#endif + enum LogLevel { eLogNone = 0, @@ -197,4 +202,42 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (!hWnd) hWnd = NULL; + + UINT uType; + switch (level) { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + case eLogNone : + case eLogInfo : + case eLogDebug : + default : + uType = MB_ICONINFORMATION; + break; + } + MessageBox( hWnd, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + #endif // LOG_H__ diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 195f664f..dba73e50 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1195,7 +1195,10 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); +#endif continue; } @@ -1218,7 +1221,10 @@ namespace transport auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); +#endif continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 9fe5d415..fe420ac6 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -823,7 +823,10 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); } catch ( std::exception & ex ) { /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to v4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); +#endif continue; } @@ -846,7 +849,10 @@ namespace transport auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port); + LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); +#endif continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f101443f..ae2caf62 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -53,6 +53,9 @@ namespace transport LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); } catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); +#endif } } @@ -67,6 +70,9 @@ namespace transport LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); } catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); +#endif } } @@ -197,7 +203,7 @@ namespace transport m_SocketV6.close (); OpenSocketV6 (); ReceiveV6 (); - } + } } } } @@ -580,7 +586,7 @@ namespace transport { return session->GetState () == eSessionStateEstablished && session != excluded; } - ); + ); } template @@ -604,7 +610,7 @@ namespace transport { return session->GetState () == eSessionStateEstablished && session != excluded; } - ); + ); } std::set SSUServer::FindIntroducers (int maxNumIntroducers) @@ -620,7 +626,7 @@ namespace transport session->GetState () == eSessionStateEstablished && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; } - ); + ); if (session) { ret.insert (session.get ()); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index fa0532c3..1e8b23cb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -58,14 +58,14 @@ namespace client uint16_t samPort; i2p::config::GetOption("sam.port", samPort); bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try - { + try { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); - m_SamBridge->Start (); - } - catch (std::exception& e) - { - LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); + m_SamBridge->Start (); + } catch (std::exception& e) { + LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); +#endif } } @@ -76,10 +76,13 @@ namespace client uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); try { - m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); - m_BOBCommandChannel->Start (); + m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); + m_BOBCommandChannel->Start (); } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); + LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); +#endif } } @@ -90,14 +93,14 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try - { + try { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); +#endif } } @@ -501,16 +504,12 @@ namespace client LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); } - void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels) { boost::property_tree::ptree pt; - try - { + try { boost::property_tree::read_ini (tunConf, pt); - } - catch (std::exception& ex) - { + } catch (std::exception& ex) { LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ()); return; } @@ -565,14 +564,11 @@ namespace client // TODO: hostnames boost::asio::ip::udp::endpoint end(boost::asio::ip::address::from_string(address), port); if (!localDestination) - { localDestination = m_SharedLocalDestination; - } + auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort); if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second) - { clientTunnel->Start(); - } else LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); @@ -598,7 +594,10 @@ namespace client } else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { - LogPrint(eLogError, "Clients: I2P Client tunnel websocks is deprecated"); + LogPrint(eLogWarning, "Clients: I2P Client tunnel websocks is deprecated, not starting ", name, " tunnel"); +#ifdef WIN32_APP + ShowMessageBox (eLogWarning, "Skipped websocks tunnel ", name, " because it's support is discontinued."); +#endif continue; } else @@ -608,6 +607,7 @@ namespace client clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); } + uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); if(timeout) { @@ -657,8 +657,8 @@ namespace client // I2CP std::map options; - ReadI2CPOptions (section, options); - + ReadI2CPOptions (section, options); + std::shared_ptr localDestination = nullptr; i2p::data::PrivateKeys k; if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) @@ -745,12 +745,14 @@ namespace client } else - LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf); - + LogPrint (eLogWarning, "Clients: Unknown section type = ", type, " of ", name, " in ", tunConf); } catch (std::exception& ex) { LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start tunnel ", name, ": ", ex.what ()); +#endif } } } @@ -761,12 +763,12 @@ namespace client bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy); if (httproxy) { - std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); - std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); - uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); - std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); - bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); + std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); + std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); + uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); + std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); + bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -781,14 +783,14 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try - { + try { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); +#endif } } } @@ -799,13 +801,13 @@ namespace client bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); if (socksproxy) { - std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); - std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); - uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); - bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy); - std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr); - uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); + std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); + std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); + uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); + bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy); + std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr); + uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort); if (socksProxyKeys.length () > 0) { @@ -820,15 +822,15 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try - { + try { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); +#endif } } } diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index c795fc5f..31f34710 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -84,7 +84,7 @@ namespace client auto itr = m_ReadyCallbacks.begin(); while(itr != m_ReadyCallbacks.end()) { - if(itr->second != NEVER_TIMES_OUT && now >= itr->second) + if(itr->second != NEVER_TIMES_OUT && now >= itr->second) { itr->first(boost::asio::error::timed_out); itr = m_ReadyCallbacks.erase(itr); @@ -94,9 +94,9 @@ namespace client } } if(!ec && m_ReadyCallbacks.size()) - TriggerReadyCheckTimer(); + TriggerReadyCheckTimer(); else - m_ReadyTimerTriggered = false; + m_ReadyTimerTriggered = false; } void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) { @@ -118,7 +118,7 @@ namespace client AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) { if(ec) { - LogPrint(eLogWarning, "I2PService::CeateStream() ", ec.message()); + LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message()); streamRequestComplete(nullptr); } else @@ -285,12 +285,8 @@ namespace client m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); // update the local end point in case port has been set zero and got updated now m_LocalEndpoint = m_Acceptor->local_endpoint(); - try { - m_Acceptor->listen (); - Accept (); - } catch (std::exception& ex) { - LogPrint (eLogError, "I2PService: failed to start ", GetName(), " acceptor: ", ex.what ()); - } + m_Acceptor->listen (); + Accept (); } void TCPIPAcceptor::Stop () From b19755644764d6016893363e3bce11cd1e5eef98 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 08:11:01 -0400 Subject: [PATCH 092/189] remove dependency from Win32App --- libi2pd/Log.h | 479 +++++++++++++++++++++++++------------------------- 1 file changed, 236 insertions(+), 243 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 8343e3b3..2737d5ed 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,243 +1,236 @@ -/* -* Copyright (c) 2013-2016, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - -#ifndef LOG_H__ -#define LOG_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Queue.h" - -#ifndef _WIN32 -#include -#endif - -#ifdef WIN32_APP -#include -#include "Win32/Win32App.h" -#endif - -enum LogLevel -{ - eLogNone = 0, - eLogError, - eLogWarning, - eLogInfo, - eLogDebug, - eNumLogLevels -}; - -enum LogType { - eLogStdout = 0, - eLogStream, - eLogFile, -#ifndef _WIN32 - eLogSyslog, -#endif -}; - -namespace i2p { -namespace log { - - struct LogMsg; /* forward declaration */ - - class Log - { - private: - - enum LogType m_Destination; - enum LogLevel m_MinLevel; - std::shared_ptr m_LogStream; - std::string m_Logfile; - std::time_t m_LastTimestamp; - char m_LastDateTime[64]; - i2p::util::Queue > m_Queue; - bool m_HasColors; - std::string m_TimeFormat; - volatile bool m_IsRunning; - std::thread * m_Thread; - - private: - - /** prevent making copies */ - Log (const Log &); - const Log& operator=(const Log&); - - void Run (); - void Process (std::shared_ptr msg); - - /** - * @brief Makes formatted string from unix timestamp - * @param ts Second since epoch - * - * This function internally caches the result for last provided value - */ - const char * TimeAsString(std::time_t ts); - - public: - - Log (); - ~Log (); - - LogType GetLogType () { return m_Destination; }; - LogLevel GetLogLevel () { return m_MinLevel; }; - - void Start (); - void Stop (); - - /** - * @brief Sets minimal allowed level for log messages - * @param level String with wanted minimal msg level - */ - void SetLogLevel (const std::string& level); - - /** - * @brief Sets log destination to logfile - * @param path Path to logfile - */ - void SendTo (const std::string &path); - - /** - * @brief Sets log destination to given output stream - * @param os Output stream - */ - void SendTo (std::shared_ptr os); - - /** - * @brief Sets format for timestamps in log - * @param format String with timestamp format - */ - void SetTimeFormat (std::string format) { m_TimeFormat = format; }; - - #ifndef _WIN32 - /** - * @brief Sets log destination to syslog - * @param name Wanted program name - * @param facility Wanted log category - */ - void SendTo (const char *name, int facility); - #endif - - /** - * @brief Format log message and write to output stream/syslog - * @param msg Pointer to processed message - */ - void Append(std::shared_ptr &); - - /** @brief Reopen log file */ - void Reopen(); - }; - - /** - * @struct LogMsg - * @brief Log message container - * - * We creating it somewhere with LogPrint(), - * then put in MsgQueue for later processing. - */ - struct LogMsg { - std::time_t timestamp; - std::string text; /**< message text as single string */ - LogLevel level; /**< message level */ - std::thread::id tid; /**< id of thread that generated message */ - - LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; - }; - - Log & Logger(); -} // log -} - -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg) noexcept -{ - s << std::forward(arg); -} - -#if (__cplusplus < 201703L) // below C++ 17 -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept -{ - LogPrint (s, std::forward(arg)); - LogPrint (s, std::forward(args)...); -} -#endif - -/** - * @brief Create log message and send it to queue - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void LogPrint (LogLevel level, TArgs&&... args) noexcept -{ - i2p::log::Log &log = i2p::log::Logger(); - if (level > log.GetLogLevel ()) - return; - - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - auto msg = std::make_shared(level, std::time(nullptr), ss.str()); - msg->tid = std::this_thread::get_id(); - log.Append(msg); -} - -#ifdef WIN32_APP -/** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept -{ - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (!hWnd) hWnd = NULL; - - UINT uType; - switch (level) { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - case eLogNone : - case eLogInfo : - case eLogDebug : - default : - uType = MB_ICONINFORMATION; - break; - } - MessageBox( hWnd, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); -} -#endif // WIN32_APP - -#endif // LOG_H__ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef LOG_H__ +#define LOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Queue.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef WIN32_APP +#include // TODO: move away to win32app +#endif + +enum LogLevel +{ + eLogNone = 0, + eLogError, + eLogWarning, + eLogInfo, + eLogDebug, + eNumLogLevels +}; + +enum LogType { + eLogStdout = 0, + eLogStream, + eLogFile, +#ifndef _WIN32 + eLogSyslog, +#endif +}; + +namespace i2p { +namespace log { + + struct LogMsg; /* forward declaration */ + + class Log + { + private: + + enum LogType m_Destination; + enum LogLevel m_MinLevel; + std::shared_ptr m_LogStream; + std::string m_Logfile; + std::time_t m_LastTimestamp; + char m_LastDateTime[64]; + i2p::util::Queue > m_Queue; + bool m_HasColors; + std::string m_TimeFormat; + volatile bool m_IsRunning; + std::thread * m_Thread; + + private: + + /** prevent making copies */ + Log (const Log &); + const Log& operator=(const Log&); + + void Run (); + void Process (std::shared_ptr msg); + + /** + * @brief Makes formatted string from unix timestamp + * @param ts Second since epoch + * + * This function internally caches the result for last provided value + */ + const char * TimeAsString(std::time_t ts); + + public: + + Log (); + ~Log (); + + LogType GetLogType () { return m_Destination; }; + LogLevel GetLogLevel () { return m_MinLevel; }; + + void Start (); + void Stop (); + + /** + * @brief Sets minimal allowed level for log messages + * @param level String with wanted minimal msg level + */ + void SetLogLevel (const std::string& level); + + /** + * @brief Sets log destination to logfile + * @param path Path to logfile + */ + void SendTo (const std::string &path); + + /** + * @brief Sets log destination to given output stream + * @param os Output stream + */ + void SendTo (std::shared_ptr os); + + /** + * @brief Sets format for timestamps in log + * @param format String with timestamp format + */ + void SetTimeFormat (std::string format) { m_TimeFormat = format; }; + + #ifndef _WIN32 + /** + * @brief Sets log destination to syslog + * @param name Wanted program name + * @param facility Wanted log category + */ + void SendTo (const char *name, int facility); + #endif + + /** + * @brief Format log message and write to output stream/syslog + * @param msg Pointer to processed message + */ + void Append(std::shared_ptr &); + + /** @brief Reopen log file */ + void Reopen(); + }; + + /** + * @struct LogMsg + * @brief Log message container + * + * We creating it somewhere with LogPrint(), + * then put in MsgQueue for later processing. + */ + struct LogMsg { + std::time_t timestamp; + std::string text; /**< message text as single string */ + LogLevel level; /**< message level */ + std::thread::id tid; /**< id of thread that generated message */ + + LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; + }; + + Log & Logger(); +} // log +} + +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg) noexcept +{ + s << std::forward(arg); +} + +#if (__cplusplus < 201703L) // below C++ 17 +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept +{ + LogPrint (s, std::forward(arg)); + LogPrint (s, std::forward(args)...); +} +#endif + +/** + * @brief Create log message and send it to queue + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void LogPrint (LogLevel level, TArgs&&... args) noexcept +{ + i2p::log::Log &log = i2p::log::Logger(); + if (level > log.GetLogLevel ()) + return; + + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + auto msg = std::make_shared(level, std::time(nullptr), ss.str()); + msg->tid = std::this_thread::get_id(); + log.Append(msg); +} + +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + UINT uType; + switch (level) + { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + default : + uType = MB_ICONINFORMATION; + } + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + +#endif // LOG_H__ From 53b43353eb121e5d4a091d7501ef905d7205269a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 08:27:56 -0400 Subject: [PATCH 093/189] fixed formatting --- libi2pd/Log.h | 472 +++++++++++++++++++++++++------------------------- 1 file changed, 236 insertions(+), 236 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 2737d5ed..eb3ce327 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,236 +1,236 @@ -/* -* Copyright (c) 2013-2016, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - -#ifndef LOG_H__ -#define LOG_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Queue.h" - -#ifndef _WIN32 -#include -#endif - -#ifdef WIN32_APP -#include // TODO: move away to win32app -#endif - -enum LogLevel -{ - eLogNone = 0, - eLogError, - eLogWarning, - eLogInfo, - eLogDebug, - eNumLogLevels -}; - -enum LogType { - eLogStdout = 0, - eLogStream, - eLogFile, -#ifndef _WIN32 - eLogSyslog, -#endif -}; - -namespace i2p { -namespace log { - - struct LogMsg; /* forward declaration */ - - class Log - { - private: - - enum LogType m_Destination; - enum LogLevel m_MinLevel; - std::shared_ptr m_LogStream; - std::string m_Logfile; - std::time_t m_LastTimestamp; - char m_LastDateTime[64]; - i2p::util::Queue > m_Queue; - bool m_HasColors; - std::string m_TimeFormat; - volatile bool m_IsRunning; - std::thread * m_Thread; - - private: - - /** prevent making copies */ - Log (const Log &); - const Log& operator=(const Log&); - - void Run (); - void Process (std::shared_ptr msg); - - /** - * @brief Makes formatted string from unix timestamp - * @param ts Second since epoch - * - * This function internally caches the result for last provided value - */ - const char * TimeAsString(std::time_t ts); - - public: - - Log (); - ~Log (); - - LogType GetLogType () { return m_Destination; }; - LogLevel GetLogLevel () { return m_MinLevel; }; - - void Start (); - void Stop (); - - /** - * @brief Sets minimal allowed level for log messages - * @param level String with wanted minimal msg level - */ - void SetLogLevel (const std::string& level); - - /** - * @brief Sets log destination to logfile - * @param path Path to logfile - */ - void SendTo (const std::string &path); - - /** - * @brief Sets log destination to given output stream - * @param os Output stream - */ - void SendTo (std::shared_ptr os); - - /** - * @brief Sets format for timestamps in log - * @param format String with timestamp format - */ - void SetTimeFormat (std::string format) { m_TimeFormat = format; }; - - #ifndef _WIN32 - /** - * @brief Sets log destination to syslog - * @param name Wanted program name - * @param facility Wanted log category - */ - void SendTo (const char *name, int facility); - #endif - - /** - * @brief Format log message and write to output stream/syslog - * @param msg Pointer to processed message - */ - void Append(std::shared_ptr &); - - /** @brief Reopen log file */ - void Reopen(); - }; - - /** - * @struct LogMsg - * @brief Log message container - * - * We creating it somewhere with LogPrint(), - * then put in MsgQueue for later processing. - */ - struct LogMsg { - std::time_t timestamp; - std::string text; /**< message text as single string */ - LogLevel level; /**< message level */ - std::thread::id tid; /**< id of thread that generated message */ - - LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; - }; - - Log & Logger(); -} // log -} - -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg) noexcept -{ - s << std::forward(arg); -} - -#if (__cplusplus < 201703L) // below C++ 17 -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept -{ - LogPrint (s, std::forward(arg)); - LogPrint (s, std::forward(args)...); -} -#endif - -/** - * @brief Create log message and send it to queue - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void LogPrint (LogLevel level, TArgs&&... args) noexcept -{ - i2p::log::Log &log = i2p::log::Logger(); - if (level > log.GetLogLevel ()) - return; - - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - auto msg = std::make_shared(level, std::time(nullptr), ss.str()); - msg->tid = std::this_thread::get_id(); - log.Append(msg); -} - -#ifdef WIN32_APP -/** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept -{ - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - UINT uType; - switch (level) - { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - default : - uType = MB_ICONINFORMATION; - } - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); -} -#endif // WIN32_APP - -#endif // LOG_H__ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef LOG_H__ +#define LOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Queue.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef WIN32_APP +#include // TODO: move away to win32app +#endif + +enum LogLevel +{ + eLogNone = 0, + eLogError, + eLogWarning, + eLogInfo, + eLogDebug, + eNumLogLevels +}; + +enum LogType { + eLogStdout = 0, + eLogStream, + eLogFile, +#ifndef _WIN32 + eLogSyslog, +#endif +}; + +namespace i2p { +namespace log { + + struct LogMsg; /* forward declaration */ + + class Log + { + private: + + enum LogType m_Destination; + enum LogLevel m_MinLevel; + std::shared_ptr m_LogStream; + std::string m_Logfile; + std::time_t m_LastTimestamp; + char m_LastDateTime[64]; + i2p::util::Queue > m_Queue; + bool m_HasColors; + std::string m_TimeFormat; + volatile bool m_IsRunning; + std::thread * m_Thread; + + private: + + /** prevent making copies */ + Log (const Log &); + const Log& operator=(const Log&); + + void Run (); + void Process (std::shared_ptr msg); + + /** + * @brief Makes formatted string from unix timestamp + * @param ts Second since epoch + * + * This function internally caches the result for last provided value + */ + const char * TimeAsString(std::time_t ts); + + public: + + Log (); + ~Log (); + + LogType GetLogType () { return m_Destination; }; + LogLevel GetLogLevel () { return m_MinLevel; }; + + void Start (); + void Stop (); + + /** + * @brief Sets minimal allowed level for log messages + * @param level String with wanted minimal msg level + */ + void SetLogLevel (const std::string& level); + + /** + * @brief Sets log destination to logfile + * @param path Path to logfile + */ + void SendTo (const std::string &path); + + /** + * @brief Sets log destination to given output stream + * @param os Output stream + */ + void SendTo (std::shared_ptr os); + + /** + * @brief Sets format for timestamps in log + * @param format String with timestamp format + */ + void SetTimeFormat (std::string format) { m_TimeFormat = format; }; + + #ifndef _WIN32 + /** + * @brief Sets log destination to syslog + * @param name Wanted program name + * @param facility Wanted log category + */ + void SendTo (const char *name, int facility); + #endif + + /** + * @brief Format log message and write to output stream/syslog + * @param msg Pointer to processed message + */ + void Append(std::shared_ptr &); + + /** @brief Reopen log file */ + void Reopen(); + }; + + /** + * @struct LogMsg + * @brief Log message container + * + * We creating it somewhere with LogPrint(), + * then put in MsgQueue for later processing. + */ + struct LogMsg { + std::time_t timestamp; + std::string text; /**< message text as single string */ + LogLevel level; /**< message level */ + std::thread::id tid; /**< id of thread that generated message */ + + LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; + }; + + Log & Logger(); +} // log +} + +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg) noexcept +{ + s << std::forward(arg); +} + +#if (__cplusplus < 201703L) // below C++ 17 +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept +{ + LogPrint (s, std::forward(arg)); + LogPrint (s, std::forward(args)...); +} +#endif + +/** + * @brief Create log message and send it to queue + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void LogPrint (LogLevel level, TArgs&&... args) noexcept +{ + i2p::log::Log &log = i2p::log::Logger(); + if (level > log.GetLogLevel ()) + return; + + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + auto msg = std::make_shared(level, std::time(nullptr), ss.str()); + msg->tid = std::this_thread::get_id(); + log.Append(msg); +} + +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + UINT uType; + switch (level) + { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + default : + uType = MB_ICONINFORMATION; + } + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + +#endif // LOG_H__ From bb7f03857c3b3c9d95f2a3a374d3d6e90167d138 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 09:35:41 -0400 Subject: [PATCH 094/189] ThrowFatal function --- libi2pd/Log.h | 25 +++++-------- libi2pd/NTCP2.cpp | 12 +++---- libi2pd/NTCPSession.cpp | 16 ++++----- libi2pd/SSU.cpp | 22 ++++++------ libi2pd_client/ClientContext.cpp | 62 ++++++++++++++++---------------- 5 files changed, 64 insertions(+), 73 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index eb3ce327..88d5c4db 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -201,36 +201,27 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } -#ifdef WIN32_APP + /** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) + * @brief Throw fatal error message with the list of arguments * @param args Array of message parts */ template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +void ThrowFatal (TArgs&&... args) noexcept { // fold message to single string std::stringstream ss(""); - #if (__cplusplus >= 201703L) // C++ 17 or higher (LogPrint (ss, std::forward(args)), ...); #else LogPrint (ss, std::forward(args)...); #endif - UINT uType; - switch (level) - { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - default : - uType = MB_ICONINFORMATION; - } - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +#ifdef WIN32_APP + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); +#else + std::cout << ss.str (); +#endif } -#endif // WIN32_APP #endif // LOG_H__ diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index dba73e50..e52f0111 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1196,9 +1196,7 @@ namespace transport catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } @@ -1220,11 +1218,11 @@ namespace transport LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index fe420ac6..4ab3c5d0 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -821,12 +821,12 @@ namespace transport { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { /** fail to bind ip4 */ LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); continue; } @@ -848,11 +848,11 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index ae2caf62..74cbe39b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,34 +45,36 @@ namespace transport void SSUServer::OpenSocket () { - try { + try + { m_Socket.open (boost::asio::ip::udp::v4()); m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_Socket.bind (m_Endpoint); LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); } } void SSUServer::OpenSocketV6 () { - try { + try + { m_SocketV6.open (boost::asio::ip::udp::v6()); m_SocketV6.set_option (boost::asio::ip::v6_only (true)); m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); } } diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 1e8b23cb..c8a9ddfe 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -58,14 +58,15 @@ namespace client uint16_t samPort; i2p::config::GetOption("sam.port", samPort); bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try { + try + { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); m_SamBridge->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); } } @@ -75,14 +76,15 @@ namespace client std::string bobAddr; i2p::config::GetOption("bob.address", bobAddr); uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); - try { + try + { m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); m_BOBCommandChannel->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); } } @@ -93,14 +95,15 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try { + try + { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); } } @@ -595,9 +598,6 @@ namespace client else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { LogPrint(eLogWarning, "Clients: I2P Client tunnel websocks is deprecated, not starting ", name, " tunnel"); -#ifdef WIN32_APP - ShowMessageBox (eLogWarning, "Skipped websocks tunnel ", name, " because it's support is discontinued."); -#endif continue; } else @@ -750,9 +750,7 @@ namespace client catch (std::exception& ex) { LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start tunnel ", name, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start tunnel ", name, ": ", ex.what ()); } } } @@ -783,14 +781,15 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try { + try + { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); } } } @@ -822,15 +821,16 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try { + try + { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); } } } From dbe1e3f577c05d3fe0c6a50ceacc26d2b8e9daff Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 10:16:16 -0400 Subject: [PATCH 095/189] ThrowFatal function --- daemon/Daemon.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 75829ef6..fc71123f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -314,14 +314,15 @@ namespace i2p std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try { + try + { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } catch (std::exception& ex) { + } + catch (std::exception& ex) + { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } @@ -338,14 +339,15 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try { + try + { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } catch (std::exception& ex) { + } + catch (std::exception& ex) + { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); } } return true; From d7d70b707ffe0435c80b1d908a51b4047d94e741 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 11:13:59 -0400 Subject: [PATCH 096/189] configurable throw function --- Win32/DaemonWin32.cpp | 6 ++++++ libi2pd/Log.cpp | 6 ++++++ libi2pd/Log.h | 19 ++++++++----------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 9fffe7fb..5524aff3 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -8,6 +8,7 @@ #ifdef _WIN32 #include "Win32/Win32Service.h" #ifdef WIN32_APP +#include #include "Win32/Win32App.h" #endif @@ -23,6 +24,11 @@ namespace util setlocale(LC_ALL, "Russian"); setlocale(LC_TIME, "C"); + i2p::log::SetThrowFunction ([](const std::string& s) + { + MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); + }); + if (!Daemon_Singleton::init(argc, argv)) return false; diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 7d77aaf8..65602674 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -236,5 +236,11 @@ namespace log { Log & Logger() { return logger; } + + static ThrowFunction g_ThrowFunction; + ThrowFunction GetThrowFunction () { return g_ThrowFunction; } + void SetThrowFunction (ThrowFunction f) { g_ThrowFunction = f; } + } // log } // i2p + diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 88d5c4db..556654e2 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -17,16 +17,13 @@ #include #include #include +#include #include "Queue.h" #ifndef _WIN32 #include #endif -#ifdef WIN32_APP -#include // TODO: move away to win32app -#endif - enum LogLevel { eLogNone = 0, @@ -155,6 +152,10 @@ namespace log { }; Log & Logger(); + + typedef std::function ThrowFunction; + ThrowFunction GetThrowFunction (); + void SetThrowFunction (ThrowFunction f); } // log } @@ -201,7 +202,6 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } - /** * @brief Throw fatal error message with the list of arguments * @param args Array of message parts @@ -209,6 +209,8 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept template void ThrowFatal (TArgs&&... args) noexcept { + auto f = i2p::log::GetThrowFunction (); + if (!f) return; // fold message to single string std::stringstream ss(""); #if (__cplusplus >= 201703L) // C++ 17 or higher @@ -216,12 +218,7 @@ void ThrowFatal (TArgs&&... args) noexcept #else LogPrint (ss, std::forward(args)...); #endif - -#ifdef WIN32_APP - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); -#else - std::cout << ss.str (); -#endif + f (ss.str ()); } #endif // LOG_H__ From c4d9c039300d94bb91279396dd4ccca363a481a6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 13:01:23 -0400 Subject: [PATCH 097/189] handle termination block --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 29 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- libi2pd/Garlic.cpp | 9 +++++++ libi2pd/Garlic.h | 1 + 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7fdf351e..4c7d15ef 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -223,16 +223,8 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); - break; - case eECIESx25519BlkDateTime: - LogPrint (eLogDebug, "Garlic: datetime"); - break; - case eECIESx25519BlkOptions: - LogPrint (eLogDebug, "Garlic: options"); - break; - case eECIESx25519BlkPadding: - LogPrint (eLogDebug, "Garlic: padding"); + if (GetOwner ()) + GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkNextKey: LogPrint (eLogDebug, "Garlic: next key"); @@ -256,6 +248,21 @@ namespace garlic m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); break; } + case eECIESx25519BlkTermination: + LogPrint (eLogDebug, "Garlic: termination"); + if (GetOwner ()) + GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey); + if (receiveTagset) receiveTagset->Expire (); + break; + case eECIESx25519BlkDateTime: + LogPrint (eLogDebug, "Garlic: datetime"); + break; + case eECIESx25519BlkOptions: + LogPrint (eLogDebug, "Garlic: options"); + break; + case eECIESx25519BlkPadding: + LogPrint (eLogDebug, "Garlic: padding"); + break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } @@ -852,7 +859,7 @@ namespace garlic CleanupUnconfirmedLeaseSet (ts); return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } - + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 79e920b5..29d75a6b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -21,7 +21,7 @@ namespace garlic const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; @@ -110,7 +110,7 @@ namespace garlic bool HandleNextMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fb3451d0..8ba4a8a1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1013,5 +1013,14 @@ namespace garlic m_ECIESx25519Sessions.emplace (staticKeyTag, session); } + void GarlicDestination::RemoveECIESx25519Session (const uint8_t * staticKey) + { + auto it = m_ECIESx25519Sessions.find (staticKey); + if (it != m_ECIESx25519Sessions.end ()) + { + it->second->SetOwner (nullptr); + m_ECIESx25519Sessions.erase (it); + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6c81dabf..86c9e432 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -233,6 +233,7 @@ namespace garlic void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); + void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); virtual void ProcessGarlicMessage (std::shared_ptr msg); From d50319064794c011b3045bf586d513a08aeb09e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 10:08:01 -0400 Subject: [PATCH 098/189] fixed crash of encrypted leaseset without authentication --- libi2pd/Destination.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 1473d41f..650ab04b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -415,7 +415,10 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetPreferredCryptoType ()); + const uint8_t * secret = nullptr; + if (m_LeaseSetPrivKey) secret = *m_LeaseSetPrivKey; // m_LeaseSetPrivKey ? *m_LeaseSetPrivKey: nullptr invokes copy contructor + auto ls2 = std::make_shared (buf + offset, len - offset, + it2->second->requestedBlindedKey, secret, GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key From 9b6facf3b01a1377577a959a5b3eab0895834911 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 14:08:54 -0400 Subject: [PATCH 099/189] fixed crash of encrypted leaseset without authentication --- libi2pd/Destination.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 650ab04b..736390a2 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -415,10 +415,8 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - const uint8_t * secret = nullptr; - if (m_LeaseSetPrivKey) secret = *m_LeaseSetPrivKey; // m_LeaseSetPrivKey ? *m_LeaseSetPrivKey: nullptr invokes copy contructor auto ls2 = std::make_shared (buf + offset, len - offset, - it2->second->requestedBlindedKey, secret, GetPreferredCryptoType ()); + it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key From 789ff702ac5eca7901c3a96a3d58e0af002b9f77 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 14:54:41 -0400 Subject: [PATCH 100/189] fixed sudden webconsole hangs --- daemon/HTTPServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a1cba3ce..de052a2b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1227,10 +1227,10 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_IsRunning = true; + m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); - m_IsRunning = true; } void HTTPServer::Stop () From 24c5f07153216f14d7b57cd67b7984eed40e1f76 Mon Sep 17 00:00:00 2001 From: Anatolii Vorona Date: Thu, 7 May 2020 12:11:30 +0200 Subject: [PATCH 101/189] added logrotate config --- contrib/rpm/i2pd-git.spec | 16 +++++++++++----- contrib/rpm/i2pd.logrotate | 9 +++++++++ contrib/rpm/i2pd.spec | 14 ++++++++++---- 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 contrib/rpm/i2pd.logrotate diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index b182dca4..6844a25f 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -24,6 +24,7 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units +Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd @@ -73,10 +74,11 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd @@ -108,16 +110,20 @@ getent passwd i2pd >/dev/null || \ %files %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd -%config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/*.conf %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/%{name}/certificates %{_sharedstatedir}/i2pd/certificates +%{_sysconfdir}/logrotate.d/i2pd %changelog +* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +- added RPM logrotate config + * Fri Apr 10 2020 orignal - 2.31.0 - update to 2.31.0 diff --git a/contrib/rpm/i2pd.logrotate b/contrib/rpm/i2pd.logrotate new file mode 100644 index 00000000..795280d4 --- /dev/null +++ b/contrib/rpm/i2pd.logrotate @@ -0,0 +1,9 @@ +"/var/log/i2pd/*.log" { + copytruncate + daily + rotate 5 + compress + delaycompress + missingok + notifempty +} diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5ece769c..bcbade2f 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.31.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -22,6 +22,7 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units +Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd @@ -71,8 +72,9 @@ pushd build chrpath -d i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates @@ -107,15 +109,19 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md %{_sbindir}/i2pd %{_datadir}/i2pd/certificates -%config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %{_sharedstatedir}/i2pd/certificates +%{_sysconfdir}/logrotate.d/i2pd %changelog +* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +- added RPM logrotate config + * Fri Apr 10 2020 orignal - 2.31.0 - update to 2.31.0 From 9274881c183f689364fc8b9c0c3279aeb5d09398 Mon Sep 17 00:00:00 2001 From: Anatolii Vorona Date: Fri, 8 May 2020 18:45:28 +0200 Subject: [PATCH 102/189] update logrotate config for reusing in debian --- contrib/{rpm => }/i2pd.logrotate | 0 contrib/rpm/i2pd-git.spec | 6 +++--- contrib/rpm/i2pd.service | 1 - contrib/rpm/i2pd.spec | 8 ++++---- 4 files changed, 7 insertions(+), 8 deletions(-) rename contrib/{rpm => }/i2pd.logrotate (100%) delete mode 120000 contrib/rpm/i2pd.service diff --git a/contrib/rpm/i2pd.logrotate b/contrib/i2pd.logrotate similarity index 100% rename from contrib/rpm/i2pd.logrotate rename to contrib/i2pd.logrotate diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6844a25f..6967f949 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -78,8 +78,8 @@ chrpath -d i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd @@ -121,7 +121,7 @@ getent passwd i2pd >/dev/null || \ %changelog -* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +* Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config * Fri Apr 10 2020 orignal - 2.31.0 diff --git a/contrib/rpm/i2pd.service b/contrib/rpm/i2pd.service deleted file mode 120000 index ca477e3b..00000000 --- a/contrib/rpm/i2pd.service +++ /dev/null @@ -1 +0,0 @@ -../i2pd.service \ No newline at end of file diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index bcbade2f..49a5e666 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.31.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -74,12 +74,12 @@ chrpath -d i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates @@ -119,7 +119,7 @@ getent passwd i2pd >/dev/null || \ %changelog -* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +* Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config * Fri Apr 10 2020 orignal - 2.31.0 From a96c205830734dfa80986ad4a50e17f09a5c549b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 8 May 2020 14:20:13 -0400 Subject: [PATCH 103/189] allow encryption type param for encrypted LeaseSet --- libi2pd/Destination.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 736390a2..105cd2e6 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -845,7 +845,8 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; - if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 && params) + if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || + GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) From 86782f347986fba71321e68f41f37b67b91b9677 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 May 2020 18:30:04 -0400 Subject: [PATCH 104/189] eliminate extra buffer allocation for incoming packets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 22 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4c7d15ef..bccf56f6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -178,8 +178,6 @@ namespace garlic MixHash (buf, 48); // h = SHA256(h || ciphertext) buf += 48; len -= 48; // 32 data + 16 poly - // decrypt payload - std::vector payload (len - 16); // KDF2 for payload bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); if (isStatic) @@ -191,6 +189,9 @@ namespace garlic } else // all zeros flags CreateNonce (1, nonce); + + // decrypt payload + std::vector payload (len - 16); // we must save original ciphertext if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); @@ -489,7 +490,7 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len) + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); @@ -541,8 +542,7 @@ namespace garlic } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload - std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; @@ -554,7 +554,7 @@ namespace garlic GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } memcpy (m_H, h, 32); // restore m_H - HandlePayload (payload.data (), len - 16, nullptr, 0); + HandlePayload (buf, len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it SetLeaseSetUpdateStatus (eLeaseSetUpToDate); @@ -584,21 +584,21 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (const uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { uint8_t nonce[12]; CreateNonce (index, nonce); // tag's index len -= 8; // tag - std::vector payload (len - 16); + uint8_t * payload = buf + 8; uint8_t key[32]; receiveTagset->GetSymmKey (index, key); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, key, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len - 16, buf, 8, key, nonce, payload, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - HandlePayload (payload.data (), len - 16, receiveTagset, index); + HandlePayload (payload, len - 16, receiveTagset, index); int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; moreTags -= (receiveTagset->GetNextIndex () - index); @@ -607,7 +607,7 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 29d75a6b..001f5e51 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -108,7 +108,7 @@ namespace garlic ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); ~ECIESX25519AEADRatchetSession (); - bool HandleNextMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); + bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } @@ -133,8 +133,8 @@ namespace garlic std::shared_ptr CreateNewSessionTagset (); bool HandleNewIncomingSession (const uint8_t * buf, size_t len); - bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); - bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); + bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); + bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); From 23be4c01dfcc32d5d747e5ccce9a00526170ae3b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 13 May 2020 18:09:26 -0400 Subject: [PATCH 105/189] CreateLeaseSetClove --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 51 ++++++++++------------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 +- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bccf56f6..4f4f56ce 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -684,10 +684,10 @@ namespace garlic if (first) payloadLen += 7;// datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()) : nullptr; + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) { - payloadLen += leaseSet->GetPayloadLength () + 13; + payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; if (!first) { // ack request @@ -725,7 +725,7 @@ namespace garlic // LeaseSet if (leaseSet) { - offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); if (!first) { // ack request @@ -815,38 +815,31 @@ namespace garlic return cloveSize + 3; } - size_t ECIESX25519AEADRatchetSession::CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len) + size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len) { - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 37 /* delivery instruction */; + if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) + { + LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send"); + return 0; + } + uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (buf + 1, cloveSize); // size buf += 3; - if (GetOwner ()) - { - auto inboundTunnel = GetOwner ()->GetTunnelPool ()->GetNextInboundTunnel (); - if (inboundTunnel) - { - // delivery instructions - *buf = eGarlicDeliveryTypeTunnel << 5; buf++; // delivery instructions flag tunnel - // hash and tunnelID sequence is reversed for Garlic - memcpy (buf, inboundTunnel->GetNextIdentHash (), 32); buf += 32;// To Hash - htobe32buf (buf, inboundTunnel->GetNextTunnelID ()); buf += 4;// tunnelID - } - else - { - LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); - return 0; - } - *buf = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 1, msg->GetMsgID ()); // msgID - htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); - } - else - return 0; + *buf = 0; buf++; // flag and delivery instructions + *buf = eI2NPDatabaseStore; buf++; // I2NP msg type + RAND_bytes (buf, 4); buf += 4; // msgID + htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration + // payload + memcpy (buf + DATABASE_STORE_KEY_OFFSET, ls->GetStoreHash (), 32); + buf[DATABASE_STORE_TYPE_OFFSET] = i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2; + memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 + buf += DATABASE_STORE_HEADER_SIZE; + memcpy (buf, ls->GetBuffer (), ls->GetBufferLen ()); + return cloveSize + 3; - } + } void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 001f5e51..ce5e2eb4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -145,8 +145,8 @@ namespace garlic std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); - size_t CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len); - + size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); + void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); void NewNextSendRatchet (); From b5b195e6283b916592df2c192374d70049e84f3d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 14 May 2020 20:59:52 +0300 Subject: [PATCH 106/189] [windows] fix msys build Signed-off-by: R4SAS --- Win32/Win32Service.cpp | 2 +- libi2pd_client/I2PTunnel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index 717bc887..9d1dedb4 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -4,7 +4,7 @@ #include "Win32Service.h" #include -#include +//#include #include #include "Daemon.h" diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index b7487441..78bc8018 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -69,15 +69,15 @@ namespace client return ourIP; } +#ifdef __linux__ static void MapToLoopback(const std::shared_ptr & sock, const i2p::data::IdentHash & addr) { - // bind to 127.x.x.x address // where x.x.x are first three bytes from ident auto ourIP = GetLoopbackAddressFor(addr); sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0)); - } +#endif void I2PTunnelConnection::Connect (bool isUniqueLocal) { From 716378bd6bb2e8417fd208fabcda9c80d7593b64 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 14 May 2020 21:52:33 +0300 Subject: [PATCH 107/189] [makefile] fix build with g++ 10 Signed-off-by: R4SAS --- Makefile.linux | 2 +- Makefile.mingw | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index fa2f2fdf..305978dd 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,7 +20,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else # not supported diff --git a/Makefile.mingw b/Makefile.mingw index 1b1b4b25..251e2e90 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -2,10 +2,19 @@ USE_WIN32_APP=yes CXX = g++ WINDRES = windres CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -NEEDED_CXXFLAGS = -std=c++11 INCFLAGS = -Idaemon -I. LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ +# detect proper flag for c++11 support by compilers +CXXVER := $(shell $(CXX) -dumpversion) +ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6 + NEEDED_CXXFLAGS += -std=c++11 +else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 + NEEDED_CXXFLAGS += -std=c++17 +else # not supported +$(error Compiler too old) +endif + # Boost libraries suffix BOOST_SUFFIX = -mt From 1e4d2fd05380c9702ed6cfb4d83b9fc30c51e14f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 14 May 2020 15:45:25 -0400 Subject: [PATCH 108/189] fixed for g++10 --- Makefile.linux | 2 +- Makefile.mingw | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index 305978dd..1cdf0a48 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,7 +20,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else # not supported diff --git a/Makefile.mingw b/Makefile.mingw index 251e2e90..2782b715 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -9,7 +9,7 @@ LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ CXXVER := $(shell $(CXX) -dumpversion) ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6 NEEDED_CXXFLAGS += -std=c++11 -else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 else # not supported $(error Compiler too old) From 0b1cfb2102dfde98617e643dcc36e1ca35c93b9e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 16 May 2020 19:10:17 -0400 Subject: [PATCH 109/189] send response to recived datagram from ECIESX25519AEADRatchet session --- libi2pd/Datagram.cpp | 9 ++++++--- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 7e04fce8..a69c86b0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -247,6 +247,8 @@ namespace datagram auto path = GetSharedRoutingPath(); if(path) path->updateTime = i2p::util::GetSecondsSinceEpoch (); + if (m_RoutingSession && m_RoutingSession->IsRatchets ()) + SendMsg (nullptr); // send empty message in case if we have some data to send } std::shared_ptr DatagramSession::GetSharedRoutingPath () @@ -352,14 +354,14 @@ namespace datagram void DatagramSession::HandleSend(std::shared_ptr msg) { - m_SendQueue.push_back(msg); + if (msg || m_SendQueue.empty ()) + m_SendQueue.push_back(msg); // flush queue right away if full if(m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); } void DatagramSession::FlushSendQueue () { - std::vector send; auto routingPath = GetSharedRoutingPath(); // if we don't have a routing path we will drop all queued messages @@ -368,7 +370,8 @@ namespace datagram for (const auto & msg : m_SendQueue) { auto m = m_RoutingSession->WrapSingleMessage(msg); - send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m}); + if (m) + send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m}); } routingPath->outboundTunnel->SendTunnelDataMsg(send); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4f4f56ce..513ac626 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -641,6 +641,7 @@ namespace garlic { auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); size_t len = payload.size (); + if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length @@ -708,11 +709,14 @@ namespace garlic { payloadLen += 6; if (m_NextSendRatchet->newKey) payloadLen += 32; + } + uint8_t paddingSize = 0; + if (payloadLen) + { + RAND_bytes (&paddingSize, 1); + paddingSize &= 0x0F; paddingSize++; // 1 - 16 + payloadLen += paddingSize + 3; } - uint8_t paddingSize; - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; std::vector v(payloadLen); size_t offset = 0; // DateTime @@ -785,9 +789,12 @@ namespace garlic } } // padding - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + if (paddingSize) + { + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + } return v; } From 329439d0ae472c9d700a38ff6f6c1494ae429f51 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 May 2020 16:49:31 -0400 Subject: [PATCH 110/189] don't copy datagram payload --- libi2pd/Datagram.cpp | 32 ++++++++++++++++---------------- libi2pd/Datagram.h | 5 ++++- libi2pd/Gzip.cpp | 30 ++++++++++++++++++++++++++++++ libi2pd/Gzip.h | 2 ++ 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index a69c86b0..04e01796 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -24,34 +24,32 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { auto owner = m_Owner; - std::vector v(MAX_DATAGRAM_SIZE); - uint8_t * buf = v.data(); - auto localIdentity = m_Owner->GetIdentity (); - auto identityLen = localIdentity->ToBuffer (buf, MAX_DATAGRAM_SIZE); - uint8_t * signature = buf + identityLen; + auto localIdentity = m_Owner->GetIdentity (); + auto identityLen = localIdentity->GetFullLen (); auto signatureLen = localIdentity->GetSignatureLen (); - uint8_t * buf1 = signature + signatureLen; size_t headerLen = identityLen + signatureLen; - - memcpy (buf1, payload, len); + + std::vector header(headerLen); + localIdentity->ToBuffer (header.data (), identityLen); + uint8_t * signature = header.data () + identityLen; if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { uint8_t hash[32]; - SHA256(buf1, len, hash); + SHA256(payload, len, hash); owner->Sign (hash, 32, signature); } else - owner->Sign (buf1, len, signature); + owner->Sign (payload, len, signature); - auto msg = CreateDataMessage (buf, len + headerLen, fromPort, toPort); auto session = ObtainSession(identity); + auto msg = CreateDataMessage ({{header.data (), headerLen}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto msg = CreateDataMessage (payload, len, fromPort, toPort, true); // raw auto session = ObtainSession(identity); + auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw session->SendMsg(msg); } @@ -122,12 +120,14 @@ namespace datagram } - std::shared_ptr DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw) + std::shared_ptr DatagramDestination::CreateDataMessage ( + const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length @@ -135,7 +135,7 @@ namespace datagram htobe16buf (buf + 6, toPort); // destination port buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol msg->len += size + 4; - msg->FillI2NPMessageHeader (eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } else msg = nullptr; @@ -247,7 +247,7 @@ namespace datagram auto path = GetSharedRoutingPath(); if(path) path->updateTime = i2p::util::GetSecondsSinceEpoch (); - if (m_RoutingSession && m_RoutingSession->IsRatchets ()) + if (IsRatchets ()) SendMsg (nullptr); // send empty message in case if we have some data to send } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 0cfec838..87f3a7a8 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -51,6 +51,8 @@ namespace datagram /** get the last time in milliseconds for when we used this datagram session */ uint64_t LastActivity() const { return m_LastUse; } + bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } + struct Info { std::shared_ptr IBGW; @@ -130,7 +132,8 @@ namespace datagram std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw = false); + std::shared_ptr CreateDataMessage (const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 2ca711b0..cb6a79af 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -116,6 +116,36 @@ namespace data return 0; } + size_t GzipDeflator::Deflate (const std::vector >& bufs, uint8_t * out, size_t outLen) + { + if (m_IsDirty) deflateReset (&m_Deflator); + m_IsDirty = true; + size_t offset = 0; + int err; + for (const auto& it: bufs) + { + m_Deflator.next_in = const_cast(it.first); + m_Deflator.avail_in = it.second; + m_Deflator.next_out = out + offset; + m_Deflator.avail_out = outLen - offset; + auto flush = (it == bufs.back ()) ? Z_FINISH : Z_NO_FLUSH; + err = deflate (&m_Deflator, flush); + if (err) + { + if (flush && err == Z_STREAM_END) + { + out[9] = 0xff; // OS is always unknown + return outLen - m_Deflator.avail_out; + } + break; + } + offset = outLen - m_Deflator.avail_out; + } + // else + LogPrint (eLogError, "Gzip: Deflate error ", err); + return 0; + } + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index cf08d920..e5b8775e 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -2,6 +2,7 @@ #define GZIP_H__ #include +#include namespace i2p { @@ -34,6 +35,7 @@ namespace data void SetCompressionLevel (int level); size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); + size_t Deflate (const std::vector >& bufs, uint8_t * out, size_t outLen); private: From e1b1032df9501b3962067305ed346dc9e33725e7 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 08:29:09 -0400 Subject: [PATCH 111/189] reseeds update --- .../reseed/hankhill19580_at_gmail.com.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 5 +-- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 contrib/certificates/reseed/hankhill19580_at_gmail.com.crt diff --git a/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt b/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt new file mode 100644 index 00000000..2f177ee1 --- /dev/null +++ b/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIRAKye34BRrKyQN6kMVPHddykwDQYJKoZIhvcNAQELBQAw +dzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE +ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxIDAeBgNVBAMM +F2hhbmtoaWxsMTk1ODBAZ21haWwuY29tMB4XDTIwMDUwNzA1MDkxMFoXDTMwMDUw +NzA1MDkxMFowdzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJY +WDEeMBwGA1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAx +IDAeBgNVBAMMF2hhbmtoaWxsMTk1ODBAZ21haWwuY29tMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA5Vt7c0SeUdVkcXXEYe3M9LmCTUyiCv/PHF2Puys6 +8luLH8lO0U/pQ4j703kFKK7s4rV65jVpGNncjHWbfSCNevvs6VcbAFoo7oJX7Yjt +5+Z4oU1g7JG86feTwU6pzfFjAs0RO2lNq2L8AyLYKWOnPsVrmuGYl2c6N5WDzTxA +Et66IudfGsppTv7oZkgX6VNUMioV8tCjBTLaPCkSfyYKBX7r6ByHY86PflhFgYES +zIB92Ma75YFtCB0ktCM+o6d7wmnt10Iy4I6craZ+z7szCDRF73jhf3Vk7vGzb2cN +aCfr2riwlRJBaKrLJP5m0dGf5RdhviMgxc6JAgkN7Ius5lkxO/p3OSy5co0DrMJ7 +lvwdZ2hu0dnO75unTt6ImR4RQ90Sqj7MUdorKR/8FcYEo+twBV8cV3s9kjuO5jxV +g976Q+GD3zDoixiege3W5UT4ff/Anm4mJpE5PKbNuO+KUjk6WA4B1PeudkEcxkO4 +tQYy0aBzfjeyENee9otd4TgN1epY4wlHIORCa3HUFmFZd9VZMQcxwv7c47wl2kc9 +Cv1L6Nae78wRzRu2CHD8zWhq+tv5q7Md2eRd3mFPI09ljsOgG2TQv6300WvHvI5M +enNdjYjLqOTRCzUJ2Jst4BZsvDxjWYkHsSZc1UORzm2LQmh2bJvbhC3m81qANGw6 +ZhcCAwEAAaNkMGIwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMC +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCAGA1UdDgQZBBdoYW5raGlsbDE5 +NTgwQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAVtMF7lrgkDLTNXlavI7h +HJqFxFHjmxPk3iu2Qrgwk302Gowqg5NjVVamT20cXeuJaUa6maTTHzDyyCai3+3e +roaosGxZQRpRf5/RBz2yhdEPLZBV9IqxGgIxvCWNqNIYB1SNk00rwC4q5heW1me0 +EsOK4Mw5IbS2jUjbi9E5th781QDj91elwltghxwtDvpE2vzAJwmxwwBhjySGsKfq +w8SBZOxN+Ih5/IIpDnYGNoN1LSkJnBVGSkjY6OpstuJRIPYWl5zX5tJtYdaxiD+8 +qNbFHBIZ5WrktMopJ3QJJxHdERyK6BFYYSzX/a1gO7woOFCkx8qMCsVzfcE/z1pp +JxJvshT32hnrKZ6MbZMd9JpTFclQ62RV5tNs3FPP3sbDsFtKBUtj87SW7XsimHbZ +OrWlPacSnQDbOoV5TfDDCqWi4PW2EqzDsDcg+Lc8EnBRIquWcAox2+4zmcQI29wO +C1TUpMT5o/wGyL/i9pf6GuTbH0D+aYukULropgSrK57EALbuvqnN3vh5l2QlX/rM ++7lCKsGCNLiJFXb0m6l/B9CC1947XVEbpMEAC/80Shwxl/UB+mKFpJxcNLFtPXzv +FYv2ixarBPbJx/FclOO8G91QC4ZhAKbsVZn5HPMSgtZe+xWM1r0/UJVChsMTafpd +CCOJyu3XtyzFf+tAeixOnuQ= +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 580e9156..b741b118 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -192,15 +192,12 @@ namespace config { ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," "https://i2p.mooo.com/netDb/," - "https://netdb.i2p2.no/," "https://reseed.i2p2.no/," - "https://reseed2.i2p2.no/," - // "https://us.reseed.i2p2.no:444/," // mamoth's shit - // "https://uk.reseed.i2p2.no:444/," // mamoth's shit "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," + "https://reseed.i2pgit.org/," "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; From d4bfeab36ce06f1eba42cfeda0bbfcec068dbea4 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 12:01:13 -0400 Subject: [PATCH 112/189] pass gzip parameter to UDP tunnels --- libi2pd/Datagram.cpp | 5 +++-- libi2pd/Datagram.h | 3 ++- libi2pd/Destination.cpp | 4 ++-- libi2pd/Destination.h | 2 +- libi2pd_client/ClientContext.cpp | 5 +++-- libi2pd_client/ClientContext.h | 1 + libi2pd_client/I2PTunnel.cpp | 8 ++++---- libi2pd_client/I2PTunnel.h | 4 ++-- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 04e01796..7eb20460 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -11,8 +11,8 @@ namespace i2p { namespace datagram { - DatagramDestination::DatagramDestination (std::shared_ptr owner): - m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr) + DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): + m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { } @@ -127,6 +127,7 @@ namespace datagram auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length + m_Deflator.SetCompressionLevel (m_Gzip ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION); size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); if (size) { diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 87f3a7a8..5fcaec3a 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -107,7 +107,7 @@ namespace datagram public: - DatagramDestination (std::shared_ptr owner); + DatagramDestination (std::shared_ptr owner, bool gzip); ~DatagramDestination (); void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); @@ -146,6 +146,7 @@ namespace datagram std::shared_ptr m_Owner; Receiver m_Receiver; // default RawReceiver m_RawReceiver; // default + bool m_Gzip; // gzip compression of data messages std::mutex m_SessionsMutex; std::map m_Sessions; std::mutex m_ReceiversMutex; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 105cd2e6..782e2841 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1105,10 +1105,10 @@ namespace client return dest; } - i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination () + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) { if (m_DatagramDestination == nullptr) - m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis ()); + m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip); return m_DatagramDestination; } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 8c423d77..04cf05f4 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -236,7 +236,7 @@ namespace client // datagram i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (); + i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c8a9ddfe..765d3dec 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -569,7 +569,8 @@ namespace client if (!localDestination) localDestination = m_SharedLocalDestination; - auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort); + bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true); + auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort, gzip); if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second) clientTunnel->Start(); else @@ -672,7 +673,7 @@ namespace client // TODO: hostnames auto localAddress = boost::asio::ip::address::from_string(address); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); - auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port); + auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 610914bf..1a56575f 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -33,6 +33,7 @@ namespace client const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address"; const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination"; const char I2P_CLIENT_TUNNEL_KEYS[] = "keys"; + const char I2P_CLIENT_TUNNEL_GZIP[] = "gzip"; const char I2P_CLIENT_TUNNEL_SIGNATURE_TYPE[] = "signaturetype"; const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 78bc8018..dc2a8811 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -696,7 +696,7 @@ namespace client } I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, - boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) : + boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip) : m_IsUniqueLocal(true), m_Name(name), m_LocalAddress(localAddress), @@ -704,7 +704,7 @@ namespace client { m_LocalDest = localDestination; m_LocalDest->Start(); - auto dgram = m_LocalDest->CreateDatagramDestination(); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); } @@ -745,7 +745,7 @@ namespace client I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, - uint16_t remotePort) : + uint16_t remotePort, bool gzip) : m_Name(name), m_RemoteDest(remoteDest), m_LocalDest(localDestination), @@ -756,7 +756,7 @@ namespace client RemotePort(remotePort), m_cancel_resolve(false) { - auto dgram = m_LocalDest->CreateDatagramDestination(); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 0d1ac9a8..fbe2f7bb 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -198,7 +198,7 @@ namespace client I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, - boost::asio::ip::udp::endpoint forwardTo, uint16_t port); + boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip); ~I2PUDPServerTunnel(); /** expire stale udp conversations */ void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT); @@ -228,7 +228,7 @@ namespace client public: I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, - uint16_t remotePort); + uint16_t remotePort, bool gzip); ~I2PUDPClientTunnel(); void Start(); const char * GetName() const { return m_Name.c_str(); } From 1c8d662e30f591bb27ac58cc39e4341eaad57bcb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 16:42:06 -0400 Subject: [PATCH 113/189] don't add padding for optimal packet size --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++++--- libi2pd/ECIESX25519AEADRatchetSession.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 513ac626..18e1c7b6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -713,9 +713,13 @@ namespace garlic uint8_t paddingSize = 0; if (payloadLen) { - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; + // don't create padding if we are close to optimal size + if (first || payloadLen + 19 <= ECIESX25519_OPTIMAL_PAYLOAD_SIZE || payloadLen > ECIESX25519_OPTIMAL_PAYLOAD_SIZE) + { + RAND_bytes (&paddingSize, 1); + paddingSize &= 0x0F; paddingSize++; // 1 - 16 + payloadLen += paddingSize + 3; + } } std::vector v(payloadLen); size_t offset = 0; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index ce5e2eb4..14f97ce9 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -26,6 +26,9 @@ namespace garlic const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; + const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ + // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ + class ECIESX25519AEADRatchetSession; class RatchetTagSet { From 7b418b3adfe1ef59922aa65658a8603243bc9c34 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 17:51:45 -0400 Subject: [PATCH 114/189] insert whole message to queue --- libi2pd/Streaming.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 2a4175f4..3355d99a 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -423,15 +423,8 @@ namespace stream size_t Stream::Send (const uint8_t * buf, size_t len) { - size_t sent = len; - while(len > MAX_PACKET_SIZE) - { - AsyncSend (buf, MAX_PACKET_SIZE, nullptr); - buf += MAX_PACKET_SIZE; - len -= MAX_PACKET_SIZE; - } AsyncSend (buf, len, nullptr); - return sent; + return len; } void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler) From c7c6e5917a49f234e190fa16cd29a687ececc1d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 20:45:25 -0400 Subject: [PATCH 115/189] Streaming MTU size 1812 for ECIESX25519AEADRatchet --- libi2pd/Streaming.cpp | 16 +++++++++++----- libi2pd/Streaming.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3355d99a..ad3f6209 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -63,7 +63,7 @@ namespace stream m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), - m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0) + m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { RAND_bytes ((uint8_t *)&m_RecvStreamID, 4); m_RemoteIdentity = remote->GetIdentity (); @@ -75,7 +75,7 @@ namespace stream m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), - m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0) + m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { RAND_bytes ((uint8_t *)&m_RecvStreamID, 4); } @@ -473,6 +473,12 @@ namespace stream { // initial packet m_Status = eStreamStatusOpen; + if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; + if (m_RemoteLeaseSet) + { + m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); + m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; + } uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; if (isNoAck) flags |= PACKET_FLAG_NO_ACK; @@ -486,7 +492,7 @@ namespace stream size += 2; // options size m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); size += identityLen; // from - htobe16buf (packet + size, STREAMING_MTU); + htobe16buf (packet + size, m_MTU); size += 2; // max packet size if (isOfflineSignature) { @@ -498,7 +504,7 @@ namespace stream memset (signature, 0, signatureLen); // zeroes for now size += signatureLen; // signature htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size - size += m_SendBuffer.Get (packet + size, STREAMING_MTU); // payload + size += m_SendBuffer.Get (packet + size, m_MTU); // payload m_LocalDestination.GetOwner ()->Sign (packet, size, signature); } else @@ -508,7 +514,7 @@ namespace stream size += 2; // flags htobuf16 (packet + size, 0); // no options size += 2; // options size - size += m_SendBuffer.Get(packet + size, STREAMING_MTU); // payload + size += m_SendBuffer.Get(packet + size, m_MTU); // payload } p->len = size; packets.push_back (p); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 64e4c18d..d3d47794 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -41,6 +41,7 @@ namespace stream const uint16_t PACKET_FLAG_OFFLINE_SIGNATURE = 0x0800; const size_t STREAMING_MTU = 1730; + const size_t STREAMING_MTU_RATCHETS = 1812; const size_t MAX_PACKET_SIZE = 4096; const size_t COMPRESSION_THRESHOLD_SIZE = 66; const int MAX_NUM_RESEND_ATTEMPTS = 6; @@ -234,6 +235,7 @@ namespace stream int m_WindowSize, m_RTT, m_RTO, m_AckDelay; uint64_t m_LastWindowSizeIncreaseTime; int m_NumResendAttempts; + size_t m_MTU; }; class StreamingDestination: public std::enable_shared_from_this From 9fb59e128b601513086f0d30e2cce10d49c56efb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 22:31:36 -0400 Subject: [PATCH 116/189] resubmit updated LeaseSet if not confirmed --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 18e1c7b6..9781a70a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -685,7 +685,10 @@ namespace garlic if (first) payloadLen += 7;// datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? GetOwner ()->GetLeaseSet () : nullptr; + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || + (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && + ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? + GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) { payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; From 3db4421aa7f808924cb7b0317665f9e03631f0b2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 10:48:23 -0400 Subject: [PATCH 117/189] don't invoke gzip for decompression if no compression --- libi2pd/Gzip.cpp | 42 +++++++++++++++++++++++++++++------------- libi2pd/I2PEndian.h | 15 +++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index cb6a79af..f098987a 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -32,18 +32,34 @@ namespace data size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) { - if (m_IsDirty) inflateReset (&m_Inflator); - m_IsDirty = true; - m_Inflator.next_in = const_cast(in); - m_Inflator.avail_in = inLen; - m_Inflator.next_out = out; - m_Inflator.avail_out = outLen; - int err; - if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) - return outLen - m_Inflator.avail_out; - // else - LogPrint (eLogError, "Gzip: Inflate error ", err); - return 0; + if (inLen < 23) return 0; + if (in[10] == 0x01) // non compressed + { + size_t len = bufle16toh (in + 11); + if (len + 23 < inLen) + { + LogPrint (eLogError, "Gzip: Incorrect length"); + return 0; + } + if (len > outLen) len = outLen; + memcpy (out, in + 15, len); + return len; + } + else + { + if (m_IsDirty) inflateReset (&m_Inflator); + m_IsDirty = true; + m_Inflator.next_in = const_cast(in); + m_Inflator.avail_in = inLen; + m_Inflator.next_out = out; + m_Inflator.avail_out = outLen; + int err; + if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) + return outLen - m_Inflator.avail_out; + // else + LogPrint (eLogError, "Gzip: Inflate error ", err); + return 0; + } } void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) @@ -148,7 +164,7 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { - static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; if (outLen < (size_t)inLen + 23) return 0; memcpy (out, gzipHeader, 11); htole16buf (out + 11, inLen); diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index 0798f688..04a9480e 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -128,5 +128,20 @@ inline void htole64buf(void *buf, uint64_t big64) htobuf64(buf, htole64(big64)); } +inline uint16_t bufle16toh(const void *buf) +{ + return le16toh(buf16toh(buf)); +} + +inline uint32_t bufle32toh(const void *buf) +{ + return le32toh(buf32toh(buf)); +} + +inline uint64_t bufle64toh(const void *buf) +{ + return le64toh(buf64toh(buf)); +} + #endif // I2PENDIAN_H__ From 7ebf2f010c463bcb3ccf30b3efa4d0846eead255 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 19:03:12 -0400 Subject: [PATCH 118/189] shorter padding for optimal packet length --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9781a70a..7b386d92 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -716,12 +716,18 @@ namespace garlic uint8_t paddingSize = 0; if (payloadLen) { - // don't create padding if we are close to optimal size - if (first || payloadLen + 19 <= ECIESX25519_OPTIMAL_PAYLOAD_SIZE || payloadLen > ECIESX25519_OPTIMAL_PAYLOAD_SIZE) - { + int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; + if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size + { RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; + paddingSize &= 0x0F; // 0 - 15 + if (delta > 3) + { + delta -= 3; + if (paddingSize >= delta) paddingSize %= delta; + } + paddingSize++; + payloadLen += paddingSize + 3; } } std::vector v(payloadLen); From 648d035a0fe6cd44fab7108f09314b9d75965231 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 21:02:32 -0400 Subject: [PATCH 119/189] GzipNoCompression for datagrams --- libi2pd/Datagram.cpp | 4 ++-- libi2pd/Gzip.cpp | 22 ++++++++++++++++++++++ libi2pd/Gzip.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 7eb20460..08cd86bf 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -127,8 +127,8 @@ namespace datagram auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - m_Deflator.SetCompressionLevel (m_Gzip ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION); - size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); + size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : + i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index f098987a..f36620ae 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -174,6 +174,28 @@ namespace data htole32buf (out + inLen + 19, inLen); return inLen + 23; } + + size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen) + { + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; + memcpy (out, gzipHeader, 11); + uint32_t crc = 0; + size_t len = 0, len1; + for (const auto& it: bufs) + { + len1 = len; + len += it.second; + if (outLen < len + 23) return 0; + memcpy (out + 15 + len1, it.first, it.second); + crc = crc32 (crc, it.first, it.second); + } + if (len > 0xffff) return 0; + htole32buf (out + len + 15, crc); + htole32buf (out + len + 19, len); + htole16buf (out + 11, len); + htole16buf (out + 13, 0xffff - len); + return len + 23; + } } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index e5b8775e..16776d35 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -44,6 +44,7 @@ namespace data }; size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K + size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen); // for total size < 64K } // data } // i2p From db6a0e6ad9124ef9b6217af487b3c844234ba5e1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 20 May 2020 09:17:54 +0000 Subject: [PATCH 120/189] [cmake] remove windows build support (#1517) Removes support for MSVC, MSYS, MinGW and included NSIS installer in cmake --- build/CMakeLists.txt | 527 ++++++++++------------------------ build/cmake-zlib-amd64.patch | 10 - build/cmake-zlib-static.patch | 28 -- 3 files changed, 158 insertions(+), 407 deletions(-) delete mode 100644 build/cmake-zlib-amd64.patch delete mode 100644 build/cmake-zlib-static.patch diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 1a459bf8..8271ce3a 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -1,28 +1,32 @@ -cmake_minimum_required ( VERSION 2.8.12 ) +cmake_minimum_required(VERSION 2.8.12) # this addresses CMP0059 with CMake > 3.3 for PCH flags -cmake_policy( VERSION 2.8.12 ) -project ( "i2pd" ) +cmake_policy(VERSION 2.8.12) +project("i2pd") # for debugging #set(CMAKE_VERBOSE_MAKEFILE on) +# Win32 build with cmake is not supported +if(WIN32 OR MSVC OR MSYS OR MINGW) + message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.") +endif() + # configurale options -option(WITH_AESNI "Use AES-NI instructions set" OFF) -option(WITH_AVX "Use AVX instructions" OFF) -option(WITH_HARDENING "Use hardening compiler flags" OFF) -option(WITH_LIBRARY "Build library" ON) -option(WITH_BINARY "Build binary" ON) -option(WITH_STATIC "Static build" OFF) -option(WITH_UPNP "Include support for UPnP client" OFF) -option(WITH_PCH "Use precompiled header" OFF) -option(WITH_GUI "Include GUI (currently MS Windows only)" ON) -option(WITH_MESHNET "Build for cjdns test network" OFF) -option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) -option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) +option(WITH_AESNI "Use AES-NI instructions set" OFF) +option(WITH_AVX "Use AVX instructions" OFF) +option(WITH_HARDENING "Use hardening compiler flags" OFF) +option(WITH_LIBRARY "Build library" ON) +option(WITH_BINARY "Build binary" ON) +option(WITH_STATIC "Static build" OFF) +option(WITH_UPNP "Include support for UPnP client" OFF) +option(WITH_PCH "Use precompiled header" OFF) +option(WITH_MESHNET "Build for cjdns test network" OFF) +option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) +option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) # paths -set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) -set ( CMAKE_SOURCE_DIR ".." ) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") +set(CMAKE_SOURCE_DIR "..") # architecture include(TargetArch) @@ -30,67 +34,65 @@ target_architecture(ARCHITECTURE) set(LIBI2PD_SRC_DIR ../libi2pd) set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) +set(DAEMON_SRC_DIR ../daemon) include_directories(${LIBI2PD_SRC_DIR}) include_directories(${LIBI2PD_CLIENT_SRC_DIR}) +include_directories(${DAEMON_SRC_DIR}) -set (LIBI2PD_SRC +set(LIBI2PD_SRC + "${LIBI2PD_SRC_DIR}/api.cpp" + "${LIBI2PD_SRC_DIR}/Base.cpp" + "${LIBI2PD_SRC_DIR}/Blinding.cpp" "${LIBI2PD_SRC_DIR}/BloomFilter.cpp" + "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" "${LIBI2PD_SRC_DIR}/Config.cpp" "${LIBI2PD_SRC_DIR}/CPU.cpp" "${LIBI2PD_SRC_DIR}/Crypto.cpp" "${LIBI2PD_SRC_DIR}/CryptoKey.cpp" + "${LIBI2PD_SRC_DIR}/Datagram.cpp" + "${LIBI2PD_SRC_DIR}/Destination.cpp" + "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" + "${LIBI2PD_SRC_DIR}/Ed25519.cpp" + "${LIBI2PD_SRC_DIR}/Elligator.cpp" + "${LIBI2PD_SRC_DIR}/Family.cpp" + "${LIBI2PD_SRC_DIR}/FS.cpp" "${LIBI2PD_SRC_DIR}/Garlic.cpp" + "${LIBI2PD_SRC_DIR}/Gost.cpp" "${LIBI2PD_SRC_DIR}/Gzip.cpp" "${LIBI2PD_SRC_DIR}/HTTP.cpp" "${LIBI2PD_SRC_DIR}/I2NPProtocol.cpp" "${LIBI2PD_SRC_DIR}/Identity.cpp" "${LIBI2PD_SRC_DIR}/LeaseSet.cpp" - "${LIBI2PD_SRC_DIR}/FS.cpp" "${LIBI2PD_SRC_DIR}/Log.cpp" - "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" - "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" "${LIBI2PD_SRC_DIR}/NetDb.cpp" + "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" + "${LIBI2PD_SRC_DIR}/NTCP2.cpp" + "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" + "${LIBI2PD_SRC_DIR}/Poly1305.cpp" "${LIBI2PD_SRC_DIR}/Profiling.cpp" "${LIBI2PD_SRC_DIR}/Reseed.cpp" "${LIBI2PD_SRC_DIR}/RouterContext.cpp" "${LIBI2PD_SRC_DIR}/RouterInfo.cpp" + "${LIBI2PD_SRC_DIR}/Signature.cpp" "${LIBI2PD_SRC_DIR}/SSU.cpp" "${LIBI2PD_SRC_DIR}/SSUData.cpp" "${LIBI2PD_SRC_DIR}/SSUSession.cpp" "${LIBI2PD_SRC_DIR}/Streaming.cpp" - "${LIBI2PD_SRC_DIR}/Destination.cpp" - "${LIBI2PD_SRC_DIR}/TransitTunnel.cpp" - "${LIBI2PD_SRC_DIR}/Tunnel.cpp" - "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" - "${LIBI2PD_SRC_DIR}/Transports.cpp" - "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" - "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" - "${LIBI2PD_SRC_DIR}/Base.cpp" - "${LIBI2PD_SRC_DIR}/util.cpp" - "${LIBI2PD_SRC_DIR}/Datagram.cpp" - "${LIBI2PD_SRC_DIR}/Family.cpp" - "${LIBI2PD_SRC_DIR}/Signature.cpp" "${LIBI2PD_SRC_DIR}/Timestamp.cpp" - "${LIBI2PD_SRC_DIR}/api.cpp" - "${LIBI2PD_SRC_DIR}/Gost.cpp" - "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" - "${LIBI2PD_SRC_DIR}/Poly1305.cpp" - "${LIBI2PD_SRC_DIR}/Ed25519.cpp" - "${LIBI2PD_SRC_DIR}/NTCP2.cpp" - "${LIBI2PD_SRC_DIR}/Blinding.cpp" - "${LIBI2PD_SRC_DIR}/Elligator.cpp" - "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" + "${LIBI2PD_SRC_DIR}/TransitTunnel.cpp" + "${LIBI2PD_SRC_DIR}/Transports.cpp" + "${LIBI2PD_SRC_DIR}/Tunnel.cpp" + "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" + "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" + "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" + "${LIBI2PD_SRC_DIR}/util.cpp" ) -if (WIN32 OR MSYS) - list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") -endif () - add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") -if (WITH_LIBRARY) +if(WITH_LIBRARY) install(TARGETS libi2pd EXPORT libi2pd ARCHIVE DESTINATION lib @@ -101,7 +103,7 @@ if (WITH_LIBRARY) # install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() -set (CLIENT_SRC +set(CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp" @@ -117,7 +119,7 @@ set (CLIENT_SRC add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") -if (WITH_LIBRARY) +if(WITH_LIBRARY) install(TARGETS libi2pdclient EXPORT libi2pdclient ARCHIVE DESTINATION lib @@ -125,9 +127,7 @@ if (WITH_LIBRARY) COMPONENT Libraries) endif() -set(DAEMON_SRC_DIR ../daemon) - -set (DAEMON_SRC +set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" "${DAEMON_SRC_DIR}/HTTPServer.cpp" "${DAEMON_SRC_DIR}/I2PControl.cpp" @@ -135,37 +135,20 @@ set (DAEMON_SRC "${DAEMON_SRC_DIR}/UPnP.cpp" ) -if (WITH_MESHNET) +if(WITH_MESHNET) add_definitions(-DMESHNET) -endif () +endif() -if (WITH_UPNP) +if(WITH_UPNP) add_definitions(-DUSE_UPNP) - if (NOT MSVC AND NOT MSYS) - set(DL_LIB ${CMAKE_DL_LIBS}) - endif () -endif () +endif() -# compiler flags customization (by vendor) -if (MSVC) - add_definitions( -DWIN32_LEAN_AND_MEAN -DNOMINMAX ) - # TODO Check & report to Boost dev, there should be no need for these two - add_definitions( -DBOOST_THREAD_NO_LIB -DBOOST_CHRONO_NO_LIB ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /INCREMENTAL:NO /LTCG" ) - set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /GL" ) - set( CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO /LTCG" ) -else() - if (MSYS OR MINGW) - add_definitions( -DWIN32_LEAN_AND_MEAN ) - endif () - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" ) - # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. - # Multiple definitions of __stack_chk_fail (libssp & libc) - set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections" ) - set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections" ) # -flto is added from above -endif () +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") +# TODO: The following is incompatible with static build and enabled hardening for OpenWRT. +# Multiple definitions of __stack_chk_fail(libssp & libc) +set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above # check for c++17 & c++11 support include(CheckCXXCompilerFlag) @@ -179,72 +162,53 @@ else() message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") endif() -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") - if (WITH_HARDENING) - add_definitions( "-D_FORTIFY_SOURCE=2" ) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security" ) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param ssp-buffer-size=4" ) - endif () -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") + if(WITH_HARDENING) + add_definitions("-D_FORTIFY_SOURCE=2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param ssp-buffer-size=4") + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # more tweaks - if (LINUX) - set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++" ) # required for + if(LINUX) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++") # required for list(APPEND CMAKE_REQUIRED_LIBRARIES "stdc++") # required to link with -stdlib=libstdc++ endif() - if (NOT (MSVC OR MSYS OR APPLE)) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions" ) + if(NOT APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions") endif() -endif () +endif() -if (WITH_HARDENING AND MSVC) - # Most security options like dynamic base, buffer & stack checks are ON by default - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:cf" ) -endif () - -# compiler flags customization (by system) -if (UNIX) - list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") - if (NOT (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE)) +# compiler flags customization(by system) +if(UNIX) + list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") + if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE)) # "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8 - add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) - endif () -elseif (WIN32 OR MSYS) - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp") - if (WITH_GUI) - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp") - set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp" - PROPERTIES COMPILE_DEFINITIONS WIN32_APP) - endif () - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Resource.rc") -endif () - -if (WITH_AESNI) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes" ) -endif() - -if (WITH_AVX) - set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx" ) -endif() - -if (WITH_ADDRSANITIZER) - if (NOT MSVC) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer" ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" ) - else () - message( SEND_ERROR "MSVC does not support address sanitizer option") + add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1") endif() endif() -if (WITH_THREADSANITIZER) - if (WITH_ADDRSANITIZER) - message( FATAL_ERROR "thread sanitizer option cannot be combined with address sanitizer") - elseif (NOT MSVC) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread" ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread" ) - else () - message( SEND_ERROR "MSVC does not support address sanitizer option") +if(WITH_AESNI) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") + add_definitions(-DAESNI) +endif() + +if(WITH_AVX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx") +endif() + +if(WITH_ADDRSANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") +endif() + +if(WITH_THREADSANITIZER) + if(WITH_ADDRSANITIZER) + message(FATAL_ERROR "thread sanitizer option cannot be combined with address sanitizer") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") endif() endif() @@ -253,141 +217,87 @@ endif() # TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826 # use imported Threads::Threads instead set(THREADS_PREFER_PTHREAD_FLAG ON) -if (IOS) +if(IOS) set(CMAKE_THREAD_LIBS_INIT "-lpthread") set(CMAKE_HAVE_THREADS_LIBRARY 1) set(CMAKE_USE_WIN32_THREADS_INIT 0) set(CMAKE_USE_PTHREADS_INIT 1) else() - find_package ( Threads REQUIRED ) + find_package(Threads REQUIRED) endif() if(THREADS_HAVE_PTHREAD_ARG) # compile time flag set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() -if (WITH_STATIC) +if(WITH_STATIC) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_RUNTIME ON) - if (WIN32 AND NOT MSYS AND NOT MINGW) - # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace - foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif () set(BUILD_SHARED_LIBS OFF) - if (${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread" ) - # set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" ) - set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,-u,pthread_create,-u,pthread_once,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_join,-u,pthread_equal,-u,pthread_detach,-u,pthread_cond_wait,-u,pthread_cond_signal,-u,pthread_cond_destroy,-u,pthread_cond_broadcast,-u,pthread_cancel" ) - endif () + if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + # set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive") + set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,-u,pthread_create,-u,pthread_once,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_join,-u,pthread_equal,-u,pthread_detach,-u,pthread_cond_wait,-u,pthread_cond_signal,-u,pthread_cond_destroy,-u,pthread_cond_broadcast,-u,pthread_cancel") + endif() else() - if (NOT WIN32 AND NOT MSYS) - # TODO: Consider separate compilation for LIBI2PD_SRC for library. - # No need in -fPIC overhead for binary if not interested in library - # HINT: revert c266cff CMakeLists.txt: compilation speed up - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) - endif () + # TODO: Consider separate compilation for LIBI2PD_SRC for library. + # No need in -fPIC overhead for binary if not interested in library + # HINT: revert c266cff CMakeLists.txt: compilation speed up + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) -endif () +endif() -if (WITH_PCH) +if(WITH_PCH) include_directories(BEFORE ${CMAKE_BINARY_DIR}) add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp") - if(MSVC) - target_compile_options(stdafx PRIVATE /Ycstdafx.h /Zm155) - add_custom_command(TARGET stdafx POST_BUILD - COMMAND xcopy /y stdafx.dir\\$\\*.pdb libi2pd.dir\\$\\ - COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pdclient.dir\\$\\ - COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pd.dir\\$\\ - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - target_compile_options(libi2pd PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - target_compile_options(libi2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - else() - string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) - get_directory_property(DEFS DEFINITIONS) - string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") - add_custom_command(TARGET stdafx PRE_BUILD - COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch - ) - target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) - target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) - endif() + string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) + get_directory_property(DEFS DEFINITIONS) + string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") + add_custom_command(TARGET stdafx PRE_BUILD + COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch + ) + target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) + target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) target_link_libraries(libi2pd stdafx) endif() target_link_libraries(libi2pdclient libi2pd) -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) message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!") endif() -find_package ( OpenSSL REQUIRED ) +find_package(OpenSSL REQUIRED) if(NOT DEFINED OPENSSL_INCLUDE_DIR) message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!") endif() -if (WITH_UPNP) - find_package ( MiniUPnPc REQUIRED ) - include_directories( SYSTEM ${MINIUPNPC_INCLUDE_DIR} ) +if(WITH_UPNP) + find_package(MiniUPnPc REQUIRED) + if(NOT MINIUPNPC_FOUND) + message(SEND_ERROR "Could not find MiniUPnPc. Please download and install it first!") + else() + include_directories(SYSTEM ${MINIUPNPC_INCLUDE_DIR}) + endif() endif() -find_package ( ZLIB ) -if (NOT ZLIB_FOUND ) - # We are probably on Windows - find_program( PATCH patch C:/Program Files/Git/usr/bin C:/msys64/usr/bin C:/msys32/usr/bin C:/Strawberry/c/bin ) - include( ExternalProject ) - if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - set( ZLIB_EXTRA -DAMD64=ON ) - else() - set( ZLIB_EXTRA -DASM686=ON "-DCMAKE_ASM_MASM_FLAGS=/W0 /safeseh" ) - endif() - ExternalProject_Add(zlib-project - URL https://zlib.net/zlib-1.2.11.tar.gz - URL_HASH SHA256=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/zlib - PATCH_COMMAND "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-static.patch - && "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-amd64.patch - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= - -DWITH_STATIC=${WITH_STATIC} ${ZLIB_EXTRA} - ) - if (WITH_PCH) - add_dependencies( stdafx zlib-project ) - else () - add_dependencies( libi2pd zlib-project ) - endif () - # ExternalProject_Get_Property(zlib-project install_dir) - set ( ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/zlib/include" CACHE FILEPATH "zlib include dir" FORCE) - if (NOT WITH_STATIC) - set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE) - endif () - link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib) -else() +find_package(ZLIB) +if(ZLIB_FOUND) link_directories(${ZLIB_ROOT}/lib) -endif () -if (WITH_STATIC AND (MSVC OR MSYS)) - set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE) -endif () +endif() # load includes -include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) - +include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) # warn if for meshnet -if (WITH_MESHNET) +if(WITH_MESHNET) message(STATUS "Building for testnet") message(WARNING "This build will NOT work on mainline i2p") endif() -include(CheckAtomic) - +if(NOT MSYS) + include(CheckAtomic) +endif() # show summary message(STATUS "---------------------------------------") @@ -414,32 +324,24 @@ message(STATUS "---------------------------------------") #Handle paths nicely include(GNUInstallDirs) -if (WITH_BINARY) - add_executable ( "${PROJECT_NAME}" ${DAEMON_SRC} ) - if (WIN32 AND WITH_GUI) - set_target_properties("${PROJECT_NAME}" PROPERTIES WIN32_EXECUTABLE TRUE ) - endif() - if(NOT MSVC) - if (WITH_STATIC) - set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static" ) - endif () +if(WITH_BINARY) + add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) + + if(WITH_STATIC) + set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") endif() - if (WITH_PCH) - if (MSVC) - target_compile_options("${PROJECT_NAME}" PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - else() - target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h) - endif() + if(WITH_PCH) + target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h) endif() - if (WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT MSYS AND NOT MINGW) - set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now" ) - endif () + if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now") + endif() - if (WITH_UPNP) - target_link_libraries("${PROJECT_NAME}" "${MINIUPNPC_LIBRARY}") - endif () + if(WITH_UPNP) + set(UPNP_LIB ${MINIUPNPC_LIBRARY}) + endif() # FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04 list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES) @@ -447,128 +349,15 @@ if (WITH_BINARY) list(REMOVE_AT Boost_LIBRARIES -1) endif() - if (MSYS OR MINGW) - set (MINGW_EXTRA -lws2_32 -lmswsock -liphlpapi ) - endif () - if (WITH_STATIC) + + if(WITH_STATIC) set(DL_LIB ${CMAKE_DL_LIBS}) endif() + target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY}) - target_link_libraries( "${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + 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}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) - set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") - set (DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin") - if (MSVC) - install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS DEBUG RELWITHDEBINFO COMPONENT Symbols) - # TODO Somehow this picks lots of unrelevant stuff with MSYS. OS X testing needed. - INSTALL(CODE " - include(BundleUtilities) - fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\") - " COMPONENT Runtime) - endif () -endif () - -install(FILES ../LICENSE - DESTINATION . - COMPONENT Runtime - ) -# Take a copy on Appveyor -install(FILES "C:/projects/openssl-$ENV{OPENSSL}/LICENSE" - DESTINATION . - COMPONENT Runtime - RENAME LICENSE_OPENSSL - OPTIONAL # for local builds only! - ) - -file(GLOB_RECURSE I2PD_SOURCES "../libi2pd/*.cpp" "../libi2pd_client/*.cpp" "../daemon/*.cpp" "../build" "../Win32" "../Makefile*") -install(FILES ${I2PD_SOURCES} DESTINATION src/ COMPONENT Source) -# install(DIRECTORY ../ DESTINATION src/ -# # OPTIONAL -# COMPONENT Source FILES_MATCHING -# PATTERN .git EXCLUDE -# PATTERN "*.cpp" -# ) - -file(GLOB I2PD_HEADERS "../libi2pd/*.h" "../libi2pd_client/*.h" "../daemon/*.h") -install(FILES ${I2PD_HEADERS} DESTINATION src/ COMPONENT Headers) -# install(DIRECTORY ../ DESTINATION src/ -# # OPTIONAL -# COMPONENT Headers FILES_MATCHING -# PATTERN .git EXCLUDE -# PATTERN "*.h" -# ) - -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Purple I2P, a C++ I2P daemon") -set(CPACK_PACKAGE_VENDOR "Purple I2P") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../README.md") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE") -file(READ ../libi2pd/version.h version_h) -string(REGEX REPLACE ".*I2PD_VERSION_MAJOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_MINOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_MICRO ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MICRO "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_PATCH ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_PATCH "${version_h}") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "Purple I2P")# ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") -include(CPackComponent) -cpack_add_component(Runtime - DESCRIPTION "Main files" - REQUIRED INSTALL_TYPES minimal) -cpack_add_component(Symbols - DISPLAY_NAME "Debug symbols" - DESCRIPTION "Debug symbols for use with WinDbg or Visual Studio" - INSTALL_TYPES recommended full - ) -cpack_add_component(Libraries - DESCRIPTION "Binary libraries for development" - INSTALL_TYPES full dev3rd - ) -cpack_add_component(Source - DISPLAY_NAME "Source code" - DESCRIPTION "I2pd source code" - INSTALL_TYPES full - ) -cpack_add_component(Headers - DISPLAY_NAME "Header files" - DESCRIPTION "I2pd header files for development" - INSTALL_TYPES full dev3rd - ) -install(FILES ${MINIUPNPC_INCLUDE_DIR}/miniupnpc/miniupnpc.dll - DESTINATION bin - COMPONENT MiniUPnPc - OPTIONAL - ) -install(FILES ${MINIUPNPC_INCLUDE_DIR}/miniupnpc/LICENSE - DESTINATION . - COMPONENT MiniUPnPc - RENAME LICENSE_MINIUPNPC - OPTIONAL - ) -cpack_add_component(MiniUPnPc - INSTALL_TYPES full recommended - # DOWNLOADED - # ARCHIVE_FILE miniupnpc-win32.zip - ) -cpack_add_install_type(recommended DISPLAY_NAME Recommended) -cpack_add_install_type(dev3rd DISPLAY_NAME "Third party development") -cpack_add_install_type(full DISPLAY_NAME Full) -cpack_add_install_type(minimal DISPLAY_NAME Minimal) -if((WIN32 OR MSYS) AND NOT UNIX) - # There is a bug in NSI that does not handle full unix paths properly. Make - # sure there is at least one set of four (4) backlasshes. - set(CPACK_NSIS_DEFINES "RequestExecutionLevel user") - set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../Win32\\\\mask.bmp") - set(CPACK_NSIS_INSTALLED_ICON_NAME "bin/i2pd.exe") - SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") - set(CPACK_NSIS_HELP_LINK "https:\\\\\\\\github.com\\\\PurpleI2P\\\\i2pd\\\\issues") - set(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\\\\\github.com\\\\PurpleI2P\\\\i2pd") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Install i2pd as windows service.lnk' '$INSTDIR\\\\bin\\\\i2pd.exe' '--service=install' -CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Remove i2pd windows service.lnk' '$INSTDIR\\\\bin\\\\i2pd.exe' '--service=remove'") - set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\Install i2pd as windows service.lnk' -Delete '$SMPROGRAMS\\\\$START_MENU\\\\Remove i2pd windows service.lnk'") -else() - set(CPACK_STRIP_FILES "bin/i2pd") - set(CPACK_SOURCE_STRIP_FILES "") + set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") + set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin") endif() -set(CPACK_PACKAGE_EXECUTABLES "i2pd" "C++ I2P daemon") -set(CPACK_SOURCE_GENERATOR "TGZ") -include(CPack) diff --git a/build/cmake-zlib-amd64.patch b/build/cmake-zlib-amd64.patch deleted file mode 100644 index 7ea1d9fe..00000000 --- a/build/cmake-zlib-amd64.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- CMakeLists.txt.orig 2015-12-07 14:19:36.447689600 -0600 -+++ CMakeLists.txt 2015-12-07 14:18:23.004419900 -0600 -@@ -165,6 +165,7 @@ - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx64/gvmat64.asm -+ contrib/masmx64/inffas8664.c - contrib/masmx64/inffasx64.asm - ) - endif() diff --git a/build/cmake-zlib-static.patch b/build/cmake-zlib-static.patch deleted file mode 100644 index 68f1400e..00000000 --- a/build/cmake-zlib-static.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- CMakeLists.txt.orig 2013-04-28 17:57:10.000000000 -0500 -+++ CMakeLists.txt 2015-12-03 12:53:52.371087900 -0600 -@@ -7,6 +7,7 @@ - - option(ASM686 "Enable building i686 assembly implementation") - option(AMD64 "Enable building amd64 assembly implementation") -+option(WITH_STATIC "Static runtime on Windows" OFF) - - set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") - set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -@@ -66,6 +67,17 @@ - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - endif() - -+if(WITH_STATIC AND (MSVC OR MSYS)) -+ # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace -+ foreach(flag_var -+ CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE -+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) -+ if(${flag_var} MATCHES "/MD") -+ string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") -+ endif(${flag_var} MATCHES "/MD") -+ endforeach(flag_var) -+endif() -+ - if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... From bdd75e11714d0d15f2d261f86b62e50558073dc7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 May 2020 14:59:18 -0400 Subject: [PATCH 121/189] build client tunnels through router with version >= 0.9.36 --- libi2pd/NetDb.cpp | 3 ++- libi2pd/NetDb.hpp | 2 ++ libi2pd/RouterInfo.cpp | 20 ++++++++++++++++++-- libi2pd/RouterInfo.h | 3 +++ libi2pd/version.h | 2 ++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 3466cf2b..86bf160e 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1121,7 +1121,8 @@ namespace data { return !router->IsHidden () && router != compatibleWith && router->IsCompatible (*compatibleWith) && - (router->GetCaps () & RouterInfo::eHighBandwidth); + (router->GetCaps () & RouterInfo::eHighBandwidth) && + router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index d9e10504..6e251ecb 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -21,6 +21,7 @@ #include "Reseed.h" #include "NetDbRequests.h" #include "Family.h" +#include "version.h" namespace i2p { @@ -32,6 +33,7 @@ namespace data const int NETDB_MIN_EXPIRATION_TIMEOUT = 90*60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27*60*60; // 27 hours const int NETDB_PUBLISH_INTERVAL = 60*40; + const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 37c2af7e..9b3b7e89 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -27,7 +27,7 @@ namespace data RouterInfo::RouterInfo (const std::string& fullPath): m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), - m_SupportedTransports (0), m_Caps (0) + m_SupportedTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; @@ -35,7 +35,8 @@ namespace data } RouterInfo::RouterInfo (const uint8_t * buf, int len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) + m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), + m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) @@ -340,6 +341,21 @@ namespace data // extract caps if (!strcmp (key, "caps")) ExtractCaps (value); + // extract version + else if (!strcmp (key, ROUTER_INFO_PROPERTY_VERSION)) + { + m_Version = 0; + char * ch = value; + while (*ch) + { + if (*ch >= '0' && *ch <= '9') + { + m_Version *= 10; + m_Version += (*ch - '0'); + } + ch++; + } + } // check netId else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ()) { diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b23625e0..f8598b1e 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -19,6 +19,7 @@ namespace data const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets"; const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters"; const char ROUTER_INFO_PROPERTY_NETID[] = "netId"; + const char ROUTER_INFO_PROPERTY_VERSION[] = "router.version"; const char ROUTER_INFO_PROPERTY_FAMILY[] = "family"; const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig"; @@ -142,6 +143,7 @@ namespace data void SetRouterIdentity (std::shared_ptr identity); std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); }; uint64_t GetTimestamp () const { return m_Timestamp; }; + int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr std::shared_ptr GetNTCPAddress (bool v4only = true) const; std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; @@ -235,6 +237,7 @@ namespace data std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; uint8_t m_SupportedTransports, m_Caps; + int m_Version; mutable std::shared_ptr m_Profile; }; } diff --git a/libi2pd/version.h b/libi2pd/version.h index 4ad1a546..fa8f9a0f 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -5,6 +5,7 @@ #define STRINGIZE(x) #x #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) +#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 31 @@ -24,5 +25,6 @@ #define I2P_VERSION_MICRO 45 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) +#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #endif From 9318388007cff0495b4b360d0480f4fc1219a9dc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 20 May 2020 22:30:02 +0300 Subject: [PATCH 122/189] [apparmor] add one more resolv.conf path (reported by user with ubuntu 18.04) Signed-off-by: R4SAS --- contrib/apparmor/usr.sbin.i2pd | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/apparmor/usr.sbin.i2pd b/contrib/apparmor/usr.sbin.i2pd index afa59563..6cc80609 100644 --- a/contrib/apparmor/usr.sbin.i2pd +++ b/contrib/apparmor/usr.sbin.i2pd @@ -19,6 +19,7 @@ /etc/nsswitch.conf r, /etc/resolv.conf r, /run/resolvconf/resolv.conf r, + /run/systemd/resolve/resolv.conf r, /run/systemd/resolve/stub-resolv.conf r, # path specific (feel free to modify if you have another paths) From e5901dad9177dc1740149d164143b1230fe78854 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 14:52:44 -0400 Subject: [PATCH 123/189] resend not more than half of window --- libi2pd/Streaming.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ad3f6209..e2047b0d 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -824,6 +824,8 @@ namespace stream } // collect packets to resend + int maxNumPackets = (m_WindowSize >> 1); // /2 + if (maxNumPackets < WINDOW_SIZE) maxNumPackets = WINDOW_SIZE; auto ts = i2p::util::GetMillisecondsSinceEpoch (); std::vector packets; for (auto it : m_SentPackets) @@ -832,6 +834,8 @@ namespace stream { it->sendTime = ts; packets.push_back (it); + maxNumPackets--; + if (maxNumPackets <= 0) break; } } @@ -843,7 +847,7 @@ namespace stream switch (m_NumResendAttempts) { case 1: // congesion avoidance - m_WindowSize /= 2; + m_WindowSize >>= 1; // /2 if (m_WindowSize < MIN_WINDOW_SIZE) m_WindowSize = MIN_WINDOW_SIZE; break; case 2: From 153aaa6d21459d50fbab54c9c553e6322a489ad1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 15:33:12 -0400 Subject: [PATCH 124/189] no compression for RouterInfo gzip --- libi2pd/I2NPProtocol.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a16ce580..3a139792 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -249,9 +249,7 @@ namespace i2p uint8_t * sizePtr = buf; buf += 2; m->len += (buf - payload); // payload size - i2p::data::GzipDeflator deflator; - deflator.SetCompressionLevel (Z_BEST_COMPRESSION); - size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + size_t size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); if (size) { htobe16buf (sizePtr, size); // size From a6c9ee446a3a89a45f741037256c88e56613f378 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 15:36:16 -0400 Subject: [PATCH 125/189] LeaseSet and encryption type for http and socks proxy --- libi2pd_client/ClientContext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 765d3dec..51f10f5e 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -468,6 +468,10 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = value; if (i2p::config::GetOption(prefix + I2CP_PARAM_MAX_TUNNEL_LATENCY, value)) options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = value; + if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_TYPE, value)) + options[I2CP_PARAM_LEASESET_TYPE] = value; + if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, value)) + options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = value; } void ClientContext::ReadTunnels () From f133a7f9fd3b70a9d23c6fc83cda772d11d5702a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 18:58:28 -0400 Subject: [PATCH 126/189] resend outstading packets again --- libi2pd/Streaming.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index e2047b0d..0af7d902 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -408,11 +408,14 @@ namespace stream else break; } - if (m_SentPackets.empty ()) - m_ResendTimer.cancel (); if (acknowledged) { + bool isPreviousResend = m_NumResendAttempts > 0; m_NumResendAttempts = 0; + if (m_SentPackets.empty ()) + m_ResendTimer.cancel (); + else if (isPreviousResend) // resend outstanding + HandleResendTimer (boost::system::error_code ()); // no error SendBuffer (); } if (m_Status == eStreamStatusClosed) From 0c2b0081b5cc4ffbedd09bed70a7141f43ca6312 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 19:38:25 -0400 Subject: [PATCH 127/189] rollback --- libi2pd/Streaming.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 0af7d902..00ee35b0 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -408,14 +408,11 @@ namespace stream else break; } + if (m_SentPackets.empty ()) + m_ResendTimer.cancel (); if (acknowledged) { - bool isPreviousResend = m_NumResendAttempts > 0; m_NumResendAttempts = 0; - if (m_SentPackets.empty ()) - m_ResendTimer.cancel (); - else if (isPreviousResend) // resend outstanding - HandleResendTimer (boost::system::error_code ()); // no error SendBuffer (); } if (m_Status == eStreamStatusClosed) @@ -827,8 +824,6 @@ namespace stream } // collect packets to resend - int maxNumPackets = (m_WindowSize >> 1); // /2 - if (maxNumPackets < WINDOW_SIZE) maxNumPackets = WINDOW_SIZE; auto ts = i2p::util::GetMillisecondsSinceEpoch (); std::vector packets; for (auto it : m_SentPackets) @@ -837,8 +832,6 @@ namespace stream { it->sendTime = ts; packets.push_back (it); - maxNumPackets--; - if (maxNumPackets <= 0) break; } } From 46ee427ee33c8a727a9bb838b5d5961145d917c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 21:54:00 -0400 Subject: [PATCH 128/189] common header for repliable datagrams --- libi2pd/Datagram.cpp | 23 +++++++++-------------- libi2pd/Datagram.h | 2 ++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 08cd86bf..6441b5e2 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,4 @@ #include -#include #include "Crypto.h" #include "Log.h" #include "TunnelBase.h" @@ -14,6 +13,10 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); + m_From.resize (identityLen); + m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); + m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); } DatagramDestination::~DatagramDestination () @@ -23,26 +26,18 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto owner = m_Owner; - auto localIdentity = m_Owner->GetIdentity (); - auto identityLen = localIdentity->GetFullLen (); - auto signatureLen = localIdentity->GetSignatureLen (); - size_t headerLen = identityLen + signatureLen; - - std::vector header(headerLen); - localIdentity->ToBuffer (header.data (), identityLen); - uint8_t * signature = header.data () + identityLen; - if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { uint8_t hash[32]; SHA256(payload, len, hash); - owner->Sign (hash, 32, signature); + m_Owner->Sign (hash, 32, m_Signature.data ()); } else - owner->Sign (payload, len, signature); + m_Owner->Sign (payload, len, m_Signature.data ()); auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{header.data (), headerLen}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 5fcaec3a..ea2a4e13 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "Base.h" #include "Identity.h" #include "LeaseSet.h" @@ -154,6 +155,7 @@ namespace datagram i2p::data::GzipInflator m_Inflator; i2p::data::GzipDeflator m_Deflator; + std::vector m_From, m_Signature; }; } } From 78640532e1c0e50b122df45702e9861e6402d2af Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 13:01:25 +0000 Subject: [PATCH 129/189] [appveyor] add build fix (#1520) Add fix due to msys2/MSYS2-packages#1967 --- appveyor.yml | 33 +++++++++++-------------------- build/appveyor-msys2-upgrade.bash | 10 ++++++++++ 2 files changed, 22 insertions(+), 21 deletions(-) create mode 100644 build/appveyor-msys2-upgrade.bash diff --git a/appveyor.yml b/appveyor.yml index d6dcf060..45a16dd8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,34 +14,25 @@ environment: CHERE_INVOKING: enabled_from_arguments matrix: - MSYSTEM: MINGW64 + MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc + MSYS_BITNESS: 64 - MSYSTEM: MINGW32 + MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc + MSYS_BITNESS: 32 install: - 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" +# TODO: revert that change when appveyor's images will be updated +- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" +# update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" - -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" - -- if "%MSYSTEM%" == "MINGW64" ( - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" - ) else ( - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-boost mingw-w64-i686-miniupnpc" - ) - -- if "%MSYSTEM%" == "MINGW64" ( - set "bitness=64" - ) else ( - set "bitness=32" - ) +# update packages and install required +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" build_script: -- cmd: >- - cd \projects\i2pd - - echo MSYSTEM = %MSYSTEM%, bitness = %bitness% - -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j2" -- 7z a -tzip -mx9 -mmt i2pd-mingw-win%bitness%.zip i2pd.exe +- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS% +- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3" +- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe test: off diff --git a/build/appveyor-msys2-upgrade.bash b/build/appveyor-msys2-upgrade.bash new file mode 100644 index 00000000..20c6af69 --- /dev/null +++ b/build/appveyor-msys2-upgrade.bash @@ -0,0 +1,10 @@ +set -e -x + +base_url='http://repo.msys2.org/msys/x86_64/' +packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz" +for p in $packages +do + curl "${base_url}$p" -o "$p" +done +pacman -U --noconfirm $packages +rm -f $packages From 9633c247f0ebf4c0613fea92b4a1b59795f6f2c4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 19:34:42 +0300 Subject: [PATCH 130/189] [readme] update docker badges --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 25e6c3e5..ec7548f0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE) [![Packaging status](https://repology.org/badge/tiny-repos/i2pd.svg)](https://repology.org/project/i2pd/versions) +[![Docker Pulls](https://img.shields.io/docker/pulls/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd) i2pd ==== @@ -68,7 +69,7 @@ Build instructions: * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. * Windows - [![Build status](https://ci.appveyor.com/api/projects/status/1908qe4p48ff1x23?svg=true)](https://ci.appveyor.com/project/PurpleI2P/i2pd) * Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) -* Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/) +* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) * Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap) * FreeBSD * Android From 7a5146ea7455136d507843c2180a3761ab401bc7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 1 Mar 2020 13:25:50 +0300 Subject: [PATCH 131/189] fix code syle(spaces->tabs, tabulations) Signed-off-by: R4SAS --- Win32/DaemonWin32.cpp | 4 +- Win32/Win32App.cpp | 910 +++++++++++----------- Win32/Win32App.h | 34 +- Win32/Win32Service.h | 70 +- Win32/resource.h | 22 +- daemon/Daemon.cpp | 45 +- daemon/Daemon.h | 14 +- daemon/HTTPServer.cpp | 4 +- daemon/HTTPServer.h | 22 +- daemon/I2PControl.cpp | 49 +- daemon/I2PControl.h | 1 + daemon/UPnP.cpp | 44 +- daemon/UPnP.h | 60 +- daemon/UnixDaemon.cpp | 1 - daemon/i2pd.cpp | 3 +- libi2pd/Base.cpp | 214 ++--- libi2pd/Base.h | 12 +- libi2pd/Blinding.cpp | 79 +- libi2pd/Blinding.h | 8 +- libi2pd/CPU.h | 6 +- libi2pd/ChaCha20.cpp | 115 ++- libi2pd/ChaCha20.h | 30 +- libi2pd/Config.cpp | 2 +- libi2pd/Config.h | 169 ++-- libi2pd/Crypto.cpp | 118 ++- libi2pd/Crypto.h | 30 +- libi2pd/CryptoKey.cpp | 7 +- libi2pd/CryptoKey.h | 13 +- libi2pd/CryptoWorker.h | 1 - libi2pd/Datagram.cpp | 32 +- libi2pd/Datagram.h | 97 +-- libi2pd/Destination.cpp | 119 ++- libi2pd/Destination.h | 31 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 752 +++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 164 ++-- libi2pd/Ed25519.cpp | 43 +- libi2pd/Ed25519.h | 14 +- libi2pd/Elligator.cpp | 87 +-- libi2pd/Elligator.h | 6 +- libi2pd/FS.h | 221 +++--- libi2pd/Family.cpp | 1 - libi2pd/Garlic.cpp | 188 ++--- libi2pd/Garlic.h | 106 +-- libi2pd/Gost.h | 8 +- libi2pd/Gzip.cpp | 26 +- libi2pd/Gzip.h | 5 +- libi2pd/I2NPProtocol.cpp | 28 +- libi2pd/I2NPProtocol.h | 6 +- libi2pd/Identity.cpp | 50 +- libi2pd/Identity.h | 13 +- libi2pd/LeaseSet.cpp | 224 +++--- libi2pd/LeaseSet.h | 39 +- libi2pd/LittleBigEndian.h | 324 ++++---- libi2pd/Log.cpp | 24 +- libi2pd/Log.h | 6 +- libi2pd/NTCP2.cpp | 20 +- libi2pd/NTCP2.h | 1 - libi2pd/NTCPSession.cpp | 15 +- libi2pd/NetDb.cpp | 28 +- libi2pd/NetDb.hpp | 37 +- libi2pd/NetDbRequests.cpp | 5 +- libi2pd/NetDbRequests.h | 1 - libi2pd/Poly1305.cpp | 3 +- libi2pd/Poly1305.h | 15 +- libi2pd/Reseed.cpp | 120 +-- libi2pd/Reseed.h | 2 +- libi2pd/RouterContext.cpp | 8 +- libi2pd/RouterContext.h | 14 +- libi2pd/RouterInfo.cpp | 54 +- libi2pd/RouterInfo.h | 4 +- libi2pd/SSU.cpp | 23 +- libi2pd/SSU.h | 3 +- libi2pd/SSUData.cpp | 3 +- libi2pd/SSUData.h | 1 - libi2pd/SSUSession.cpp | 5 +- libi2pd/SSUSession.h | 9 +- libi2pd/Signature.cpp | 52 +- libi2pd/Signature.h | 61 +- libi2pd/Siphash.h | 238 +++--- libi2pd/Streaming.cpp | 54 +- libi2pd/Tag.h | 142 ++-- libi2pd/Timestamp.cpp | 13 +- libi2pd/Timestamp.h | 13 +- libi2pd/TransitTunnel.cpp | 4 +- libi2pd/TransportSession.h | 8 +- libi2pd/Transports.cpp | 14 +- libi2pd/Transports.h | 20 +- libi2pd/TunnelEndpoint.cpp | 3 +- libi2pd/TunnelGateway.cpp | 5 +- libi2pd/TunnelPool.cpp | 12 +- libi2pd/TunnelPool.h | 24 +- libi2pd/api.cpp | 5 +- libi2pd/api.h | 1 - libi2pd/util.cpp | 51 +- libi2pd/util.h | 16 +- libi2pd_client/AddressBook.cpp | 62 +- libi2pd_client/AddressBook.h | 6 +- libi2pd_client/BOB.cpp | 50 +- libi2pd_client/BOB.h | 27 +- libi2pd_client/ClientContext.cpp | 64 +- libi2pd_client/ClientContext.h | 10 +- libi2pd_client/HTTPProxy.cpp | 12 +- libi2pd_client/HTTPProxy.h | 3 + libi2pd_client/I2CP.cpp | 53 +- libi2pd_client/I2CP.h | 9 +- libi2pd_client/I2PService.cpp | 22 +- libi2pd_client/I2PService.h | 26 +- libi2pd_client/I2PTunnel.cpp | 12 +- libi2pd_client/I2PTunnel.h | 36 +- libi2pd_client/MatchedDestination.cpp | 8 +- libi2pd_client/MatchedDestination.h | 32 +- libi2pd_client/SAM.cpp | 99 ++- libi2pd_client/SAM.h | 17 +- libi2pd_client/SOCKS.cpp | 9 +- libi2pd_client/SOCKS.h | 2 + 115 files changed, 3206 insertions(+), 3161 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 5524aff3..7ba3ffc3 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -27,8 +27,8 @@ namespace util i2p::log::SetThrowFunction ([](const std::string& s) { MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); - }); - + }); + if (!Daemon_Singleton::init(argc, argv)) return false; diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 7ae4e419..3bcb24b3 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,455 +1,455 @@ -#include -#include -#include -#include -#include "ClientContext.h" -#include "Config.h" -#include "NetDb.hpp" -#include "RouterContext.h" -#include "Transports.h" -#include "Tunnel.h" -#include "version.h" -#include "resource.h" -#include "Daemon.h" -#include "Win32App.h" -#include "Win32NetState.h" - -#define ID_ABOUT 2000 -#define ID_EXIT 2001 -#define ID_CONSOLE 2002 -#define ID_APP 2003 -#define ID_GRACEFUL_SHUTDOWN 2004 -#define ID_STOP_GRACEFUL_SHUTDOWN 2005 -#define ID_RELOAD 2006 -#define ID_ACCEPT_TRANSIT 2007 -#define ID_DECLINE_TRANSIT 2008 - -#define ID_TRAY_ICON 2050 -#define WM_TRAYICON (WM_USER + 1) - -#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100 -#define FRAME_UPDATE_TIMER 2101 -#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102 - -namespace i2p -{ -namespace win32 -{ - static DWORD GracefulShutdownEndtime = 0; - - typedef DWORD (* IPN)(); - IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); - - static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) - { - HMENU hPopup = CreatePopupMenu(); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); - if(!i2p::context.AcceptsTunnels()) - InsertMenu (hPopup, -1, - i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING, - ID_ACCEPT_TRANSIT, "Accept &transit"); - else - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config"); - if (!i2p::util::DaemonWin32::Instance ().isGraceful) - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); - else - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); - SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); - SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); - - POINT p; - if (!curpos) - { - GetCursorPos (&p); - curpos = &p; - } - - WORD cmd = TrackPopupMenu (hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, curpos->x, curpos->y, 0, hWnd, NULL); - SendMessage (hWnd, WM_COMMAND, cmd, 0); - - DestroyMenu(hPopup); - } - - static void AddTrayIcon (HWND hWnd) - { - NOTIFYICONDATA nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = hWnd; - nid.uID = ID_TRAY_ICON; - nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; - nid.uCallbackMessage = WM_TRAYICON; - nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); - strcpy (nid.szTip, "i2pd"); - strcpy (nid.szInfo, "i2pd is starting"); - Shell_NotifyIcon(NIM_ADD, &nid ); - } - - static void RemoveTrayIcon (HWND hWnd) - { - NOTIFYICONDATA nid; - nid.hWnd = hWnd; - nid.uID = ID_TRAY_ICON; - Shell_NotifyIcon (NIM_DELETE, &nid); - } - - static void ShowUptime (std::stringstream& s, int seconds) - { - int num; - - if ((num = seconds / 86400) > 0) { - s << num << " days, "; - seconds -= num * 86400; - } - if ((num = seconds / 3600) > 0) { - s << num << " hours, "; - seconds -= num * 3600; - } - if ((num = seconds / 60) > 0) { - s << num << " min, "; - seconds -= num * 60; - } - s << seconds << " seconds\n"; - } - - template static void ShowTransfered (std::stringstream& s, size transfer) - { - auto bytes = transfer & 0x03ff; - transfer >>= 10; - auto kbytes = transfer & 0x03ff; - transfer >>= 10; - auto mbytes = transfer & 0x03ff; - transfer >>= 10; - auto gbytes = transfer & 0x03ff; - - if (gbytes) - s << gbytes << " GB, "; - if (mbytes) - s << mbytes << " MB, "; - if (kbytes) - s << kbytes << " KB, "; - s << bytes << " Bytes\n"; - } - - static void PrintMainWindowText (std::stringstream& s) - { - s << "\n"; - s << "Status: "; - switch (i2p::context.GetStatus()) - { - case eRouterStatusOK: s << "OK"; break; - case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - case eRouterStatusError: - { - switch (i2p::context.GetError()) - { - case eRouterErrorClockSkew: s << "Clock skew"; break; - default: s << "Error"; - } - break; - } - default: s << "Unknown"; - } - s << "; "; - s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; - s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); - if (GracefulShutdownEndtime != 0) - { - DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; - s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); - } - else - s << "\n"; - s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; "; - s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n"; - s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes()); - s << "Sent: "; ShowTransfered (s, i2p::transport::transports.GetTotalSentBytes()); - s << "\n"; - s << "Routers: " << i2p::data::netdb.GetNumRouters () << "; "; - s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << "; "; - s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "\n"; - s << "Tunnels: "; - s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; "; - s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; "; - s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n"; - s << "\n"; - } - - static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - static UINT s_uTaskbarRestart; - - switch (uMsg) - { - case WM_CREATE: - { - s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); - AddTrayIcon (hWnd); - break; - } - case WM_CLOSE: - { - RemoveTrayIcon (hWnd); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); - PostQuitMessage (0); - break; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case ID_ABOUT: - { - std::stringstream text; - text << "Version: " << I2PD_VERSION << " " << CODENAME; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_EXIT: - { - PostMessage (hWnd, WM_CLOSE, 0, 0); - return 0; - } - case ID_ACCEPT_TRANSIT: - { - i2p::context.SetAcceptsTunnels (true); - std::stringstream text; - text << "I2Pd now accept transit tunnels"; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_DECLINE_TRANSIT: - { - i2p::context.SetAcceptsTunnels (false); - std::stringstream text; - text << "I2Pd now decline new transit tunnels"; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_GRACEFUL_SHUTDOWN: - { - i2p::context.SetAcceptsTunnels (false); - SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes - SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second - GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; - i2p::util::DaemonWin32::Instance ().isGraceful = true; - return 0; - } - case ID_STOP_GRACEFUL_SHUTDOWN: - { - i2p::context.SetAcceptsTunnels (true); - KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); - GracefulShutdownEndtime = 0; - i2p::util::DaemonWin32::Instance ().isGraceful = false; - return 0; - } - case ID_RELOAD: - { - i2p::client::context.ReloadConfig(); - std::stringstream text; - text << "I2Pd reloading configs..."; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_CONSOLE: - { - char buf[30]; - std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); - ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL); - return 0; - } - case ID_APP: - { - ShowWindow(hWnd, SW_SHOW); - SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); - return 0; - } - } - break; - } - case WM_SYSCOMMAND: - { - switch (wParam) - { - case SC_MINIMIZE: - { - ShowWindow(hWnd, SW_HIDE); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - return 0; - } - case SC_CLOSE: - { - std::string close; i2p::config::GetOption("close", close); - if (0 == close.compare("ask")) - switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?" - " You can add 'close' configuration option. Valid values are: ask, minimize, exit.", - "Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1)) - { - case IDYES: close = "minimize"; break; - case IDNO: close = "exit"; break; - default: return 0; - } - if (0 == close.compare("minimize")) - { - ShowWindow(hWnd, SW_HIDE); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - return 0; - } - if (0 != close.compare("exit")) - { - ::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING); - return 0; - } - } - } - } - case WM_TRAYICON: - { - switch (lParam) - { - case WM_LBUTTONUP: - case WM_RBUTTONUP: - { - SetForegroundWindow (hWnd); - ShowPopupMenu(hWnd, NULL, -1); - PostMessage (hWnd, WM_APP + 1, 0, 0); - break; - } - } - break; - } - case WM_TIMER: - { - switch(wParam) - { - case IDT_GRACEFUL_SHUTDOWN_TIMER: - { - GracefulShutdownEndtime = 0; - PostMessage (hWnd, WM_CLOSE, 0, 0); // exit - return 0; - } - case IDT_GRACEFUL_TUNNELCHECK_TIMER: - { - if (i2p::tunnel::tunnels.CountTransitTunnels() == 0) - PostMessage (hWnd, WM_CLOSE, 0, 0); - else - SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); - return 0; - } - case FRAME_UPDATE_TIMER: - { - InvalidateRect(hWnd, NULL, TRUE); - return 0; - } - } - break; - } - case WM_PAINT: - { - HDC hDC; - PAINTSTRUCT ps; - RECT rp; - HFONT hFont; - std::stringstream s; PrintMainWindowText (s); - hDC = BeginPaint (hWnd, &ps); - GetClientRect(hWnd, &rp); - SetTextColor(hDC, 0x00D43B69); - hFont = CreateFont(18,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,TEXT("Times New Roman")); - SelectObject(hDC,hFont); - DrawText(hDC, TEXT(s.str().c_str()), s.str().length(), &rp, DT_CENTER|DT_VCENTER); - DeleteObject(hFont); - EndPaint(hWnd, &ps); - break; - } - default: - { - if (uMsg == s_uTaskbarRestart) - AddTrayIcon (hWnd); - break; - } - } - return DefWindowProc( hWnd, uMsg, wParam, lParam); - } - - bool StartWin32App () - { - if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"))) - { - MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK); - return false; - } - // register main window - auto hInst = GetModuleHandle(NULL); - WNDCLASSEX wclx; - memset (&wclx, 0, sizeof(wclx)); - wclx.cbSize = sizeof(wclx); - wclx.style = 0; - wclx.lpfnWndProc = WndProc; - //wclx.cbClsExtra = 0; - //wclx.cbWndExtra = 0; - wclx.hInstance = hInst; - wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON)); - wclx.hCursor = LoadCursor (NULL, IDC_ARROW); - //wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wclx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wclx.lpszMenuName = NULL; - wclx.lpszClassName = I2PD_WIN32_CLASSNAME; - RegisterClassEx (&wclx); - // create new window - if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL)) - { - MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); - return false; - } - SubscribeToEvents(); - return true; - } - - int RunWin32App () - { - MSG msg; - while (GetMessage (&msg, NULL, 0, 0 )) - { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - return msg.wParam; - } - - void StopWin32App () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); - // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app - UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); - } - - bool GracefulShutdown () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); - return hWnd; - } - - bool StopGracefulShutdown () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); - return hWnd; - } -} -} +#include +#include +#include +#include +#include "ClientContext.h" +#include "Config.h" +#include "NetDb.hpp" +#include "RouterContext.h" +#include "Transports.h" +#include "Tunnel.h" +#include "version.h" +#include "resource.h" +#include "Daemon.h" +#include "Win32App.h" +#include "Win32NetState.h" + +#define ID_ABOUT 2000 +#define ID_EXIT 2001 +#define ID_CONSOLE 2002 +#define ID_APP 2003 +#define ID_GRACEFUL_SHUTDOWN 2004 +#define ID_STOP_GRACEFUL_SHUTDOWN 2005 +#define ID_RELOAD 2006 +#define ID_ACCEPT_TRANSIT 2007 +#define ID_DECLINE_TRANSIT 2008 + +#define ID_TRAY_ICON 2050 +#define WM_TRAYICON (WM_USER + 1) + +#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100 +#define FRAME_UPDATE_TIMER 2101 +#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102 + +namespace i2p +{ +namespace win32 +{ + static DWORD GracefulShutdownEndtime = 0; + + typedef DWORD (* IPN)(); + IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); + + static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) + { + HMENU hPopup = CreatePopupMenu(); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); + if(!i2p::context.AcceptsTunnels()) + InsertMenu (hPopup, -1, + i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING, + ID_ACCEPT_TRANSIT, "Accept &transit"); + else + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config"); + if (!i2p::util::DaemonWin32::Instance ().isGraceful) + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); + else + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); + SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); + SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); + + POINT p; + if (!curpos) + { + GetCursorPos (&p); + curpos = &p; + } + + WORD cmd = TrackPopupMenu (hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, curpos->x, curpos->y, 0, hWnd, NULL); + SendMessage (hWnd, WM_COMMAND, cmd, 0); + + DestroyMenu(hPopup); + } + + static void AddTrayIcon (HWND hWnd) + { + NOTIFYICONDATA nid; + memset(&nid, 0, sizeof(nid)); + nid.cbSize = sizeof(nid); + nid.hWnd = hWnd; + nid.uID = ID_TRAY_ICON; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); + strcpy (nid.szTip, "i2pd"); + strcpy (nid.szInfo, "i2pd is starting"); + Shell_NotifyIcon(NIM_ADD, &nid ); + } + + static void RemoveTrayIcon (HWND hWnd) + { + NOTIFYICONDATA nid; + nid.hWnd = hWnd; + nid.uID = ID_TRAY_ICON; + Shell_NotifyIcon (NIM_DELETE, &nid); + } + + static void ShowUptime (std::stringstream& s, int seconds) + { + int num; + + if ((num = seconds / 86400) > 0) { + s << num << " days, "; + seconds -= num * 86400; + } + if ((num = seconds / 3600) > 0) { + s << num << " hours, "; + seconds -= num * 3600; + } + if ((num = seconds / 60) > 0) { + s << num << " min, "; + seconds -= num * 60; + } + s << seconds << " seconds\n"; + } + + template static void ShowTransfered (std::stringstream& s, size transfer) + { + auto bytes = transfer & 0x03ff; + transfer >>= 10; + auto kbytes = transfer & 0x03ff; + transfer >>= 10; + auto mbytes = transfer & 0x03ff; + transfer >>= 10; + auto gbytes = transfer & 0x03ff; + + if (gbytes) + s << gbytes << " GB, "; + if (mbytes) + s << mbytes << " MB, "; + if (kbytes) + s << kbytes << " KB, "; + s << bytes << " Bytes\n"; + } + + static void PrintMainWindowText (std::stringstream& s) + { + s << "\n"; + s << "Status: "; + switch (i2p::context.GetStatus()) + { + case eRouterStatusOK: s << "OK"; break; + case eRouterStatusTesting: s << "Testing"; break; + case eRouterStatusFirewalled: s << "Firewalled"; break; + case eRouterStatusError: + { + switch (i2p::context.GetError()) + { + case eRouterErrorClockSkew: s << "Clock skew"; break; + default: s << "Error"; + } + break; + } + default: s << "Unknown"; + } + s << "; "; + s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; + s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); + if (GracefulShutdownEndtime != 0) + { + DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; + s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); + } + else + s << "\n"; + s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; "; + s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n"; + s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes()); + s << "Sent: "; ShowTransfered (s, i2p::transport::transports.GetTotalSentBytes()); + s << "\n"; + s << "Routers: " << i2p::data::netdb.GetNumRouters () << "; "; + s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << "; "; + s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "\n"; + s << "Tunnels: "; + s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; "; + s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; "; + s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n"; + s << "\n"; + } + + static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + static UINT s_uTaskbarRestart; + + switch (uMsg) + { + case WM_CREATE: + { + s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + AddTrayIcon (hWnd); + break; + } + case WM_CLOSE: + { + RemoveTrayIcon (hWnd); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); + PostQuitMessage (0); + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_ABOUT: + { + std::stringstream text; + text << "Version: " << I2PD_VERSION << " " << CODENAME; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_EXIT: + { + PostMessage (hWnd, WM_CLOSE, 0, 0); + return 0; + } + case ID_ACCEPT_TRANSIT: + { + i2p::context.SetAcceptsTunnels (true); + std::stringstream text; + text << "I2Pd now accept transit tunnels"; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_DECLINE_TRANSIT: + { + i2p::context.SetAcceptsTunnels (false); + std::stringstream text; + text << "I2Pd now decline new transit tunnels"; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (false); + SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes + SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second + GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; + i2p::util::DaemonWin32::Instance ().isGraceful = true; + return 0; + } + case ID_STOP_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (true); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); + GracefulShutdownEndtime = 0; + i2p::util::DaemonWin32::Instance ().isGraceful = false; + return 0; + } + case ID_RELOAD: + { + i2p::client::context.ReloadConfig(); + std::stringstream text; + text << "I2Pd reloading configs..."; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_CONSOLE: + { + char buf[30]; + std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); + ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL); + return 0; + } + case ID_APP: + { + ShowWindow(hWnd, SW_SHOW); + SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); + return 0; + } + } + break; + } + case WM_SYSCOMMAND: + { + switch (wParam) + { + case SC_MINIMIZE: + { + ShowWindow(hWnd, SW_HIDE); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + return 0; + } + case SC_CLOSE: + { + std::string close; i2p::config::GetOption("close", close); + if (0 == close.compare("ask")) + switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?" + " You can add 'close' configuration option. Valid values are: ask, minimize, exit.", + "Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1)) + { + case IDYES: close = "minimize"; break; + case IDNO: close = "exit"; break; + default: return 0; + } + if (0 == close.compare("minimize")) + { + ShowWindow(hWnd, SW_HIDE); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + return 0; + } + if (0 != close.compare("exit")) + { + ::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING); + return 0; + } + } + } + } + case WM_TRAYICON: + { + switch (lParam) + { + case WM_LBUTTONUP: + case WM_RBUTTONUP: + { + SetForegroundWindow (hWnd); + ShowPopupMenu(hWnd, NULL, -1); + PostMessage (hWnd, WM_APP + 1, 0, 0); + break; + } + } + break; + } + case WM_TIMER: + { + switch(wParam) + { + case IDT_GRACEFUL_SHUTDOWN_TIMER: + { + GracefulShutdownEndtime = 0; + PostMessage (hWnd, WM_CLOSE, 0, 0); // exit + return 0; + } + case IDT_GRACEFUL_TUNNELCHECK_TIMER: + { + if (i2p::tunnel::tunnels.CountTransitTunnels() == 0) + PostMessage (hWnd, WM_CLOSE, 0, 0); + else + SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); + return 0; + } + case FRAME_UPDATE_TIMER: + { + InvalidateRect(hWnd, NULL, TRUE); + return 0; + } + } + break; + } + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + RECT rp; + HFONT hFont; + std::stringstream s; PrintMainWindowText (s); + hDC = BeginPaint (hWnd, &ps); + GetClientRect(hWnd, &rp); + SetTextColor(hDC, 0x00D43B69); + hFont = CreateFont(18,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,TEXT("Times New Roman")); + SelectObject(hDC,hFont); + DrawText(hDC, TEXT(s.str().c_str()), s.str().length(), &rp, DT_CENTER|DT_VCENTER); + DeleteObject(hFont); + EndPaint(hWnd, &ps); + break; + } + default: + { + if (uMsg == s_uTaskbarRestart) + AddTrayIcon (hWnd); + break; + } + } + return DefWindowProc( hWnd, uMsg, wParam, lParam); + } + + bool StartWin32App () + { + if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"))) + { + MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK); + return false; + } + // register main window + auto hInst = GetModuleHandle(NULL); + WNDCLASSEX wclx; + memset (&wclx, 0, sizeof(wclx)); + wclx.cbSize = sizeof(wclx); + wclx.style = 0; + wclx.lpfnWndProc = WndProc; + //wclx.cbClsExtra = 0; + //wclx.cbWndExtra = 0; + wclx.hInstance = hInst; + wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON)); + wclx.hCursor = LoadCursor (NULL, IDC_ARROW); + //wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wclx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wclx.lpszMenuName = NULL; + wclx.lpszClassName = I2PD_WIN32_CLASSNAME; + RegisterClassEx (&wclx); + // create new window + if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL)) + { + MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); + return false; + } + SubscribeToEvents(); + return true; + } + + int RunWin32App () + { + MSG msg; + while (GetMessage (&msg, NULL, 0, 0 )) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + return msg.wParam; + } + + void StopWin32App () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); + // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app + UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); + } + + bool GracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } + + bool StopGracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } +} +} diff --git a/Win32/Win32App.h b/Win32/Win32App.h index b230eb06..23082842 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -1,17 +1,17 @@ -#ifndef WIN32APP_H__ -#define WIN32APP_H__ - -#define I2PD_WIN32_CLASSNAME "i2pd main window" - -namespace i2p -{ -namespace win32 -{ - bool StartWin32App (); - void StopWin32App (); - int RunWin32App (); - bool GracefulShutdown (); - bool StopGracefulShutdown (); -} -} -#endif // WIN32APP_H__ +#ifndef WIN32APP_H__ +#define WIN32APP_H__ + +#define I2PD_WIN32_CLASSNAME "i2pd main window" + +namespace i2p +{ +namespace win32 +{ + bool StartWin32App (); + void StopWin32App (); + int RunWin32App (); + bool GracefulShutdown (); + bool StopGracefulShutdown (); +} +} +#endif // WIN32APP_H__ diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 2830d237..05a6b9f9 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -26,48 +26,48 @@ class I2PService { -public: + public: - I2PService(PSTR pszServiceName, - BOOL fCanStop = TRUE, - BOOL fCanShutdown = TRUE, - BOOL fCanPauseContinue = FALSE); + I2PService(PSTR pszServiceName, + BOOL fCanStop = TRUE, + BOOL fCanShutdown = TRUE, + BOOL fCanPauseContinue = FALSE); - virtual ~I2PService(void); + virtual ~I2PService(void); - static BOOL isService(); - static BOOL Run(I2PService &service); - void Stop(); + static BOOL isService(); + static BOOL Run(I2PService &service); + void Stop(); -protected: + protected: - virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); - virtual void OnStop(); - virtual void OnPause(); - virtual void OnContinue(); - virtual void OnShutdown(); - void SetServiceStatus(DWORD dwCurrentState, - DWORD dwWin32ExitCode = NO_ERROR, - DWORD dwWaitHint = 0); + virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); + virtual void OnStop(); + virtual void OnPause(); + virtual void OnContinue(); + virtual void OnShutdown(); + void SetServiceStatus(DWORD dwCurrentState, + DWORD dwWin32ExitCode = NO_ERROR, + DWORD dwWaitHint = 0); -private: + private: - static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv); - static void WINAPI ServiceCtrlHandler(DWORD dwCtrl); - void WorkerThread(); - void Start(DWORD dwArgc, PSTR *pszArgv); - void Pause(); - void Continue(); - void Shutdown(); - static I2PService* s_service; - PSTR m_name; - SERVICE_STATUS m_status; - SERVICE_STATUS_HANDLE m_statusHandle; + static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv); + static void WINAPI ServiceCtrlHandler(DWORD dwCtrl); + void WorkerThread(); + void Start(DWORD dwArgc, PSTR *pszArgv); + void Pause(); + void Continue(); + void Shutdown(); + static I2PService* s_service; + PSTR m_name; + SERVICE_STATUS m_status; + SERVICE_STATUS_HANDLE m_statusHandle; - BOOL m_fStopping; - HANDLE m_hStoppedEvent; + BOOL m_fStopping; + HANDLE m_hStoppedEvent; - std::thread* _worker; + std::thread* _worker; }; void InstallService( @@ -77,8 +77,8 @@ void InstallService( PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword - ); +); void UninstallService(PCSTR pszServiceName); -#endif // WIN_32_SERVICE_H__ \ No newline at end of file +#endif // WIN_32_SERVICE_H__ diff --git a/Win32/resource.h b/Win32/resource.h index 3b188481..daa1ddcb 100644 --- a/Win32/resource.h +++ b/Win32/resource.h @@ -1,11 +1,11 @@ -//{{NO_DEPENDENCIES}} -#define MAINICON 101 - -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +#define MAINICON 101 + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index fc71123f..dd302fce 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -127,8 +127,8 @@ namespace i2p i2p::context.SetNetID (netID); i2p::context.Init (); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + bool ipv6; i2p::config::GetOption("ipv6", ipv6); + bool ipv4; i2p::config::GetOption("ipv4", ipv4); #ifdef MESHNET // manual override for meshnet ipv4 = false; @@ -143,8 +143,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + i2p::context.PublishNTCPAddress (ntcp, !ipv6); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -172,10 +172,13 @@ namespace i2p SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (isFloodfill) { + if (isFloodfill) + { LogPrint(eLogInfo, "Daemon: router will be floodfill"); i2p::context.SetFloodfill (true); - } else { + } + else + { i2p::context.SetFloodfill (false); } @@ -243,7 +246,8 @@ namespace i2p i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } - if (routers.length() > 0) { + if (routers.length() > 0) + { std::set idents; size_t pos = 0, comma; do @@ -279,7 +283,8 @@ namespace i2p i2p::data::netdb.Start(); bool upnp; i2p::config::GetOption("upnp.enabled", upnp); - if (upnp) { + if (upnp) + { d.UPnP = std::unique_ptr(new i2p::transport::UPnP); d.UPnP->Start (); } @@ -292,15 +297,15 @@ namespace i2p } bool ntcp; i2p::config::GetOption("ntcp", ntcp); - bool ssu; i2p::config::GetOption("ssu", ssu); + bool ssu; i2p::config::GetOption("ssu", ssu); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled"); i2p::transport::transports.Start(ntcp, ssu); - if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ @@ -310,23 +315,23 @@ namespace i2p } bool http; i2p::config::GetOption("http.enabled", http); - if (http) { + if (http) + { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try + try { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } - LogPrint(eLogInfo, "Daemon: starting Tunnels"); i2p::tunnel::tunnels.Start(); @@ -339,12 +344,12 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try + try { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); @@ -361,7 +366,7 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping Tunnels"); i2p::tunnel::tunnels.Stop(); - if (d.UPnP) + if (d.UPnP) { d.UPnP->Stop (); d.UPnP = nullptr; diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 1745b980..050cc7e8 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -13,9 +13,10 @@ namespace util class Daemon_Singleton { public: - virtual bool init(int argc, char* argv[], std::shared_ptr logstream); - virtual bool init(int argc, char* argv[]); - virtual bool start(); + + virtual bool init(int argc, char* argv[], std::shared_ptr logstream); + virtual bool init(int argc, char* argv[]); + virtual bool start(); virtual bool stop(); virtual void run () {}; @@ -23,6 +24,7 @@ namespace util bool running; protected: + Daemon_Singleton(); virtual ~Daemon_Singleton(); @@ -39,6 +41,7 @@ namespace util class DaemonQT: public i2p::util::Daemon_Singleton { public: + static DaemonQT& Instance() { static DaemonQT instance; @@ -51,6 +54,7 @@ namespace util class DaemonWin32 : public Daemon_Singleton { public: + static DaemonWin32& Instance() { static DaemonWin32 instance; @@ -72,6 +76,7 @@ namespace util class DaemonAndroid: public i2p::util::Daemon_Singleton { public: + static DaemonAndroid& Instance() { static DaemonAndroid instance; @@ -83,6 +88,7 @@ namespace util class DaemonLinux : public Daemon_Singleton { public: + static DaemonLinux& Instance() { static DaemonLinux instance; @@ -94,10 +100,12 @@ namespace util void run (); private: + std::string pidfile; int pidFH; public: + int gracefulShutdownInterval; // in seconds }; #endif diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index de052a2b..6f903e7e 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -892,8 +892,8 @@ namespace http { void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), - std::bind(&HTTPConnection::HandleReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&HTTPConnection::HandleReceive, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); } void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index abc4fea5..fe62c271 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -79,17 +79,17 @@ namespace http std::string m_Hostname; }; - //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml - enum OutputFormatEnum { forWebConsole, forQtUi }; - void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat); - void ShowLocalDestinations (std::stringstream& s); - void ShowLeasesSets(std::stringstream& s); - void ShowTunnels (std::stringstream& s); - void ShowTransitTunnels (std::stringstream& s); - void ShowTransports (std::stringstream& s); - void ShowSAMSessions (std::stringstream& s); - void ShowI2PTunnels (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); + //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml + enum OutputFormatEnum { forWebConsole, forQtUi }; + void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat); + void ShowLocalDestinations (std::stringstream& s); + void ShowLeasesSets(std::stringstream& s); + void ShowTunnels (std::stringstream& s); + void ShowTransitTunnels (std::stringstream& s); + void ShowTransports (std::stringstream& s); + void ShowSAMSessions (std::stringstream& s); + void ShowI2PTunnels (std::stringstream& s); + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); } // http } // i2p diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index acf054f1..fb00dc29 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -59,29 +59,28 @@ namespace client m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem); // handlers - m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; - m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; - m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; - m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; - m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; - m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; - m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; + m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; + m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; + m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; + m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; + m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; + m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; + m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; // I2PControl m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; // RouterInfo - m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; - m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; - m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; - m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; - m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; - m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; + m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; + m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; + m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; + m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; + m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; + m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; - m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = -&I2PControlService::TunnelsSuccessRateHandler; + m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; @@ -97,10 +96,10 @@ namespace client // ClientServicesInfo m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; - m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; - m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; - m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; - m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; + m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; + m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; + m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; + m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; } I2PControlService::~I2PControlService () @@ -401,8 +400,8 @@ namespace client auto it1 = m_RouterInfoHandlers.find (it->first); if (it1 != m_RouterInfoHandlers.end ()) { - if (!first) results << ","; - else first = false; + if (!first) results << ","; + else first = false; (this->*(it1->second))(results); } else @@ -500,7 +499,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } @@ -514,7 +513,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index 3233ad12..eb28af76 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -27,6 +27,7 @@ namespace client class I2PControlService { typedef boost::asio::ssl::stream ssl_socket; + public: I2PControlService (const std::string& address, int port); diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index b2ebb005..92e79c11 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -80,10 +80,10 @@ namespace transport void UPnP::Discover () { bool isError; - int err; + int err; #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) - err = UPNPDISCOVER_SUCCESS; + err = UPNPDISCOVER_SUCCESS; #if (MINIUPNPC_API_VERSION >= 14) m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err); @@ -92,9 +92,9 @@ namespace transport #endif isError = err != UPNPDISCOVER_SUCCESS; -#else // MINIUPNPC_API_VERSION >= 8 - err = 0; - m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); +#else // MINIUPNPC_API_VERSION >= 8 + err = 0; + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); isError = m_Devlist == NULL; #endif // MINIUPNPC_API_VERSION >= 8 { @@ -105,15 +105,15 @@ namespace transport if (isError) { - LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); + LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); return; } err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); - m_upnpUrlsInitialized=err!=0; + m_upnpUrlsInitialized = err != 0; if (err == UPNP_IGD_VALID_CONNECTED) { - err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(err != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: unable to get external address: error ", err); @@ -124,14 +124,14 @@ namespace transport LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL); if (!m_externalIPAddress[0]) { - LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); + LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); return; } } } else { - LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); + LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); return; } @@ -182,7 +182,7 @@ namespace transport err = CheckMapping (strPort.c_str (), strType.c_str ()); if (err != UPNPCOMMAND_SUCCESS) // if mapping not found { - LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); + LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL); @@ -202,7 +202,7 @@ namespace transport } else { - LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); + LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); return; } } @@ -219,14 +219,14 @@ namespace transport void UPnP::CloseMapping (std::shared_ptr address) { - if(!m_upnpUrlsInitialized) { - return; - } + if(!m_upnpUrlsInitialized) { + return; + } std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int err = UPNPCOMMAND_SUCCESS; - + err = CheckMapping (strPort.c_str (), strType.c_str ()); - if (err == UPNPCOMMAND_SUCCESS) + if (err == UPNPCOMMAND_SUCCESS) { err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err); @@ -237,11 +237,11 @@ namespace transport { freeUPNPDevlist (m_Devlist); m_Devlist = 0; - if(m_upnpUrlsInitialized){ - FreeUPNPUrls (&m_upnpUrls); - m_upnpUrlsInitialized=false; - } - } + if(m_upnpUrlsInitialized){ + FreeUPNPUrls (&m_upnpUrls); + m_upnpUrlsInitialized=false; + } + } std::string UPnP::GetProto (std::shared_ptr address) { diff --git a/daemon/UPnP.h b/daemon/UPnP.h index e66f0aff..29f9e3e6 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -33,41 +33,41 @@ namespace transport { public: - UPnP (); - ~UPnP (); - void Close (); + UPnP (); + ~UPnP (); + void Close (); - void Start (); - void Stop (); + void Start (); + void Stop (); private: - void Discover (); - int CheckMapping (const char* port, const char* type); - void PortMapping (); - void TryPortMapping (std::shared_ptr address); - void CloseMapping (); - void CloseMapping (std::shared_ptr address); + void Discover (); + int CheckMapping (const char* port, const char* type); + void PortMapping (); + void TryPortMapping (std::shared_ptr address); + void CloseMapping (); + void CloseMapping (std::shared_ptr address); - void Run (); - std::string GetProto (std::shared_ptr address); + void Run (); + std::string GetProto (std::shared_ptr address); private: - bool m_IsRunning; - std::unique_ptr m_Thread; - std::condition_variable m_Started; - std::mutex m_StartedMutex; - boost::asio::io_service m_Service; - boost::asio::deadline_timer m_Timer; - bool m_upnpUrlsInitialized=false; - struct UPNPUrls m_upnpUrls; - struct IGDdatas m_upnpData; + bool m_IsRunning; + std::unique_ptr m_Thread; + std::condition_variable m_Started; + std::mutex m_StartedMutex; + boost::asio::io_service m_Service; + boost::asio::deadline_timer m_Timer; + bool m_upnpUrlsInitialized = false; + struct UPNPUrls m_upnpUrls; + struct IGDdatas m_upnpData; - // For miniupnpc - struct UPNPDev * m_Devlist = 0; - char m_NetworkAddr[64]; - char m_externalIPAddress[40]; + // For miniupnpc + struct UPNPDev * m_Devlist = 0; + char m_NetworkAddr[64]; + char m_externalIPAddress[40]; }; } } @@ -79,10 +79,10 @@ namespace transport { class UPnP { public: - UPnP () {}; - ~UPnP () {}; - void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } - void Stop () {}; + UPnP () {}; + ~UPnP () {}; + void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } + void Stop () {}; }; } } diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index b7af779c..a59fc693 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -196,5 +196,4 @@ namespace i2p } } } - #endif diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 425c2560..7b68c073 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -2,7 +2,6 @@ #include "Daemon.h" #if defined(QT_GUI_LIB) - namespace i2p { namespace qt @@ -10,11 +9,11 @@ namespace qt int RunQT (int argc, char* argv[]); } } + int main( int argc, char* argv[] ) { return i2p::qt::RunQT (argc, argv); } - #else int main( int argc, char* argv[] ) { diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index f80f2751..51f5f225 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -7,7 +7,8 @@ namespace i2p { namespace data { - static const char T32[32] = { + static const char T32[32] = + { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', @@ -29,15 +30,16 @@ namespace data * Direct Substitution Table */ - static const char T64[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '~' + static const char T64[64] = + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '~' }; const char * GetBase64SubstitutionTable () @@ -67,14 +69,12 @@ namespace data * */ - size_t /* Number of bytes in the encoded buffer */ - ByteStreamToBase64 ( - const uint8_t * InBuffer, /* Input buffer, binary data */ - size_t InCount, /* Number of bytes in the input buffer */ - char * OutBuffer, /* output buffer */ - size_t len /* length of output buffer */ + size_t ByteStreamToBase64 ( /* Number of bytes in the encoded buffer */ + const uint8_t * InBuffer, /* Input buffer, binary data */ + size_t InCount, /* Number of bytes in the input buffer */ + char * OutBuffer, /* output buffer */ + size_t len /* length of output buffer */ ) - { unsigned char * ps; unsigned char * pd; @@ -83,55 +83,60 @@ namespace data int i; int n; int m; - size_t outCount; + size_t outCount; ps = (unsigned char *)InBuffer; - n = InCount/3; - m = InCount%3; + n = InCount / 3; + m = InCount % 3; if (!m) - outCount = 4*n; + outCount = 4 * n; else - outCount = 4*(n+1); + outCount = 4 * (n + 1); + if (outCount > len) return 0; + pd = (unsigned char *)OutBuffer; - for ( i = 0; i>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; /* base64 digit #2 */ - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<=2; - acc_2 = *ps++; - acc_1 |= acc_2>>6; /* base64 digit #3 */ - *pd++ = T64[acc_1]; - acc_2 &= 0x3f; /* base64 digit #4 */ - *pd++ = T64[acc_2]; + for ( i = 0; i < n; i++ ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x30; + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + acc_1 = *ps++; + acc_2 |= acc_1 >> 4; /* base64 digit #2 */ + *pd++ = T64[acc_2]; + acc_1 &= 0x0f; + acc_1 <<= 2; + acc_2 = *ps++; + acc_1 |= acc_2 >> 6; /* base64 digit #3 */ + *pd++ = T64[acc_1]; + acc_2 &= 0x3f; /* base64 digit #4 */ + *pd++ = T64[acc_2]; } - if ( m == 1 ){ - acc_1 = *ps++; - acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */ - acc_1 >>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - *pd++ = T64[acc_2]; - *pd++ = P64; - *pd++ = P64; + if ( m == 1 ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x3f; /* base64 digit #2 */ + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + *pd++ = T64[acc_2]; + *pd++ = P64; + *pd++ = P64; } - else if ( m == 2 ){ - acc_1 = *ps++; - acc_2 = (acc_1<<4)&0x3f; - acc_1 >>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; /* base64 digit #2 */ - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<=2; /* base64 digit #3 */ - *pd++ = T64[acc_1]; - *pd++ = P64; + else if ( m == 2 ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x3f; + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + acc_1 = *ps++; + acc_2 |= acc_1 >> 4; /* base64 digit #2 */ + *pd++ = T64[acc_2]; + acc_1 &= 0x0f; + acc_1 <<= 2; /* base64 digit #3 */ + *pd++ = T64[acc_1]; + *pd++ = P64; } return outCount; @@ -147,12 +152,11 @@ namespace data * */ - size_t /* Number of output bytes */ - Base64ToByteStream ( - const char * InBuffer, /* BASE64 encoded buffer */ - size_t InCount, /* Number of input bytes */ - uint8_t * OutBuffer, /* output buffer length */ - size_t len /* length of output buffer */ + size_t Base64ToByteStream ( /* Number of output bytes */ + const char * InBuffer, /* BASE64 encoded buffer */ + size_t InCount, /* Number of input bytes */ + uint8_t * OutBuffer, /* output buffer length */ + size_t len /* length of output buffer */ ) { unsigned char * ps; @@ -162,42 +166,52 @@ namespace data int i; int n; int m; - size_t outCount; + size_t outCount; + + if (isFirstTime) + iT64Build(); + + n = InCount / 4; + m = InCount % 4; - if (isFirstTime) iT64Build(); - n = InCount/4; - m = InCount%4; if (InCount && !m) - outCount = 3*n; - else { - outCount = 0; - return 0; + outCount = 3 * n; + else + { + outCount = 0; + return 0; } ps = (unsigned char *)(InBuffer + InCount - 1); - while ( *ps-- == P64 ) outCount--; + while ( *ps-- == P64 ) + outCount--; ps = (unsigned char *)InBuffer; - if (outCount > len) return -1; + if (outCount > len) + return -1; + pd = OutBuffer; auto endOfOutBuffer = OutBuffer + outCount; - for ( i = 0; i < n; i++ ){ - acc_1 = iT64[*ps++]; - acc_2 = iT64[*ps++]; - acc_1 <<= 2; - acc_1 |= acc_2>>4; - *pd++ = acc_1; - if (pd >= endOfOutBuffer) break; + for ( i = 0; i < n; i++ ) + { + acc_1 = iT64[*ps++]; + acc_2 = iT64[*ps++]; + acc_1 <<= 2; + acc_1 |= acc_2 >> 4; + *pd++ = acc_1; + if (pd >= endOfOutBuffer) + break; - acc_2 <<= 4; - acc_1 = iT64[*ps++]; - acc_2 |= acc_1 >> 2; - *pd++ = acc_2; - if (pd >= endOfOutBuffer) break; + acc_2 <<= 4; + acc_1 = iT64[*ps++]; + acc_2 |= acc_1 >> 2; + *pd++ = acc_2; + if (pd >= endOfOutBuffer) + break; - acc_2 = iT64[*ps++]; - acc_2 |= acc_1 << 6; - *pd++ = acc_2; + acc_2 = iT64[*ps++]; + acc_2 |= acc_1 << 6; + *pd++ = acc_2; } return outCount; @@ -206,20 +220,25 @@ namespace data size_t Base64EncodingBufferSize (const size_t input_size) { auto d = div (input_size, 3); - if (d.rem) d.quot++; - return 4*d.quot; + if (d.rem) + d.quot++; + + return 4 * d.quot; } std::string ToBase64Standard (const std::string& in) { - auto len = Base64EncodingBufferSize (in.length ()); - char * str = new char[len+1]; + auto len = Base64EncodingBufferSize (in.length ()); + char * str = new char[len + 1]; auto l = ByteStreamToBase64 ((const uint8_t *)in.c_str (), in.length (), str, len); str[l] = 0; // replace '-' by '+' and '~' by '/' for (size_t i = 0; i < l; i++) - if (str[i] == '-') str[i] = '+'; - else if (str[i] == '~') str[i] = '/'; + if (str[i] == '-') + str[i] = '+'; + else if (str[i] == '~') + str[i] = '/'; + std::string s(str); delete[] str; return s; @@ -236,10 +255,10 @@ namespace data static void iT64Build() { - int i; + int i; isFirstTime = 0; - for ( i=0; i<256; i++ ) iT64[i] = -1; - for ( i=0; i<64; i++ ) iT64[(int)T64[i]] = i; + for ( i = 0; i < 256; i++ ) iT64[i] = -1; + for ( i = 0; i < 64; i++ ) iT64[(int)T64[i]] = i; iT64[(int)P64] = 0; } @@ -302,4 +321,3 @@ namespace data } } } - diff --git a/libi2pd/Base.h b/libi2pd/Base.h index a273f468..5d550092 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -15,13 +15,13 @@ namespace data { size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen); size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen); - /** - Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes - */ + /** + Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes + */ size_t Base64EncodingBufferSize(const size_t input_size); - - std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization - + + std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization + } // data } // i2p diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 8d3f4b40..287d3648 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -17,21 +17,21 @@ namespace i2p namespace data { static EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) - { + { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); + BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order (group, q, ctx); // calculate alpha = seed mod q BIGNUM * alpha = BN_CTX_get (ctx); - BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian BN_mod (alpha, alpha, q, ctx); // % q // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) auto p = EC_POINT_new (group); EC_POINT_mul (group, p, alpha, nullptr, nullptr, ctx); // B*alpha EC_POINT_add (group, p, pub, p, ctx); // pub + B*alpha BN_CTX_end (ctx); - BN_CTX_free (ctx); + BN_CTX_free (ctx); return p; } @@ -39,18 +39,18 @@ namespace data { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); + BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order (group, q, ctx); // calculate alpha = seed mod q BIGNUM * alpha = BN_CTX_get (ctx); - BN_bin2bn (seed, 64, alpha); // seed is in BigEndian - BN_mod (alpha, alpha, q, ctx); // % q + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q BN_add (alpha, alpha, priv); // alpha = alpha + priv - // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q BN_mod (blindedPriv, alpha, q, ctx); // % q BN_CTX_end (ctx); BN_CTX_free (ctx); - } + } static void BlindEncodedPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) { @@ -63,7 +63,7 @@ namespace data EC_POINT_get_affine_coordinates_GFp (group, p1, x, y, NULL); EC_POINT_free (p1); i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); - i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); + i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); BN_free (x); BN_free (y); } @@ -85,7 +85,7 @@ namespace data i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); BN_free (x); BN_free (y); - } + } template static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args) @@ -97,7 +97,7 @@ namespace data { case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { - publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; + publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); break; } @@ -116,18 +116,18 @@ namespace data default: LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA"); } - if (group) + if (group) { blind (publicKeyLength, group, key, seed, std::forward(args)...); EC_GROUP_free (group); - } + } return publicKeyLength; } //---------------------------------------------------------- const uint8_t B33_TWO_BYTES_SIGTYPE_FLAG = 0x01; - const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now + const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now const uint8_t B33_PER_CLIENT_AUTH_FLAG = 0x04; BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, bool clientAuth): @@ -138,7 +138,7 @@ namespace data m_PublicKey.resize (len); memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); m_SigType = identity->GetSigningKeyType (); - m_BlindedSigType = m_SigType; + m_BlindedSigType = m_SigType; } BlindedPublicKey::BlindedPublicKey (const std::string& b33): @@ -150,12 +150,12 @@ namespace data { LogPrint (eLogError, "Blinding: malformed b33 ", b33); return; - } - uint32_t checksum = crc32 (0, addr + 3, l - 3); + } + uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); uint8_t flags = addr[0]; - size_t offset = 1; + size_t offset = 1; if (flags & B33_TWO_BYTES_SIGTYPE_FLAG) // two bytes signatures { m_SigType = bufbe16toh (addr + offset); offset += 2; @@ -178,7 +178,7 @@ namespace data memcpy (m_PublicKey.data (), addr + offset, len); } else - LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); + LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); } else LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33"); @@ -189,25 +189,25 @@ namespace data if (m_PublicKey.size () > 32) return ""; // assume 25519 uint8_t addr[35]; char str[60]; // TODO: define actual length uint8_t flags = 0; - if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; + if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; addr[0] = flags; // flags addr[1] = m_SigType; // sig type addr[2] = m_BlindedSigType; // blinded sig type memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); - uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); + uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); auto l = ByteStreamToBase32 (addr, m_PublicKey.size () + 3, str, 60); return std::string (str, str + l); } void BlindedPublicKey::GetCredential (uint8_t * credential) const { - // A = destination's signing public key + // A = destination's signing public key // stA = signature type of A, 2 bytes big endian uint16_t stA = htobe16 (GetSigType ()); // stA1 = signature type of blinded A, 2 bytes big endian - uint16_t stA1 = htobe16 (GetBlindedSigType ()); + uint16_t stA1 = htobe16 (GetBlindedSigType ()); // credential = H("credential", A || stA || stA1) H ("credential", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, credential); } @@ -224,15 +224,15 @@ namespace data { uint16_t stA = htobe16 (GetSigType ()), stA1 = htobe16 (GetBlindedSigType ()); uint8_t salt[32]; - //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) + //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) H ("I2PGenerateAlpha", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); } size_t BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const { - uint8_t seed[64]; - GenerateAlpha (date, seed); + uint8_t seed[64]; + GenerateAlpha (date, seed); size_t publicKeyLength = 0; switch (m_SigType) @@ -244,7 +244,7 @@ namespace data break; case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: - i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); + i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; break; default: @@ -255,8 +255,8 @@ namespace data size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const { - uint8_t seed[64]; - GenerateAlpha (date, seed); + uint8_t seed[64]; + GenerateAlpha (date, seed); size_t publicKeyLength = 0; switch (m_SigType) { @@ -272,15 +272,15 @@ namespace data default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } - return publicKeyLength; + return publicKeyLength; } - void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const + void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const { SHA256_CTX ctx; SHA256_Init (&ctx); SHA256_Update (&ctx, p.c_str (), p.length ()); - for (const auto& it: bufs) + for (const auto& it: bufs) SHA256_Update (&ctx, it.first, it.second); SHA256_Final (hash, &ctx); } @@ -289,15 +289,15 @@ namespace data { i2p::data::IdentHash hash; uint8_t blinded[128]; - size_t publicKeyLength = 0; + size_t publicKeyLength = 0; if (date) publicKeyLength = GetBlindedKey (date, blinded); else { char currentDate[9]; i2p::util::GetCurrentDate (currentDate); - publicKeyLength = GetBlindedKey (currentDate, blinded); - } + publicKeyLength = GetBlindedKey (currentDate, blinded); + } if (publicKeyLength) { auto stA1 = htobe16 (m_BlindedSigType); @@ -308,10 +308,9 @@ namespace data SHA256_Final ((uint8_t *)hash, &ctx); } else - LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); + LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); return hash; } } } - diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 65b8c0f8..3e0ad3fc 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -15,7 +15,7 @@ namespace data public: BlindedPublicKey (std::shared_ptr identity, bool clientAuth = false); - BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p + BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const; const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; @@ -25,14 +25,14 @@ namespace data bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes - size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length - size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length + size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length + size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null private: void GetCredential (uint8_t * credential) const; // 32 bytes - void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" + void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" void H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const; private: diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index b4c19607..e1fd450c 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -5,10 +5,10 @@ namespace i2p { namespace cpu { - extern bool aesni; - extern bool avx; + extern bool aesni; + extern bool avx; - void Detect(); + void Detect(); } } diff --git a/libi2pd/ChaCha20.cpp b/libi2pd/ChaCha20.cpp index 222111b7..1d1e9bc6 100644 --- a/libi2pd/ChaCha20.cpp +++ b/libi2pd/ChaCha20.cpp @@ -12,73 +12,72 @@ #include "I2PEndian.h" #include "ChaCha20.h" -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto { namespace chacha { -void u32t8le(uint32_t v, uint8_t * p) +void u32t8le(uint32_t v, uint8_t * p) { - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; + p[0] = v & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; } -uint32_t u8t32le(const uint8_t * p) +uint32_t u8t32le(const uint8_t * p) { - uint32_t value = p[3]; + uint32_t value = p[3]; - value = (value << 8) | p[2]; - value = (value << 8) | p[1]; - value = (value << 8) | p[0]; + value = (value << 8) | p[2]; + value = (value << 8) | p[1]; + value = (value << 8) | p[0]; - return value; + return value; } -uint32_t rotl32(uint32_t x, int n) +uint32_t rotl32(uint32_t x, int n) { - return x << n | (x >> (-n & 31)); + return x << n | (x >> (-n & 31)); } -void quarterround(uint32_t *x, int a, int b, int c, int d) +void quarterround(uint32_t *x, int a, int b, int c, int d) { - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12); - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7); + x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16); + x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12); + x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8); + x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7); } void Chacha20Block::operator << (const Chacha20State & st) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < 16; i++) u32t8le(st.data[i], data + (i << 2)); } void block (Chacha20State &input, int rounds) { - int i; - Chacha20State x; - x.Copy(input); - - for (i = rounds; i > 0; i -= 2) - { - quarterround(x.data, 0, 4, 8, 12); - quarterround(x.data, 1, 5, 9, 13); - quarterround(x.data, 2, 6, 10, 14); - quarterround(x.data, 3, 7, 11, 15); - quarterround(x.data, 0, 5, 10, 15); - quarterround(x.data, 1, 6, 11, 12); - quarterround(x.data, 2, 7, 8, 13); - quarterround(x.data, 3, 4, 9, 14); - } - x += input; - input.block << x; + int i; + Chacha20State x; + x.Copy(input); + for (i = rounds; i > 0; i -= 2) + { + quarterround(x.data, 0, 4, 8, 12); + quarterround(x.data, 1, 5, 9, 13); + quarterround(x.data, 2, 6, 10, 14); + quarterround(x.data, 3, 7, 11, 15); + quarterround(x.data, 0, 5, 10, 15); + quarterround(x.data, 1, 6, 11, 12); + quarterround(x.data, 2, 7, 8, 13); + quarterround(x.data, 3, 4, 9, 14); + } + x += input; + input.block << x; } void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter) @@ -87,52 +86,52 @@ void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * state.data[1] = 0x3320646e; state.data[2] = 0x79622d32; state.data[3] = 0x6b206574; - for (size_t i = 0; i < 8; i++) - state.data[4 + i] = chacha::u8t32le(key + i * 4); - + for (size_t i = 0; i < 8; i++) + state.data[4 + i] = chacha::u8t32le(key + i * 4); + state.data[12] = htole32 (counter); - for (size_t i = 0; i < 3; i++) - state.data[13 + i] = chacha::u8t32le(nonce + i * 4); + for (size_t i = 0; i < 3; i++) + state.data[13 + i] = chacha::u8t32le(nonce + i * 4); } void Chacha20SetCounter (Chacha20State& state, uint32_t counter) { state.data[12] = htole32 (counter); state.offset = 0; -} +} void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz) -{ +{ if (state.offset > 0) { - // previous block if any - auto s = chacha::blocksize - state.offset; + // previous block if any + auto s = chacha::blocksize - state.offset; if (sz < s) s = sz; for (size_t i = 0; i < s; i++) buf[i] ^= state.block.data[state.offset + i]; buf += s; sz -= s; state.offset += s; - if (state.offset >= chacha::blocksize) state.offset = 0; + if (state.offset >= chacha::blocksize) state.offset = 0; } - for (size_t i = 0; i < sz; i += chacha::blocksize) + for (size_t i = 0; i < sz; i += chacha::blocksize) { - chacha::block(state, chacha::rounds); - state.data[12]++; - for (size_t j = i; j < i + chacha::blocksize; j++) - { - if (j >= sz) + chacha::block(state, chacha::rounds); + state.data[12]++; + for (size_t j = i; j < i + chacha::blocksize; j++) + { + if (j >= sz) { state.offset = j & 0x3F; // % 64 break; } - buf[j] ^= state.block.data[j - i]; - } + buf[j] ^= state.block.data[j - i]; + } } } + } // namespace chacha +} // namespace crypto +} // namespace i2p -} -} #endif - diff --git a/libi2pd/ChaCha20.h b/libi2pd/ChaCha20.h index b2eec320..a8bb1d56 100644 --- a/libi2pd/ChaCha20.h +++ b/libi2pd/ChaCha20.h @@ -21,23 +21,23 @@ namespace i2p { namespace crypto { - const std::size_t CHACHA20_KEY_BYTES = 32; - const std::size_t CHACHA20_NOUNCE_BYTES = 12; - + const std::size_t CHACHA20_KEY_BYTES = 32; + const std::size_t CHACHA20_NOUNCE_BYTES = 12; + namespace chacha { - constexpr std::size_t blocksize = 64; + constexpr std::size_t blocksize = 64; constexpr int rounds = 20; struct Chacha20State; struct Chacha20Block { - Chacha20Block () {}; - Chacha20Block (Chacha20Block &&) = delete; + Chacha20Block () {}; + Chacha20Block (Chacha20Block &&) = delete; - uint8_t data[blocksize]; + uint8_t data[blocksize]; - void operator << (const Chacha20State & st); + void operator << (const Chacha20State & st); }; struct Chacha20State @@ -54,19 +54,19 @@ namespace chacha void Copy(const Chacha20State & other) { - memcpy(data, other.data, sizeof(uint32_t) * 16); + memcpy(data, other.data, sizeof(uint32_t) * 16); } uint32_t data[16]; Chacha20Block block; - size_t offset; + size_t offset; }; void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter); void Chacha20SetCounter (Chacha20State& state, uint32_t counter); - void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place -} -} -} -#endif + void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place +} // namespace chacha +} // namespace crypto +} // namespace i2p #endif +#endif diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b741b118..59b51c00 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -242,7 +242,7 @@ namespace config { "1.pool.ntp.org," "2.pool.ntp.org," "3.pool.ntp.org" - ), "Comma separated list of NTCP servers") + ), "Comma separated list of NTCP servers") ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") ; diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 679ae3bb..679795b1 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -18,98 +18,101 @@ namespace i2p { namespace config { - extern boost::program_options::variables_map m_Options; + extern boost::program_options::variables_map m_Options; - /** - * @brief Initialize list of acceptable parameters - * - * Should be called before any Parse* functions. - */ - void Init(); + /** + * @brief Initialize list of acceptable parameters + * + * Should be called before any Parse* functions. + */ + void Init(); - /** - * @brief Parse cmdline parameters, and show help if requested - * @param argc Cmdline arguments count, should be passed from main(). - * @param argv Cmdline parameters array, should be passed from main() - * - * If --help is given in parameters, shows its list with description - * and terminates the program with exitcode 0. - * - * In case of parameter misuse boost throws an exception. - * We internally handle type boost::program_options::unknown_option, - * and then terminate the program with exitcode 1. - * - * Other exceptions will be passed to higher level. - */ - void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false); + /** + * @brief Parse cmdline parameters, and show help if requested + * @param argc Cmdline arguments count, should be passed from main(). + * @param argv Cmdline parameters array, should be passed from main() + * + * If --help is given in parameters, shows its list with description + * and terminates the program with exitcode 0. + * + * In case of parameter misuse boost throws an exception. + * We internally handle type boost::program_options::unknown_option, + * and then terminate the program with exitcode 1. + * + * Other exceptions will be passed to higher level. + */ + void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false); - /** - * @brief Load and parse given config file - * @param path Path to config file - * - * If error occurred when opening file path is points to, - * we show the error message and terminate program. - * - * In case of parameter misuse boost throws an exception. - * We internally handle type boost::program_options::unknown_option, - * and then terminate program with exitcode 1. - * - * Other exceptions will be passed to higher level. - */ - void ParseConfig(const std::string& path); + /** + * @brief Load and parse given config file + * @param path Path to config file + * + * If error occurred when opening file path is points to, + * we show the error message and terminate program. + * + * In case of parameter misuse boost throws an exception. + * We internally handle type boost::program_options::unknown_option, + * and then terminate program with exitcode 1. + * + * Other exceptions will be passed to higher level. + */ + void ParseConfig(const std::string& path); - /** - * @brief Used to combine options from cmdline, config and default values - */ - void Finalize(); + /** + * @brief Used to combine options from cmdline, config and default values + */ + void Finalize(); - /* @brief Accessor to parameters by name - * @param name Name of the requested parameter - * @param value Variable where to store option - * @return this function returns false if parameter not found - * - * Example: uint16_t port; GetOption("sam.port", port); - */ - template - bool GetOption(const char *name, T& value) { - if (!m_Options.count(name)) - return false; - value = m_Options[name].as(); - return true; - } + /** + * @brief Accessor to parameters by name + * @param name Name of the requested parameter + * @param value Variable where to store option + * @return this function returns false if parameter not found + * + * Example: uint16_t port; GetOption("sam.port", port); + */ + template + bool GetOption(const char *name, T& value) + { + if (!m_Options.count(name)) + return false; + value = m_Options[name].as(); + return true; + } - template - bool GetOption(const std::string& name, T& value) - { - return GetOption (name.c_str (), value); - } + template + bool GetOption(const std::string& name, T& value) + { + return GetOption (name.c_str (), value); + } - bool GetOptionAsAny(const char *name, boost::any& value); - bool GetOptionAsAny(const std::string& name, boost::any& value); + bool GetOptionAsAny(const char *name, boost::any& value); + bool GetOptionAsAny(const std::string& name, boost::any& value); - /** - * @brief Set value of given parameter - * @param name Name of settable parameter - * @param value New parameter value - * @return true if value set up successful, false otherwise - * - * Example: uint16_t port = 2827; SetOption("bob.port", port); - */ - template - bool SetOption(const char *name, const T& value) { - if (!m_Options.count(name)) - return false; - m_Options.at(name).value() = value; - notify(m_Options); - return true; - } + /** + * @brief Set value of given parameter + * @param name Name of settable parameter + * @param value New parameter value + * @return true if value set up successful, false otherwise + * + * Example: uint16_t port = 2827; SetOption("bob.port", port); + */ + template + bool SetOption(const char *name, const T& value) + { + if (!m_Options.count(name)) + return false; + m_Options.at(name).value() = value; + notify(m_Options); + return true; + } - /** - * @brief Check is value explicitly given or default - * @param name Name of checked parameter - * @return true if value set to default, false otherwise - */ - bool IsDefault(const char *name); + /** + * @brief Check is value explicitly given or default + * @param name Name of checked parameter + * @return true if value set to default, false otherwise + */ + bool IsDefault(const char *name); } } diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 567ae574..d4d3519e 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -286,14 +286,14 @@ namespace crypto #if OPENSSL_X25519 m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); m_Pkey = nullptr; -#else +#else m_Ctx = BN_CTX_new (); -#endif - } +#endif + } X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) { -#if OPENSSL_X25519 +#if OPENSSL_X25519 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); if (pub) @@ -302,33 +302,33 @@ namespace crypto { size_t len = 32; EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); - } + } #else - m_Ctx = BN_CTX_new (); + m_Ctx = BN_CTX_new (); memcpy (m_PrivateKey, priv, 32); if (pub) memcpy (m_PublicKey, pub, 32); else GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); -#endif - } - +#endif + } + X25519Keys::~X25519Keys () { #if OPENSSL_X25519 EVP_PKEY_CTX_free (m_Ctx); - if (m_Pkey) EVP_PKEY_free (m_Pkey); -#else + if (m_Pkey) EVP_PKEY_free (m_Pkey); +#else BN_CTX_free (m_Ctx); -#endif - } +#endif + } void X25519Keys::GenerateKeys () { #if OPENSSL_X25519 if (m_Pkey) - { - EVP_PKEY_free (m_Pkey); + { + EVP_PKEY_free (m_Pkey); m_Pkey = nullptr; } EVP_PKEY_keygen_init (m_Ctx); @@ -337,26 +337,26 @@ namespace crypto m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? size_t len = 32; EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); -#else +#else RAND_bytes (m_PrivateKey, 32); GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); -#endif - } +#endif + } void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) { -#if OPENSSL_X25519 +#if OPENSSL_X25519 EVP_PKEY_derive_init (m_Ctx); auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); EVP_PKEY_derive_set_peer (m_Ctx, pkey); size_t len = 32; EVP_PKEY_derive (m_Ctx, shared, &len); EVP_PKEY_free (pkey); -#else +#else GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); -#endif - } - +#endif + } + void X25519Keys::GetPrivateKey (uint8_t * priv) const { #if OPENSSL_X25519 @@ -369,14 +369,14 @@ namespace crypto void X25519Keys::SetPrivateKey (const uint8_t * priv) { -#if OPENSSL_X25519 - if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); +#if OPENSSL_X25519 + if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Pkey) EVP_PKEY_free (m_Pkey); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); #else memcpy (m_PrivateKey, priv, 32); -#endif +#endif } // ElGamal @@ -681,12 +681,12 @@ namespace crypto // AES #ifdef __AES__ - #ifdef ARM64AES - void init_aesenc(void){ + #ifdef ARM64AES + void init_aesenc(void){ // TODO: Implementation - } + } - #endif + #endif #define KeyExpansion256(round0,round1) \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \ @@ -884,7 +884,6 @@ namespace crypto } } - void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { #ifdef __AES__ @@ -1139,10 +1138,10 @@ namespace crypto } EVP_CIPHER_CTX_free (ctx); -#else +#else chacha::Chacha20State state; // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); + chacha::Chacha20Init (state, nonce, key, 0); uint64_t polyKey[8]; memset(polyKey, 0, sizeof(polyKey)); chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); @@ -1158,7 +1157,7 @@ namespace crypto { // padding1 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } } // encrypt/decrypt data and add to hash @@ -1174,20 +1173,20 @@ namespace crypto { polyHash.Update (buf, msgLen); // before decryption chacha::Chacha20Encrypt (state, buf, msgLen); // decrypt - } + } auto rem = msgLen & 0x0F; // %16 if (rem) { // padding2 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } // adLen and msgLen htole64buf (padding, adLen); htole64buf (padding + 8, msgLen); - polyHash.Update (padding, 16); - + polyHash.Update (padding, 16); + if (encrypt) // calculate Poly1305 tag and write in after encrypted data polyHash.Finish ((uint64_t *)(buf + msgLen)); @@ -1195,7 +1194,7 @@ namespace crypto { uint64_t tag[4]; // calculate Poly1305 tag - polyHash.Finish (tag); + polyHash.Finish (tag); if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided } #endif @@ -1211,20 +1210,20 @@ namespace crypto EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); - for (const auto& it: bufs) + for (const auto& it: bufs) EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second); EVP_EncryptFinal_ex(ctx, NULL, &outlen); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); EVP_CIPHER_CTX_free (ctx); -#else +#else chacha::Chacha20State state; // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); + chacha::Chacha20Init (state, nonce, key, 0); uint64_t polyKey[8]; memset(polyKey, 0, sizeof(polyKey)); chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); Poly1305 polyHash (polyKey); - // encrypt buffers + // encrypt buffers Chacha20SetCounter (state, 1); size_t size = 0; for (const auto& it: bufs) @@ -1234,22 +1233,22 @@ namespace crypto size += it.second; } // padding - uint8_t padding[16]; + uint8_t padding[16]; memset (padding, 0, 16); auto rem = size & 0x0F; // %16 if (rem) { // padding2 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } // adLen and msgLen // adLen is always zero htole64buf (padding + 8, size); - polyHash.Update (padding, 16); + polyHash.Update (padding, 16); // MAC - polyHash.Finish ((uint64_t *)mac); -#endif + polyHash.Finish ((uint64_t *)mac); +#endif } void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out) @@ -1265,13 +1264,13 @@ namespace crypto EVP_CIPHER_CTX_free (ctx); #else chacha::Chacha20State state; - chacha::Chacha20Init (state, nonce, key, 1); + chacha::Chacha20Init (state, nonce, key, 1); if (out != msg) memcpy (out, msg, msgLen); chacha::Chacha20Encrypt (state, out, msgLen); #endif } - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen) { #if OPENSSL_HKDF @@ -1279,10 +1278,10 @@ namespace crypto EVP_PKEY_derive_init (pctx); EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256()); if (key && keyLen) - { + { EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32); EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen); - } + } else { // zerolen @@ -1290,22 +1289,22 @@ namespace crypto uint8_t tempKey[32]; unsigned int len; HMAC(EVP_sha256(), salt, 32, nullptr, 0, tempKey, &len); EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len); - } + } if (info.length () > 0) EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ()); EVP_PKEY_derive (pctx, out, &outLen); EVP_PKEY_CTX_free (pctx); #else uint8_t prk[32]; unsigned int len; - HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len); + HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len); auto l = info.length (); memcpy (out, info.c_str (), l); out[l] = 0x01; HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len); if (outLen > 32) // 64 - { + { memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02; - HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); - } + HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); + } #endif } @@ -1323,10 +1322,10 @@ namespace crypto } }*/ - + void InitCrypto (bool precomputation) { - i2p::cpu::Detect (); + i2p::cpu::Detect (); #if LEGACY_OPENSSL SSL_library_init (); #endif @@ -1364,4 +1363,3 @@ namespace crypto } } } - diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 32410daf..2dfd6d0e 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -28,13 +28,13 @@ #else # define LEGACY_OPENSSL 0 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_HKDF 1 -# define OPENSSL_EDDSA 1 -# define OPENSSL_X25519 1 -# define OPENSSL_SIPHASH 1 +# define OPENSSL_HKDF 1 +# define OPENSSL_EDDSA 1 +# define OPENSSL_X25519 1 +# define OPENSSL_SIPHASH 1 # endif # if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them -# define OPENSSL_AEAD_CHACHA20_POLY1305 1 +# define OPENSSL_AEAD_CHACHA20_POLY1305 1 # endif #endif @@ -81,20 +81,20 @@ namespace crypto const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; void SetPrivateKey (const uint8_t * priv); // wihout calculating public - void Agree (const uint8_t * pub, uint8_t * shared); + void Agree (const uint8_t * pub, uint8_t * shared); private: - uint8_t m_PublicKey[32]; + uint8_t m_PublicKey[32]; #if OPENSSL_X25519 EVP_PKEY_CTX * m_Ctx; EVP_PKEY * m_Pkey; -#else +#else BN_CTX * m_Ctx; uint8_t m_PrivateKey[32]; -#endif +#endif }; - + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); @@ -117,15 +117,15 @@ namespace crypto void operator^=(const ChipherBlock& other) // XOR { if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ? - { + { for (int i = 0; i < 4; i++) reinterpret_cast(buf)[i] ^= reinterpret_cast(other.buf)[i]; - } + } else - { + { for (int i = 0; i < 16; i++) buf[i] ^= other.buf[i]; - } + } } }; @@ -297,7 +297,7 @@ namespace crypto // HKDF - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 // init and terminate void InitCrypto (bool precomputation); diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 878e984a..2abcb111 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -151,7 +151,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub) { memcpy (m_PublicKey, pub, 32); - } + } void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) { @@ -166,16 +166,15 @@ namespace crypto bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { m_StaticKeys.Agree (epub, sharedSecret); - return true; + return true; } void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) { X25519Keys k; - k.GenerateKeys (); + k.GenerateKeys (); k.GetPrivateKey (priv); memcpy (pub, k.GetPublicKey (), 32); } } } - diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 701e9482..43bd3aaa 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -45,7 +45,7 @@ namespace crypto ElGamalDecryptor (const uint8_t * priv); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); size_t GetPublicKeyLen () const { return 256; }; - + private: uint8_t m_PrivateKey[256]; @@ -76,7 +76,7 @@ namespace crypto ~ECIESP256Decryptor (); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); size_t GetPublicKeyLen () const { return 64; }; - + private: EC_GROUP * m_Curve; @@ -109,7 +109,7 @@ namespace crypto ~ECIESGOSTR3410Decryptor (); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); size_t GetPublicKeyLen () const { return 64; }; - + private: BIGNUM * m_PrivateKey; @@ -119,14 +119,14 @@ namespace crypto // ECIES-X25519-AEAD-Ratchet - class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor + class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor { public: ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); - // copies m_PublicKey to pub + // copies m_PublicKey to pub private: @@ -139,7 +139,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const { return 32; }; @@ -153,4 +153,3 @@ namespace crypto } #endif - diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h index d43e356c..baeb7f14 100644 --- a/libi2pd/CryptoWorker.h +++ b/libi2pd/CryptoWorker.h @@ -77,5 +77,4 @@ namespace worker } } - #endif diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 6441b5e2..2da73649 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -13,10 +13,10 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { - auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); - m_From.resize (identityLen); - m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); - m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); + m_From.resize (identityLen); + m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); + m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); } DatagramDestination::~DatagramDestination () @@ -36,7 +36,7 @@ namespace datagram m_Owner->Sign (payload, len, m_Signature.data ()); auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } @@ -46,8 +46,8 @@ namespace datagram auto session = ObtainSession(identity); auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw session->SendMsg(msg); - } - + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -86,8 +86,8 @@ namespace datagram m_RawReceiver (fromPort, toPort, buf, len); else LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram"); - } - + } + DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port) { std::lock_guard lock(m_ReceiversMutex); @@ -107,23 +107,22 @@ namespace datagram { if (isRaw) HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen); - else + else HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); - } + } else LogPrint (eLogWarning, "Datagram: decompression failed"); } - std::shared_ptr DatagramDestination::CreateDataMessage ( - const std::vector >& payloads, - uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) + const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : - i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); + i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length @@ -186,7 +185,7 @@ namespace datagram } DatagramSession::DatagramSession(std::shared_ptr localDestination, - const i2p::data::IdentHash & remoteIdent) : + const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), m_SendQueueTimer(localDestination->GetService()), @@ -384,4 +383,3 @@ namespace datagram } } } - diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index ea2a4e13..72e7340c 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -32,68 +32,71 @@ namespace datagram const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000; // milliseconds minimum time between path switches const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000; - // max 64 messages buffered in send queue for each datagram session - const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64; + // max 64 messages buffered in send queue for each datagram session + const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64; class DatagramSession : public std::enable_shared_from_this { - public: - DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent); - void Start (); - void Stop (); + public: + + DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent); + + void Start (); + void Stop (); - /** @brief ack the garlic routing path */ - void Ack(); + /** @brief ack the garlic routing path */ + void Ack(); - /** send an i2np message to remote endpoint for this session */ - void SendMsg(std::shared_ptr msg); - /** get the last time in milliseconds for when we used this datagram session */ - uint64_t LastActivity() const { return m_LastUse; } + /** send an i2np message to remote endpoint for this session */ + void SendMsg(std::shared_ptr msg); + /** get the last time in milliseconds for when we used this datagram session */ + uint64_t LastActivity() const { return m_LastUse; } bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } - + struct Info { std::shared_ptr IBGW; std::shared_ptr OBEP; const uint64_t activity; - Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {} - Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) : - activity(a) { - if(ibgw) IBGW = std::make_shared(ibgw); - else IBGW = nullptr; - if(obep) OBEP = std::make_shared(obep); - else OBEP = nullptr; - } - }; + Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {} + Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) : + activity(a) { + if(ibgw) IBGW = std::make_shared(ibgw); + else IBGW = nullptr; + if(obep) OBEP = std::make_shared(obep); + else OBEP = nullptr; + } + }; - Info GetSessionInfo() const; + Info GetSessionInfo() const; - private: + private: - void FlushSendQueue(); - void ScheduleFlushSendQueue(); + void FlushSendQueue(); + void ScheduleFlushSendQueue(); - void HandleSend(std::shared_ptr msg); + void HandleSend(std::shared_ptr msg); - std::shared_ptr GetSharedRoutingPath(); + std::shared_ptr GetSharedRoutingPath(); - void HandleLeaseSetUpdated(std::shared_ptr ls); + void HandleLeaseSetUpdated(std::shared_ptr ls); - private: - std::shared_ptr m_LocalDestination; - i2p::data::IdentHash m_RemoteIdent; - std::shared_ptr m_RemoteLeaseSet; - std::shared_ptr m_RoutingSession; - std::shared_ptr m_CurrentRemoteLease; - std::shared_ptr m_CurrentOutboundTunnel; - boost::asio::deadline_timer m_SendQueueTimer; - std::vector > m_SendQueue; - uint64_t m_LastUse; - bool m_RequestingLS; + private: + + std::shared_ptr m_LocalDestination; + i2p::data::IdentHash m_RemoteIdent; + std::shared_ptr m_RemoteLeaseSet; + std::shared_ptr m_RoutingSession; + std::shared_ptr m_CurrentRemoteLease; + std::shared_ptr m_CurrentOutboundTunnel; + boost::asio::deadline_timer m_SendQueueTimer; + std::vector > m_SendQueue; + uint64_t m_LastUse; + bool m_RequestingLS; }; typedef std::shared_ptr DatagramSession_ptr; @@ -104,17 +107,15 @@ namespace datagram typedef std::function Receiver; typedef std::function RawReceiver; - public: - - DatagramDestination (std::shared_ptr owner, bool gzip); + DatagramDestination (std::shared_ptr owner, bool gzip); ~DatagramDestination (); void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); - + void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; void ResetReceiver () { m_Receiver = nullptr; }; @@ -123,7 +124,7 @@ namespace datagram void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; }; void ResetRawReceiver () { m_RawReceiver = nullptr; }; - + std::shared_ptr GetInfoForRemote(const i2p::data::IdentHash & remote); // clean up stale sessions @@ -131,14 +132,14 @@ namespace datagram private: - std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); + std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); - std::shared_ptr CreateDataMessage (const std::vector >& payloads, + std::shared_ptr CreateDataMessage (const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); - + /** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */ Receiver FindReceiver(uint16_t port); diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 782e2841..921e55f0 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -16,8 +16,8 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service, - bool isPublic, const std::map * params): - m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), + bool isPublic, const std::map * params): + m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) @@ -160,13 +160,12 @@ namespace client bool LeaseSetDestination::Reconfigure(std::map params) { - auto itr = params.find("i2cp.dontPublishLeaseSet"); if (itr != params.end()) { m_IsPublic = itr->second != "true"; } - + int inLen, outLen, inQuant, outQuant, numTags, minLatency, maxLatency; std::map intOpts = { {I2CP_PARAM_INBOUND_TUNNEL_LENGTH, inLen}, @@ -185,7 +184,7 @@ namespace client outQuant = pool->GetNumOutboundTunnels(); minLatency = 0; maxLatency = 0; - + for (auto & opt : intOpts) { itr = params.find(opt.first); @@ -197,7 +196,7 @@ namespace client pool->RequireLatency(minLatency, maxLatency); return pool->Reconfigure(inLen, outLen, inQuant, outQuant); } - + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; @@ -266,7 +265,7 @@ namespace client std::lock_guard l(m_LeaseSetMutex); return m_LeaseSet; } - + void LeaseSetDestination::SetLeaseSet (std::shared_ptr newLeaseSet) { { @@ -281,7 +280,7 @@ namespace client { s->m_PublishVerificationTimer.cancel (); s->Publish (); - }); + }); } } @@ -565,12 +564,12 @@ namespace client m_PublishReplyToken = 0; if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) { - LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); + LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); Publish (); } else { - LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ()); + LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ()); // Java floodfill never sends confirmation back for unknown crypto type // assume it successive and try to verify m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); @@ -591,7 +590,7 @@ namespace client { LogPrint (eLogWarning, "Destination: couldn't verify LeaseSet for ", GetIdentHash().ToBase32()); return; - } + } auto s = shared_from_this (); // we must capture this for gcc 4.7 due the bug RequestLeaseSet (ls->GetStoreHash (), @@ -643,9 +642,9 @@ namespace client if (requestComplete) m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; - } + } auto storeHash = dest->GetStoreHash (); - auto leaseSet = FindLeaseSet (storeHash); + auto leaseSet = FindLeaseSet (storeHash); if (leaseSet) { if (requestComplete) @@ -720,7 +719,7 @@ namespace client } bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, - std::shared_ptr nextFloodfill, std::shared_ptr request) + std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) request->replyTunnel = m_Pool->GetNextInboundTunnel (); @@ -783,7 +782,7 @@ namespace client } else { - LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); + LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); done = true; } @@ -829,13 +828,13 @@ namespace client i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const { if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; - return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; - } - - ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; + return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; + } + + ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (service, isPublic, params), + LeaseSetDestination (service, isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(service) @@ -846,7 +845,7 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || - GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) + GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) @@ -864,37 +863,37 @@ namespace client { LogPrint (eLogInfo, "Destination: Unexpected crypto type ", it1, ". ", ex.what ()); continue; - } - } - } - } - // if no param or valid crypto type use from identity - bool isSingleKey = false; - if (encryptionKeyTypes.empty ()) + } + } + } + } + // if no param or valid crypto type use from identity + bool isSingleKey = false; + if (encryptionKeyTypes.empty ()) { isSingleKey = true; encryptionKeyTypes.insert (GetIdentity ()->GetCryptoKeyType ()); - } + } for (auto& it: encryptionKeyTypes) - { + { auto encryptionKey = new EncryptionKey (it); - if (isPublic) + if (isPublic) PersistTemporaryKeys (encryptionKey, isSingleKey); else encryptionKey->GenerateKeys (); - encryptionKey->CreateDecryptor (); + encryptionKey->CreateDecryptor (); if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) m_ECIESx25519EncryptionKey.reset (encryptionKey); else - m_StandardEncryptionKey.reset (encryptionKey); - } - + m_StandardEncryptionKey.reset (encryptionKey); + } + if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); try - { + { if (params) { // extract streaming params @@ -910,9 +909,9 @@ namespace client { m_AuthKeys = std::make_shared >(); if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) - ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) - ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else LogPrint (eLogError, "Destination: Unexpected auth type ", authType); if (m_AuthKeys->size ()) @@ -920,7 +919,7 @@ namespace client else { LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType); - m_AuthKeys = nullptr; + m_AuthKeys = nullptr; } } } @@ -1002,7 +1001,7 @@ namespace client m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, true); else LogPrint (eLogError, "Destination: Missing raw datagram destination"); - break; + break; default: LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } @@ -1105,7 +1104,7 @@ namespace client return dest; } - i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip); @@ -1130,7 +1129,7 @@ namespace client { if (!keys) return; std::string ident = GetIdentHash().ToBase32(); - std::string path = i2p::fs::DataDirPath("destinations", + std::string path = i2p::fs::DataDirPath("destinations", isSingleKey ? (ident + ".dat") : (ident + "." + std::to_string (keys->keyType) + ".dat")); std::ifstream f(path, std::ifstream::binary); @@ -1142,12 +1141,12 @@ namespace client LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p"); memset (keys->priv, 0, 256); - memset (keys->pub, 0, 256); + memset (keys->pub, 0, 256); keys->GenerateKeys (); // TODO:: persist crypto key type std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out); if (f1) { - f1.write ((char *)keys->pub, 256); + f1.write ((char *)keys->pub, 256); f1.write ((char *)keys->priv, 256); return; } @@ -1160,11 +1159,11 @@ namespace client if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) { if (m_StandardEncryptionKey) - { + { leaseSet = std::make_shared (GetIdentity (), m_StandardEncryptionKey->pub, tunnels); // sign - Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); - } + Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); + } else LogPrint (eLogError, "Destinations: Wrong encryption key type for LeaseSet type 1"); } @@ -1175,9 +1174,9 @@ namespace client if (m_ECIESx25519EncryptionKey) keySections.push_back ({m_ECIESx25519EncryptionKey->keyType, 32, m_ECIESx25519EncryptionKey->pub} ); if (m_StandardEncryptionKey) - keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub} ); + keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub} ); - bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; + bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, keySections, tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 @@ -1204,18 +1203,18 @@ namespace client return false; } - bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const - { + bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const + { return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519EncryptionKey : (bool)m_StandardEncryptionKey; } - const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const - { + const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const + { if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub : nullptr; return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub : nullptr; } - + void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) { for (auto it: *params) @@ -1229,7 +1228,7 @@ namespace client m_AuthKeys->push_back (pubKey); else LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1)); - } + } } } @@ -1241,10 +1240,10 @@ namespace client if (it.second->DeleteStream (recvStreamID)) return true; return false; - } - + } + RunnableClientDestination::RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - RunnableService ("Destination"), + RunnableService ("Destination"), ClientDestination (GetIOService (), keys, isPublic, params) { } @@ -1253,7 +1252,7 @@ namespace client { if (IsRunning ()) Stop (); - } + } void RunnableClientDestination::Start () { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 04cf05f4..dbdc3704 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -52,13 +52,13 @@ namespace client const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname"; const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; - const int DEFAULT_LEASESET_TYPE = 1; + const int DEFAULT_LEASESET_TYPE = 1; const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType"; const char I2CP_PARAM_LEASESET_PRIV_KEY[] = "i2cp.leaseSetPrivKey"; // PSK decryption key, base64 const char I2CP_PARAM_LEASESET_AUTH_TYPE[] = "i2cp.leaseSetAuthType"; const char I2CP_PARAM_LEASESET_CLIENT_DH[] = "i2cp.leaseSetClient.dh"; // group of i2cp.leaseSetClient.dh.nnn const char I2CP_PARAM_LEASESET_CLIENT_PSK[] = "i2cp.leaseSetClient.psk"; // group of i2cp.leaseSetClient.psk.nnn - + // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; const int DEFAULT_MIN_TUNNEL_LATENCY = 0; @@ -94,7 +94,6 @@ namespace client } }; - public: LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); @@ -107,12 +106,12 @@ namespace client /** i2cp reconfigure */ virtual bool Reconfigure(std::map i2cpOpts); - + std::shared_ptr GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr); - bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); + bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true); void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify = true); @@ -155,7 +154,7 @@ namespace client void HandleDeliveryStatusMessage (uint32_t msgID); void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey = nullptr); - bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); + bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); @@ -202,11 +201,11 @@ namespace client EncryptionKey (i2p::data::CryptoKeyType t):keyType(t) { memset (pub, 0, 256); memset (priv, 0, 256); }; void GenerateKeys () { i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv, pub); }; void CreateDecryptor () { decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv); }; - }; - + }; + public: - ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); @@ -235,13 +234,13 @@ namespace client int GetStreamingAckDelay () const { return m_StreamingAckDelay; } // datagram - i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); + i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; + i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; protected: @@ -259,8 +258,8 @@ namespace client void PersistTemporaryKeys (EncryptionKey * keys, bool isSingleKey); void ReadAuthKey (const std::string& group, const std::map * params); - private: - + private: + i2p::data::PrivateKeys m_Keys; std::unique_ptr m_StandardEncryptionKey; std::unique_ptr m_ECIESx25519EncryptionKey; @@ -273,7 +272,7 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; - std::shared_ptr > m_AuthKeys; // we don't need them for I2CP + std::shared_ptr > m_AuthKeys; // we don't need them for I2CP public: @@ -287,7 +286,7 @@ namespace client public: RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); - ~RunnableClientDestination (); + ~RunnableClientDestination (); void Start (); void Stop (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7b386d92..f3b1a685 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -15,54 +15,54 @@ namespace i2p namespace garlic { - void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) - { - // DH_INITIALIZE(rootKey, k) - uint8_t keydata[64]; - i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) - memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31] - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); - // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) + { + // DH_INITIALIZE(rootKey, k) + uint8_t keydata[64]; + i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) + memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31] + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); + // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32); m_NextSymmKeyIndex = 0; - } + } - void RatchetTagSet::NextSessionTagRatchet () - { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) - memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32); + void RatchetTagSet::NextSessionTagRatchet () + { + i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32); m_NextIndex = 0; - } + } - uint64_t RatchetTagSet::GetNextSessionTag () - { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - m_NextIndex++; - if (m_NextIndex >= 65535) + uint64_t RatchetTagSet::GetNextSessionTag () + { + i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + m_NextIndex++; + if (m_NextIndex >= 65535) { LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); return 0; - } - return m_KeyData.GetTag (); - } + } + return m_KeyData.GetTag (); + } void RatchetTagSet::GetSymmKey (int index, uint8_t * key) { if (index >= m_NextSymmKeyIndex) - { + { auto num = index + 1 - m_NextSymmKeyIndex; if (!m_NextSymmKeyIndex) { i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) m_NextSymmKeyIndex = 1; num--; - } + } for (int i = 0; i < num; i++) - { + { i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); if (i < num - 1) m_ItermediateSymmKeys.emplace (m_NextSymmKeyIndex + i, m_CurrentSymmKeyCK + 32); - } + } m_NextSymmKeyIndex += num; memcpy (key, m_CurrentSymmKeyCK + 32, 32); } @@ -70,30 +70,30 @@ namespace garlic { auto it = m_ItermediateSymmKeys.find (index); if (it != m_ItermediateSymmKeys.end ()) - { + { memcpy (key, it->second, 32); m_ItermediateSymmKeys.erase (it); - } + } else LogPrint (eLogError, "Garlic: Missing symmetric key for index ", index); - } - } + } + } void RatchetTagSet::Expire () { if (!m_ExpirationTimestamp) m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; - } - - ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): - GarlicRoutingSession (owner, attachLeaseSet) - { - ResetKeys (); - } + } - ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () - { - } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): + GarlicRoutingSession (owner, attachLeaseSet) + { + ResetKeys (); + } + + ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () + { + } void ECIESX25519AEADRatchetSession::ResetKeys () { @@ -109,65 +109,65 @@ namespace garlic }; // SHA256 (protocolNameHash) memcpy (m_CK, protocolNameHash, 32); memcpy (m_H, hh, 32); - } - - void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; + } + + void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; SHA256_Init (&ctx); SHA256_Update (&ctx, m_H, 32); SHA256_Update (&ctx, buf, len); SHA256_Final (m_H, &ctx); - } - - void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) - { - memset (nonce, 0, 4); - htole64buf (nonce + 4, seqn); } - bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) - { - for (int i = 0; i < 10; i++) - { - m_EphemeralKeys.GenerateKeys (); - if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) - return true; // success - } - return false; - } + void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, seqn); + } - std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () - { - uint8_t tagsetKey[32]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) - // Session Tag Ratchet - auto tagsetNsr = std::make_shared(shared_from_this ()); - tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) - tagsetNsr->NextSessionTagRatchet (); - return tagsetNsr; - } - - bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) - { - if (!GetOwner ()) return false; - // we are Bob - // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) - - if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) - { - LogPrint (eLogError, "Garlic: Can't decode elligator"); - return false; + bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) + { + for (int i = 0; i < 10; i++) + { + m_EphemeralKeys.GenerateKeys (); + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) + return true; // success } - buf += 32; len -= 32; - MixHash (m_Aepk, 32); // h = SHA256(h || aepk) - - uint8_t sharedSecret[32]; + return false; + } + + std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () + { + uint8_t tagsetKey[32]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) + // Session Tag Ratchet + auto tagsetNsr = std::make_shared(shared_from_this ()); + tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) + tagsetNsr->NextSessionTagRatchet (); + return tagsetNsr; + } + + bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) + { + if (!GetOwner ()) return false; + // we are Bob + // KDF1 + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) + + if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) + { + LogPrint (eLogError, "Garlic: Can't decode elligator"); + return false; + } + buf += 32; len -= 32; + MixHash (m_Aepk, 32); // h = SHA256(h || aepk) + + uint8_t sharedSecret[32]; GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - - // decrypt flags/static + + // decrypt flags/static uint8_t nonce[12], fs[32]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt @@ -179,17 +179,17 @@ namespace garlic buf += 48; len -= 48; // 32 data + 16 poly // KDF2 for payload - bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); + bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); if (isStatic) { // static key, fs is apk - memcpy (m_RemoteStaticKey, fs, 32); + memcpy (m_RemoteStaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags CreateNonce (1, nonce); - + // decrypt payload std::vector payload (len - 16); // we must save original ciphertext if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt @@ -198,17 +198,17 @@ namespace garlic return false; } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) - m_State = eSessionStateNewSessionReceived; + m_State = eSessionStateNewSessionReceived; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); - HandlePayload (payload.data (), len - 16, nullptr, 0); + HandlePayload (payload.data (), len - 16, nullptr, 0); - return true; - } + return true; + } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) - { - size_t offset = 0; + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) + { + size_t offset = 0; while (offset < len) { uint8_t blk = buf[offset]; @@ -228,48 +228,48 @@ namespace garlic GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkNextKey: - LogPrint (eLogDebug, "Garlic: next key"); + LogPrint (eLogDebug, "Garlic: next key"); HandleNextKey (buf + offset, size, receiveTagset); break; case eECIESx25519BlkAck: - { + { LogPrint (eLogDebug, "Garlic: ack"); int numAcks = size >> 2; // /4 - auto offset1 = offset; + auto offset1 = offset; for (auto i = 0; i < numAcks; i++) - { + { offset1 += 2; // tagsetid MessageConfirmed (bufbe16toh (buf + offset1)); offset1 += 2; // N } break; - } + } case eECIESx25519BlkAckRequest: - { + { LogPrint (eLogDebug, "Garlic: ack request"); - m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); - break; - } + m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); + break; + } case eECIESx25519BlkTermination: LogPrint (eLogDebug, "Garlic: termination"); if (GetOwner ()) GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey); if (receiveTagset) receiveTagset->Expire (); - break; + break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); - break; + break; case eECIESx25519BlkOptions: LogPrint (eLogDebug, "Garlic: options"); break; case eECIESx25519BlkPadding: LogPrint (eLogDebug, "Garlic: padding"); - break; + break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } offset += size; } - } + } void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset) { @@ -279,7 +279,7 @@ namespace garlic if (!m_SendForwardKey || !m_NextSendRatchet) return; uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || - (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) + (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) { if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); @@ -288,15 +288,15 @@ namespace garlic i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared (shared_from_this ()); newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); - newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); + newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - m_SendTagset = newTagset; + m_SendTagset = newTagset; m_SendForwardKey = false; LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created"); } else LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID); - } + } else { uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID @@ -305,38 +305,38 @@ namespace garlic if (!m_NextReceiveRatchet) m_NextReceiveRatchet.reset (new DHRatchet ()); else - { - if (keyID == m_NextReceiveRatchet->keyID && newKey == m_NextReceiveRatchet->newKey) + { + if (keyID == m_NextReceiveRatchet->keyID && newKey == m_NextReceiveRatchet->newKey) { LogPrint (eLogDebug, "Garlic: Duplicate ", newKey ? "new" : "old", " key ", keyID, " received"); return; - } + } m_NextReceiveRatchet->keyID = keyID; } int tagsetID = 2*keyID; if (newKey) - { + { m_NextReceiveRatchet->key.GenerateKeys (); m_NextReceiveRatchet->newKey = true; tagsetID++; - } + } else m_NextReceiveRatchet->newKey = false; if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextReceiveRatchet->remote, buf, 32); - + uint8_t sharedSecret[32], tagsetKey[32]; m_NextReceiveRatchet->key.Agree (m_NextReceiveRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) - auto newTagset = std::make_shared(shared_from_this ()); - newTagset->SetTagSetID (tagsetID); - newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); + auto newTagset = std::make_shared(shared_from_this ()); + newTagset->SetTagSetID (tagsetID); + newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); - } - } + } + } void ECIESX25519AEADRatchetSession::NewNextSendRatchet () { @@ -346,49 +346,49 @@ namespace garlic { m_NextSendRatchet->keyID++; m_NextSendRatchet->newKey = true; - } + } else m_NextSendRatchet->newKey = false; - } + } else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) m_NextSendRatchet->key.GenerateKeys (); - + m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); - } - - bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - ResetKeys (); - // we are Alice, bpk is m_RemoteStaticKey - size_t offset = 0; - if (!GenerateEphemeralKeysAndEncode (out + offset)) - { - LogPrint (eLogError, "Garlic: Can't encode elligator"); - return false; - } - offset += 32; + } - // KDF1 - MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) - uint8_t sharedSecret[32]; + bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + ResetKeys (); + // we are Alice, bpk is m_RemoteStaticKey + size_t offset = 0; + if (!GenerateEphemeralKeysAndEncode (out + offset)) + { + LogPrint (eLogError, "Garlic: Can't encode elligator"); + return false; + } + offset += 32; + + // KDF1 + MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - // encrypt static key section - uint8_t nonce[12]; + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + // encrypt static key section + uint8_t nonce[12]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; } - MixHash (out + offset, 48); // h = SHA256(h || ciphertext) - offset += 48; - // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) + MixHash (out + offset, 48); // h = SHA256(h || ciphertext) + offset += 48; + // KDF2 + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt @@ -399,169 +399,169 @@ namespace garlic MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) m_State = eSessionStateNewSessionSent; - if (GetOwner ()) + if (GetOwner ()) GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); - return true; - } + return true; + } - bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Bob + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Bob m_NSRTagset = CreateNewSessionTagset (); - uint64_t tag = m_NSRTagset->GetNextSessionTag (); - - size_t offset = 0; - memcpy (out + offset, &tag, 8); - offset += 8; - if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk - { + uint64_t tag = m_NSRTagset->GetNextSessionTag (); + + size_t offset = 0; + memcpy (out + offset, &tag, 8); + offset += 8; + if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk + { LogPrint (eLogError, "Garlic: Can't encode elligator"); - return false; + return false; } memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR memcpy (m_NSRH, m_H, 32); - offset += 32; - // KDF for Reply Key Section - MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) - uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + offset += 32; + // KDF for Reply Key Section + MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; + m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); - // calulate hash for zero length + // calculate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } - MixHash (out + offset, 16); // h = SHA256(h || ciphertext) - offset += 16; - // KDF for payload - uint8_t keydata[64]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + MixHash (out + offset, 16); // h = SHA256(h || ciphertext) + offset += 16; + // KDF for payload + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) // k_ab = keydata[0:31], k_ba = keydata[32:63] auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) receiveTagset->NextSessionTagRatchet (); m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) - m_SendTagset->NextSessionTagRatchet (); + m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + m_SendTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); return false; } m_State = eSessionStateNewSessionReplySent; - - return true; - } + + return true; + } bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Bob and sent NSR already - uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag - memcpy (out, &tag, 8); + { + // we are Bob and sent NSR already + uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + memcpy (out, &tag, 8); memcpy (out + 8, m_NSREncodedKey, 32); - // recalculte h with new tag + // recalculate h with new tag memcpy (m_H, m_NSRH, 32); MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; - CreateNonce (0, nonce); + CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } - MixHash (out + 40, 16); // h = SHA256(h || ciphertext) + MixHash (out + 40, 16); // h = SHA256(h || ciphertext) // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); return false; } return true; - } - - bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) - { + } + + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) + { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); const uint8_t * tag = buf; buf += 8; len -= 8; // tag - uint8_t bepk[32]; // Bob's ephemeral key + uint8_t bepk[32]; // Bob's ephemeral key if (!i2p::crypto::GetElligator ()->Decode (buf, bepk)) - { + { LogPrint (eLogError, "Garlic: Can't decode elligator"); - return false; - } + return false; + } buf += 32; len -= 32; - // KDF for Reply Key Section + // KDF for Reply Key Section uint8_t h[32]; memcpy (h, m_H, 32); // save m_H - MixHash (tag, 8); // h = SHA256(h || tag) - MixHash (bepk, 32); // h = SHA256(h || bepk) - uint8_t sharedSecret[32]; + MixHash (tag, 8); // h = SHA256(h || tag) + MixHash (bepk, 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; if (m_State == eSessionStateNewSessionSent) - { + { // only fist time, we assume ephemeral keys the same - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - } + } uint8_t nonce[12]; CreateNonce (0, nonce); - // calulate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + // calculate hash for zero length + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed"); return false; } - MixHash (buf, 16); // h = SHA256(h || ciphertext) + MixHash (buf, 16); // h = SHA256(h || ciphertext) buf += 16; len -= 16; // KDF for payload - uint8_t keydata[64]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) if (m_State == eSessionStateNewSessionSent) - { - // k_ab = keydata[0:31], k_ba = keydata[32:63] + { + // k_ab = keydata[0:31], k_ba = keydata[32:63] m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_SendTagset->NextSessionTagRatchet (); auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); - } - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + } + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } if (m_State == eSessionStateNewSessionSent) - { + { m_State = eSessionStateEstablished; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } - memcpy (m_H, h, 32); // restore m_H - HandlePayload (buf, len - 16, nullptr, 0); + memcpy (m_H, h, 32); // restore m_H + HandlePayload (buf, len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it SetLeaseSetUpdateStatus (eLeaseSetUpToDate); SetLeaseSetUpdateMsgID (0); - - return true; - } + + return true; + } bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { @@ -578,18 +578,18 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; - } + } if (index >= ECIESX25519_TAGSET_MAX_NUM_TAGS && !m_SendForwardKey) - NewNextSendRatchet (); + NewNextSendRatchet (); return true; } - bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { uint8_t nonce[12]; CreateNonce (index, nonce); // tag's index - len -= 8; // tag + len -= 8; // tag uint8_t * payload = buf + 8; uint8_t key[32]; receiveTagset->GetSymmKey (index, key); @@ -597,17 +597,17 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; - } - HandlePayload (payload, len - 16, receiveTagset, index); + } + HandlePayload (payload, len - 16, receiveTagset, index); int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; - moreTags -= (receiveTagset->GetNextIndex () - index); + moreTags -= (receiveTagset->GetNextIndex () - index); if (moreTags > 0) - GenerateMoreReceiveTags (receiveTagset, moreTags); + GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } - bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); @@ -617,8 +617,8 @@ namespace garlic m_State = eSessionStateEstablished; m_NSRTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif + [[fallthrough]]; +#endif case eSessionStateEstablished: if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; // check NSR just in case @@ -637,77 +637,77 @@ namespace garlic return true; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) - { - auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); - size_t len = payload.size (); + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) + { + auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); + size_t len = payload.size (); if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - - switch (m_State) - { + + switch (m_State) + { case eSessionStateEstablished: if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) return nullptr; len += 24; - break; - case eSessionStateNew: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 96; - break; - case eSessionStateNewSessionReceived: - if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 72; - break; + break; + case eSessionStateNew: + if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 96; + break; + case eSessionStateNewSessionReceived: + if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 72; + break; case eSessionStateNewSessionReplySent: if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 72; - break; - default: - return nullptr; - } - - htobe32buf (m->GetPayload (), len); + return nullptr; + len += 72; + break; + default: + return nullptr; + } + + htobe32buf (m->GetPayload (), len); m->len += len + 4; m->FillI2NPMessageHeader (eI2NPGarlic); return m; - } + } - std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) - { + std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) + { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); - size_t payloadLen = 0; - if (first) payloadLen += 7;// datatime - if (msg && m_Destination) - payloadLen += msg->GetPayloadLength () + 13 + 32; + size_t payloadLen = 0; + if (first) payloadLen += 7;// datatime + if (msg && m_Destination) + payloadLen += msg->GetPayloadLength () + 13 + 32; auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || - (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && - ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? + (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && + ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) - { - payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; - if (!first) + { + payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; + if (!first) { // ack request SetLeaseSetUpdateStatus (eLeaseSetSubmitted); SetLeaseSetUpdateMsgID (m_SendTagset->GetNextIndex ()); SetLeaseSetSubmissionTime (ts); - payloadLen += 4; - } - } + payloadLen += 4; + } + } if (m_AckRequests.size () > 0) payloadLen += m_AckRequests.size ()*4 + 3; if (m_SendReverseKey) - { + { payloadLen += 6; if (m_NextReceiveRatchet->newKey) payloadLen += 32; - } + } if (m_SendForwardKey) { payloadLen += 6; @@ -715,110 +715,110 @@ namespace garlic } uint8_t paddingSize = 0; if (payloadLen) - { + { int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size { RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; // 0 - 15 if (delta > 3) - { + { delta -= 3; - if (paddingSize >= delta) paddingSize %= delta; - } + if (paddingSize >= delta) paddingSize %= delta; + } paddingSize++; - payloadLen += paddingSize + 3; - } - } - std::vector v(payloadLen); - size_t offset = 0; - // DateTime + payloadLen += paddingSize + 3; + } + } + std::vector v(payloadLen); + size_t offset = 0; + // DateTime if (first) - { - v[offset] = eECIESx25519BlkDateTime; offset++; - htobe16buf (v.data () + offset, 4); offset += 2; - htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds - } - // LeaseSet - if (leaseSet) - { - offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); + { + v[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (v.data () + offset, 4); offset += 2; + htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds + } + // LeaseSet + if (leaseSet) + { + offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); if (!first) - { + { // ack request v[offset] = eECIESx25519BlkAckRequest; offset++; htobe16buf (v.data () + offset, 1); offset += 2; v[offset] = 0; offset++; // flags - } - } - // msg - if (msg && m_Destination) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + } + } + // msg + if (msg && m_Destination) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); // ack if (m_AckRequests.size () > 0) { v[offset] = eECIESx25519BlkAck; offset++; - htobe16buf (v.data () + offset, m_AckRequests.size ()*4); offset += 2; + htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2; for (auto& it: m_AckRequests) { htobe16buf (v.data () + offset, it.first); offset += 2; htobe16buf (v.data () + offset, it.second); offset += 2; - } + } m_AckRequests.clear (); - } + } // next keys if (m_SendReverseKey) { v[offset] = eECIESx25519BlkNextKey; offset++; htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; + v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; int keyID = m_NextReceiveRatchet->keyID - 1; - if (m_NextReceiveRatchet->newKey) - { + if (m_NextReceiveRatchet->newKey) + { v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; keyID++; - } + } offset++; // flag htobe16buf (v.data () + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) - { - memcpy (v.data () + offset, m_NextReceiveRatchet->key.GetPublicKey (), 32); + { + memcpy (v.data () + offset, m_NextReceiveRatchet->key.GetPublicKey (), 32); offset += 32; // public key - } + } m_SendReverseKey = false; - } + } if (m_SendForwardKey) { v[offset] = eECIESx25519BlkNextKey; offset++; htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; + v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only offset++; // flag htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) - { - memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + { + memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); offset += 32; // public key - } - } - // padding + } + } + // padding if (paddingSize) - { - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; - } - return v; - } + { + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + } + return v; + } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) - { - if (!msg) return 0; - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) + { + if (!msg) return 0; + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; if (isDestination) cloveSize += 32; - if ((int)len < cloveSize + 3) return 0; - buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size + if ((int)len < cloveSize + 3) return 0; + buf[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (buf + 1, cloveSize); // size buf += 3; if (isDestination) { @@ -826,88 +826,86 @@ namespace garlic memcpy (buf + 1, *m_Destination, 32); buf += 32; } else - *buf = 0; + *buf = 0; buf++; // flag and delivery instructions - *buf = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 1, msg->GetMsgID ()); // msgID - htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); - return cloveSize + 3; - } + *buf = msg->GetTypeID (); // I2NP msg type + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration () / 1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); + return cloveSize + 3; + } size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len) - { + { if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) { LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send"); return 0; - } + } uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size + htobe16buf (buf + 1, cloveSize); // size buf += 3; *buf = 0; buf++; // flag and delivery instructions *buf = eI2NPDatabaseStore; buf++; // I2NP msg type RAND_bytes (buf, 4); buf += 4; // msgID - htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration + htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration // payload memcpy (buf + DATABASE_STORE_KEY_OFFSET, ls->GetStoreHash (), 32); buf[DATABASE_STORE_TYPE_OFFSET] = i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2; - memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 + memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 buf += DATABASE_STORE_HEADER_SIZE; memcpy (buf, ls->GetBuffer (), ls->GetBufferLen ()); return cloveSize + 3; } - + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { for (int i = 0; i < numTags; i++) GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); - } + } bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) - { + { CleanupUnconfirmedLeaseSet (ts); - return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; - } - + return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; + } + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 + memset (nonce, 0, 12); // n = 0 size_t offset = 0; memcpy (buf + offset, &tag, 8); offset += 8; auto payload = buf + offset; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; size_t len = cloveSize + 3; - payload[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (payload + 1, cloveSize); // size + payload[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (payload + 1, cloveSize); // size payload += 3; - *payload = 0; payload++; // flag and delivery instructions - *payload = msg->GetTypeID (); // I2NP msg type - htobe32buf (payload + 1, msg->GetMsgID ()); // msgID - htobe32buf (payload + 5, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); + *payload = 0; payload++; // flag and delivery instructions + *payload = msg->GetTypeID (); // I2NP msg type + htobe32buf (payload + 1, msg->GetMsgID ()); // msgID + htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds + memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; - } + } offset += len + 16; - + htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); return m; } - + } } - - diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 14f97ce9..d5a83f89 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -25,22 +25,22 @@ namespace garlic const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; - - const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ - // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ - - class ECIESX25519AEADRatchetSession; - class RatchetTagSet - { - public: - RatchetTagSet (std::shared_ptr session): m_Session (session) {}; - - void DHInitialize (const uint8_t * rootKey, const uint8_t * k); - void NextSessionTagRatchet (); - uint64_t GetNextSessionTag (); + const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ + // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ + + class ECIESX25519AEADRatchetSession; + class RatchetTagSet + { + public: + + RatchetTagSet (std::shared_ptr session): m_Session (session) {}; + + void DHInitialize (const uint8_t * rootKey, const uint8_t * k); + void NextSessionTagRatchet (); + uint64_t GetNextSessionTag (); const uint8_t * GetNextRootKey () const { return m_NextRootKey; }; - int GetNextIndex () const { return m_NextIndex; }; + int GetNextIndex () const { return m_NextIndex; }; void GetSymmKey (int index, uint8_t * key); std::shared_ptr GetSession () { return m_Session.lock (); }; @@ -49,54 +49,54 @@ namespace garlic void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + private: - - union - { - uint64_t ll[8]; - uint8_t buf[64]; - const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31] - const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63] - uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39] - - } m_KeyData; - uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; - int m_NextIndex, m_NextSymmKeyIndex; - std::unordered_map > m_ItermediateSymmKeys; - std::weak_ptr m_Session; - int m_TagSetID = 0; - uint64_t m_ExpirationTimestamp = 0; - }; + union + { + uint64_t ll[8]; + uint8_t buf[64]; - enum ECIESx25519BlockType + const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31] + const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63] + uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39] + + } m_KeyData; + uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; + int m_NextIndex, m_NextSymmKeyIndex; + std::unordered_map > m_ItermediateSymmKeys; + std::weak_ptr m_Session; + int m_TagSetID = 0; + uint64_t m_ExpirationTimestamp = 0; + }; + + enum ECIESx25519BlockType { - eECIESx25519BlkDateTime = 0, - eECIESx25519BlkSessionID = 1, + eECIESx25519BlkDateTime = 0, + eECIESx25519BlkSessionID = 1, eECIESx25519BlkTermination = 4, - eECIESx25519BlkOptions = 5, - eECIESx25519BlkNextKey = 7, - eECIESx25519BlkAck = 8, - eECIESx25519BlkAckRequest = 9, - eECIESx25519BlkGalicClove = 11, - eECIESx25519BlkPadding = 254 - }; + eECIESx25519BlkOptions = 5, + eECIESx25519BlkNextKey = 7, + eECIESx25519BlkAck = 8, + eECIESx25519BlkAckRequest = 9, + eECIESx25519BlkGalicClove = 11, + eECIESx25519BlkPadding = 254 + }; const uint8_t ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG = 0x01; const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02; const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; - - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this - { - enum SessionState - { - eSessionStateNew =0, - eSessionStateNewSessionReceived, + + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this + { + enum SessionState + { + eSessionStateNew = 0, + eSessionStateNewSessionReceived, eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, - eSessionStateEstablished - }; + eSessionStateEstablished + }; struct DHRatchet { @@ -104,65 +104,65 @@ namespace garlic i2p::crypto::X25519Keys key; uint8_t remote[32]; // last remote public key bool newKey = true; - }; - - public: + }; - ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); - ~ECIESX25519AEADRatchetSession (); + public: + + ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); + ~ECIESX25519AEADRatchetSession (); bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); - std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - - const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } void SetDestination (const i2p::data::IdentHash& dest) // TODO: { if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - + bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsRatchets () const { return true; }; - - private: + + private: void ResetKeys (); - void MixHash (const uint8_t * buf, size_t len); + void MixHash (const uint8_t * buf, size_t len); void CreateNonce (uint64_t seqn, uint8_t * nonce); - bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes + bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes std::shared_ptr CreateNewSessionTagset (); bool HandleNewIncomingSession (const uint8_t * buf, size_t len); - bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); + bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); - void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); + void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); - - bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + + bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - - std::vector CreatePayload (std::shared_ptr msg, bool first); - size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + + std::vector CreatePayload (std::shared_ptr msg, bool first); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); - + void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); void NewNextSendRatchet (); - - private: - uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; + private: + + uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only - i2p::crypto::X25519Keys m_EphemeralKeys; - SessionState m_State = eSessionStateNew; + i2p::crypto::X25519Keys m_EphemeralKeys; + SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset, m_NSRTagset; - std::unique_ptr m_Destination;// TODO: might not need it + std::shared_ptr m_SendTagset, m_NSRTagset; + std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; @@ -174,8 +174,8 @@ namespace garlic i2p::data::IdentHash GetDestination () const { return m_Destination ? *m_Destination : i2p::data::IdentHash (); - } - }; + } + }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); } diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 69fec4e8..8de5e3a1 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -121,7 +121,7 @@ namespace crypto return passed; } - void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, + void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const { BN_CTX * bnCtx = BN_CTX_new (); @@ -153,7 +153,7 @@ namespace crypto BN_CTX_free (bnCtx); } - void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, + void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const { BN_CTX * bnCtx = BN_CTX_new (); @@ -164,16 +164,16 @@ namespace crypto SHA512_CTX ctx; SHA512_Init (&ctx); SHA512_Update (&ctx, T, 80); - SHA512_Update (&ctx, publicKeyEncoded, 32); + SHA512_Update (&ctx, publicKeyEncoded, 32); SHA512_Update (&ctx, buf, len); // data uint8_t digest[64]; SHA512_Final (digest, &ctx); - BIGNUM * r = DecodeBN<64> (digest); - BN_mod (r, r, l, bnCtx); // % l + BIGNUM * r = DecodeBN<64> (digest); + BN_mod (r, r, l, bnCtx); // % l EncodeBN (r, digest, 32); // calculate R uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf - EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); + EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); // calculate S SHA512_Init (&ctx); SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R @@ -182,7 +182,7 @@ namespace crypto SHA512_Final (digest, &ctx); BIGNUM * h = DecodeBN<64> (digest); // S = (r + h*a) % l - BIGNUM * a = DecodeBN (privateKey); + BIGNUM * a = DecodeBN (privateKey); BN_mod_mul (h, h, a, l, bnCtx); // %l BN_mod_add (h, h, r, l, bnCtx); // %l memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2); @@ -190,7 +190,7 @@ namespace crypto BN_free (r); BN_free (h); BN_free (a); BN_CTX_free (bnCtx); } - + EDDSAPoint Ed25519::Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const { // x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2) @@ -467,7 +467,7 @@ namespace crypto --bits; auto k_t = BN_is_bit_set(k, bits) ? 1 : 0; swap ^= k_t; - if (swap) + if (swap) { std::swap (x2, x3); std::swap (z2, z3); @@ -492,7 +492,7 @@ namespace crypto BN_mod_mul(z3, x1, z2, q, ctx); BN_mod_mul(z2, tmp1, tmp0, q, ctx); } - if (swap) + if (swap) { std::swap (x2, x3); std::swap (z2, z3); @@ -533,9 +533,9 @@ namespace crypto { BN_CTX * ctx = BN_CTX_new (); // calculate alpha = seed mod l - BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian + BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian BN_mod (alpha, alpha, l, ctx); // % l - uint8_t priv[32]; + uint8_t priv[32]; EncodeBN (alpha, priv, 32); // back to Little Endian BN_free (alpha); // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) @@ -548,16 +548,16 @@ namespace crypto { BN_CTX * ctx = BN_CTX_new (); // calculate alpha = seed mod l - BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian + BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian BN_mod (alpha, alpha, l, ctx); // % l - BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian + BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian BN_add (alpha, alpha, p); // alpha = alpha + priv - // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L BN_mod (alpha, alpha, l, ctx); // % l EncodeBN (alpha, blindedPriv, 32); - // A' = DERIVE_PUBLIC(a') + // A' = DERIVE_PUBLIC(a') auto A1 = MulB (blindedPriv, ctx); - EncodePublicKey (A1, blindedPub, ctx); + EncodePublicKey (A1, blindedPub, ctx); BN_free (alpha); BN_free (p); BN_CTX_free (ctx); } @@ -574,14 +574,14 @@ namespace crypto { uint8_t seed[32]; RAND_bytes (seed, 32); - BIGNUM * p = DecodeBN<32> (seed); + BIGNUM * p = DecodeBN<32> (seed); BN_CTX * ctx = BN_CTX_new (); BN_mod (p, p, l, ctx); // % l - EncodeBN (p, priv, 32); + EncodeBN (p, priv, 32); BN_CTX_free (ctx); BN_free (p); - } - + } + static std::unique_ptr g_Ed25519; std::unique_ptr& GetEd25519 () { @@ -597,4 +597,3 @@ namespace crypto } } } - diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index 84501b03..10061ad0 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -86,10 +86,10 @@ namespace crypto bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const; void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; void SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; - + static void ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey); // key - 32 bytes, expandedKey - 64 bytes void CreateRedDSAPrivateKey (uint8_t * priv); // priv is 32 bytes - + private: EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const; @@ -97,8 +97,8 @@ namespace crypto EDDSAPoint Mul (const EDDSAPoint& p, const BIGNUM * e, BN_CTX * ctx) const; EDDSAPoint MulB (const uint8_t * e, BN_CTX * ctx) const; // B*e, e is 32 bytes Little Endian EDDSAPoint Normalize (const EDDSAPoint& p, BN_CTX * ctx) const; - - bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const; + + bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const; BIGNUM * RecoverX (const BIGNUM * y, BN_CTX * ctx) const; EDDSAPoint DecodePoint (const uint8_t * buf, BN_CTX * ctx) const; void EncodePoint (const EDDSAPoint& p, uint8_t * buf) const; @@ -109,7 +109,7 @@ namespace crypto #if !OPENSSL_X25519 // for x25519 - BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const; + BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const; #endif private: @@ -121,13 +121,11 @@ namespace crypto // if j > 128 we use 256 - j and carry 1 to next byte // Bi256[0][0] = B, base point EDDSAPoint Bi256Carry; // Bi256[32][0] - }; + }; std::unique_ptr& GetEd25519 (); } } - #endif - diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 48a5a7ac..8fefb2ae 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -6,7 +6,7 @@ namespace i2p { namespace crypto { - + Elligator2::Elligator2 () { // TODO: share with Ed22519 @@ -21,32 +21,32 @@ namespace crypto A = BN_new (); BN_set_word (A, 486662); nA = BN_new (); BN_sub (nA, p, A); - BN_CTX * ctx = BN_CTX_new (); - // calculate sqrt(-1) + BN_CTX * ctx = BN_CTX_new (); + // calculate sqrt(-1) sqrtn1 = BN_new (); - BN_set_word (sqrtn1, 2); + BN_set_word (sqrtn1, 2); BN_mod_exp (sqrtn1, sqrtn1, p14, p, ctx); // 2^((p-1)/4 - + u = BN_new (); BN_set_word (u, 2); - iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); - + iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); + BN_CTX_free (ctx); } Elligator2::~Elligator2 () { BN_free (p); BN_free (p38); BN_free (p12); BN_free (p14); - BN_free (sqrtn1); BN_free (A); BN_free (nA); - BN_free (u); BN_free (iu); + BN_free (sqrtn1); BN_free (A); BN_free (nA); + BN_free (u); BN_free (iu); } bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const - { + { bool ret = true; BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - uint8_t key1[32]; + uint8_t key1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { key1[i] = key[31 - i]; @@ -59,35 +59,35 @@ namespace crypto BIGNUM * uxxA = BN_CTX_get (ctx); // u*x*xA BN_mod_mul (uxxA, u, x, p, ctx); - BN_mod_mul (uxxA, uxxA, xA, p, ctx); - + BN_mod_mul (uxxA, uxxA, xA, p, ctx); + if (Legendre (uxxA, ctx) != -1) - { - uint8_t randByte = 0; // random highest bits and high y + { + uint8_t randByte = 0; // random highest bits and high y if (random) - { - RAND_bytes (&randByte, 1); - highY = randByte & 0x01; + { + RAND_bytes (&randByte, 1); + highY = randByte & 0x01; } - + BIGNUM * r = BN_CTX_get (ctx); if (highY) { BN_mod_inverse (r, x, p, ctx); - BN_mod_mul (r, r, xA, p, ctx); + BN_mod_mul (r, r, xA, p, ctx); } else { - BN_mod_inverse (r, xA, p, ctx); + BN_mod_inverse (r, xA, p, ctx); BN_mod_mul (r, r, x, p, ctx); - } - BN_mod_mul (r, r, iu, p, ctx); - + } + BN_mod_mul (r, r, iu, p, ctx); + SquareRoot (r, r, ctx); bn2buf (r, encoded, 32); if (random) - encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte + encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = encoded[i]; @@ -98,7 +98,7 @@ namespace crypto else ret = false; - BN_CTX_end (ctx); + BN_CTX_end (ctx); BN_CTX_free (ctx); return ret; } @@ -109,31 +109,31 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - uint8_t encoded1[32]; + uint8_t encoded1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { encoded1[i] = encoded[31 - i]; encoded1[31 - i] = encoded[i]; } - encoded1[0] &= 0x3F; // drop two highest bits + encoded1[0] &= 0x3F; // drop two highest bits BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); if (BN_cmp (r, p12) <= 0) // r < (p-1)/2 { // v = -A/(1+u*r^2) - BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); + BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); BN_mod_mul (v, v, u, p, ctx); BN_add_word (v, 1); - BN_mod_inverse (v, v, p, ctx); + BN_mod_inverse (v, v, p, ctx); BN_mod_mul (v, v, nA, p, ctx); BIGNUM * vpA = BN_CTX_get (ctx); BN_add (vpA, v, A); // v + A // t = v^3+A*v^2+v = v^2*(v+A)+v - BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); - BN_mod_mul (t, t, vpA, p, ctx); - BN_mod_add (t, t, v, p, ctx); + BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); + BN_mod_mul (t, t, vpA, p, ctx); + BN_mod_add (t, t, v, p, ctx); int legendre = Legendre (t, ctx); BIGNUM * x = BN_CTX_get (ctx); @@ -143,9 +143,9 @@ namespace crypto { BN_sub (x, p, v); BN_mod_sub (x, x, A, p, ctx); - } - - bn2buf (x, key, 32); + } + + bn2buf (x, key, 32); for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = key[i]; @@ -156,7 +156,7 @@ namespace crypto else ret = false; - BN_CTX_end (ctx); + BN_CTX_end (ctx); BN_CTX_free (ctx); return ret; @@ -170,21 +170,21 @@ namespace crypto BN_add_word (t, 1); if (!BN_cmp (t, p)) - BN_mod_mul (r, r, sqrtn1, p, ctx); + BN_mod_mul (r, r, sqrtn1, p, ctx); if (BN_cmp (r, p12) > 0) // r > (p-1)/2 BN_sub (r, p, r); - } - + } + int Elligator2::Legendre (const BIGNUM * a, BN_CTX * ctx) const { // assume a < p, so don't check for a % p = 0, but a = 0 only - if (BN_is_zero(a)) return 0; + if (BN_is_zero(a)) return 0; BIGNUM * r = BN_CTX_get (ctx); BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p - if (BN_is_word(r, 1)) + if (BN_is_word(r, 1)) return 1; - else if (BN_is_zero(r)) + else if (BN_is_zero(r)) return 0; return -1; } @@ -204,4 +204,3 @@ namespace crypto } } } - diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 7cdcbbfe..56fbc2eb 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -20,11 +20,11 @@ namespace crypto bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false, bool random = true) const; bool Decode (const uint8_t * encoded, uint8_t * key) const; - private: + private: void SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const; int Legendre (const BIGNUM * a, BN_CTX * ctx) const; // a/p - + private: BIGNUM * p, * p38, * p12, * p14, * sqrtn1, * A, * nA, * u, * iu; @@ -35,5 +35,3 @@ namespace crypto } #endif - - diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 6f112218..054ac2a3 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -17,133 +17,136 @@ namespace i2p { namespace fs { - extern std::string dirSep; + extern std::string dirSep; - /** - * @brief Class to work with NetDb & Router profiles - * - * Usage: - * - * const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; - * auto h = HashedStorage("name", "y", "z-", ".txt"); - * h.SetPlace("/tmp/hs-test"); - * h.GetName() -> gives "name" - * h.GetRoot() -> gives "/tmp/hs-test/name" - * h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet - * h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt - * h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists - * std::vector files; - * h.Traverse(files); <- finds all files in storage and saves in given vector - */ - class HashedStorage { - protected: - std::string root; /**< path to storage with it's name included */ - std::string name; /**< name of the storage */ - std::string prefix1; /**< hashed directory prefix */ - std::string prefix2; /**< prefix of file in storage */ - std::string suffix; /**< suffix of file in storage (extension) */ + /** + * @brief Class to work with NetDb & Router profiles + * + * Usage: + * + * const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; + * auto h = HashedStorage("name", "y", "z-", ".txt"); + * h.SetPlace("/tmp/hs-test"); + * h.GetName() -> gives "name" + * h.GetRoot() -> gives "/tmp/hs-test/name" + * h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet + * h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt + * h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists + * std::vector files; + * h.Traverse(files); <- finds all files in storage and saves in given vector + */ + class HashedStorage + { + protected: - public: - typedef std::function FilenameVisitor; - HashedStorage(const char *n, const char *p1, const char *p2, const char *s): - name(n), prefix1(p1), prefix2(p2), suffix(s) {}; + std::string root; /**< path to storage with it's name included */ + std::string name; /**< name of the storage */ + std::string prefix1; /**< hashed directory prefix */ + std::string prefix2; /**< prefix of file in storage */ + std::string suffix; /**< suffix of file in storage (extension) */ - /** create subdirs in storage */ - bool Init(const char* chars, size_t cnt); - const std::string & GetRoot() const { return root; } - const std::string & GetName() const { return name; } - /** set directory where to place storage directory */ - void SetPlace(const std::string & path); - /** path to file with given ident */ - std::string Path(const std::string & ident) const; - /** remove file by ident */ - void Remove(const std::string & ident); - /** find all files in storage and store list in provided vector */ - void Traverse(std::vector & files); - /** visit every file in this storage with a visitor */ - void Iterate(FilenameVisitor v); - }; + public: - /** @brief Returns current application name, default 'i2pd' */ + typedef std::function FilenameVisitor; + HashedStorage(const char *n, const char *p1, const char *p2, const char *s): + name(n), prefix1(p1), prefix2(p2), suffix(s) {}; + + /** create subdirs in storage */ + bool Init(const char* chars, size_t cnt); + const std::string & GetRoot() const { return root; } + const std::string & GetName() const { return name; } + /** set directory where to place storage directory */ + void SetPlace(const std::string & path); + /** path to file with given ident */ + std::string Path(const std::string & ident) const; + /** remove file by ident */ + void Remove(const std::string & ident); + /** find all files in storage and store list in provided vector */ + void Traverse(std::vector & files); + /** visit every file in this storage with a visitor */ + void Iterate(FilenameVisitor v); + }; + + /** @brief Returns current application name, default 'i2pd' */ const std::string & GetAppName (); - /** @brief Set application name, affects autodetection of datadir */ + /** @brief Set application name, affects autodetection of datadir */ void SetAppName (const std::string& name); - /** @brief Returns datadir path */ - const std::string & GetDataDir(); + /** @brief Returns datadir path */ + const std::string & GetDataDir(); - /** - * @brief Set datadir either from cmdline option or using autodetection - * @param cmdline_param Value of cmdline parameter --datadir= - * @param isService Value of cmdline parameter --service - * - * Examples of autodetected paths: - * - * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\ - * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\ - * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/ - * Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/ - */ - void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); + /** + * @brief Set datadir either from cmdline option or using autodetection + * @param cmdline_param Value of cmdline parameter --datadir= + * @param isService Value of cmdline parameter --service + * + * Examples of autodetected paths: + * + * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\ + * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\ + * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/ + * Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/ + */ + void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); - /** - * @brief Create subdirectories inside datadir - */ - bool Init(); + /** + * @brief Create subdirectories inside datadir + */ + bool Init(); - /** - * @brief Get list of files in directory - * @param path Path to directory - * @param files Vector to store found files - * @return true on success and false if directory not exists - */ - bool ReadDir(const std::string & path, std::vector & files); + /** + * @brief Get list of files in directory + * @param path Path to directory + * @param files Vector to store found files + * @return true on success and false if directory not exists + */ + bool ReadDir(const std::string & path, std::vector & files); - /** - * @brief Remove file with given path - * @param path Absolute path to file - * @return true on success, false if file not exists, throws exception on error - */ - bool Remove(const std::string & path); + /** + * @brief Remove file with given path + * @param path Absolute path to file + * @return true on success, false if file not exists, throws exception on error + */ + bool Remove(const std::string & path); - /** - * @brief Check existence of file - * @param path Absolute path to file - * @return true if file exists, false otherwise - */ - bool Exists(const std::string & path); + /** + * @brief Check existence of file + * @param path Absolute path to file + * @return true if file exists, false otherwise + */ + bool Exists(const std::string & path); - uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch + uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch - bool CreateDirectory (const std::string& path); + bool CreateDirectory (const std::string& path); - template - void _ExpandPath(std::stringstream & path, T c) { - path << i2p::fs::dirSep << c; - } + template + void _ExpandPath(std::stringstream & path, T c) { + path << i2p::fs::dirSep << c; + } - template - void _ExpandPath(std::stringstream & path, T c, Other ... other) { - _ExpandPath(path, c); - _ExpandPath(path, other ...); - } + template + void _ExpandPath(std::stringstream & path, T c, Other ... other) { + _ExpandPath(path, c); + _ExpandPath(path, other ...); + } - /** - * @brief Get path relative to datadir - * - * Examples (with datadir = "/tmp/i2pd"): - * - * i2p::fs::Path("test") -> '/tmp/i2pd/test' - * i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt' - */ - template - std::string DataDirPath(Other ... components) { - std::stringstream s(""); - s << i2p::fs::GetDataDir(); - _ExpandPath(s, components ...); + /** + * @brief Get path relative to datadir + * + * Examples (with datadir = "/tmp/i2pd"): + * + * i2p::fs::Path("test") -> '/tmp/i2pd/test' + * i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt' + */ + template + std::string DataDirPath(Other ... components) { + std::stringstream s(""); + s << i2p::fs::GetDataDir(); + _ExpandPath(s, components ...); - return s.str(); - } + return s.str(); + } template std::string StorageRootPath (const Storage& storage, Filename... filenames) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index bc99bb52..e5ac9990 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -179,4 +179,3 @@ namespace data } } } - diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 8ba4a8a1..5d07155e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -38,9 +38,9 @@ namespace garlic if (!m_SharedRoutingPath) return nullptr; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); if (m_SharedRoutingPath->numTimesUsed >= ROUTING_PATH_MAX_NUM_TIMES_USED || - !m_SharedRoutingPath->outboundTunnel->IsEstablished () || + !m_SharedRoutingPath->outboundTunnel->IsEstablished () || ts*1000LL > m_SharedRoutingPath->remoteLease->endDate || - ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT) + ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT) m_SharedRoutingPath = nullptr; if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++; return m_SharedRoutingPath; @@ -68,7 +68,7 @@ namespace garlic return true; } return false; - } + } void GarlicRoutingSession::CleanupUnconfirmedLeaseSet (uint64_t ts) { @@ -78,8 +78,8 @@ namespace garlic GetOwner ()->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); m_LeaseSetUpdateMsgID = 0; } - } - + } + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) { auto msg = CreateDeliveryStatusMsg (msgID); @@ -94,12 +94,12 @@ namespace garlic msg = garlic.WrapSingleMessage (msg); } return msg; - } - - ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, - std::shared_ptr destination, int numTags, bool attachLeaseSet): - GarlicRoutingSession (owner, attachLeaseSet), - m_Destination (destination), m_NumTags (numTags) + } + + ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, + std::shared_ptr destination, int numTags, bool attachLeaseSet): + GarlicRoutingSession (owner, attachLeaseSet), + m_Destination (destination), m_NumTags (numTags) { // create new session tags and session key RAND_bytes (m_SessionKey, 32); @@ -115,7 +115,7 @@ namespace garlic m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch (); } - std::shared_ptr ElGamalAESSession::WrapSingleMessage (std::shared_ptr msg) + std::shared_ptr ElGamalAESSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -181,7 +181,7 @@ namespace garlic return m; } - size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) + size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) { size_t blockSize = 0; bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3); @@ -329,10 +329,10 @@ namespace garlic // create msg auto msg = CreateEncryptedDeliveryStatusMsg (msgID); if (msg) - { + { memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); size += msg->GetLength (); - } + } // fill clove uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 8000; // 8 sec uint32_t cloveID; @@ -353,7 +353,7 @@ namespace garlic return size; } - ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags () + ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags () { auto tags = new UnconfirmedTags (m_NumTags); tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch (); @@ -487,7 +487,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes"); } else - { + { bool found = false; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) { @@ -500,15 +500,15 @@ namespace garlic found = true; auto session = it1->second.tagset->GetSession (); if (!session || !session->HandleNextMessage (buf, length, it1->second.tagset, it1->second.index)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); } - } - - if (!found) // assume new session + } + + if (!found) // assume new session { - // AES tag not found. Handle depending on encryption type - // try ElGamal/AES first if leading block is 514 + // AES tag not found. Handle depending on encryption type + // try ElGamal/AES first if leading block is 514 ElGamalBlock elGamal; if (mod == 2 && length >= 514 && SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) @@ -521,16 +521,16 @@ namespace garlic HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - { - // otherwise ECIESx25519 + { + // otherwise ECIESx25519 auto session = std::make_shared (this, false); // incoming if (!session->HandleNextMessage (buf, length, nullptr, 0)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); - } + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + } else - LogPrint (eLogError, "Garlic: Failed to decrypt message"); + LogPrint (eLogError, "Garlic: Failed to decrypt message"); } - } + } } void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, @@ -703,41 +703,41 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && - SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - { - ECIESX25519AEADRatchetSessionPtr session; - uint8_t staticKey[32]; - destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key - auto it = m_ECIESx25519Sessions.find (staticKey); + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + { + ECIESX25519AEADRatchetSessionPtr session; + uint8_t staticKey[32]; + destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) - session = it->second; - if (!session) + session = it->second; + if (!session) { session = std::make_shared (this, true); session->SetRemoteStaticKey (staticKey); - } + } session->SetDestination (destination->GetIdentHash ()); // TODO: remove - return session; - } - else - { - ElGamalAESSessionPtr session; - { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (destination->GetIdentHash ()); - if (it != m_Sessions.end ()) - session = it->second; - } - if (!session) - { - session = std::make_shared (this, destination, - attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests - std::unique_lock l(m_SessionsMutex); - m_Sessions[destination->GetIdentHash ()] = session; - } - return session; - } + return session; + } + else + { + ElGamalAESSessionPtr session; + { + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (destination->GetIdentHash ()); + if (it != m_Sessions.end ()) + session = it->second; + } + if (!session) + { + session = std::make_shared (this, destination, + attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests + std::unique_lock l(m_SessionsMutex); + m_Sessions[destination->GetIdentHash ()] = session; + } + return session; + } } void GarlicDestination::CleanupExpiredTags () @@ -791,7 +791,7 @@ namespace garlic if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else - ++it; + ++it; } for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) @@ -800,7 +800,7 @@ namespace garlic { it->second->SetOwner (nullptr); it = m_ECIESx25519Sessions.erase (it); - } + } else ++it; } @@ -925,28 +925,28 @@ namespace garlic std::vector files; i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it: files) + for (auto it: files) if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT) i2p::fs::Remove (it); } - void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) - { - const uint8_t * buf1 = buf; + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + { + const uint8_t * buf1 = buf; uint8_t flag = buf[0]; buf++; // flag GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); switch (deliveryType) { case eGarlicDeliveryTypeDestination: - LogPrint (eLogDebug, "Garlic: type destination"); + LogPrint (eLogDebug, "Garlic: type destination"); buf += 32; // TODO: check destination -#if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here case eGarlicDeliveryTypeLocal: { - LogPrint (eLogDebug, "Garlic: type local"); + LogPrint (eLogDebug, "Garlic: type local"); I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid buf += (4 + 4); // msgID + expiration ptrdiff_t offset = buf - buf1; @@ -957,8 +957,8 @@ namespace garlic break; } case eGarlicDeliveryTypeTunnel: - { - LogPrint (eLogDebug, "Garlic: type tunnel"); + { + LogPrint (eLogDebug, "Garlic: type tunnel"); // gwHash and gwTunnel sequence is reverted const uint8_t * gwHash = buf; buf += 32; @@ -968,47 +968,47 @@ namespace garlic LogPrint (eLogError, "Garlic: message is too short"); break; } - uint32_t gwTunnel = bufbe32toh (buf); buf += 4; - I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + uint32_t gwTunnel = bufbe32toh (buf); buf += 4; + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid buf += (4 + 4); // msgID + expiration - offset += 13; + offset += 13; if (GetTunnelPool ()) - { - auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); - if (tunnel) - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + { + auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + if (tunnel) + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); else - LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); - } + LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + } else LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); - break; - } + break; + } default: LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); - } - } + } + } - void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) - { + void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) + { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); - } + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); + } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) { i2p::data::Tag<32> staticKeyTag (staticKey); auto it = m_ECIESx25519Sessions.find (staticKeyTag); if (it != m_ECIESx25519Sessions.end ()) - { + { if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) m_ECIESx25519Sessions.erase (it); else { - LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); + LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); return; - } + } } m_ECIESx25519Sessions.emplace (staticKeyTag, session); } @@ -1020,7 +1020,7 @@ namespace garlic { it->second->SetOwner (nullptr); m_ECIESx25519Sessions.erase (it); - } - } + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 86c9e432..55ebe795 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -87,8 +87,8 @@ namespace garlic class GarlicDestination; class GarlicRoutingSession { - protected: - + protected: + enum LeaseSetUpdateStatus { eLeaseSetUpToDate = 0, @@ -103,10 +103,10 @@ namespace garlic GarlicRoutingSession (); virtual ~GarlicRoutingSession (); virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; - virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession + virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); virtual bool IsRatchets () const { return false; }; - + void SetLeaseSetUpdated () { if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated; @@ -115,23 +115,23 @@ namespace garlic bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; }; uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; } void CleanupUnconfirmedLeaseSet (uint64_t ts); - + std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); GarlicDestination * GetOwner () const { return m_Owner; } void SetOwner (GarlicDestination * owner) { m_Owner = owner; } - - protected: - - LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } - void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } - uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } - void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } - void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } + + protected: + + LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } + void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } + uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } + void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } + void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } std::shared_ptr CreateEncryptedDeliveryStatusMsg (uint32_t msgID); - + private: GarlicDestination * m_Owner; @@ -143,38 +143,39 @@ namespace garlic std::shared_ptr m_SharedRoutingPath; public: + // for HTTP only virtual size_t GetNumOutgoingTags () const { return 0; }; }; - //using GarlicRoutingSessionPtr = std::shared_ptr; - typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 + //using GarlicRoutingSessionPtr = std::shared_ptr; + typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 - class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this - { - struct UnconfirmedTags - { - UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; - ~UnconfirmedTags () { delete[] sessionTags; }; - uint32_t msgID; - int numTags; - SessionTag * sessionTags; - uint32_t tagsCreationTime; - }; + class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this + { + struct UnconfirmedTags + { + UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; + ~UnconfirmedTags () { delete[] sessionTags; }; + uint32_t msgID; + int numTags; + SessionTag * sessionTags; + uint32_t tagsCreationTime; + }; - public: + public: - ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, + ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, int numTags, bool attachLeaseSet); ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption ~ElGamalAESSession () {}; - std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - - bool MessageConfirmed (uint32_t msgID); + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + bool MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left bool CleanupUnconfirmedTags (); // returns true if something has been deleted - private: + private: size_t CreateAESBlock (uint8_t * buf, std::shared_ptr msg); size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr msg, UnconfirmedTags * newTags); @@ -183,32 +184,33 @@ namespace garlic void TagsConfirmed (uint32_t msgID); UnconfirmedTags * GenerateSessionTags (); - - private: - - std::shared_ptr m_Destination; - i2p::crypto::AESKey m_SessionKey; + private: + + std::shared_ptr m_Destination; + + i2p::crypto::AESKey m_SessionKey; std::list m_SessionTags; int m_NumTags; std::map > m_UnconfirmedTagsMsgs; // msgID->tags - i2p::crypto::CBCEncryption m_Encryption; + i2p::crypto::CBCEncryption m_Encryption; + + public: - public: // for HTTP only - size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; - }; - typedef std::shared_ptr ElGamalAESSessionPtr; + size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; + }; + typedef std::shared_ptr ElGamalAESSessionPtr; - class ECIESX25519AEADRatchetSession; - typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; + class ECIESX25519AEADRatchetSession; + typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; class RatchetTagSet; typedef std::shared_ptr RatchetTagSetPtr; struct ECIESX25519AEADRatchetIndexTagset - { - int index; - RatchetTagSetPtr tagset; + { + int index; + RatchetTagSetPtr tagset; uint64_t creationTime; // seconds since epoch }; @@ -226,12 +228,12 @@ namespace garlic void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); std::shared_ptr WrapMessage (std::shared_ptr destination, - std::shared_ptr msg, bool attachLeaseSet = false); + std::shared_ptr msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); - void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); + void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); @@ -266,10 +268,10 @@ namespace garlic int m_NumTags; std::mutex m_SessionsMutex; std::unordered_map m_Sessions; - std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session + std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming std::unordered_map, std::hash > > m_Tags; - std::unordered_map m_ECIESx25519Tags; // session tag -> session + std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session diff --git a/libi2pd/Gost.h b/libi2pd/Gost.h index 30386104..a4cc9741 100644 --- a/libi2pd/Gost.h +++ b/libi2pd/Gost.h @@ -13,11 +13,11 @@ namespace crypto enum GOSTR3410ParamSet { - eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 + eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 // XchA = A, XchB = C - //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 - //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 - eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1 + //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 + //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 + eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1 eGOSTR3410NumParamSets }; diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index f36620ae..5709719b 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -40,13 +40,13 @@ namespace data { LogPrint (eLogError, "Gzip: Incorrect length"); return 0; - } + } if (len > outLen) len = outLen; memcpy (out, in + 15, len); return len; } else - { + { if (m_IsDirty) inflateReset (&m_Inflator); m_IsDirty = true; m_Inflator.next_in = const_cast(in); @@ -59,7 +59,7 @@ namespace data // else LogPrint (eLogError, "Gzip: Inflate error ", err); return 0; - } + } } void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) @@ -126,7 +126,7 @@ namespace data { out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; - } + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; @@ -147,21 +147,21 @@ namespace data auto flush = (it == bufs.back ()) ? Z_FINISH : Z_NO_FLUSH; err = deflate (&m_Deflator, flush); if (err) - { + { if (flush && err == Z_STREAM_END) { out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; - } + } break; } offset = outLen - m_Deflator.avail_out; - } + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; - } - + } + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; @@ -176,7 +176,7 @@ namespace data } size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen) - { + { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; memcpy (out, gzipHeader, 11); uint32_t crc = 0; @@ -186,9 +186,9 @@ namespace data len1 = len; len += it.second; if (outLen < len + 23) return 0; - memcpy (out + 15 + len1, it.first, it.second); + memcpy (out + 15 + len1, it.first, it.second); crc = crc32 (crc, it.first, it.second); - } + } if (len > 0xffff) return 0; htole32buf (out + len + 15, crc); htole32buf (out + len + 19, len); @@ -196,6 +196,6 @@ namespace data htole16buf (out + 13, 0xffff - len); return len + 23; } - + } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 16776d35..6489b79b 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -4,9 +4,9 @@ #include #include -namespace i2p +namespace i2p { -namespace data +namespace data { class GzipInflator { @@ -45,7 +45,6 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen); // for total size < 64K - } // data } // i2p diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 3a139792..170bb864 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -180,9 +180,9 @@ namespace i2p // excluded if (cnt > 512) { - LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup"); + LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup"); cnt = 0; - } + } htobe16buf (buf, cnt); buf += 2; if (cnt > 0) @@ -205,7 +205,7 @@ namespace i2p } std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, - std::vector routers) + std::vector routers) { auto m = NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); @@ -268,7 +268,7 @@ namespace i2p auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); memcpy (payload + DATABASE_STORE_KEY_OFFSET, storeHash, 32); - payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet + payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); size_t size = DATABASE_STORE_HEADER_SIZE; memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ()); @@ -278,7 +278,7 @@ namespace i2p return m; } - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken, std::shared_ptr replyTunnel) + std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken, std::shared_ptr replyTunnel) { if (!leaseSet) return nullptr; auto m = NewI2NPShortMessage (); @@ -347,11 +347,11 @@ namespace i2p auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, - clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, + clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40); + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0; } @@ -386,7 +386,7 @@ namespace i2p return; } - auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); + auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); if (tunnel) { // endpoint of inbound tunnel @@ -414,7 +414,7 @@ namespace i2p transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -440,7 +440,7 @@ namespace i2p transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -592,13 +592,13 @@ namespace i2p switch (typeID) { case eI2NPVariableTunnelBuild: - HandleVariableTunnelBuildMsg (msgID, buf, size); + HandleVariableTunnelBuildMsg (msgID, buf, size); break; case eI2NPVariableTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; case eI2NPTunnelBuild: - HandleTunnelBuildMsg (buf, size); + HandleTunnelBuildMsg (buf, size); break; case eI2NPTunnelBuildReply: // TODO: @@ -667,7 +667,7 @@ namespace i2p Flush (); } - void I2NPMessagesHandler::PutNextMessage (std::shared_ptr msg) + void I2NPMessagesHandler::PutNextMessage (std::shared_ptr msg) { if (msg) { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index c8957b5f..4ecba2eb 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -27,7 +27,7 @@ namespace i2p const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4; // I2NP NTCP2 header - const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4; + const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4; // Tunnel Gateway header const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0; @@ -75,7 +75,7 @@ namespace i2p enum I2NPMessageType { - eI2NPDummyMsg = 0, + eI2NPDummyMsg = 0, eI2NPDatabaseStore = 1, eI2NPDatabaseLookup = 2, eI2NPDatabaseSearchReply = 3, @@ -209,7 +209,7 @@ namespace tunnel SetExpiration (bufbe32toh (ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET)*1000LL); SetSize (len - offset - I2NP_HEADER_SIZE); SetChks (0); - } + } void ToNTCP2 () { diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 0c2dc50e..77a1f7e2 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -356,7 +356,7 @@ namespace data } return nullptr; } - + void IdentityEx::CreateVerifier () const { if (m_Verifier) return; // don't create again @@ -369,15 +369,15 @@ namespace data else { // for P521 - uint8_t * signingKey = new uint8_t[keyLen]; + uint8_t * signingKey = new uint8_t[keyLen]; memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = keyLen - 128; + size_t excessLen = keyLen - 128; memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types verifier->SetPublicKey (signingKey); - delete[] signingKey; - } - } - UpdateVerifier (verifier); + delete[] signingKey; + } + } + UpdateVerifier (verifier); } void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const @@ -390,7 +390,7 @@ namespace data else del = true; } - if (del) + if (del) delete verifier; } @@ -426,7 +426,7 @@ namespace data LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)keyType); }; return nullptr; - } + } std::shared_ptr IdentityEx::CreateEncryptor (const uint8_t * key) const { @@ -460,9 +460,9 @@ namespace data return *this; } - size_t PrivateKeys::GetFullLen () const - { - size_t ret = m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); + size_t PrivateKeys::GetFullLen () const + { + size_t ret = m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); if (IsOfflineSignature ()) ret += m_OfflineSignature.size () + m_TransientSigningPrivateKeyLen; return ret; @@ -483,7 +483,7 @@ namespace data // check if signing private key is all zeros bool allzeros = true; for (size_t i = 0; i < signingPrivateKeySize; i++) - if (m_SigningPrivateKey[i]) + if (m_SigningPrivateKey[i]) { allzeros = false; break; @@ -500,7 +500,7 @@ namespace data if (keyLen + ret > len) return 0; transientVerifier->SetPublicKey (buf + ret); ret += keyLen; if (m_Public->GetSignatureLen () + ret > len) return 0; - if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret)) + if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret)) { LogPrint (eLogError, "Identity: offline signature verification failed"); return 0; @@ -511,7 +511,7 @@ namespace data size_t offlineInfoLen = buf + ret - offlineInfo; m_OfflineSignature.resize (offlineInfoLen); memcpy (m_OfflineSignature.data (), offlineInfo, offlineInfoLen); - // override signing private key + // override signing private key m_TransientSigningPrivateKeyLen = transientVerifier->GetPrivateKeyLen (); if (m_TransientSigningPrivateKeyLen + ret > len || m_TransientSigningPrivateKeyLen > 128) return 0; memcpy (m_SigningPrivateKey, buf + ret, m_TransientSigningPrivateKeyLen); @@ -586,10 +586,10 @@ namespace data else CreateSigner (m_Public->GetSigningKeyType ()); } - + void PrivateKeys::CreateSigner (SigningKeyType keyType) const { - if (m_Signer) return; + if (m_Signer) return; if (keyType == SIGNING_KEY_TYPE_DSA_SHA1) m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); else if (keyType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 && !IsOfflineSignature ()) @@ -599,7 +599,7 @@ namespace data // public key is not required auto signer = CreateSigner (keyType, m_SigningPrivateKey); if (signer) m_Signer.reset (signer); - } + } } i2p::crypto::Signer * PrivateKeys::CreateSigner (SigningKeyType keyType, const uint8_t * priv) @@ -630,8 +630,8 @@ namespace data return new i2p::crypto::GOSTR3410_512_Signer (i2p::crypto::eGOSTR3410TC26A512, priv); break; case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: - return new i2p::crypto::RedDSA25519Signer (priv); - break; + return new i2p::crypto::RedDSA25519Signer (priv); + break; default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } @@ -719,8 +719,8 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA512_4096: LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA"); #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif + [[fallthrough]]; +#endif // no break here case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: i2p::crypto::CreateEDDSA25519RandomKeys (priv, pub); @@ -733,7 +733,7 @@ namespace data break; case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: i2p::crypto::CreateRedDSA25519RandomKeys (priv, pub); - break; + break; default: LogPrint (eLogWarning, "Identity: Signing key type ", (int)type, " is not supported. Create DSA-SHA1"); i2p::crypto::CreateDSARandomKeys (priv, pub); // DSA-SHA1 @@ -765,7 +765,7 @@ namespace data PrivateKeys PrivateKeys::CreateOfflineKeys (SigningKeyType type, uint32_t expires) const { PrivateKeys keys (*this); - std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); + std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); if (verifier) { size_t pubKeyLen = verifier->GetPublicKeyLen (); @@ -775,7 +775,7 @@ namespace data htobe32buf (keys.m_OfflineSignature.data (), expires); // expires htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key - Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature + Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature // recreate signer keys.m_Signer = nullptr; keys.CreateSigner (type); diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index da14e141..08baba01 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -56,7 +56,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; - const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; + const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES @@ -115,7 +115,7 @@ namespace data void RecalculateIdentHash(uint8_t * buff=nullptr); static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType); - static std::shared_ptr CreateEncryptor (CryptoKeyType keyType, const uint8_t * key); + static std::shared_ptr CreateEncryptor (CryptoKeyType keyType, const uint8_t * key); private: @@ -148,7 +148,7 @@ namespace data const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; size_t GetSignatureLen () const; // might not match identity bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; }; - uint8_t * GetPadding(); + uint8_t * GetPadding(); void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } void Sign (const uint8_t * buf, int len, uint8_t * signature) const; @@ -163,12 +163,12 @@ namespace data static std::shared_ptr CreateDecryptor (CryptoKeyType cryptoType, const uint8_t * key); static PrivateKeys CreateRandomKeys (SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL); - static void GenerateSigningKeyPair (SigningKeyType type, uint8_t * priv, uint8_t * pub); + static void GenerateSigningKeyPair (SigningKeyType type, uint8_t * priv, uint8_t * pub); static void GenerateCryptoKeyPair (CryptoKeyType type, uint8_t * priv, uint8_t * pub); // priv and pub are 256 bytes long static i2p::crypto::Signer * CreateSigner (SigningKeyType keyType, const uint8_t * priv); // offline keys - PrivateKeys CreateOfflineKeys (SigningKeyType type, uint32_t expires) const; + PrivateKeys CreateOfflineKeys (SigningKeyType type, uint32_t expires) const; const std::vector& GetOfflineSignature () const { return m_OfflineSignature; }; private: @@ -204,7 +204,7 @@ namespace data IdentHash CreateRoutingKey (const IdentHash& ident); XORMetric operator^(const IdentHash& key1, const IdentHash& key2); - // destination for delivery instuctions + // destination for delivery instructions class RoutingDestination { public: @@ -235,5 +235,4 @@ namespace data } } - #endif diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 6ce77792..1aa7fa6d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -12,9 +12,8 @@ namespace i2p { namespace data { - LeaseSet::LeaseSet (bool storeLeases): - m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr), + m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr), m_Buffer (nullptr), m_BufferLen (0) { } @@ -62,7 +61,7 @@ namespace data { if (!m_EncryptionKey) m_EncryptionKey = new uint8_t[256]; memcpy (m_EncryptionKey, m_Buffer + size, 256); - } + } size += 256; // encryption key size += m_Identity->GetSigningPublicKeyLen (); // unused signing key uint8_t num = m_Buffer[size]; @@ -191,10 +190,10 @@ namespace data return m_ExpirationTime - now <= dlt; } - const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const - { - return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold); - } + const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const + { + return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold); + } const std::vector > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const { @@ -249,19 +248,19 @@ namespace data if (len <= m_BufferLen) m_BufferLen = len; else LogPrint (eLogError, "LeaseSet2: actual buffer size ", len , " exceeds full buffer size ", m_BufferLen); - } - + } + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto): LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) - { - SetBuffer (buf, len); + { + SetBuffer (buf, len); if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ReadFromBufferEncrypted (buf, len, nullptr, nullptr); else ReadFromBuffer (buf, len); } - LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, + LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret, CryptoKeyType preferredCrypto): LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_EncryptionType (preferredCrypto) { @@ -269,10 +268,10 @@ namespace data } void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature) - { + { SetBuffer (buf, len); if (GetStoreType () != NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) - ReadFromBuffer (buf, len, false, verifySignature); + ReadFromBuffer (buf, len, false, verifySignature); // TODO: implement encrypted } @@ -281,13 +280,13 @@ namespace data uint64_t expiration; return ExtractPublishedTimestamp (buf, len, expiration) > m_PublishedTimestamp; } - + void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity, bool verifySignature) { // standard LS2 header std::shared_ptr identity; if (readIdentity) - { + { identity = std::make_shared(buf, len); SetIdentity (identity); } @@ -304,7 +303,7 @@ namespace data // transient key m_TransientVerifier = ProcessOfflineSignature (identity, buf, len, offset); if (!m_TransientVerifier) - { + { LogPrint (eLogError, "LeaseSet2: offline signature failed"); return; } @@ -314,7 +313,7 @@ namespace data { m_IsPublishedEncrypted = true; m_IsPublic = true; - } + } // type specific part size_t s = 0; switch (m_StoreType) @@ -331,11 +330,11 @@ namespace data if (!s) return; offset += s; if (verifySignature || m_TransientVerifier) - { + { // verify signature bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) : - VerifySignature (identity, buf, len, offset); - SetIsValid (verified); + VerifySignature (identity, buf, len, offset); + SetIsValid (verified); } offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen (); SetBufferLen (offset); @@ -346,10 +345,10 @@ namespace data { if (signatureOffset + verifier->GetSignatureLen () > len) return false; // we assume buf inside DatabaseStore message, so buf[-1] is valid memory - // change it for signature verification, and restore back + // change it for signature verification, and restore back uint8_t c = buf[-1]; const_cast(buf)[-1] = m_StoreType; - bool verified = verifier->Verify (buf - 1, signatureOffset + 1, buf + signatureOffset); + bool verified = verifier->Verify (buf - 1, signatureOffset + 1, buf + signatureOffset); const_cast(buf)[-1] = c; if (!verified) LogPrint (eLogWarning, "LeaseSet2: verification failed"); @@ -360,7 +359,7 @@ namespace data { size_t offset = 0; // properties - uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; + uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; offset += propertiesLen; // skip for now. TODO: implement properties if (offset + 1 >= len) return 0; // key sections @@ -371,7 +370,7 @@ namespace data { uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption key type if (offset + 2 >= len) return 0; - uint16_t encryptionKeyLen = bufbe16toh (buf + offset); offset += 2; + uint16_t encryptionKeyLen = bufbe16toh (buf + offset); offset += 2; if (offset + encryptionKeyLen >= len) return 0; if (IsStoreLeases () && !preferredKeyFound) // create encryptor with leases only { @@ -384,10 +383,10 @@ namespace data if (keyType == preferredKeyType) preferredKeyFound = true; } } - offset += encryptionKeyLen; - } + offset += encryptionKeyLen; + } // leases - if (offset + 1 >= len) return 0; + if (offset + 1 >= len) return 0; int numLeases = buf[offset]; offset++; auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (IsStoreLeases ()) @@ -413,9 +412,9 @@ namespace data { size_t offset = 0; // properties - uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; + uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; offset += propertiesLen; // skip for now. TODO: implement properties - // entries + // entries if (offset + 1 >= len) return 0; int numEntries = buf[offset]; offset++; for (int i = 0; i < numEntries; i++) @@ -423,12 +422,12 @@ namespace data if (offset + 40 >= len) return 0; offset += 32; // hash offset += 3; // flags - offset += 1; // cost + offset += 1; // cost offset += 4; // expires } // revocations if (offset + 1 >= len) return 0; - int numRevocations = buf[offset]; offset++; + int numRevocations = buf[offset]; offset++; for (int i = 0; i < numRevocations; i++) { if (offset + 32 > len) return 0; @@ -446,7 +445,7 @@ namespace data uint16_t blindedKeyType = bufbe16toh (stA1); offset += 2; std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType)); if (!blindedVerifier) return; - auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); + auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); if (offset + blindedKeyLen >= len) return; const uint8_t * blindedPublicKey = buf + offset; blindedVerifier->SetPublicKey (blindedPublicKey); offset += blindedKeyLen; @@ -461,7 +460,7 @@ namespace data { // transient key m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset); - if (!m_TransientVerifier) + if (!m_TransientVerifier) { LogPrint (eLogError, "LeaseSet2: offline signature failed"); return; @@ -470,16 +469,16 @@ namespace data // outer ciphertext if (offset + 2 > len) return; uint16_t lenOuterCiphertext = bufbe16toh (buf + offset); offset += 2; - const uint8_t * outerCiphertext = buf + offset; - offset += lenOuterCiphertext; + const uint8_t * outerCiphertext = buf + offset; + offset += lenOuterCiphertext; // verify signature bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) : - VerifySignature (blindedVerifier, buf, len, offset); + VerifySignature (blindedVerifier, buf, len, offset); SetIsValid (verified); // handle ciphertext if (verified && key && lenOuterCiphertext >= 32) { - SetIsValid (false); // we must verify it again in Layer 2 + SetIsValid (false); // we must verify it again in Layer 2 if (blindedKeyType == key->GetBlindedSigType ()) { // verify blinding @@ -491,13 +490,13 @@ namespace data { LogPrint (eLogError, "LeaseSet2: blinded public key doesn't match"); return; - } - } + } + } else { LogPrint (eLogError, "LeaseSet2: Unexpected blinded key type ", blindedKeyType, " instead ", key->GetBlindedSigType ()); return; - } + } // outer key // outerInput = subcredential || publishedTimestamp uint8_t subcredential[36]; @@ -518,10 +517,10 @@ namespace data // innerSalt = innerCiphertext[0:32] // keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44) uint8_t innerInput[68]; - size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput); + size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput); if (authDataLen > 0) { - memcpy (innerInput + 32, subcredential, 36); + memcpy (innerInput + 32, subcredential, 36); i2p::crypto::HKDF (outerPlainText.data () + 1 + authDataLen, innerInput, 68, "ELS2_L2K", keys); } else @@ -537,20 +536,20 @@ namespace data if (innerPlainText[0] == NETDB_STORE_TYPE_STANDARD_LEASESET2 || innerPlainText[0] == NETDB_STORE_TYPE_META_LEASESET2) { // override store type and buffer - m_StoreType = innerPlainText[0]; + m_StoreType = innerPlainText[0]; SetBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1); // parse and verify Layer 2 ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1); } else LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); - } + } else { // we set actual length of encrypted buffer offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : blindedVerifier->GetSignatureLen (); SetBufferLen (offset); - } + } } // helper for ExtractClientAuthData @@ -563,12 +562,12 @@ namespace data { // clientKey_i = okm[0:31] // clientIV_i = okm[32:43] - i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i + i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i return true; - } + } } - return false; - } + return false; + } size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const { @@ -581,7 +580,7 @@ namespace data const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients - if (offset > len) + if (offset > len) { LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data"); return 0; @@ -595,19 +594,19 @@ namespace data memcpy (authInput + 32, ck.GetPublicKey (), 32); // cpk_i memcpy (authInput + 64, subcredential, 36); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); + i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); if (!GetAuthCookie (authClients, numClients, okm, authCookie)) - LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); + LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); } else - LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); + LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); } else if (flag & 0x02) // PSK, bit 1 is set to 1 { const uint8_t * authSalt = buf + offset; offset += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients - if (offset > len) + if (offset > len) { LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data"); return 0; @@ -619,7 +618,7 @@ namespace data memcpy (authInput, secret, 32); memcpy (authInput + 32, subcredential, 36); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); if (!GetAuthCookie (authClients, numClients, okm, authCookie)) LogPrint (eLogError, "LeaseSet2: Client cookie PSK not found"); } @@ -627,7 +626,7 @@ namespace data LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); } else - LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag); + LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag); } return offset - 1; } @@ -636,7 +635,7 @@ namespace data { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, ctx, true); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const @@ -648,7 +647,7 @@ namespace data uint64_t LeaseSet2::ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const { - if (len < 8) return 0; + if (len < 8) return 0; if (m_StoreType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { // encrypted LS2 @@ -656,11 +655,11 @@ namespace data uint16_t blindedKeyType = bufbe16toh (buf + offset); offset += 2; std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType)); if (!blindedVerifier) return 0 ; - auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); + auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); if (offset + blindedKeyLen + 6 >= len) return 0; offset += blindedKeyLen; - uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; - uint16_t expires = bufbe16toh (buf + offset); offset += 2; + uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; + uint16_t expires = bufbe16toh (buf + offset); offset += 2; expiration = (timestamp + expires)* 1000LL; return timestamp; } @@ -670,13 +669,13 @@ namespace data if (!identity) return 0; size_t offset = identity->GetFullLen (); if (offset + 6 >= len) return 0; - uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; - uint16_t expires = bufbe16toh (buf + offset); offset += 2; + uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; + uint16_t expires = bufbe16toh (buf + offset); offset += 2; expiration = (timestamp + expires)* 1000LL; return timestamp; } - } - + } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): m_ExpirationTime (0), m_Identity (identity) { @@ -770,36 +769,35 @@ namespace data return ident.Verify(ptr, leases - ptr, leases); } - LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, - std::vector > tunnels, + LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, + const KeySections& encryptionKeys, std::vector > tunnels, bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { auto identity = keys.GetPublic (); - // assume standard LS2 + // assume standard LS2 int num = tunnels.size (); if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES; size_t keySectionsLen = 0; for (const auto& it: encryptionKeys) - keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; + keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; m_BufferLen = identity->GetFullLen () + 4/*published*/ + 2/*expires*/ + 2/*flag*/ + 2/*properties len*/ + 1/*num keys*/ + keySectionsLen + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); uint16_t flags = 0; - if (keys.IsOfflineSignature ()) + if (keys.IsOfflineSignature ()) { flags |= LEASESET2_FLAG_OFFLINE_KEYS; - m_BufferLen += keys.GetOfflineSignature ().size (); + m_BufferLen += keys.GetOfflineSignature ().size (); } - if (isPublishedEncrypted) + if (isPublishedEncrypted) { flags |= LEASESET2_FLAG_PUBLISHED_ENCRYPTED; - isPublic = true; + isPublic = true; } if (!isPublic) flags |= LEASESET2_FLAG_UNPUBLISHED_LEASESET; m_Buffer = new uint8_t[m_BufferLen + 1]; - m_Buffer[0] = storeType; + m_Buffer[0] = storeType; // LS2 header auto offset = identity->ToBuffer (m_Buffer + 1, m_BufferLen) + 1; auto timestamp = i2p::util::GetSecondsSinceEpoch (); @@ -814,14 +812,14 @@ namespace data offset += offlineSignature.size (); } htobe16buf (m_Buffer + offset, 0); offset += 2; // properties len - // keys + // keys m_Buffer[offset] = encryptionKeys.size (); offset++; // 1 key for (const auto& it: encryptionKeys) - { - htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type - htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len + { + htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type + htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len memcpy (m_Buffer + offset, it.encryptionPublicKey, it.keyLen); offset += it.keyLen; // key - } + } // leases uint32_t expirationTime = 0; // in seconds m_Buffer[offset] = num; offset++; // num leases @@ -835,11 +833,11 @@ namespace data if (ts > expirationTime) expirationTime = ts; htobe32buf (m_Buffer + offset, ts); offset += 4; // end date - } + } // update expiration - SetExpirationTime (expirationTime*1000LL); + SetExpirationTime (expirationTime*1000LL); auto expires = expirationTime - timestamp; - htobe16buf (expiresBuf, expires > 0 ? expires : 0); + htobe16buf (expiresBuf, expires > 0 ? expires : 0); // sign keys.Sign (m_Buffer, offset, m_Buffer + offset); // LS + leading store type } @@ -853,7 +851,7 @@ namespace data m_Buffer[0] = storeType; } - LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, + LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { @@ -863,16 +861,16 @@ namespace data { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 - if (layer1Flags) + if (layer1Flags) lenOuterPlaintext += 32 + 2 + authKeys->size ()*40; // auth data len - } + } size_t lenOuterCiphertext = lenOuterPlaintext + 32; - - m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; - m_Buffer = new uint8_t[m_BufferLen + 1]; + + m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; + m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; BlindedPublicKey blindedKey (ls->GetIdentity ()); - auto timestamp = i2p::util::GetSecondsSinceEpoch (); + auto timestamp = i2p::util::GetSecondsSinceEpoch (); char date[9]; i2p::util::GetDateString (timestamp, date); uint8_t blindedPriv[64], blindedPub[128]; // 64 and 128 max @@ -883,25 +881,25 @@ namespace data memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key htobe32buf (m_Buffer + offset, timestamp); offset += 4; // published timestamp (seconds) auto nextMidnight = (timestamp/86400LL + 1)*86400LL; // 86400 = 24*3600 seconds - auto expirationTime = ls->GetExpirationTime ()/1000LL; + auto expirationTime = ls->GetExpirationTime ()/1000LL; if (expirationTime > nextMidnight) expirationTime = nextMidnight; SetExpirationTime (expirationTime*1000LL); htobe16buf (m_Buffer + offset, expirationTime > timestamp ? expirationTime - timestamp : 0); offset += 2; // expires uint16_t flags = 0; - htobe16buf (m_Buffer + offset, flags); offset += 2; // flags + htobe16buf (m_Buffer + offset, flags); offset += 2; // flags htobe16buf (m_Buffer + offset, lenOuterCiphertext); offset += 2; // lenOuterCiphertext // outerChipherText - // Layer 1 + // Layer 1 uint8_t subcredential[36]; blindedKey.GetSubcredential (blindedPub, 32, subcredential); htobe32buf (subcredential + 32, timestamp); // outerInput = subcredential || publishedTimestamp // keys = HKDF(outerSalt, outerInput, "ELS2_L1K", 44) uint8_t keys1[64]; // 44 bytes actual data - RAND_bytes (m_Buffer + offset, 32); // outerSalt = CSRNG(32) + RAND_bytes (m_Buffer + offset, 32); // outerSalt = CSRNG(32) i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L1K", keys1); offset += 32; // outerSalt - uint8_t * outerPlainText = m_Buffer + offset; - m_Buffer[offset] = layer1Flags; offset++; // layer 1 flags + uint8_t * outerPlainText = m_Buffer + offset; + m_Buffer[offset] = layer1Flags; offset++; // layer 1 flags // auth data uint8_t innerInput[68]; // authCookie || subcredential || publishedTimestamp if (layer1Flags) @@ -909,20 +907,20 @@ namespace data RAND_bytes (innerInput, 32); // authCookie CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer + offset); offset += 32 + 2 + authKeys->size ()*40; // auth clients - } + } // Layer 2 // keys = HKDF(outerSalt, outerInput, "ELS2_L2K", 44) uint8_t keys2[64]; // 44 bytes actual data - RAND_bytes (m_Buffer + offset, 32); // innerSalt = CSRNG(32) + RAND_bytes (m_Buffer + offset, 32); // innerSalt = CSRNG(32) if (layer1Flags) { memcpy (innerInput + 32, subcredential, 36); // + subcredential || publishedTimestamp - i2p::crypto::HKDF (m_Buffer + offset, innerInput, 68, "ELS2_L2K", keys2); + i2p::crypto::HKDF (m_Buffer + offset, innerInput, 68, "ELS2_L2K", keys2); } else i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L2K", keys2); // no authCookie - offset += 32; // innerSalt - m_Buffer[offset] = ls->GetStoreType (); + offset += 32; // innerSalt + m_Buffer[offset] = ls->GetStoreType (); memcpy (m_Buffer + offset + 1, ls->GetBuffer (), ls->GetBufferLen ()); i2p::crypto::ChaCha20 (m_Buffer + offset, lenInnerPlaintext, keys2, keys2 + 32, m_Buffer + offset); // encrypt Layer 2 offset += lenInnerPlaintext; @@ -930,14 +928,14 @@ namespace data // signature blindedSigner->Sign (m_Buffer, offset, m_Buffer + offset); // store hash - m_StoreHash = blindedKey.GetStoreHash (date); + m_StoreHash = blindedKey.GetStoreHash (date); } LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len): - LocalLeaseSet2 (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2, identity, buf, len) + LocalLeaseSet2 (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2, identity, buf, len) { - // fill inner LeaseSet2 - auto blindedKey = std::make_shared(identity); + // fill inner LeaseSet2 + auto blindedKey = std::make_shared(identity); i2p::data::LeaseSet2 ls (buf, len, blindedKey); // inner layer if (ls.IsValid ()) { @@ -945,10 +943,10 @@ namespace data m_StoreHash = blindedKey->GetStoreHash (); } else - LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); + LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) { @@ -963,9 +961,9 @@ namespace data ek.Agree (it, authInput); // sharedSecret = DH(esk, cpk_i) memcpy (authInput + 32, it, 32); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); + i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); memcpy (authData, okm + 44, 8); authData += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i } } else // assume PSK @@ -980,10 +978,10 @@ namespace data { memcpy (authInput, it, 32); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); memcpy (authData, okm + 44, 8); authData += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i - } + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i + } } } } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 4d084da3..479594e1 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -48,11 +48,11 @@ namespace data }; }; - typedef std::function LeaseInspectFunc; + typedef std::function LeaseInspectFunc; const size_t MAX_LS_BUFFER_SIZE = 3072; const size_t LEASE_SIZE = 44; // 32 + 4 + 8 - const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 + const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 const uint8_t MAX_NUM_LEASES = 16; const uint8_t NETDB_STORE_TYPE_LEASESET = 1; @@ -70,7 +70,7 @@ namespace data size_t GetBufferLen () const { return m_BufferLen; }; bool IsValid () const { return m_IsValid; }; const std::vector > GetNonExpiredLeases (bool withThreshold = true) const; - const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; + const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; bool HasExpiredLeases () const; bool IsExpired () const; bool IsEmpty () const { return m_Leases.empty (); }; @@ -80,7 +80,7 @@ namespace data { return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); }; virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; virtual uint32_t GetPublishedTimestamp () const { return 0; }; // should be set for LeaseSet2 only - virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; + virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; virtual bool IsPublishedEncrypted () const { return false; }; // implements RoutingDestination @@ -97,7 +97,7 @@ namespace data // called from LeaseSet2 LeaseSet (bool storeLeases); void SetBuffer (const uint8_t * buf, size_t len); - void SetBufferLen (size_t len); + void SetBufferLen (size_t len); void SetIdentity (std::shared_ptr identity) { m_Identity = identity; }; void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; }; void SetIsValid (bool isValid) { m_IsValid = isValid; }; @@ -130,7 +130,7 @@ namespace data const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7; const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; - const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; + const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; const uint16_t LEASESET2_FLAG_PUBLISHED_ENCRYPTED = 0x0004; class LeaseSet2: public LeaseSet @@ -167,7 +167,7 @@ namespace data private: - uint8_t m_StoreType; + uint8_t m_StoreType; uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; @@ -175,7 +175,7 @@ namespace data std::shared_ptr m_Encryptor; // for standardLS2 }; - // also called from Streaming.cpp + // also called from Streaming.cpp template std::shared_ptr ProcessOfflineSignature (const Verifier& verifier, const uint8_t * buf, size_t len, size_t& offset) { @@ -191,7 +191,7 @@ namespace data transientVerifier->SetPublicKey (buf + offset); offset += keyLen; if (offset + verifier->GetSignatureLen () >= len) return nullptr; if (!verifier->Verify (signedData, keyLen + 6, buf + offset)) return nullptr; - offset += verifier->GetSignatureLen (); + offset += verifier->GetSignatureLen (); return transientVerifier; } @@ -238,17 +238,18 @@ namespace data { uint16_t keyType, keyLen; const uint8_t * encryptionPublicKey; - }; + }; typedef std::vector KeySections; - - LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, - std::vector > tunnels, + + LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, + const KeySections& encryptionKeys, + std::vector > tunnels, bool isPublic, bool isPublishedEncrypted = false); - LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP - + + LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP + virtual ~LocalLeaseSet2 () { delete[] m_Buffer; }; - + uint8_t * GetBuffer () const { return m_Buffer + 1; }; size_t GetBufferLen () const { return m_BufferLen; }; @@ -269,13 +270,13 @@ namespace data const int ENCRYPTED_LEASESET_AUTH_TYPE_DH = 1; const int ENCRYPTED_LEASESET_AUTH_TYPE_PSK = 2; - typedef i2p::data::Tag<32> AuthPublicKey; + typedef i2p::data::Tag<32> AuthPublicKey; class LocalEncryptedLeaseSet2: public LocalLeaseSet2 { public: - LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP diff --git a/libi2pd/LittleBigEndian.h b/libi2pd/LittleBigEndian.h index 69f10ee9..55039fb6 100644 --- a/libi2pd/LittleBigEndian.h +++ b/libi2pd/LittleBigEndian.h @@ -29,35 +29,35 @@ struct BigEndian; template struct LittleEndian { - union - { - unsigned char bytes[sizeof(T)]; - T raw_value; - }; + union + { + unsigned char bytes[sizeof(T)]; + T raw_value; + }; - LittleEndian(T t = T()) - { - operator =(t); - } + LittleEndian(T t = T()) + { + operator =(t); + } - LittleEndian(const LittleEndian & t) - { - raw_value = t.raw_value; - } + LittleEndian(const LittleEndian & t) + { + raw_value = t.raw_value; + } - LittleEndian(const BigEndian & t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[i] = t.bytes[sizeof(T)-1-i]; - } + LittleEndian(const BigEndian & t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[i] = t.bytes[sizeof(T)-1-i]; + } - operator const T() const - { - T t = T(); - for (unsigned i = 0; i < sizeof(T); i++) - t |= T(bytes[i]) << (i << 3); - return t; - } + operator const T() const + { + T t = T(); + for (unsigned i = 0; i < sizeof(T); i++) + t |= T(bytes[i]) << (i << 3); + return t; + } const T operator = (const T t) { @@ -66,68 +66,68 @@ struct LittleEndian return t; } - // operators + // operators - const T operator += (const T t) - { - return (*this = *this + t); - } + const T operator += (const T t) + { + return (*this = *this + t); + } - const T operator -= (const T t) - { - return (*this = *this - t); - } + const T operator -= (const T t) + { + return (*this = *this - t); + } - const T operator *= (const T t) - { - return (*this = *this * t); - } + const T operator *= (const T t) + { + return (*this = *this * t); + } - const T operator /= (const T t) - { - return (*this = *this / t); - } + const T operator /= (const T t) + { + return (*this = *this / t); + } - const T operator %= (const T t) - { - return (*this = *this % t); - } + const T operator %= (const T t) + { + return (*this = *this % t); + } - LittleEndian operator ++ (int) - { - LittleEndian tmp(*this); - operator ++ (); - return tmp; - } + LittleEndian operator ++ (int) + { + LittleEndian tmp(*this); + operator ++ (); + return tmp; + } - LittleEndian & operator ++ () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - ++bytes[i]; - if (bytes[i] != 0) - break; - } - return (*this); - } + LittleEndian & operator ++ () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + ++bytes[i]; + if (bytes[i] != 0) + break; + } + return (*this); + } - LittleEndian operator -- (int) - { - LittleEndian tmp(*this); - operator -- (); - return tmp; - } + LittleEndian operator -- (int) + { + LittleEndian tmp(*this); + operator -- (); + return tmp; + } - LittleEndian & operator -- () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - --bytes[i]; - if (bytes[i] != (T)(-1)) - break; - } - return (*this); - } + LittleEndian & operator -- () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + --bytes[i]; + if (bytes[i] != (T)(-1)) + break; + } + return (*this); + } }; #pragma pack(pop) @@ -137,105 +137,105 @@ struct LittleEndian template struct BigEndian { - union - { - unsigned char bytes[sizeof(T)]; - T raw_value; - }; + union + { + unsigned char bytes[sizeof(T)]; + T raw_value; + }; - BigEndian(T t = T()) - { - operator =(t); - } + BigEndian(T t = T()) + { + operator =(t); + } - BigEndian(const BigEndian & t) - { - raw_value = t.raw_value; - } + BigEndian(const BigEndian & t) + { + raw_value = t.raw_value; + } - BigEndian(const LittleEndian & t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[i] = t.bytes[sizeof(T)-1-i]; - } + BigEndian(const LittleEndian & t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[i] = t.bytes[sizeof(T)-1-i]; + } - operator const T() const - { - T t = T(); - for (unsigned i = 0; i < sizeof(T); i++) - t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3); - return t; - } + operator const T() const + { + T t = T(); + for (unsigned i = 0; i < sizeof(T); i++) + t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3); + return t; + } - const T operator = (const T t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[sizeof(T) - 1 - i] = t >> (i << 3); - return t; - } + const T operator = (const T t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[sizeof(T) - 1 - i] = t >> (i << 3); + return t; + } - // operators + // operators - const T operator += (const T t) - { - return (*this = *this + t); - } + const T operator += (const T t) + { + return (*this = *this + t); + } - const T operator -= (const T t) - { - return (*this = *this - t); - } + const T operator -= (const T t) + { + return (*this = *this - t); + } - const T operator *= (const T t) - { - return (*this = *this * t); - } + const T operator *= (const T t) + { + return (*this = *this * t); + } - const T operator /= (const T t) - { - return (*this = *this / t); - } + const T operator /= (const T t) + { + return (*this = *this / t); + } - const T operator %= (const T t) - { - return (*this = *this % t); - } + const T operator %= (const T t) + { + return (*this = *this % t); + } - BigEndian operator ++ (int) - { - BigEndian tmp(*this); - operator ++ (); - return tmp; - } + BigEndian operator ++ (int) + { + BigEndian tmp(*this); + operator ++ (); + return tmp; + } - BigEndian & operator ++ () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - ++bytes[sizeof(T) - 1 - i]; - if (bytes[sizeof(T) - 1 - i] != 0) - break; - } - return (*this); - } + BigEndian & operator ++ () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + ++bytes[sizeof(T) - 1 - i]; + if (bytes[sizeof(T) - 1 - i] != 0) + break; + } + return (*this); + } - BigEndian operator -- (int) - { - BigEndian tmp(*this); - operator -- (); - return tmp; - } + BigEndian operator -- (int) + { + BigEndian tmp(*this); + operator -- (); + return tmp; + } - BigEndian & operator -- () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - --bytes[sizeof(T) - 1 - i]; - if (bytes[sizeof(T) - 1 - i] != (T)(-1)) - break; - } - return (*this); - } + BigEndian & operator -- () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + --bytes[sizeof(T) - 1 - i]; + if (bytes[sizeof(T) - 1 - i] != (T)(-1)) + break; + } + return (*this); + } }; #pragma pack(pop) diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 65602674..6f2eb5bd 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -110,18 +110,18 @@ namespace log { } } - std::string str_tolower(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - // static_cast(std::tolower) // wrong - // [](int c){ return std::tolower(c); } // wrong - // [](char c){ return std::tolower(c); } // wrong - [](unsigned char c){ return std::tolower(c); } // correct - ); - return s; - } + std::string str_tolower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), + // static_cast(std::tolower) // wrong + // [](int c){ return std::tolower(c); } // wrong + // [](char c){ return std::tolower(c); } // wrong + [](unsigned char c){ return std::tolower(c); } // correct + ); + return s; + } - void Log::SetLogLevel (const std::string& level_) { - std::string level=str_tolower(level_); + void Log::SetLogLevel (const std::string& level_) { + std::string level=str_tolower(level_); if (level == "none") { m_MinLevel = eLogNone; } else if (level == "error") { m_MinLevel = eLogError; } else if (level == "warn") { m_MinLevel = eLogWarning; } @@ -240,7 +240,7 @@ namespace log { static ThrowFunction g_ThrowFunction; ThrowFunction GetThrowFunction () { return g_ThrowFunction; } void SetThrowFunction (ThrowFunction f) { g_ThrowFunction = f; } - + } // log } // i2p diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 556654e2..fbd122a8 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -155,9 +155,9 @@ namespace log { typedef std::function ThrowFunction; ThrowFunction GetThrowFunction (); - void SetThrowFunction (ThrowFunction f); + void SetThrowFunction (ThrowFunction f); } // log -} +} // i2p /** internal usage only -- folding args array to single string */ template @@ -203,7 +203,7 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept } /** - * @brief Throw fatal error message with the list of arguments + * @brief Throw fatal error message with the list of arguments * @param args Array of message parts */ template diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e52f0111..eec3a5a5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -114,7 +114,7 @@ namespace transport void NTCP2Establisher::KDF2Bob () { - KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); + KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); } void NTCP2Establisher::KDF3Alice () @@ -707,7 +707,7 @@ namespace transport auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); if (m_Server.AddNTCP2Session (shared_from_this (), true)) - { + { Established (); ReceiveLength (); } @@ -1200,7 +1200,7 @@ namespace transport continue; } - LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v4 TCP port ", address->port); auto conn = std::make_shared(*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } @@ -1218,8 +1218,8 @@ namespace transport LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); @@ -1485,7 +1485,7 @@ namespace transport } }); auto readbuff = std::make_shared >(2); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) { if(ec) @@ -1531,8 +1531,8 @@ namespace transport std::ostream out(&writebuff); out << req.to_string(); - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) { (void) transferred; if(ec) @@ -1540,8 +1540,8 @@ namespace transport }); boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) { if(ec) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 10170fda..8b8c6acb 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -126,7 +126,6 @@ namespace transport { public: - NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr); ~NTCP2Session (); void Terminate (); diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 4ab3c5d0..56c69e05 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -26,7 +26,7 @@ namespace transport { std::shared_ptr session; }; - + NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), m_Server (server), m_Socket (m_Server.GetService ()), @@ -468,7 +468,7 @@ namespace transport LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock"); if (ecode != boost::asio::error::operation_aborted) { - // this router doesn't like us + // this router doesn't like us i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); Terminate (); } @@ -736,13 +736,11 @@ namespace transport } } - void NTCPSession::SendTimeSyncMessage () { Send (nullptr); } - void NTCPSession::SendI2NPMessages (const std::vector >& msgs) { m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); @@ -821,8 +819,8 @@ namespace transport { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { /** fail to bind ip4 */ LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); @@ -848,8 +846,8 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); @@ -904,7 +902,6 @@ namespace transport } } - void NTCPServer::Run () { while (m_IsRunning) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 86bf160e..30916f1a 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -216,10 +216,10 @@ namespace data LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); std::unique_lock l(m_FloodfillsMutex); if (wasFloodfill) - m_Floodfills.remove (r); - else + m_Floodfills.remove (r); + else m_Floodfills.push_back (r); - } + } } else { @@ -390,7 +390,7 @@ namespace data } } - m_Reseeder->Bootstrap (); + m_Reseeder->Bootstrap (); } void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills) @@ -532,12 +532,12 @@ namespace data auto total = m_RouterInfos.size (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); - auto uptime = i2p::context.GetUptime (); + auto uptime = i2p::context.GetUptime (); // routers don't expire if less than 90 or uptime is less than 1 hour bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes if (checkForExpiration && uptime > 3600) // 1 hour expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL : - NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; + NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; for (auto& it: m_RouterInfos) { @@ -555,7 +555,7 @@ namespace data // find & mark expired routers if (it.second->UsesIntroducer ()) { - if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) + if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) // RouterInfo expires after 1 hour if uses introducer it.second->SetUnreachable (true); } @@ -873,7 +873,7 @@ namespace data std::shared_ptr replyMsg; if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP) { - LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded"); + LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded"); std::set excludedRouters; for (int i = 0; i < numExcluded; i++) { @@ -894,7 +894,7 @@ namespace data } else { - if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || + if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP) { auto router = FindRouter (ident); @@ -907,7 +907,7 @@ namespace data } } - if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP || + if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)) { auto leaseSet = FindLeaseSet (ident); @@ -957,12 +957,12 @@ namespace data replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); } else - { + { const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); replyMsg = garlic.WrapSingleMessage (replyMsg); - } - if (!replyMsg) + } + if (!replyMsg) LogPrint (eLogError, "NetDb: failed to wrap message"); } else @@ -1103,7 +1103,7 @@ namespace data { return !router->IsHidden () && router->IsSSUV6 (); }); - } + } std::shared_ptr NetDb::GetRandomIntroducer () const { diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 6e251ecb..47a6fab5 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -28,12 +28,12 @@ namespace i2p namespace data { const int NETDB_MIN_ROUTERS = 90; - const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60*60; // 1 hour, in seconds - const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65*60; - const int NETDB_MIN_EXPIRATION_TIMEOUT = 90*60; // 1.5 hours - const int NETDB_MAX_EXPIRATION_TIMEOUT = 27*60*60; // 27 hours - const int NETDB_PUBLISH_INTERVAL = 60*40; - const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36 + const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds + const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60; + const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours + const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours + const int NETDB_PUBLISH_INTERVAL = 60 * 40; + const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; @@ -63,13 +63,13 @@ namespace data std::shared_ptr FindRouterProfile (const IdentHash& ident) const; void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr); - void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); + void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); void HandleDatabaseStoreMsg (std::shared_ptr msg); void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void HandleDatabaseLookupMsg (std::shared_ptr msg); void HandleNTCP2RouterInfoMsg (std::shared_ptr m); - + std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith) const; @@ -80,13 +80,13 @@ namespace data std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; - std::shared_ptr GetRandomRouterInFamily(const std::string & fam) const; + std::shared_ptr GetRandomRouterInFamily(const std::string & fam) const; void SetUnreachable (const IdentHash& ident, bool unreachable); void PostI2NPMsg (std::shared_ptr msg); - /** set hidden mode, aka don't publish our RI to netdb and don't explore */ - void SetHidden(bool hide); + /** set hidden mode, aka don't publish our RI to netdb and don't explore */ + void SetHidden(bool hide); void Reseed (); Families& GetFamilies () { return m_Families; }; @@ -119,12 +119,13 @@ namespace data void ManageLeaseSets (); void ManageRequests (); - void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20); + void ReseedFromFloodfill(const RouterInfo & ri, int numRouters = 40, int numFloodfills = 20); std::shared_ptr AddRouterInfo (const uint8_t * buf, int len, bool& updated); std::shared_ptr AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated); - template - std::shared_ptr GetRandomRouter (Filter filter) const; + + template + std::shared_ptr GetRandomRouter (Filter filter) const; private: @@ -150,12 +151,12 @@ namespace data bool m_PersistProfiles; - /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ - std::shared_ptr m_FloodfillBootstrap; + /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ + std::shared_ptr m_FloodfillBootstrap; - /** true if in hidden mode */ - bool m_HiddenMode; + /** true if in hidden mode */ + bool m_HiddenMode; }; extern NetDb netdb; diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index f1853124..b1eb9380 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -14,8 +14,8 @@ namespace data std::shared_ptr msg; if(replyTunnel) msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, - replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory, - &m_ExcludedPeers); + replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory, + &m_ExcludedPeers); else msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers); if(router) @@ -158,4 +158,3 @@ namespace data } } } - diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 7a7a55ab..c5e077bf 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -66,4 +66,3 @@ namespace data } #endif - diff --git a/libi2pd/Poly1305.cpp b/libi2pd/Poly1305.cpp index bf94c9a9..23098d74 100644 --- a/libi2pd/Poly1305.cpp +++ b/libi2pd/Poly1305.cpp @@ -7,12 +7,11 @@ */ -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto { - void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz) { Poly1305 p(key); diff --git a/libi2pd/Poly1305.h b/libi2pd/Poly1305.h index 800fbfd9..f91a037e 100644 --- a/libi2pd/Poly1305.h +++ b/libi2pd/Poly1305.h @@ -1,9 +1,9 @@ /** - This code is licensed under the MCGSI Public License - Copyright 2018 Jeff Becker - - Kovri go write your own code - + * This code is licensed under the MCGSI Public License + * Copyright 2018 Jeff Becker + * + * Kovri go write your own code + * */ #ifndef LIBI2PD_POLY1305_H #define LIBI2PD_POLY1305_H @@ -11,7 +11,7 @@ #include #include "Crypto.h" -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto @@ -24,7 +24,6 @@ namespace crypto namespace poly1305 { - struct LongBlock { unsigned long data[17]; @@ -252,8 +251,8 @@ namespace crypto poly1305::LongBlock m_HR; uint8_t m_Final; }; + void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz); - } } #endif diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 98f95dc3..4f26e520 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -32,73 +32,76 @@ namespace data { } - /** @brief tries to bootstrap into I2P network (from local files and servers, with respect of options) - */ - void Reseeder::Bootstrap () - { - std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName); - std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName); + /** + @brief tries to bootstrap into I2P network (from local files and servers, with respect of options) + */ + void Reseeder::Bootstrap () + { + std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName); + std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName); - if (su3FileName.length() > 0) // bootstrap from SU3 file or URL - { - int num; - if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://") - { - num = ReseedFromSU3Url (su3FileName); // from https URL - } - else - { - num = ProcessSU3File (su3FileName.c_str ()); - } - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName); - } - else if (zipFileName.length() > 0) // bootstrap from ZIP file - { - int num = ProcessZIPFile (zipFileName.c_str ()); - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName); - } - else // bootstrap from reseed servers - { - int num = ReseedFromServers (); - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from servers"); - } - } + if (su3FileName.length() > 0) // bootstrap from SU3 file or URL + { + int num; + if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://") + { + num = ReseedFromSU3Url (su3FileName); // from https URL + } + else + { + num = ProcessSU3File (su3FileName.c_str ()); + } + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName); + } + else if (zipFileName.length() > 0) // bootstrap from ZIP file + { + int num = ProcessZIPFile (zipFileName.c_str ()); + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName); + } + else // bootstrap from reseed servers + { + int num = ReseedFromServers (); + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from servers"); + } + } - /** @brief bootstrap from random server, retry 10 times - * @return number of entries added to netDb - */ + /** + * @brief bootstrap from random server, retry 10 times + * @return number of entries added to netDb + */ int Reseeder::ReseedFromServers () { std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs); - std::vector httpsReseedHostList; - boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); + std::vector httpsReseedHostList; + boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); - if (reseedURLs.length () == 0) - { - LogPrint (eLogWarning, "Reseed: No reseed servers specified"); - return 0; - } + if (reseedURLs.length () == 0) + { + LogPrint (eLogWarning, "Reseed: No reseed servers specified"); + return 0; + } - int reseedRetries = 0; - while (reseedRetries < 10) - { - auto ind = rand () % httpsReseedHostList.size (); - std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3"; - auto num = ReseedFromSU3Url (reseedUrl); - if (num > 0) return num; // success - reseedRetries++; - } - LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts"); - return 0; + int reseedRetries = 0; + while (reseedRetries < 10) + { + auto ind = rand () % httpsReseedHostList.size (); + std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3"; + auto num = ReseedFromSU3Url (reseedUrl); + if (num > 0) return num; // success + reseedRetries++; + } + LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts"); + return 0; } - /** @brief bootstrap from HTTPS URL with SU3 file - * @param url - * @return number of entries added to netDb - */ + /** + * @brief bootstrap from HTTPS URL with SU3 file + * @param url + * @return number of entries added to netDb + */ int Reseeder::ReseedFromSU3Url (const std::string& url) { LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url); @@ -702,4 +705,3 @@ namespace data } } } - diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index a69969bf..5f402988 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -21,7 +21,7 @@ namespace data Reseeder(); ~Reseeder(); - void Bootstrap (); + void Bootstrap (); int ReseedFromServers (); int ReseedFromSU3Url (const std::string& url); int ProcessSU3File (const char * filename); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b86ed8f2..b855fc29 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -338,10 +338,10 @@ namespace i2p { case low : /* not set */; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' - case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; - #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; - #endif + case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here, extra + high means 'X' case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 28c324c4..6382189b 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -15,7 +15,7 @@ namespace i2p { const char ROUTER_INFO[] = "router.info"; const char ROUTER_KEYS[] = "router.keys"; - const char NTCP2_KEYS[] = "ntcp2.keys"; + const char NTCP2_KEYS[] = "ntcp2.keys"; const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes enum RouterStatus @@ -36,12 +36,12 @@ namespace i2p { private: - struct NTCP2PrivateKeys + struct NTCP2PrivateKeys { uint8_t staticPublicKey[32]; uint8_t staticPrivateKey[32]; uint8_t iv[16]; - }; + }; public: @@ -63,7 +63,7 @@ namespace i2p const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; - i2p::crypto::X25519Keys& GetStaticKeys (); + i2p::crypto::X25519Keys& GetStaticKeys (); uint32_t GetUptime () const; // in seconds uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; @@ -77,7 +77,7 @@ namespace i2p void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; - void UpdatePort (int port); // called from Daemon + void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish = true, bool v4only = false); void UpdateNTCP2Address (bool enable); @@ -124,7 +124,7 @@ namespace i2p // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented private: @@ -141,7 +141,7 @@ namespace i2p i2p::data::PrivateKeys m_Keys; std::shared_ptr m_Decryptor; uint64_t m_LastUpdateTime; // in seconds - bool m_AcceptsTunnels, m_IsFloodfill; + bool m_AcceptsTunnels, m_IsFloodfill; std::chrono::time_point m_StartupTime; uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9b3b7e89..bf81a8af 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -35,12 +35,12 @@ namespace data } RouterInfo::RouterInfo (const uint8_t * buf, int len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), + m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) - { + { m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; memcpy (m_Buffer, buf, len); m_BufferLen = len; @@ -173,7 +173,6 @@ namespace data LogPrint (eLogError, "RouterInfo: malformed message"); m_IsUnreachable = true; } - } void RouterInfo::ReadFromStream (std::istream& s) @@ -192,7 +191,7 @@ namespace data s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->date, sizeof (address->date)); bool isNTCP2Only = false; - char transportStyle[6]; + char transportStyle[6]; auto transportStyleLen = ReadString (transportStyle, 6, s) - 1; if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2 { @@ -231,13 +230,13 @@ namespace data address->host.to_string (ecode); if (!ecode) #endif - { + { // add supported protocol if (address->host.is_v4 ()) supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4; else supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6; - } + } } } else if (!strcmp (key, "port")) @@ -262,15 +261,15 @@ namespace data { if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; - Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); - } + Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); + } else if (!strcmp (key, "i")) // ntcp2 iv { if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; - Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); + Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); address->ntcp2->isPublished = true; // presence if "i" means "published" - } + } else if (key[0] == 'i') { // introducers @@ -278,7 +277,7 @@ namespace data { LogPrint (eLogError, "RouterInfo: Introducer is presented for non-SSU address. Skipped"); continue; - } + } introducers = true; size_t l = strlen(key); unsigned char index = key[l-1] - '0'; // TODO: @@ -309,7 +308,7 @@ namespace data } if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true; - if (supportedTransports) + if (supportedTransports) { addresses->push_back(address); m_SupportedTransports |= supportedTransports; @@ -349,13 +348,13 @@ namespace data while (*ch) { if (*ch >= '0' && *ch <= '9') - { - m_Version *= 10; + { + m_Version *= 10; m_Version += (*ch - '0'); - } + } ch++; - } - } + } + } // check netId else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ()) { @@ -384,9 +383,10 @@ namespace data SetUnreachable (true); } - bool RouterInfo::IsFamily(const std::string & fam) const { - return m_Family == fam; - } + bool RouterInfo::IsFamily(const std::string & fam) const + { + return m_Family == fam; + } void RouterInfo::ExtractCaps (const char * value) { @@ -580,7 +580,7 @@ namespace data properties << '='; WriteString (boost::lexical_cast(address.port), properties); properties << ';'; - } + } if (address.IsNTCP2 ()) { // publish s and v for NTCP2 @@ -588,7 +588,7 @@ namespace data WriteString (address.ntcp2->staticKey.ToBase64 (), properties); properties << ';'; WriteString ("v", properties); properties << '='; WriteString ("2", properties); properties << ';'; - } + } uint16_t size = htobe16 (properties.str ().size ()); s.write ((char *)&size, sizeof (size)); @@ -742,7 +742,7 @@ namespace data addr->ntcp2->isNTCP2Only = true; // NTCP2 only address if (port) addr->ntcp2->isPublished = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); - memcpy (addr->ntcp2->iv, iv, 16); + memcpy (addr->ntcp2->iv, iv, 16); m_Addresses->push_back(std::move(addr)); } @@ -854,7 +854,7 @@ namespace data m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6; } - void RouterInfo::EnableV4 () + void RouterInfo::EnableV4 () { if (!IsV4 ()) m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4; @@ -877,7 +877,7 @@ namespace data } } - void RouterInfo::DisableV4 () + void RouterInfo::DisableV4 () { if (IsV4 ()) { @@ -926,7 +926,7 @@ namespace data }); } - template + template std::shared_ptr RouterInfo::GetAddress (Filter filter) const { // TODO: make it more generic using comparator @@ -937,7 +937,7 @@ namespace data #endif for (const auto& address : *addresses) if (filter (address)) return address; - + return nullptr; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f8598b1e..5bdb0f8f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -203,8 +203,8 @@ namespace data void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; - /** return true if we are in a router family and the signature is valid */ - bool IsFamily(const std::string & fam) const; + /** return true if we are in a router family and the signature is valid */ + bool IsFamily(const std::string & fam) const; // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 74cbe39b..4a33ff3a 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,15 +45,15 @@ namespace transport void SSUServer::OpenSocket () { - try + try { m_Socket.open (boost::asio::ip::udp::v4()); m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_Socket.bind (m_Endpoint); LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); ThrowFatal ("Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); @@ -62,7 +62,7 @@ namespace transport void SSUServer::OpenSocketV6 () { - try + try { m_SocketV6.open (boost::asio::ip::udp::v6()); m_SocketV6.set_option (boost::asio::ip::v6_only (true)); @@ -70,8 +70,8 @@ namespace transport m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); ThrowFatal ("Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); @@ -184,7 +184,7 @@ namespace transport m_Socket.close (); OpenSocket (); Receive (); - } + } } } } @@ -359,10 +359,10 @@ namespace transport { if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous { - if (session) - { - session->FlushData (); - session = nullptr; + if (session) + { + session->FlushData (); + session = nullptr; } auto it = sessions->find (packet->from); if (it != sessions->end ()) @@ -826,4 +826,3 @@ namespace transport } } } - diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 10e5ec06..942d0e64 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -40,7 +40,7 @@ namespace transport public: SSUServer (int port); - SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor + SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor ~SSUServer (); void Start (); void Stop (); @@ -135,4 +135,3 @@ namespace transport } #endif - diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 866da277..4eb90522 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -496,7 +496,7 @@ namespace transport } // decay if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || - i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) + i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) m_ReceivedMessages.clear (); ScheduleIncompleteMessagesCleanup (); @@ -504,4 +504,3 @@ namespace transport } } } - diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index fbd167bf..98d60c41 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -128,4 +128,3 @@ namespace transport } #endif - diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 88dbcf04..e29af479 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -336,7 +336,7 @@ namespace transport m_SignedData->Insert (payload, 4); // insert Alice's signed on time payload += 4; // signed-on time size_t paddingSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen (); - paddingSize &= 0x0F; // %16 + paddingSize &= 0x0F; // %16 if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; // verify signature @@ -934,7 +934,7 @@ namespace transport for (const auto& it: msgs) if (it) { - if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) + if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) m_Data.Send (it); else LogPrint (eLogError, "SSU: I2NP message of size ", it->GetLength (), " can't be sent. Dropped"); @@ -1206,4 +1206,3 @@ namespace transport } } } - diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 8f81838a..4f73158a 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -28,7 +28,7 @@ namespace transport const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_CLOCK_SKEW = 60; // in seconds - const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; + const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; // payload types (4 bits) const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; @@ -81,12 +81,12 @@ namespace transport void Done (); void Failed (); const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; - + bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice - SessionState GetState () const { return m_State; }; + SessionState GetState () const { return m_State; }; size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; @@ -158,10 +158,7 @@ namespace transport std::unique_ptr m_SignedData; // we need it for SessionConfirmed only std::map > m_RelayRequests; // nonce->Charlie }; - - } } #endif - diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 21d08f30..64aff5bc 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -6,11 +6,11 @@ namespace i2p { namespace crypto { -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA EDDSA25519Verifier::EDDSA25519Verifier (): m_Pkey (nullptr) { - m_MDCtx = EVP_MD_CTX_create (); + m_MDCtx = EVP_MD_CTX_create (); } EDDSA25519Verifier::~EDDSA25519Verifier () @@ -23,21 +23,21 @@ namespace crypto { m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - } - + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); } - -#else + +#else EDDSA25519Verifier::EDDSA25519Verifier () { } EDDSA25519Verifier::~EDDSA25519Verifier () { - } + } void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) { @@ -45,8 +45,8 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); m_PublicKey = GetEd25519 ()->DecodePublicKey (m_PublicKeyEncoded, ctx); BN_CTX_free (ctx); - } - + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { uint8_t digest[64]; @@ -83,19 +83,19 @@ namespace crypto EDDSA25519SignerCompat::~EDDSA25519SignerCompat () { - } - + } + void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } - -#if OPENSSL_EDDSA + +#if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): m_Fallback (nullptr) - { + { m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); - uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; + uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) @@ -105,10 +105,10 @@ namespace crypto m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); } else - { - m_MDCtx = EVP_MD_CTX_create (); + { + m_MDCtx = EVP_MD_CTX_create (); EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - } + } } EDDSA25519Signer::~EDDSA25519Signer () @@ -118,22 +118,20 @@ namespace crypto { EVP_MD_CTX_destroy (m_MDCtx); EVP_PKEY_free (m_Pkey); - } + } } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const { if (m_Fallback) return m_Fallback->Sign (buf, len, signature); else - { - size_t l = 64; + { + size_t l = 64; uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 - EVP_DigestSign (m_MDCtx, sig, &l, buf, len); + EVP_DigestSign (m_MDCtx, sig, &l, buf, len); memcpy (signature, sig, 64); - } - } -#endif + } + } +#endif } } - - diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 0c5f27d6..26184639 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -46,9 +46,9 @@ namespace crypto { m_PublicKey = CreateDSA (); } - + void SetPublicKey (const uint8_t * signingKey) - { + { DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); } @@ -163,9 +163,9 @@ namespace crypto { m_PublicKey = EC_KEY_new_by_curve_name (curve); } - + void SetPublicKey (const uint8_t * signingKey) - { + { BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL); EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y); @@ -287,7 +287,7 @@ namespace crypto EDDSA25519Verifier (); void SetPublicKey (const uint8_t * signingKey); ~EDDSA25519Verifier (); - + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; @@ -298,10 +298,10 @@ namespace crypto #if OPENSSL_EDDSA EVP_PKEY * m_Pkey; EVP_MD_CTX * m_MDCtx; -#else +#else EDDSAPoint m_PublicKey; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; -#endif +#endif }; class EDDSA25519SignerCompat: public Signer @@ -311,17 +311,17 @@ namespace crypto EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); // we pass signingPublicKey to check if it matches private key ~EDDSA25519SignerCompat (); - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation private: - + uint8_t m_ExpandedPrivateKey[64]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; }; -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA class EDDSA25519Signer: public Signer { public: @@ -329,23 +329,23 @@ namespace crypto EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); // we pass signingPublicKey to check if it matches private key ~EDDSA25519Signer (); - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; private: EVP_PKEY * m_Pkey; - EVP_MD_CTX * m_MDCtx; + EVP_MD_CTX * m_MDCtx; EDDSA25519SignerCompat * m_Fallback; }; #else typedef EDDSA25519SignerCompat EDDSA25519Signer; - -#endif - + +#endif + inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL); EVP_PKEY_keygen_init (pctx); @@ -355,12 +355,12 @@ namespace crypto EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len); len = EDDSA25519_PRIVATE_KEY_LENGTH; EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len); - EVP_PKEY_free (pkey); -#else + EVP_PKEY_free (pkey); +#else RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); EDDSA25519Signer signer (signingPrivateKey); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); -#endif +#endif } @@ -399,18 +399,18 @@ namespace crypto GOSTR3410Verifier (GOSTR3410ParamSet paramSet): m_ParamSet (paramSet), m_PublicKey (nullptr) { - } + } - void SetPublicKey (const uint8_t * signingKey) + void SetPublicKey (const uint8_t * signingKey) { BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL); m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); BN_free (x); BN_free (y); } - ~GOSTR3410Verifier () - { - if (m_PublicKey) EC_POINT_free (m_PublicKey); + ~GOSTR3410Verifier () + { + if (m_PublicKey) EC_POINT_free (m_PublicKey); } bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const @@ -501,18 +501,18 @@ namespace crypto auto publicKey = GetEd25519 ()->GeneratePublicKey (m_PrivateKey, ctx); GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); BN_CTX_free (ctx); - } + } ~RedDSA25519Signer () {}; - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const { - GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature); + GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature); } - + const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation private: - + uint8_t m_PrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; }; @@ -521,10 +521,9 @@ namespace crypto { GetEd25519 ()->CreateRedDSAPrivateKey (signingPrivateKey); RedDSA25519Signer signer (signingPrivateKey); - memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); + memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); } } } #endif - diff --git a/libi2pd/Siphash.h b/libi2pd/Siphash.h index 70822466..78b22b90 100644 --- a/libi2pd/Siphash.h +++ b/libi2pd/Siphash.h @@ -1,9 +1,9 @@ /** - This code is licensed under the MCGSI Public License - Copyright 2018 Jeff Becker - - Kovri go write your own code - + * This code is licensed under the MCGSI Public License + * Copyright 2018 Jeff Becker + * + * Kovri go write your own code + * */ #ifndef SIPHASH_H #define SIPHASH_H @@ -14,140 +14,140 @@ #if !OPENSSL_SIPHASH namespace i2p { -namespace crypto +namespace crypto { - namespace siphash - { - constexpr int crounds = 2; - constexpr int drounds = 4; + namespace siphash + { + constexpr int crounds = 2; + constexpr int drounds = 4; - inline uint64_t rotl(const uint64_t & x, int b) - { - uint64_t ret = x << b; - ret |= x >> (64 - b); - return ret; - } + inline uint64_t rotl(const uint64_t & x, int b) + { + uint64_t ret = x << b; + ret |= x >> (64 - b); + return ret; + } - inline void u32to8le(const uint32_t & v, uint8_t * p) - { - p[0] = (uint8_t) v; - p[1] = (uint8_t) (v >> 8); - p[2] = (uint8_t) (v >> 16); - p[3] = (uint8_t) (v >> 24); - } + inline void u32to8le(const uint32_t & v, uint8_t * p) + { + p[0] = (uint8_t) v; + p[1] = (uint8_t) (v >> 8); + p[2] = (uint8_t) (v >> 16); + p[3] = (uint8_t) (v >> 24); + } - inline void u64to8le(const uint64_t & v, uint8_t * p) - { - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; - p[4] = (v >> 32) & 0xff; - p[5] = (v >> 40) & 0xff; - p[6] = (v >> 48) & 0xff; - p[7] = (v >> 56) & 0xff; - } + inline void u64to8le(const uint64_t & v, uint8_t * p) + { + p[0] = v & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; + p[4] = (v >> 32) & 0xff; + p[5] = (v >> 40) & 0xff; + p[6] = (v >> 48) & 0xff; + p[7] = (v >> 56) & 0xff; + } - inline uint64_t u8to64le(const uint8_t * p) - { - uint64_t i = 0; - int idx = 0; - while(idx < 8) - { - i |= ((uint64_t) p[idx]) << (idx * 8); - ++idx; - } - return i; - } - - inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3) - { - _v0 += _v1; - _v1 = rotl(_v1, 13); - _v1 ^= _v0; - _v0 = rotl(_v0, 32); - _v2 += _v3; - _v3 = rotl(_v3, 16); - _v3 ^= _v2; - _v0 += _v3; - _v3 = rotl(_v3, 21); - _v3 ^= _v0; - _v2 += _v1; - _v1 = rotl(_v1, 17); - _v1 ^= _v2; - _v2 = rotl(_v2, 32); - } - } - - /** hashsz must be 8 or 16 */ - template - inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key) - { - uint64_t v0 = 0x736f6d6570736575ULL; - uint64_t v1 = 0x646f72616e646f6dULL; - uint64_t v2 = 0x6c7967656e657261ULL; - uint64_t v3 = 0x7465646279746573ULL; - const uint64_t k0 = siphash::u8to64le(key); - const uint64_t k1 = siphash::u8to64le(key + 8); - uint64_t msg; - int i; - const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t)); - auto left = bufsz & 7; - uint64_t b = ((uint64_t)bufsz) << 56; - v3 ^= k1; - v2 ^= k0; - v1 ^= k1; - v0 ^= k0; + inline uint64_t u8to64le(const uint8_t * p) + { + uint64_t i = 0; + int idx = 0; + while(idx < 8) + { + i |= ((uint64_t) p[idx]) << (idx * 8); + ++idx; + } + return i; + } - if(hashsz == 16) v1 ^= 0xee; + inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3) + { + _v0 += _v1; + _v1 = rotl(_v1, 13); + _v1 ^= _v0; + _v0 = rotl(_v0, 32); + _v2 += _v3; + _v3 = rotl(_v3, 16); + _v3 ^= _v2; + _v0 += _v3; + _v3 = rotl(_v3, 21); + _v3 ^= _v0; + _v2 += _v1; + _v1 = rotl(_v1, 17); + _v1 ^= _v2; + _v2 = rotl(_v2, 32); + } + } - while(buf != end) - { - msg = siphash::u8to64le(buf); - v3 ^= msg; - for(i = 0; i < siphash::crounds; ++i) - siphash::round(v0, v1, v2, v3); - - v0 ^= msg; - buf += 8; - } + /** hashsz must be 8 or 16 */ + template + inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key) + { + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f6dULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + const uint64_t k0 = siphash::u8to64le(key); + const uint64_t k1 = siphash::u8to64le(key + 8); + uint64_t msg; + int i; + const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t)); + auto left = bufsz & 7; + uint64_t b = ((uint64_t)bufsz) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; - while(left) - { - --left; - b |= ((uint64_t)(buf[left])) << (left * 8); - } + if(hashsz == 16) v1 ^= 0xee; - v3 ^= b; + while(buf != end) + { + msg = siphash::u8to64le(buf); + v3 ^= msg; + for(i = 0; i < siphash::crounds; ++i) + siphash::round(v0, v1, v2, v3); - for(i = 0; i < siphash::crounds; ++i) - siphash::round(v0, v1, v2, v3); + v0 ^= msg; + buf += 8; + } - v0 ^= b; + while(left) + { + --left; + b |= ((uint64_t)(buf[left])) << (left * 8); + } + + v3 ^= b; + + for(i = 0; i < siphash::crounds; ++i) + siphash::round(v0, v1, v2, v3); + + v0 ^= b; - if(hashsz == 16) - v2 ^= 0xee; - else - v2 ^= 0xff; + if(hashsz == 16) + v2 ^= 0xee; + else + v2 ^= 0xff; - for(i = 0; i < siphash::drounds; ++i) - siphash::round(v0, v1, v2, v3); + for(i = 0; i < siphash::drounds; ++i) + siphash::round(v0, v1, v2, v3); - b = v0 ^ v1 ^ v2 ^ v3; + b = v0 ^ v1 ^ v2 ^ v3; - siphash::u64to8le(b, h); + siphash::u64to8le(b, h); - if(hashsz == 8) return; + if(hashsz == 8) return; - v1 ^= 0xdd; + v1 ^= 0xdd; - for (i = 0; i < siphash::drounds; ++i) - siphash::round(v0, v1, v2, v3); + for (i = 0; i < siphash::drounds; ++i) + siphash::round(v0, v1, v2, v3); - b = v0 ^ v1 ^ v2 ^ v3; - siphash::u64to8le(b, h + 8); - } + b = v0 ^ v1 ^ v2 ^ v3; + siphash::u64to8le(b, h + 8); + } } } #endif diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 00ee35b0..ac527cb4 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -34,7 +34,7 @@ namespace stream else { // partially - rem = len - offset; + rem = len - offset; memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset); nextBuffer->offset += (len - offset); offset = len; // break @@ -60,7 +60,7 @@ namespace stream m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local), m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), - m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), + m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) @@ -73,7 +73,7 @@ namespace stream m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), - m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { @@ -228,7 +228,7 @@ namespace stream Terminate (); return; } - + packet->offset = packet->GetPayload () - packet->buf; if (packet->GetLength () > 0) { @@ -258,7 +258,7 @@ namespace stream bool Stream::ProcessOptions (uint16_t flags, Packet * packet) { const uint8_t * optionData = packet->GetOptionData (); - size_t optionSize = packet->GetOptionSize (); + size_t optionSize = packet->GetOptionSize (); if (flags & PACKET_FLAG_DELAY_REQUESTED) optionData += 2; @@ -269,7 +269,7 @@ namespace stream m_RemoteIdentity = std::make_shared(optionData, optionSize); if (m_RemoteIdentity->IsRSA ()) { - LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded"); + LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded"); return false; } optionData += m_RemoteIdentity->GetFullLen (); @@ -306,11 +306,11 @@ namespace stream size_t offset = 0; m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset); optionData += offset; - if (!m_TransientVerifier) + if (!m_TransientVerifier) { LogPrint (eLogError, "Streaming: offline signature failed"); return false; - } + } } } @@ -322,7 +322,7 @@ namespace stream { memcpy (signature, optionData, signatureLen); memset (const_cast(optionData), 0, signatureLen); - bool verified = m_TransientVerifier ? + bool verified = m_TransientVerifier ? m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) : m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature); if (!verified) @@ -340,7 +340,7 @@ namespace stream return false; } } - return true; + return true; } void Stream::ProcessAck (Packet * packet) @@ -435,7 +435,7 @@ namespace stream m_SendBuffer.Add (buf, len, handler); } else if (handler) - handler(boost::system::error_code ()); + handler(boost::system::error_code ()); m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ())); } @@ -471,14 +471,14 @@ namespace stream size++; // resend delay if (m_Status == eStreamStatusNew) { - // initial packet + // initial packet m_Status = eStreamStatusOpen; if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; if (m_RemoteLeaseSet) - { + { m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; - } + } uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; if (isNoAck) flags |= PACKET_FLAG_NO_ACK; @@ -488,7 +488,7 @@ namespace stream size += 2; // flags size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen (); size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); - uint8_t * optionsSize = packet + size; // set options size later + uint8_t * optionsSize = packet + size; // set options size later size += 2; // options size m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); size += identityLen; // from @@ -654,7 +654,7 @@ namespace stream size += 4; // receiveStreamID htobe32buf (packet + size, m_SequenceNumber++); size += 4; // sequenceNum - htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0); + htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0); size += 4; // ack Through packet[size] = 0; size++; // NACK count @@ -748,7 +748,7 @@ namespace stream auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet - ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD) + ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD) UpdateCurrentRemoteLease (true); if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { @@ -785,7 +785,7 @@ namespace stream if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT) { // LeaseSet was not confirmed, should try other tunnels - LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit"); + LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit"); m_RoutingSession->SetSharedRoutingPath (nullptr); m_CurrentOutboundTunnel = nullptr; m_CurrentRemoteLease = nullptr; @@ -848,9 +848,9 @@ namespace stream break; case 2: m_RTO = INITIAL_RTO; // drop RTO to initial upon tunnels pair change first time -#if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here case 4: if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); @@ -911,7 +911,7 @@ namespace stream // LeaseSet updated m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity (); m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier (); - } + } } if (m_RemoteLeaseSet) { @@ -926,7 +926,7 @@ namespace stream m_LocalDestination.GetOwner ()->RequestDestinationWithEncryptedLeaseSet ( std::make_shared(m_RemoteIdentity)); else - m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); + m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); leases = m_RemoteLeaseSet->GetNonExpiredLeases (true); // then with threshold } if (!leases.empty ()) @@ -994,7 +994,7 @@ namespace stream { std::unique_lock l(m_StreamsMutex); for (auto it: m_Streams) - it.second->Terminate (false); // we delete here + it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); } @@ -1136,8 +1136,8 @@ namespace stream return false; DeleteStream (it->second); return true; - } - + } + void StreamingDestination::SetAcceptor (const Acceptor& acceptor) { m_Acceptor = acceptor; // we must set it immediately for IsAcceptorSet @@ -1164,7 +1164,7 @@ namespace stream m_Owner->GetService ().post([acceptor, this](void) { if (!m_PendingIncomingStreams.empty ()) - { + { acceptor (m_PendingIncomingStreams.front ()); m_PendingIncomingStreams.pop_front (); if (m_PendingIncomingStreams.empty ()) diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index 010b160f..eefab6de 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -16,93 +16,91 @@ namespace i2p { namespace data { - -template -class Tag -{ - BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes"); - -public: - - Tag () = default; - Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); } - - bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); } - bool operator!= (const Tag& other) const { return !(*this == other); } - bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; } - - uint8_t * operator()() { return m_Buf; } - const uint8_t * operator()() const { return m_Buf; } - - operator uint8_t * () { return m_Buf; } - operator const uint8_t * () const { return m_Buf; } - - const uint8_t * data() const { return m_Buf; } - const uint64_t * GetLL () const { return ll; } - - bool IsZero () const + template + class Tag { - for (size_t i = 0; i < sz/8; ++i) - if (ll[i]) return false; - return true; - } + BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes"); - void Fill(uint8_t c) - { - memset(m_Buf, c, sz); - } + public: - void Randomize() - { - RAND_bytes(m_Buf, sz); - } + Tag () = default; + Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); } - std::string ToBase64 () const - { - char str[sz*2]; - size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); - return std::string (str, str + l); - } + bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); } + bool operator!= (const Tag& other) const { return !(*this == other); } + bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; } - std::string ToBase32 () const - { - char str[sz*2]; - size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); - return std::string (str, str + l); - } + uint8_t * operator()() { return m_Buf; } + const uint8_t * operator()() const { return m_Buf; } - size_t FromBase32 (const std::string& s) - { - return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } + operator uint8_t * () { return m_Buf; } + operator const uint8_t * () const { return m_Buf; } - size_t FromBase64 (const std::string& s) - { - return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } + const uint8_t * data() const { return m_Buf; } + const uint64_t * GetLL () const { return ll; } -private: + bool IsZero () const + { + for (size_t i = 0; i < sz/8; ++i) + if (ll[i]) return false; + return true; + } - union // 8 bytes aligned - { - uint8_t m_Buf[sz]; - uint64_t ll[sz/8]; + void Fill(uint8_t c) + { + memset(m_Buf, c, sz); + } + + void Randomize() + { + RAND_bytes(m_Buf, sz); + } + + std::string ToBase64 () const + { + char str[sz*2]; + size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); + return std::string (str, str + l); + } + + std::string ToBase32 () const + { + char str[sz*2]; + size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); + return std::string (str, str + l); + } + + size_t FromBase32 (const std::string& s) + { + return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + size_t FromBase64 (const std::string& s) + { + return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + private: + + union // 8 bytes aligned + { + uint8_t m_Buf[sz]; + uint64_t ll[sz/8]; + }; }; -}; - } // data } // i2p namespace std { - // hash for std::unordered_map - template struct hash > - { - size_t operator()(const i2p::data::Tag& s) const - { - return s.GetLL ()[0]; - } - }; + // hash for std::unordered_map + template struct hash > + { + size_t operator()(const i2p::data::Tag& s) const + { + return s.GetLL ()[0]; + } + }; } #endif /* TAG_H__ */ diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index acc9cb10..9e435e21 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -24,26 +24,26 @@ namespace util static uint64_t GetLocalMillisecondsSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static uint32_t GetLocalHoursSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static uint64_t GetLocalSecondsSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static int64_t g_TimeOffset = 0; // in seconds static void SyncTimeWithNTP (const std::string& address) { - LogPrint (eLogInfo, "Timestamp: NTP request to ", address); + LogPrint (eLogInfo, "Timestamp: NTP request to ", address); boost::asio::io_service service; boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp"); boost::system::error_code ec; @@ -148,11 +148,11 @@ namespace util } void NTPTimeSync::Sync () - { + { if (m_NTPServersList.size () > 0) SyncTimeWithNTP (m_NTPServersList[rand () % m_NTPServersList.size ()]); else - m_IsRunning = false; + m_IsRunning = false; if (m_IsRunning) { @@ -200,4 +200,3 @@ namespace util } } } - diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index 31dc86aa..7d183cd3 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -15,8 +15,8 @@ namespace util uint32_t GetHoursSinceEpoch (); uint64_t GetSecondsSinceEpoch (); - void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes - void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes + void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes + void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes class NTPTimeSync { @@ -26,17 +26,17 @@ namespace util ~NTPTimeSync (); void Start (); - void Stop (); + void Stop (); private: - + void Run (); - void Sync (); + void Sync (); private: bool m_IsRunning; - std::unique_ptr m_Thread; + std::unique_ptr m_Thread; boost::asio::io_service m_Service; boost::asio::deadline_timer m_Timer; int m_SyncInterval; @@ -46,4 +46,3 @@ namespace util } #endif - diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 1adc4178..02aac23f 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -12,7 +12,7 @@ namespace i2p namespace tunnel { TransitTunnel::TransitTunnel (uint32_t receiveTunnelID, - const uint8_t * nextIdent, uint32_t nextTunnelID, + const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * layerKey,const uint8_t * ivKey): TunnelBase (receiveTunnelID, nextTunnelID, nextIdent) { @@ -88,7 +88,7 @@ namespace tunnel std::shared_ptr CreateTransitTunnel (uint32_t receiveTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID, - const uint8_t * layerKey,const uint8_t * ivKey, + const uint8_t * layerKey,const uint8_t * ivKey, bool isGateway, bool isEndpoint) { if (isEndpoint) diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 55c39c7a..69b772cb 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -68,15 +68,15 @@ namespace transport std::string GetIdentHashBase64() const { return m_RemoteIdentity ? m_RemoteIdentity->GetIdentHash().ToBase64() : ""; } - std::shared_ptr GetRemoteIdentity () + std::shared_ptr GetRemoteIdentity () { std::lock_guard l(m_RemoteIdentityMutex); - return m_RemoteIdentity; + return m_RemoteIdentity; } - void SetRemoteIdentity (std::shared_ptr ident) + void SetRemoteIdentity (std::shared_ptr ident) { std::lock_guard l(m_RemoteIdentityMutex); - m_RemoteIdentity = ident; + m_RemoteIdentity = ident; } size_t GetNumSentBytes () const { return m_NumSentBytes; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index bb74e2ad..15820584 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -220,10 +220,10 @@ namespace transport return; } else - { + { m_NTCP2Server = new NTCP2Server (); m_NTCP2Server->Start (); - } + } } // create acceptors @@ -390,7 +390,7 @@ namespace transport { auto r = netdb.FindRouter (ident); { - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, i2p::util::GetSecondsSinceEpoch (), {} })).first; } @@ -553,13 +553,13 @@ namespace transport { auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 if (router) - m_SSUServer->CreateSession (router, true, isv4); // peer test + m_SSUServer->CreateSession (router, true, isv4); // peer test else { // if not peer test capable routers found pick any router = i2p::data::netdb.GetRandomRouter (); if (router && router->IsSSU ()) - m_SSUServer->CreateSession (router); // no peer test + m_SSUServer->CreateSession (router); // no peer test } } if (i2p::context.SupportsV6 ()) @@ -574,7 +574,7 @@ namespace transport if (addr) m_SSUServer->GetServiceV6 ().post ([this, router, addr] { - m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); + m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); }); } } @@ -713,7 +713,7 @@ namespace transport { profile->TunnelNonReplied(); } - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } else diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 117092ad..37cfa269 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -103,7 +103,7 @@ namespace transport uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; }; uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; } void UpdateTotalTransitTransmittedBytes (uint32_t add) { m_TotalTransitTransmittedBytes += add; }; - uint32_t GetInBandwidth () const { return m_InBandwidth; }; + uint32_t GetInBandwidth () const { return m_InBandwidth; }; uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; }; bool IsBandwidthExceeded () const; @@ -111,16 +111,16 @@ namespace transport size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer () const; - /** get a trusted first hop for restricted routes */ - std::shared_ptr GetRestrictedPeer() const; - /** do we want to use restricted routes? */ - bool RoutesRestricted() const; - /** restrict routes to use only these router families for first hops */ - void RestrictRoutesToFamilies(std::set families); - /** restrict routes to use only these routers for first hops */ - void RestrictRoutesToRouters(std::set routers); + /** get a trusted first hop for restricted routes */ + std::shared_ptr GetRestrictedPeer() const; + /** do we want to use restricted routes? */ + bool RoutesRestricted() const; + /** restrict routes to use only these router families for first hops */ + void RestrictRoutesToFamilies(std::set families); + /** restrict routes to use only these routers for first hops */ + void RestrictRoutesToRouters(std::set routers); - bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; + bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; void PeerTest (); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 324d5315..6e453d91 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -64,8 +64,7 @@ namespace tunnel m.hash = i2p::data::IdentHash (fragment); fragment += 32; // to hash break; - default: - ; + default: ; } bool isFragmented = flag & 0x08; diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 7d0069a9..3f4069e1 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -51,7 +51,7 @@ namespace tunnel // create fragments const std::shared_ptr & msg = block.data; size_t fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length - + if (!messageCreated && fullMsgLen > m_RemainingSize) // check if we should complete previous message { size_t numFollowOnFragments = fullMsgLen / TUNNEL_DATA_MAX_PAYLOAD_SIZE; @@ -172,7 +172,7 @@ namespace tunnel SHA256(payload, size+16, hash); memcpy (buf+20, hash, 4); // checksum payload[-1] = 0; // zero - ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1 + ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1 if (paddingSize > 0) { // non-zero padding @@ -219,4 +219,3 @@ namespace tunnel } } } - diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7256b2db..54459960 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -16,7 +16,6 @@ namespace i2p { namespace tunnel { - TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true), @@ -67,7 +66,8 @@ namespace tunnel m_Tests.clear (); } - bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) { + bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) + { if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0) { m_NumInboundHops = inHops; @@ -78,7 +78,7 @@ namespace tunnel } return false; } - + void TunnelPool::TunnelCreated (std::shared_ptr createdTunnel) { if (!m_IsActive) return; @@ -180,8 +180,8 @@ namespace tunnel { if (it->IsEstablished () && it != excluded) { - tunnel = it; - i++; + tunnel = it; + i++; } if (i > ind && tunnel) break; } @@ -411,7 +411,7 @@ namespace tunnel { std::lock_guard lock(m_CustomPeerSelectorMutex); if (m_CustomPeerSelector) - return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); + return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); } // explicit peers in use if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index d6fb91cc..149a5efa 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -75,23 +75,23 @@ namespace tunnel /** i2cp reconfigure */ bool Reconfigure(int inboundHops, int outboundHops, int inboundQuant, int outboundQuant); - + void SetCustomPeerSelector(ITunnelPeerSelector * selector); void UnsetCustomPeerSelector(); bool HasCustomPeerSelector(); - /** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */ - void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; } + /** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */ + void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; } - /** @brief return true if this tunnel pool has a latency requirement */ - bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; } + /** @brief return true if this tunnel pool has a latency requirement */ + bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; } - /** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */ - std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude=nullptr) const; - std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude=nullptr) const; + /** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */ + std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude = nullptr) const; + std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude = nullptr) const; - // for overriding tunnel peer selection - std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; + // for overriding tunnel peer selection + std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; private: @@ -118,8 +118,8 @@ namespace tunnel std::mutex m_CustomPeerSelectorMutex; ITunnelPeerSelector * m_CustomPeerSelector; - uint64_t m_MinLatency=0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms - uint64_t m_MaxLatency=0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms + uint64_t m_MinLatency = 0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms + uint64_t m_MaxLatency = 0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms public: diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 0a76bda7..3bac4878 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -31,8 +31,8 @@ namespace api bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); i2p::crypto::InitCrypto (precomputation); - int netID; i2p::config::GetOption("netid", netID); - i2p::context.SetNetID (netID); + int netID; i2p::config::GetOption("netid", netID); + i2p::context.SetNetID (netID); i2p::context.Init (); } @@ -133,4 +133,3 @@ namespace api } } } - diff --git a/libi2pd/api.h b/libi2pd/api.h index f64590d1..444667f0 100644 --- a/libi2pd/api.h +++ b/libi2pd/api.h @@ -35,4 +35,3 @@ namespace api } #endif - diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index c1b741fc..37898167 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -64,9 +64,9 @@ namespace util { m_IsRunning = true; m_Thread.reset (new std::thread (std::bind (& RunnableService::Run, this))); - } + } } - + void RunnableService::StopIOService () { if (m_IsRunning) @@ -79,7 +79,7 @@ namespace util m_Thread = nullptr; } } - } + } void RunnableService::Run () { @@ -94,28 +94,28 @@ namespace util LogPrint (eLogError, m_Name, ": runtime exception: ", ex.what ()); } } - } - + } + namespace net { #ifdef WIN32 bool IsWindowsXPorLater() { - static bool isRequested = false; - static bool isXP = false; - if (!isRequested) - { - // request - OSVERSIONINFO osvi; + static bool isRequested = false; + static bool isXP = false; + if (!isRequested) + { + // request + OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); - isXP = osvi.dwMajorVersion <= 5; - isRequested = true; - } - return isXP; + isXP = osvi.dwMajorVersion <= 5; + isRequested = true; + } + return isXP; } int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) @@ -246,22 +246,24 @@ namespace net std::string localAddressUniversal = localAddress.to_string(); #endif - typedef int (* IPN)(int af, const char *src, void *dst); + typedef int (* IPN)(int af, const char *src, void *dst); IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); - if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found + if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if(localAddress.is_v4()) { sockaddr_in inputAddress; - inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } else if(localAddress.is_v6()) { sockaddr_in6 inputAddress; - inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); return GetMTUWindowsIpv6(inputAddress, fallback); - } else { + } + else + { LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported"); return fallback; } @@ -355,7 +357,7 @@ namespace net if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af) { // match - char addr[INET6_ADDRSTRLEN]; + char addr[INET6_ADDRSTRLEN]; memset (addr, 0, INET6_ADDRSTRLEN); if(af == AF_INET) inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN); @@ -379,7 +381,6 @@ namespace net LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname); } return boost::asio::ip::address::from_string(fallback); - #endif } } diff --git a/libi2pd/util.h b/libi2pd/util.h index 2202ccd9..aa83ed7b 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -132,34 +132,34 @@ namespace util boost::asio::io_service& GetIOService () { return m_Service; } bool IsRunning () const { return m_IsRunning; }; - + void StartIOService (); void StopIOService (); private: void Run (); - + private: std::string m_Name; volatile bool m_IsRunning; std::unique_ptr m_Thread; boost::asio::io_service m_Service; - }; + }; class RunnableServiceWithWork: public RunnableService { protected: - RunnableServiceWithWork (const std::string& name): - RunnableService (name), m_Work (GetIOService ()) {} - + RunnableServiceWithWork (const std::string& name): + RunnableService (name), m_Work (GetIOService ()) {} + private: boost::asio::io_service::work m_Work; - }; - + }; + namespace net { int GetMTU (const boost::asio::ip::address& localAddress); diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 0e40c76e..8e14c526 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -31,7 +31,7 @@ namespace client std::string etagsPath, indexPath, localPath; public: - AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") + AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") { i2p::config::GetOption("persist.addressbook", m_IsPersist); } @@ -77,10 +77,10 @@ namespace client std::shared_ptr AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const { - if (!m_IsPersist) + if (!m_IsPersist) { LogPrint(eLogDebug, "Addressbook: Persistence is disabled"); - return nullptr; + return nullptr; } std::string filename = storage.Path(ident.ToBase32()); std::ifstream f(filename, std::ifstream::binary); @@ -121,7 +121,7 @@ namespace client void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident) { - if (!m_IsPersist) return; + if (!m_IsPersist) return; storage.Remove( ident.ToBase32() ); } @@ -189,7 +189,7 @@ namespace client } for (const auto& it: addresses) - { + { f << it.first << ","; if (it.second->IsIdentHash ()) f << it.second->identHash.ToBase32 (); @@ -251,12 +251,12 @@ namespace client if (blindedPublicKey->IsValid ()) addressType = eAddressBlindedPublicKey; } - } + } Address::Address (const i2p::data::IdentHash& hash) { addressType = eAddressIndentHash; - identHash = hash; + identHash = hash; } AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false), @@ -322,7 +322,7 @@ namespace client { auto pos = address.find(".b32.i2p"); if (pos != std::string::npos) - { + { auto addr = std::make_shared(address.substr (0, pos)); return addr->IsValid () ? addr : nullptr; } @@ -333,10 +333,10 @@ namespace client { auto addr = FindAddress (address); if (!addr) - LookupAddress (address); // TODO: + LookupAddress (address); // TODO: return addr; - } - } + } + } // if not .b32 we assume full base64 address i2p::data::IdentityEx dest; if (!dest.FromBase64 (address)) @@ -359,10 +359,10 @@ namespace client { m_Addresses[address] = std::make_shared
(jump.substr (0, pos)); LogPrint (eLogInfo, "Addressbook: added ", address," -> ", jump); - } + } else - { - // assume base64 + { + // assume base64 auto ident = std::make_shared(); if (ident->FromBase64 (jump)) { @@ -487,18 +487,18 @@ namespace client LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead"); } else if (!i2p::config::IsDefault("addressbook.subscriptions")) - { - // using config file items - std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs); - std::vector subsList; - boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); + { + // using config file items + std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs); + std::vector subsList; + boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); - for (size_t i = 0; i < subsList.size (); i++) - { - m_Subscriptions.push_back (std::make_shared (*this, subsList[i])); - } - LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); - } + for (size_t i = 0; i < subsList.size (); i++) + { + m_Subscriptions.push_back (std::make_shared (*this, subsList[i])); + } + LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); + } } else LogPrint (eLogError, "Addressbook: subscriptions already loaded"); @@ -515,7 +515,7 @@ namespace client if (dot != std::string::npos) { auto domain = it.first.substr (dot + 1); - auto it1 = m_Addresses.find (domain); // find domain in our addressbook + auto it1 = m_Addresses.find (domain); // find domain in our addressbook if (it1 != m_Addresses.end () && it1->second->IsIdentHash ()) { auto dest = context.FindLocalDestination (it1->second->identHash); @@ -610,7 +610,7 @@ namespace client { // download it from default subscription LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription."); - std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL); + std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL); if (!m_DefaultSubscription) m_DefaultSubscription = std::make_shared(*this, defaultSubURL); m_IsDownloading = true; @@ -743,13 +743,13 @@ namespace client i2p::http::URL url; // must be run in separate thread LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link); - if (!url.parse(m_Link)) + if (!url.parse(m_Link)) { LogPrint(eLogError, "Addressbook: failed to parse url: ", m_Link); return false; } auto addr = m_Book.GetAddress (url.host); - if (!addr || !addr->IsIdentHash ()) + if (!addr || !addr->IsIdentHash ()) { LogPrint (eLogError, "Addressbook: Can't resolve ", url.host); return false; @@ -802,7 +802,7 @@ namespace client /* convert url to relative */ url.schema = ""; url.host = ""; - req.uri = url.to_string(); + req.uri = url.to_string(); auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port); std::string request = req.to_string(); stream->Send ((const uint8_t *) request.data(), request.length()); @@ -920,7 +920,7 @@ namespace client { auto datagram = m_LocalDestination->GetDatagramDestination (); if (datagram) - datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT); + datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT); } } diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index 82ba167b..fb69dad3 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -37,8 +37,8 @@ namespace client i2p::data::IdentHash identHash; std::shared_ptr blindedPublicKey; - Address (const std::string& b32); - Address (const i2p::data::IdentHash& hash); + Address (const std::string& b32); + Address (const i2p::data::IdentHash& hash); bool IsIdentHash () const { return addressType == eAddressIndentHash; }; bool IsValid () const { return addressType != eAddressInvalid; }; }; @@ -160,5 +160,3 @@ namespace client } #endif - - diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index c7bbdb46..e5d5404b 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -50,10 +50,10 @@ namespace client void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr receiver) { receiver->socket->async_read_some (boost::asio::buffer( - receiver->buffer + receiver->bufferOffset, - BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset), + receiver->buffer + receiver->bufferOffset, + BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset), std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this, - std::placeholders::_1, std::placeholders::_2, receiver)); + std::placeholders::_1, std::placeholders::_2, receiver)); } void BOBI2PInboundTunnel::HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred, @@ -255,7 +255,7 @@ namespace client std::bind(&BOBCommandSession::HandleReceivedLine, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - + void BOBCommandSession::HandleReceivedLine(const boost::system::error_code& ecode, std::size_t bytes_transferred) { if(ecode) @@ -267,14 +267,14 @@ namespace client else { std::string line; - + std::istream is(&m_ReceiveBuffer); std::getline(is, line); - + std::string command, operand; std::istringstream iss(line); iss >> command >> operand; - + // process command auto& handlers = m_Owner.GetCommandHandlers(); auto it = handlers.find(command); @@ -346,7 +346,7 @@ namespace client std::ostream os(&m_SendBuffer); os << data << std::endl; } - + void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) { // helper lambdas @@ -355,7 +355,7 @@ namespace client const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; }; const auto destReady = [](const BOBDestination * const dest) { return dest->GetLocalDestination()->IsReady(); }; const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str - + // tunnel info const std::string nickname = currentTunnel ? m_Nickname : dest->GetNickname(); const bool quiet = currentTunnel ? m_IsQuiet : dest->GetQuiet(); @@ -367,7 +367,7 @@ namespace client const bool starting = destExists(dest) && !destReady(dest); const bool running = destExists(dest) && destReady(dest); const bool stopping = false; - + // build line std::stringstream ss; ss << "DATA " @@ -433,11 +433,11 @@ namespace client return; } } - + if (!m_CurrentDestination) { m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command - m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); + m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); m_Owner.AddDestination (m_Nickname, m_CurrentDestination); } if (m_InPort) @@ -613,25 +613,24 @@ namespace client } auto localDestination = m_CurrentDestination ? m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination (); if (addr->IsIdentHash ()) - { + { // we might have leaseset already auto leaseSet = localDestination->FindLeaseSet (addr->identHash); if (leaseSet) - { + { SendReplyOK (leaseSet->GetIdentity ()->ToBase64 ().c_str ()); return; } } // trying to request - auto s = shared_from_this (); - auto requstCallback = - [s](std::shared_ptr ls) - { - if (ls) - s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ()); - else - s->SendReplyError ("LeaseSet Not found"); - }; + auto s = shared_from_this (); + auto requstCallback = [s](std::shared_ptr ls) + { + if (ls) + s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ()); + else + s->SendReplyError ("LeaseSet Not found"); + }; if (addr->IsIdentHash ()) localDestination->RequestDestination (addr->identHash, requstCallback); else @@ -794,7 +793,7 @@ namespace client BOBCommandChannel::~BOBCommandChannel () { - if (IsRunning ()) + if (IsRunning ()) Stop (); for (const auto& it: m_Destinations) delete it.second; @@ -856,8 +855,7 @@ namespace client session->SendVersion (); } else - LogPrint (eLogError, "BOB: accept error: ", ecode.message ()); + LogPrint (eLogError, "BOB: accept error: ", ecode.message ()); } } } - diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 15a0afaf..a3d58148 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -39,7 +39,7 @@ namespace client const char BOB_COMMAND_OPTION[] = "option"; const char BOB_COMMAND_STATUS[] = "status"; const char BOB_COMMAND_HELP[] = "help"; - + const char BOB_HELP_ZAP[] = "zap - Shuts down BOB."; const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB."; const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel."; @@ -75,15 +75,15 @@ namespace client class BOBI2PInboundTunnel: public BOBI2PTunnel { - struct AddressReceiver - { - std::shared_ptr socket; - char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address - uint8_t * data; // pointer to buffer - size_t dataLen, bufferOffset; + struct AddressReceiver + { + std::shared_ptr socket; + char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address + uint8_t * data; // pointer to buffer + size_t dataLen, bufferOffset; - AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {}; - }; + AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {}; + }; public: @@ -115,7 +115,7 @@ namespace client { public: - BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); + BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); void Start (); void Stop (); @@ -162,7 +162,7 @@ namespace client std::shared_ptr m_LocalDestination; BOBI2POutboundTunnel * m_OutboundTunnel; BOBI2PInboundTunnel * m_InboundTunnel; - + std::string m_Nickname; std::string m_InHost, m_OutHost; int m_InPort, m_OutPort; @@ -215,14 +215,14 @@ namespace client void SendReplyOK (const char * msg = nullptr); void SendReplyError (const char * msg); void SendRaw (const char * data); - + void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out); private: BOBCommandChannel& m_Owner; boost::asio::ip::tcp::socket m_Socket; - boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; + boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; bool m_IsOpen, m_IsQuiet, m_IsActive; std::string m_Nickname, m_InHost, m_OutHost; int m_InPort, m_OutPort; @@ -269,4 +269,3 @@ namespace client } #endif - diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 51f10f5e..03c756a1 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -52,18 +52,18 @@ namespace client // SAM bool sam; i2p::config::GetOption("sam.enabled", sam); - if (sam) + if (sam) { std::string samAddr; i2p::config::GetOption("sam.address", samAddr); uint16_t samPort; i2p::config::GetOption("sam.port", samPort); - bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); + bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try + try { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); m_SamBridge->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); @@ -76,12 +76,12 @@ namespace client std::string bobAddr; i2p::config::GetOption("bob.address", bobAddr); uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); - try + try { m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); m_BOBCommandChannel->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); @@ -95,12 +95,12 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try + try { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); @@ -407,13 +407,13 @@ namespace client template std::string ClientContext::GetI2CPOption (const Section& section, const std::string& name, const Type& value) const { - return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); } template std::string ClientContext::GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const { - return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); } template @@ -423,13 +423,13 @@ namespace client { if (it.first.length () >= group.length () && !it.first.compare (0, group.length (), group)) options[it.first] = it.second.get_value (""); - } + } } - + template void ClientContext::ReadI2CPOptions (const Section& section, std::map& options) const { - options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); + options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY); options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY); @@ -528,10 +528,10 @@ namespace client { std::string type = section.second.get (I2P_TUNNELS_SECTION_TYPE); if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT - || type == I2P_TUNNELS_SECTION_TYPE_SOCKS - || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS - || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY - || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + || type == I2P_TUNNELS_SECTION_TYPE_SOCKS + || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS + || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY + || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { // mandatory params std::string dest; @@ -640,9 +640,9 @@ namespace client } } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER - || type == I2P_TUNNELS_SECTION_TYPE_HTTP - || type == I2P_TUNNELS_SECTION_TYPE_IRC - || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) + || type == I2P_TUNNELS_SECTION_TYPE_HTTP + || type == I2P_TUNNELS_SECTION_TYPE_IRC + || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { // mandatory params std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); @@ -699,7 +699,7 @@ namespace client continue; } - std::shared_ptr serverTunnel; + std::shared_ptr serverTunnel; if (type == I2P_TUNNELS_SECTION_TYPE_HTTP) serverTunnel = std::make_shared (name, host, port, localDestination, hostOverride, inPort, gzip); else if (type == I2P_TUNNELS_SECTION_TYPE_IRC) @@ -745,7 +745,7 @@ namespace client ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ()); } ins.first->second->isUpdated = true; - LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); + LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); } } @@ -769,9 +769,9 @@ namespace client std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -786,12 +786,12 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try + try { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); @@ -826,13 +826,13 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try + try { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 1a56575f..110f0970 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -75,10 +75,11 @@ namespace client const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); - std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, - const i2p::data::PrivateKeys& keys, bool isPublic = true, + std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); // same as previous but on external io_service - std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params = nullptr); + std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, + const std::string & name, const std::map * params = nullptr); void DeleteLocalDestination (std::shared_ptr destination); std::shared_ptr FindLocalDestination (const i2p::data::IdentHash& destination) const; bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, @@ -114,7 +115,7 @@ namespace client template void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain - void CreateNewSharedLocalDestination (); + void CreateNewSharedLocalDestination (); void AddLocalDestination (std::shared_ptr localDestination); private: @@ -141,6 +142,7 @@ namespace client std::unique_ptr m_CleanupUDPTimer; public: + // for HTTP const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; }; const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; }; diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index af4d2913..0c915921 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -191,7 +191,7 @@ namespace proxy { res.body = ss.str(); std::string response = res.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(), - std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); + std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm) @@ -406,7 +406,7 @@ namespace proxy { void HTTPReqHandler::ForwardToUpstreamProxy() { LogPrint(eLogDebug, "HTTPProxy: forward to upstream"); - // build http requset + // build http request m_ClientRequestURL = m_RequestURL; LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host); @@ -458,7 +458,7 @@ namespace proxy { if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { - m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); + m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); })); } else @@ -562,14 +562,16 @@ namespace proxy { if(m_ClientRequest.method == "CONNECT") { m_ClientResponse.code = 200; m_send_buf = m_ClientResponse.to_string(); - boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { + boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) + { if(ec) GenericProxyError("socks proxy error", ec.message().c_str()); else HandoverToUpstreamProxy(); }); } else { m_send_buf = m_ClientRequestBuffer.str(); LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes"); - boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) { + boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) + { if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str()); else HandoverToUpstreamProxy(); }); diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 590166e3..4504eedd 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -6,6 +6,7 @@ namespace proxy { class HTTPProxy: public i2p::client::TCPIPAcceptor { public: + HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination); HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr localDestination = nullptr) : HTTPProxy(name, address, port, "", true, localDestination) {} ; @@ -15,11 +16,13 @@ namespace proxy { bool GetHelperSupport() { return m_Addresshelper; } protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return m_Name.c_str (); } private: + std::string m_Name; std::string m_OutproxyUrl; bool m_Addresshelper; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index f4c8a91e..2cea5098 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,7 +24,7 @@ namespace client { I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), + RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) { } @@ -33,26 +33,26 @@ namespace client { if (IsRunning ()) Stop (); - } - + } + void I2CPDestination::Start () { if (!IsRunning ()) - { + { LeaseSetDestination::Start (); StartIOService (); - } + } } - + void I2CPDestination::Stop () { if (IsRunning ()) - { + { LeaseSetDestination::Stop (); StopIOService (); - } - } - + } + } + void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { memcpy (m_EncryptionPrivateKey, key, 256); @@ -98,7 +98,7 @@ namespace client auto ls = (storeType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ? std::make_shared (m_Identity, buf, len): std::make_shared (storeType, m_Identity, buf, len); - ls->SetExpirationTime (m_LeaseSetExpirationTime); + ls->SetExpirationTime (m_LeaseSetExpirationTime); SetLeaseSet (ls); } @@ -221,7 +221,7 @@ namespace client auto s = shared_from_this (); m_Socket->async_read_some (boost::asio::buffer (m_Header, 1), [s](const boost::system::error_code& ecode, std::size_t bytes_transferred) - { + { if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE) s->ReceiveHeader (); else @@ -247,15 +247,15 @@ namespace client if (m_PayloadLen > 0) { if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH) - { + { m_Payload = new uint8_t[m_PayloadLen]; ReceivePayload (); } else { - LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); + LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); Terminate (); - } + } } else // no following payload { @@ -323,7 +323,7 @@ namespace client memcpy (buf + I2CP_HEADER_SIZE, payload, len); boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + std::placeholders::_1, std::placeholders::_2, buf)); } else LogPrint (eLogError, "I2CP: Can't write to the socket"); @@ -510,8 +510,8 @@ namespace client } else LogPrint(eLogError, "I2CP: short message"); - SendSessionStatusMessage (status); - } + SendSessionStatusMessage (status); + } void I2CPSession::SendSessionStatusMessage (uint8_t status) { @@ -568,12 +568,12 @@ namespace client { LogPrint (eLogError, "I2CP: invalid LeaseSet2 of type ", storeType); return; - } + } offset += ls.GetBufferLen (); // private keys int numPrivateKeys = buf[offset]; offset++; uint16_t currentKeyType = 0; - const uint8_t * currentKey = nullptr; + const uint8_t * currentKey = nullptr; for (int i = 0; i < numPrivateKeys; i++) { if (offset + 4 > len) return; @@ -586,7 +586,7 @@ namespace client currentKey = buf + offset; } offset += keyLen; - } + } // TODO: support multiple keys if (currentKey) { @@ -594,7 +594,7 @@ namespace client m_Destination->SetEncryptionType (currentKeyType); } - m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); + m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); } } else @@ -779,14 +779,14 @@ namespace client memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + std::placeholders::_1, std::placeholders::_2, buf)); } I2CPServer::I2CPServer (const std::string& interface, int port): m_IsRunning (false), m_Thread (nullptr), m_Acceptor (m_Service, #ifdef ANDROID - I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address + I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address #else I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port)) #endif @@ -823,10 +823,10 @@ namespace client m_IsRunning = false; m_Acceptor.cancel (); { - auto sessions = m_Sessions; + auto sessions = m_Sessions; for (auto& it: sessions) it.second->Stop (); - } + } m_Sessions.clear (); m_Service.stop (); if (m_Thread) @@ -899,4 +899,3 @@ namespace client } } } - diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 7f590555..08dbaa21 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -25,7 +25,7 @@ namespace client const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; - + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; @@ -69,10 +69,10 @@ namespace client I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); ~I2CPDestination (); - + void Start (); void Stop (); - + void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession @@ -82,7 +82,7 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; - // TODO: implement GetEncryptionPublicKey + // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; protected: @@ -220,4 +220,3 @@ namespace client } #endif - diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 31f34710..7a30decd 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -115,22 +115,24 @@ namespace client { if(m_ConnectTimeout && !m_LocalDestination->IsReady()) { - AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) { + AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) + { if(ec) { LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message()); streamRequestComplete(nullptr); } else - { if (address->IsIdentHash ()) + { + if (address->IsIdentHash ()) this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port); else - this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); + this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); } }); } else - { + { if (address->IsIdentHash ()) m_LocalDestination->CreateStream (streamRequestComplete, address->identHash, port); else @@ -180,7 +182,7 @@ namespace client { m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE), std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); } else LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket"); @@ -191,7 +193,7 @@ namespace client if (m_down) { m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE), std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); } else LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket"); @@ -205,8 +207,8 @@ namespace client boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleUpstreamWrite, - shared_from_this(), - std::placeholders::_1)); + shared_from_this(), + std::placeholders::_1)); } else LogPrint(eLogError, "TCPIPPipe: upstream write: no socket"); @@ -220,8 +222,8 @@ namespace client boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleDownstreamWrite, - shared_from_this(), - std::placeholders::_1)); + shared_from_this(), + std::placeholders::_1)); } else LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index e0dfd2da..be935b93 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -18,10 +18,12 @@ namespace client class I2PService : public std::enable_shared_from_this { public: + typedef std::function ReadyCallback; public: - I2PService (std::shared_ptr localDestination = nullptr); + + I2PService (std::shared_ptr localDestination = nullptr); I2PService (i2p::data::SigningKeyType kt); virtual ~I2PService (); @@ -42,7 +44,7 @@ namespace client void AddReadyCallback(ReadyCallback cb); inline std::shared_ptr GetLocalDestination () { return m_LocalDestination; } - inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } + inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } inline void SetLocalDestination (std::shared_ptr dest) { if (m_LocalDestination) m_LocalDestination->Release (); @@ -59,21 +61,24 @@ namespace client virtual const char* GetName() { return "Generic I2P Service"; } private: + void TriggerReadyCheckTimer(); void HandleReadyCheckTimer(const boost::system::error_code & ec); private: + std::shared_ptr m_LocalDestination; std::unordered_set > m_Handlers; std::mutex m_HandlersMutex; std::vector > m_ReadyCallbacks; boost::asio::deadline_timer m_ReadyTimer; - bool m_ReadyTimerTriggered; + bool m_ReadyTimerTriggered; uint32_t m_ConnectTimeout; - const size_t NEVER_TIMES_OUT = 0; - + const size_t NEVER_TIMES_OUT = 0; + public: + bool isUpdated; // transient, used during reload only }; @@ -81,6 +86,7 @@ namespace client class I2PServiceHandler { public: + I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { } virtual ~I2PServiceHandler() { } //If you override this make sure you call it from the children @@ -89,6 +95,7 @@ namespace client void Terminate () { Kill (); }; protected: + // Call when terminating or handing over to avoid race conditions inline bool Kill () { return m_Dead.exchange(true); } // Call to know if the handler is dead @@ -99,6 +106,7 @@ namespace client inline I2PService * GetOwner() { return m_Service; } private: + I2PService *m_Service; std::atomic m_Dead; //To avoid cleaning up multiple times }; @@ -109,11 +117,13 @@ namespace client class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this { public: + TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); ~TCPIPPipe(); void Start(); protected: + void Terminate(); void AsyncReceiveUpstream(); void AsyncReceiveDownstream(); @@ -125,6 +135,7 @@ namespace client void DownstreamWrite(size_t len); private: + uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE]; uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; std::shared_ptr m_up, m_down; @@ -135,6 +146,7 @@ namespace client class TCPIPAcceptor: public I2PService { public: + TCPIPAcceptor (const std::string& address, int port, std::shared_ptr localDestination = nullptr) : I2PService(localDestination), m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), @@ -149,14 +161,16 @@ namespace client //If you override this make sure you call it from the children void Stop (); - const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; + const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } protected: + virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; private: + void Accept(); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); boost::asio::ip::tcp::endpoint m_LocalEndpoint; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index dc2a8811..b7a15c26 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -168,7 +168,7 @@ namespace client { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2), + std::placeholders::_1, std::placeholders::_2), I2P_TUNNEL_CONNECTION_MAX_IDLE); } else // closed by peer @@ -257,7 +257,7 @@ namespace client if (!m_ConnectionSent && !line.compare(0, 10, "Connection")) { /* close connection, if not Connection: (U|u)pgrade (for websocket) */ - auto x = line.find("pgrade"); + auto x = line.find("pgrade"); if (x != std::string::npos && std::tolower(line[x - 1]) == 'u') m_OutHeader << line << "\r\n"; else @@ -281,7 +281,7 @@ namespace client if (endOfHeader) { if (!m_ConnectionSent) m_OutHeader << "Connection: close\r\n"; - if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n"; + if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n"; m_OutHeader << "\r\n"; // end of header m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); @@ -462,7 +462,7 @@ namespace client } /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ - std::shared_ptr I2PClientTunnel::GetAddress () + std::shared_ptr I2PClientTunnel::GetAddress () { if (!m_Address) { @@ -477,7 +477,7 @@ namespace client { auto address = GetAddress (); if (address) - return std::make_shared(this, address, m_DestinationPort, socket); + return std::make_shared(this, address, m_DestinationPort, socket); else return nullptr; } @@ -826,7 +826,7 @@ namespace client { LogPrint(eLogError, "UDP Tunnel: ", m_RemoteDest, " not found"); return; - } + } m_RemoteIdent = new i2p::data::IdentHash; *m_RemoteIdent = addr->identHash; LogPrint(eLogInfo, "UDP Tunnel: resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32()); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index fbe2f7bb..94f63e48 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -30,6 +30,7 @@ namespace client class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this { public: + I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr leaseSet, int port = 0); // to I2P I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, @@ -41,6 +42,7 @@ namespace client void Connect (bool isUniqueLocal = true); protected: + void Terminate (); void Receive (); @@ -55,6 +57,7 @@ namespace client std::shared_ptr GetSocket () const { return m_Socket; }; private: + uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE]; std::shared_ptr m_Socket; std::shared_ptr m_Stream; @@ -65,15 +68,18 @@ namespace client class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection { public: + I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream): I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false), m_ConnectionSent (false), m_ProxyConnectionSent (false) {}; protected: + void Write (const uint8_t * buf, size_t len); private: + std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent; }; @@ -81,14 +87,17 @@ namespace client class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection { public: + I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host); protected: + void Write (const uint8_t * buf, size_t len); private: + std::string m_Host; std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent; @@ -98,14 +107,17 @@ namespace client class I2PTunnelConnectionIRC: public I2PTunnelConnection { public: + I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass); protected: + void Write (const uint8_t * buf, size_t len); private: + std::shared_ptr m_From; std::stringstream m_OutPacket, m_InPacket; bool m_NeedsWebIrc; @@ -116,10 +128,12 @@ namespace client class I2PClientTunnel: public TCPIPAcceptor { protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); public: + I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort = 0); ~I2PClientTunnel () {} @@ -130,9 +144,11 @@ namespace client const char* GetName() { return m_Name.c_str (); } private: + std::shared_ptr GetAddress (); private: + std::string m_Name, m_Destination; std::shared_ptr m_Address; int m_DestinationPort; @@ -160,9 +176,9 @@ namespace client uint8_t m_Buffer[I2P_UDP_MAX_MTU]; UDPSession(boost::asio::ip::udp::endpoint localEndpoint, - const std::shared_ptr & localDestination, - boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident, - uint16_t ourPort, uint16_t theirPort); + const std::shared_ptr & localDestination, + boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident, + uint16_t ourPort, uint16_t theirPort); void HandleReceived(const boost::system::error_code & ecode, std::size_t len); void Receive(); }; @@ -195,6 +211,7 @@ namespace client class I2PUDPServerTunnel { public: + I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, @@ -210,10 +227,12 @@ namespace client void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; } private: + void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); private: + bool m_IsUniqueLocal; const std::string m_Name; boost::asio::ip::address m_LocalAddress; @@ -226,6 +245,7 @@ namespace client class I2PUDPClientTunnel { public: + I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, uint16_t remotePort, bool gzip); @@ -240,6 +260,7 @@ namespace client void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT); private: + typedef std::pair UDPConvo; void RecvFromLocal(); void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); @@ -263,6 +284,7 @@ namespace client class I2PServerTunnel: public I2PService { public: + I2PServerTunnel (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, int inport = 0, bool gzip = true); @@ -282,6 +304,7 @@ namespace client const char* GetName() { return m_Name.c_str (); } private: + void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, std::shared_ptr resolver); @@ -290,6 +313,7 @@ namespace client virtual std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + bool m_IsUniqueLocal; std::string m_Name, m_Address; int m_Port; @@ -302,28 +326,34 @@ namespace client class I2PServerTunnelHTTP: public I2PServerTunnel { public: + I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, const std::string& host, int inport = 0, bool gzip = true); private: + std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + std::string m_Host; }; class I2PServerTunnelIRC: public I2PServerTunnel { public: + I2PServerTunnelIRC (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, const std::string& webircpass, int inport = 0, bool gzip = true); private: + std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + std::string m_WebircPass; }; } diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 5cec178f..a4c82504 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -14,10 +14,10 @@ namespace client void MatchedTunnelDestination::ResolveCurrentLeaseSet() { - auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName); + auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName); if(addr && addr->IsIdentHash ()) { - m_RemoteIdent = addr->identHash; + m_RemoteIdent = addr->identHash; auto ls = FindLeaseSet(m_RemoteIdent); if(ls) HandleFoundCurrentLeaseSet(ls); @@ -39,7 +39,7 @@ namespace client { m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1)); m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) { - if(!ec) ResolveCurrentLeaseSet(); + if(!ec) ResolveCurrentLeaseSet(); }); } } @@ -50,7 +50,7 @@ namespace client ClientDestination::Start(); m_ResolveTimer = std::make_shared(GetService()); GetTunnelPool()->SetCustomPeerSelector(this); - ResolveCurrentLeaseSet(); + ResolveCurrentLeaseSet(); } void MatchedTunnelDestination::Stop() diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 9d61799a..53cae203 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -8,26 +8,30 @@ namespace i2p namespace client { /** - client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination + * client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination */ class MatchedTunnelDestination : public RunnableClientDestination, public i2p::tunnel::ITunnelPeerSelector { - public: - MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, const std::map * params = nullptr); - void Start(); - void Stop(); + public: - bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); + MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, + const std::map * params = nullptr); + void Start(); + void Stop(); - private: - void ResolveCurrentLeaseSet(); - void HandleFoundCurrentLeaseSet(std::shared_ptr ls); + bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); - private: - std::string m_RemoteName; - i2p::data::IdentHash m_RemoteIdent; - std::shared_ptr m_RemoteLeaseSet; - std::shared_ptr m_ResolveTimer; + private: + + void ResolveCurrentLeaseSet(); + void HandleFoundCurrentLeaseSet(std::shared_ptr ls); + + private: + + std::string m_RemoteName; + i2p::data::IdentHash m_RemoteIdent; + std::shared_ptr m_RemoteLeaseSet; + std::shared_ptr m_ResolveTimer; }; } } diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index d0942221..086cbe69 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -17,7 +17,7 @@ namespace client { SAMSocket::SAMSocket (SAMBridge& owner): m_Owner (owner), m_Socket(owner.GetService()), m_Timer (m_Owner.GetService ()), - m_BufferOffset (0), + m_BufferOffset (0), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false), m_IsAccepting (false), m_Stream (nullptr) { @@ -26,7 +26,7 @@ namespace client SAMSocket::~SAMSocket () { m_Stream = nullptr; - } + } void SAMSocket::Terminate (const char* reason) { @@ -54,8 +54,7 @@ namespace client } break; } - default: - ; + default: ; } m_SocketType = eSAMSocketTypeTerminated; if (m_Socket.is_open ()) @@ -68,7 +67,7 @@ namespace client } void SAMSocket::ReceiveHandshake () - { + { m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE), std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -152,7 +151,7 @@ namespace client size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); #endif boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (), - std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), + std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } else @@ -170,7 +169,7 @@ namespace client { return id == m_ID; } - + void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -350,7 +349,7 @@ namespace client } std::shared_ptr forward = nullptr; - if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && + if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end()) { // udp forward selected @@ -372,7 +371,7 @@ namespace client } forward = std::make_shared(addr, port); } - + //ensure we actually received a destination if (destination.empty()) { @@ -381,7 +380,7 @@ namespace client } if (destination != SAM_VALUE_TRANSIENT) - { + { //ensure it's a base64 string i2p::data::PrivateKeys keys; if (!keys.FromBase64(destination)) @@ -389,7 +388,7 @@ namespace client SendMessageReply(SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), true); return; } - } + } // create destination auto session = m_Owner.CreateSession (id, type, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms); @@ -542,7 +541,7 @@ namespace client m_SocketType = eSAMSocketTypeAcceptor; if (!session->localDestination->IsAcceptingStreams ()) { - m_IsAccepting = true; + m_IsAccepting = true; session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); @@ -567,7 +566,7 @@ namespace client { i2p::data::IdentityEx dest; dest.FromBase64 (params[SAM_PARAM_DESTINATION]); - if (session->Type == eSAMSessionTypeDatagram) + if (session->Type == eSAMSessionTypeDatagram) d->SendDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); else // raw d->SendRawDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); @@ -598,20 +597,20 @@ namespace client if (it != params.end ()) { if (!m_Owner.ResolveSignatureType (it->second, signatureType)) - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); } it = params.find (SAM_PARAM_CRYPTO_TYPE); if (it != params.end ()) { try - { + { cryptoType = std::stoi(it->second); } - catch (const std::exception& ex) + catch (const std::exception& ex) { - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); - } - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } auto keys = i2p::data::PrivateKeys::CreateRandomKeys (signatureType, cryptoType); #ifdef _MSC_VER size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY, @@ -647,12 +646,12 @@ namespace client else dest->RequestDestination (addr->identHash, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, - shared_from_this (), std::placeholders::_1, name)); + shared_from_this (), std::placeholders::_1, name)); } else dest->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, - shared_from_this (), std::placeholders::_1, name)); + shared_from_this (), std::placeholders::_1, name)); } else { @@ -762,7 +761,7 @@ namespace client if (m_Stream) { if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew || - m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular + m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE), std::bind (&SAMSocket::HandleI2PReceive, shared_from_this(), @@ -800,7 +799,7 @@ namespace client { delete [] buff; } - + void SAMSocket::WriteI2PData(size_t sz) { boost::asio::async_write ( @@ -809,7 +808,7 @@ namespace client boost::asio::transfer_all(), std::bind(&SAMSocket::HandleWriteI2PData, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - + void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -955,7 +954,7 @@ namespace client auto ep = session->UDPEndpoint; if (ep) // udp forward enabled - m_Owner.SendTo(buf, len, ep); + m_Owner.SendTo(buf, len, ep); else { #ifdef _MSC_VER @@ -978,7 +977,7 @@ namespace client { m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); } - + SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type, std::shared_ptr dest): m_Bridge(parent), localDestination (dest), @@ -986,7 +985,7 @@ namespace client Name(id), Type (type) { } - + SAMSession::~SAMSession () { i2p::client::context.DeleteLocalDestination (localDestination); @@ -1001,7 +1000,7 @@ namespace client } SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): - RunnableService ("SAM"), m_IsSingleThread (singleThread), + RunnableService ("SAM"), m_IsSingleThread (singleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes @@ -1063,7 +1062,7 @@ namespace client std::unique_lock lock(m_OpenSocketsMutex); m_OpenSockets.remove_if([socket](const std::shared_ptr & item) -> bool { return item == socket; }); } - + void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket) { if (!ecode) @@ -1089,7 +1088,7 @@ namespace client Accept (); } - std::shared_ptr SAMBridge::CreateSession (const std::string& id, SAMSessionType type, + std::shared_ptr SAMBridge::CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, const std::map * params) { std::shared_ptr localDestination = nullptr; @@ -1097,7 +1096,7 @@ namespace client { i2p::data::PrivateKeys keys; if (!keys.FromBase64 (destination)) return nullptr; - localDestination = m_IsSingleThread ? + localDestination = m_IsSingleThread ? i2p::client::context.CreateNewLocalDestination (GetIOService (), keys, true, params) : i2p::client::context.CreateNewLocalDestination (keys, true, params); } @@ -1110,24 +1109,24 @@ namespace client { auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); if (it != params->end ()) - { + { if (!ResolveSignatureType (it->second, signatureType)) - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); + } it = params->find (SAM_PARAM_CRYPTO_TYPE); if (it != params->end ()) - { + { try - { + { cryptoType = std::stoi(it->second); } - catch (const std::exception& ex) + catch (const std::exception& ex) { - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); - } - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } } - localDestination = m_IsSingleThread ? + localDestination = m_IsSingleThread ? i2p::client::context.CreateNewLocalDestination (GetIOService (), true, signatureType, cryptoType, params) : i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); } @@ -1165,11 +1164,11 @@ namespace client { auto timer = std::make_shared(GetService ()); timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds - timer->async_wait ([timer, session](const boost::system::error_code& ecode) + timer->async_wait ([timer, session](const boost::system::error_code& ecode) { // session's destructor is called here }); - } + } } } @@ -1193,7 +1192,7 @@ namespace client } return list; } - + void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote) { if(remote) @@ -1261,7 +1260,7 @@ namespace client bool SAMBridge::ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const { try - { + { type = std::stoi (name); } catch (const std::invalid_argument& ex) @@ -1273,12 +1272,12 @@ namespace client else return false; } - catch (const std::exception& ex) + catch (const std::exception& ex) { - return false; - } - // name has been resolved - return true; + return false; + } + // name has been resolved + return true; } } } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 5a447c06..51a8bc57 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -87,7 +87,7 @@ namespace client typedef boost::asio::ip::tcp::socket Socket_t; SAMSocket (SAMBridge& owner); - ~SAMSocket (); + ~SAMSocket (); Socket_t& GetSocket () { return m_Socket; }; void ReceiveHandshake (); @@ -97,10 +97,11 @@ namespace client void Terminate (const char* reason); bool IsSession(const std::string & id) const; - - private: + + private: + void TerminateClose() { Terminate(nullptr); } - + void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred); @@ -137,7 +138,7 @@ namespace client void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff); void HandleStreamSend(const boost::system::error_code & ec); - + private: SAMBridge& m_Owner; @@ -186,7 +187,7 @@ namespace client void Stop (); boost::asio::io_service& GetService () { return GetIOService (); }; - std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient + std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); std::shared_ptr FindSession (const std::string& id) const; @@ -197,8 +198,8 @@ namespace client void SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote); void RemoveSocket(const std::shared_ptr & socket); - - bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; + + bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; private: diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index a70ac2b7..272ac178 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -41,6 +41,7 @@ namespace proxy class SOCKSHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this { private: + enum state { GET_SOCKSV, @@ -137,7 +138,7 @@ namespace proxy void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; @@ -165,6 +166,7 @@ namespace proxy const uint16_t m_UpstreamProxyPort; public: + SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : I2PServiceHandler(parent), m_proxy_resolver(parent->GetService()), @@ -652,8 +654,7 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async upstream sock read"); if (m_upstreamSock) { m_upstreamSock->async_read_some(boost::asio::buffer(m_upstream_response, SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE), - std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError, "SOCKS: no upstream socket for read"); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -773,7 +774,7 @@ namespace proxy SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination) : - TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name) + TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name) { m_UseUpstreamProxy = false; if (outAddress.length() > 0 && outEnable) diff --git a/libi2pd_client/SOCKS.h b/libi2pd_client/SOCKS.h index 87f08de4..fc43415a 100644 --- a/libi2pd_client/SOCKS.h +++ b/libi2pd_client/SOCKS.h @@ -14,6 +14,7 @@ namespace proxy class SOCKSServer: public i2p::client::TCPIPAcceptor { public: + SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination = nullptr); ~SOCKSServer() {}; @@ -21,6 +22,7 @@ namespace proxy void SetUpstreamProxy(const std::string & addr, const uint16_t port); protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return m_Name.c_str (); } From 8bae4975fbd923c55971278f6b389bef155b9258 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 16:18:41 +0300 Subject: [PATCH 132/189] add copyright headers Signed-off-by: R4SAS --- Win32/DaemonWin32.cpp | 8 ++++++++ Win32/Win32App.cpp | 8 ++++++++ Win32/Win32App.h | 8 ++++++++ Win32/Win32NetState.cpp | 8 ++++++++ Win32/Win32NetState.h | 8 ++++++++ Win32/Win32Service.cpp | 8 ++++++++ Win32/Win32Service.h | 8 ++++++++ android/jni/DaemonAndroid.cpp | 8 ++++++++ android/jni/DaemonAndroid.h | 8 ++++++++ android/jni/i2pd_android.cpp | 8 ++++++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 8 ++++++++ daemon/Daemon.cpp | 8 ++++++++ daemon/Daemon.h | 8 ++++++++ daemon/HTTPServer.cpp | 8 ++++++++ daemon/HTTPServer.h | 8 ++++++++ daemon/I2PControl.cpp | 8 ++++++++ daemon/I2PControl.h | 8 ++++++++ daemon/UPnP.cpp | 8 ++++++++ daemon/UPnP.h | 8 ++++++++ daemon/UnixDaemon.cpp | 8 ++++++++ daemon/i2pd.cpp | 8 ++++++++ libi2pd/Base.cpp | 8 ++++++++ libi2pd/Base.h | 8 ++++++++ libi2pd/Blinding.cpp | 8 ++++++++ libi2pd/Blinding.h | 8 ++++++++ libi2pd/BloomFilter.cpp | 8 ++++++++ libi2pd/BloomFilter.h | 8 ++++++++ libi2pd/CPU.cpp | 8 ++++++++ libi2pd/CPU.h | 8 ++++++++ libi2pd/ChaCha20.cpp | 2 +- libi2pd/ChaCha20.h | 2 +- libi2pd/Config.cpp | 2 +- libi2pd/Config.h | 8 ++++++++ libi2pd/Crypto.cpp | 8 ++++++++ libi2pd/Crypto.h | 8 ++++++++ libi2pd/CryptoKey.cpp | 8 ++++++++ libi2pd/CryptoKey.h | 8 ++++++++ libi2pd/CryptoWorker.h | 8 ++++++++ libi2pd/Datagram.cpp | 8 ++++++++ libi2pd/Datagram.h | 8 ++++++++ libi2pd/Destination.cpp | 8 ++++++++ libi2pd/Destination.h | 8 ++++++++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 8 ++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 8 ++++++++ libi2pd/Ed25519.cpp | 8 ++++++++ libi2pd/Ed25519.h | 8 ++++++++ libi2pd/Elligator.cpp | 8 ++++++++ libi2pd/Elligator.h | 8 ++++++++ libi2pd/FS.cpp | 2 +- libi2pd/FS.h | 2 +- libi2pd/Family.cpp | 8 ++++++++ libi2pd/Family.h | 8 ++++++++ libi2pd/Garlic.cpp | 8 ++++++++ libi2pd/Garlic.h | 8 ++++++++ libi2pd/Gost.cpp | 8 ++++++++ libi2pd/Gost.h | 8 ++++++++ libi2pd/Gzip.cpp | 2 +- libi2pd/Gzip.h | 8 ++++++++ libi2pd/HTTP.cpp | 2 +- libi2pd/HTTP.h | 2 +- libi2pd/I2NPProtocol.cpp | 8 ++++++++ libi2pd/I2NPProtocol.h | 8 ++++++++ libi2pd/I2PEndian.cpp | 8 ++++++++ libi2pd/I2PEndian.h | 8 ++++++++ libi2pd/Identity.cpp | 8 ++++++++ libi2pd/Identity.h | 8 ++++++++ libi2pd/LeaseSet.cpp | 8 ++++++++ libi2pd/LeaseSet.h | 8 ++++++++ libi2pd/LittleBigEndian.h | 8 ++++++++ libi2pd/Log.cpp | 2 +- libi2pd/Log.h | 2 +- libi2pd/NTCPSession.cpp | 8 ++++++++ libi2pd/NTCPSession.h | 8 ++++++++ libi2pd/NetDb.cpp | 8 ++++++++ libi2pd/NetDb.hpp | 8 ++++++++ libi2pd/NetDbRequests.cpp | 8 ++++++++ libi2pd/NetDbRequests.h | 8 ++++++++ libi2pd/Profiling.cpp | 8 ++++++++ libi2pd/Profiling.h | 8 ++++++++ libi2pd/Queue.h | 8 ++++++++ libi2pd/Reseed.cpp | 8 ++++++++ libi2pd/Reseed.h | 8 ++++++++ libi2pd/RouterContext.cpp | 8 ++++++++ libi2pd/RouterContext.h | 8 ++++++++ libi2pd/RouterInfo.cpp | 8 ++++++++ libi2pd/RouterInfo.h | 8 ++++++++ libi2pd/SSU.cpp | 8 ++++++++ libi2pd/SSU.h | 8 ++++++++ libi2pd/SSUData.cpp | 8 ++++++++ libi2pd/SSUData.h | 8 ++++++++ libi2pd/SSUSession.cpp | 8 ++++++++ libi2pd/SSUSession.h | 8 ++++++++ libi2pd/Signature.cpp | 8 ++++++++ libi2pd/Signature.h | 8 ++++++++ libi2pd/Streaming.cpp | 8 ++++++++ libi2pd/Streaming.h | 8 ++++++++ libi2pd/Tag.h | 8 ++++++++ libi2pd/Timestamp.cpp | 8 ++++++++ libi2pd/Timestamp.h | 8 ++++++++ libi2pd/TransitTunnel.cpp | 8 ++++++++ libi2pd/TransitTunnel.h | 8 ++++++++ libi2pd/TransportSession.h | 8 ++++++++ libi2pd/Transports.cpp | 8 ++++++++ libi2pd/Transports.h | 8 ++++++++ libi2pd/Tunnel.cpp | 8 ++++++++ libi2pd/Tunnel.h | 8 ++++++++ libi2pd/TunnelBase.h | 8 ++++++++ libi2pd/TunnelConfig.h | 8 ++++++++ libi2pd/TunnelEndpoint.cpp | 8 ++++++++ libi2pd/TunnelEndpoint.h | 8 ++++++++ libi2pd/TunnelGateway.cpp | 8 ++++++++ libi2pd/TunnelGateway.h | 8 ++++++++ libi2pd/TunnelPool.cpp | 8 ++++++++ libi2pd/TunnelPool.h | 8 ++++++++ libi2pd/api.cpp | 8 ++++++++ libi2pd/api.h | 8 ++++++++ libi2pd/util.cpp | 8 ++++++++ libi2pd/util.h | 8 ++++++++ libi2pd/version.h | 8 ++++++++ libi2pd_client/AddressBook.cpp | 8 ++++++++ libi2pd_client/AddressBook.h | 8 ++++++++ libi2pd_client/BOB.cpp | 8 ++++++++ libi2pd_client/BOB.h | 8 ++++++++ libi2pd_client/ClientContext.cpp | 8 ++++++++ libi2pd_client/ClientContext.h | 8 ++++++++ libi2pd_client/HTTPProxy.cpp | 2 +- libi2pd_client/HTTPProxy.h | 8 ++++++++ libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 2 +- libi2pd_client/I2PService.cpp | 8 ++++++++ libi2pd_client/I2PService.h | 8 ++++++++ libi2pd_client/I2PTunnel.cpp | 8 ++++++++ libi2pd_client/I2PTunnel.h | 8 ++++++++ libi2pd_client/MatchedDestination.cpp | 8 ++++++++ libi2pd_client/MatchedDestination.h | 8 ++++++++ libi2pd_client/SAM.cpp | 8 ++++++++ libi2pd_client/SAM.h | 8 ++++++++ libi2pd_client/SOCKS.cpp | 8 ++++++++ libi2pd_client/SOCKS.h | 8 ++++++++ 139 files changed, 1021 insertions(+), 13 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 7ba3ffc3..1214ff68 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Config.h" diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 3bcb24b3..df345b11 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/Win32/Win32App.h b/Win32/Win32App.h index 23082842..d242f7d3 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef WIN32APP_H__ #define WIN32APP_H__ diff --git a/Win32/Win32NetState.cpp b/Win32/Win32NetState.cpp index 9a650179..dd4dd08c 100644 --- a/Win32/Win32NetState.cpp +++ b/Win32/Win32NetState.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #if WINVER != 0x0501 // supported since Vista #include "Win32NetState.h" #include diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h index f043b171..bcb6c8d7 100644 --- a/Win32/Win32NetState.h +++ b/Win32/Win32NetState.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef WIN_32_NETSTATE_H__ #define WIN_32_NETSTATE_H__ diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index 9d1dedb4..7a6d7abf 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS // to use freopen #endif diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 05a6b9f9..40fff787 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef WIN_32_SERVICE_H__ #define WIN_32_SERVICE_H__ diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index c3a1b805..39c06ea0 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index 64bf64fd..912f6f49 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef DAEMON_ANDROID_H #define DAEMON_ANDROID_H diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index 177bfd7c..c6e309dd 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "org_purplei2p_i2pd_I2PD_JNI.h" #include "DaemonAndroid.h" diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index d5c2f15f..68935ad1 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class org_purplei2p_i2pd_I2PD_JNI */ diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index dd302fce..264013cf 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 050cc7e8..836c2a8e 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef DAEMON_H__ #define DAEMON_H__ diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 6f903e7e..7268ae01 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index fe62c271..a977e3e8 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef HTTP_SERVER_H__ #define HTTP_SERVER_H__ diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index fb00dc29..77614f2f 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index eb28af76..d731c24e 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2P_CONTROL_H__ #define I2P_CONTROL_H__ diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 92e79c11..852122f2 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifdef USE_UPNP #include #include diff --git a/daemon/UPnP.h b/daemon/UPnP.h index 29f9e3e6..e8220e24 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef __UPNP_H__ #define __UPNP_H__ diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index a59fc693..ffc5f1c0 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Daemon.h" #ifndef _WIN32 diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 7b68c073..028aa916 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Daemon.h" diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 51f5f225..921c20af 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include diff --git a/libi2pd/Base.h b/libi2pd/Base.h index 5d550092..073d9b40 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef BASE_H__ #define BASE_H__ diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 287d3648..6770d223 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include // for crc32 #include #include diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 3e0ad3fc..2f670882 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef BLINDING_H__ #define BLINDING_H__ diff --git a/libi2pd/BloomFilter.cpp b/libi2pd/BloomFilter.cpp index b92039df..de077e60 100644 --- a/libi2pd/BloomFilter.cpp +++ b/libi2pd/BloomFilter.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "BloomFilter.h" #include "I2PEndian.h" #include diff --git a/libi2pd/BloomFilter.h b/libi2pd/BloomFilter.h index 2745fbf5..ade854e4 100644 --- a/libi2pd/BloomFilter.h +++ b/libi2pd/BloomFilter.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef BLOOM_FILTER_H_ #define BLOOM_FILTER_H_ #include diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index a707c3dc..e7eff473 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "CPU.h" #if defined(__x86_64__) || defined(__i386__) #include diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index e1fd450c..9677b293 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef LIBI2PD_CPU_H #define LIBI2PD_CPU_H diff --git a/libi2pd/ChaCha20.cpp b/libi2pd/ChaCha20.cpp index 1d1e9bc6..66bc135f 100644 --- a/libi2pd/ChaCha20.cpp +++ b/libi2pd/ChaCha20.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/ChaCha20.h b/libi2pd/ChaCha20.h index a8bb1d56..4364024b 100644 --- a/libi2pd/ChaCha20.h +++ b/libi2pd/ChaCha20.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 59b51c00..19d72104 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2017, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 679795b1..dac5fc80 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef CONFIG_H #define CONFIG_H diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index d4d3519e..6db124c0 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 2dfd6d0e..56c8c10b 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef CRYPTO_H__ #define CRYPTO_H__ diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 2abcb111..d786e193 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Log.h" #include "Gost.h" diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 43bd3aaa..1c8b0a71 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef CRYPTO_KEY_H__ #define CRYPTO_KEY_H__ diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h index baeb7f14..27b012e7 100644 --- a/libi2pd/CryptoWorker.h +++ b/libi2pd/CryptoWorker.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef CRYPTO_WORKER_H_ #define CRYPTO_WORKER_H_ diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 2da73649..85b435d1 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Crypto.h" #include "Log.h" diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 72e7340c..e81f738a 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef DATAGRAM_H__ #define DATAGRAM_H__ diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 921e55f0..cd447773 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index dbdc3704..139423c6 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef DESTINATION_H__ #define DESTINATION_H__ diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index f3b1a685..61e67339 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Log.h" diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index d5a83f89..dd958060 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ECIES_X25519_AEAD_RATCHET_SESSION_H__ #define ECIES_X25519_AEAD_RATCHET_SESSION_H__ diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 8de5e3a1..791bd685 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Log.h" #include "Crypto.h" diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index 10061ad0..28d4e930 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ED25519_H__ #define ED25519_H__ diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 8fefb2ae..712e514a 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Crypto.h" #include "Elligator.h" diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 56fbc2eb..eacb03cd 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ELLIGATOR_H__ #define ELLIGATOR_H__ diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index f8b3ed7e..32fc3ec0 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 054ac2a3..698e9b6b 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index e5ac9990..fbb7b9ee 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Family.h b/libi2pd/Family.h index a1b5a789..2a9149ba 100644 --- a/libi2pd/Family.h +++ b/libi2pd/Family.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef FAMILY_H__ #define FAMILY_H__ diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5d07155e..7e717829 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "I2PEndian.h" #include diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 55ebe795..6b34231a 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef GARLIC_H__ #define GARLIC_H__ diff --git a/libi2pd/Gost.cpp b/libi2pd/Gost.cpp index c401f8be..5e84a95d 100644 --- a/libi2pd/Gost.cpp +++ b/libi2pd/Gost.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Gost.h b/libi2pd/Gost.h index a4cc9741..0a79c30b 100644 --- a/libi2pd/Gost.h +++ b/libi2pd/Gost.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef GOST_H__ #define GOST_H__ diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 5709719b..07c6a96e 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2017, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 6489b79b..d0bb28ed 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef GZIP_H__ #define GZIP_H__ diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 64acb6ea..4f7b03a1 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index f156fef0..c0cf1285 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 170bb864..a03ad7ed 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Base.h" diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 4ecba2eb..695de798 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2NP_PROTOCOL_H__ #define I2NP_PROTOCOL_H__ diff --git a/libi2pd/I2PEndian.cpp b/libi2pd/I2PEndian.cpp index b8a041d8..32ca4e26 100644 --- a/libi2pd/I2PEndian.cpp +++ b/libi2pd/I2PEndian.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "I2PEndian.h" // http://habrahabr.ru/post/121811/ diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index 04a9480e..9ffc28d0 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2PENDIAN_H__ #define I2PENDIAN_H__ #include diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 77a1f7e2..b2b5f2b4 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Crypto.h" #include "I2PEndian.h" #include "Log.h" diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 08baba01..534b8f4c 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef IDENTITY_H__ #define IDENTITY_H__ diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 1aa7fa6d..6b8b7545 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "I2PEndian.h" #include "Crypto.h" diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 479594e1..cd31bf30 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef LEASE_SET_H__ #define LEASE_SET_H__ diff --git a/libi2pd/LittleBigEndian.h b/libi2pd/LittleBigEndian.h index 55039fb6..8c081187 100644 --- a/libi2pd/LittleBigEndian.h +++ b/libi2pd/LittleBigEndian.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + // LittleBigEndian.h fixed for 64-bits added union // diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 6f2eb5bd..a0014841 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Log.h b/libi2pd/Log.h index fbd122a8..972a00e1 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 56c69e05..4d3f1da6 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/NTCPSession.h b/libi2pd/NTCPSession.h index e2207eb7..d3aa6f7c 100644 --- a/libi2pd/NTCPSession.h +++ b/libi2pd/NTCPSession.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef NTCP_SESSION_H__ #define NTCP_SESSION_H__ diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 30916f1a..466016c5 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 47a6fab5..1c65969a 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef NETDB_H__ #define NETDB_H__ // this file is called NetDb.hpp to resolve conflict with libc's netdb.h on case insensitive fs diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index b1eb9380..e7aab34c 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Log.h" #include "I2NPProtocol.h" #include "Transports.h" diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index c5e077bf..16ea430d 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef NETDB_REQUESTS_H__ #define NETDB_REQUESTS_H__ diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 3840eb32..850774d9 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 4ba6702f..dab50e6b 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef PROFILING_H__ #define PROFILING_H__ diff --git a/libi2pd/Queue.h b/libi2pd/Queue.h index 0438cc37..d43567a5 100644 --- a/libi2pd/Queue.h +++ b/libi2pd/Queue.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef QUEUE_H__ #define QUEUE_H__ diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 4f26e520..2812f413 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index 5f402988..345b45bf 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef RESEED_H #define RESEED_H diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b855fc29..cbbd961e 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Config.h" diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 6382189b..6f08a87a 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ROUTER_CONTEXT_H__ #define ROUTER_CONTEXT_H__ diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index bf81a8af..91c12b60 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "I2PEndian.h" diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 5bdb0f8f..ef902c0e 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ROUTER_INFO_H__ #define ROUTER_INFO_H__ diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 4a33ff3a..c435715f 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Log.h" diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 942d0e64..6a79f754 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SSU_H__ #define SSU_H__ diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 4eb90522..5068f006 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Log.h" diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 98d60c41..f4a5ba4f 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SSU_DATA_H__ #define SSU_DATA_H__ diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index e29af479..73699d6a 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "version.h" #include "Crypto.h" diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 4f73158a..066e01eb 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SSU_SESSION_H__ #define SSU_SESSION_H__ diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 64aff5bc..88ee4060 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Log.h" #include "Signature.h" diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 26184639..18084603 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SIGNATURE_H__ #define SIGNATURE_H__ diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ac527cb4..ff8915c0 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Crypto.h" #include "Log.h" #include "RouterInfo.h" diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index d3d47794..a56b0565 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef STREAMING_H__ #define STREAMING_H__ diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index eefab6de..3856abd9 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TAG_H__ #define TAG_H__ diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 9e435e21..4362a878 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index 7d183cd3..91175a49 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TIMESTAMP_H__ #define TIMESTAMP_H__ diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 02aac23f..73ca977c 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "I2PEndian.h" #include "Log.h" diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index 5b891dc3..e71ec750 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TRANSIT_TUNNEL_H__ #define TRANSIT_TUNNEL_H__ diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 69b772cb..a97f246f 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TRANSPORT_SESSION_H__ #define TRANSPORT_SESSION_H__ diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 15820584..2f5e92f5 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Log.h" #include "Crypto.h" #include "RouterContext.h" diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 37cfa269..cdfbfccf 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TRANSPORTS_H__ #define TRANSPORTS_H__ diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 879ee2d3..fe7e36af 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "I2PEndian.h" #include diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index f97bcc63..1fb12af9 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_H__ #define TUNNEL_H__ diff --git a/libi2pd/TunnelBase.h b/libi2pd/TunnelBase.h index 53782ae3..f98066d3 100644 --- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_BASE_H__ #define TUNNEL_BASE_H__ diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 48e66f2e..0bd8a842 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_CONFIG_H__ #define TUNNEL_CONFIG_H__ diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 6e453d91..eb70bdca 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "I2PEndian.h" #include #include "Crypto.h" diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index c2ffe53d..43b836f1 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_ENDPOINT_H__ #define TUNNEL_ENDPOINT_H__ diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 3f4069e1..8f01bc4e 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Crypto.h" #include "I2PEndian.h" diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index 7959b57b..01101a36 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_GATEWAY_H__ #define TUNNEL_GATEWAY_H__ diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 54459960..d0fd401f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "I2PEndian.h" diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 149a5efa..04ff4ae7 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TUNNEL_POOL__ #define TUNNEL_POOL__ diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 3bac4878..569fbd8c 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include "Config.h" diff --git a/libi2pd/api.h b/libi2pd/api.h index 444667f0..9b0256d8 100644 --- a/libi2pd/api.h +++ b/libi2pd/api.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef API_H__ #define API_H__ diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 37898167..f5204a50 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd/util.h b/libi2pd/util.h index aa83ed7b..cb8fd8f1 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef UTIL_H #define UTIL_H diff --git a/libi2pd/version.h b/libi2pd/version.h index fa8f9a0f..d862f46e 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef _VERSION_H_ #define _VERSION_H_ diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 8e14c526..8b8e781d 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index fb69dad3..04600792 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef ADDRESS_BOOK_H__ #define ADDRESS_BOOK_H__ diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index e5d5404b..c4447808 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Log.h" #include "ClientContext.h" diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index a3d58148..74418011 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef BOB_H__ #define BOB_H__ diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 03c756a1..6a58d63c 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 110f0970..8a4835c8 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef CLIENT_CONTEXT_H__ #define CLIENT_CONTEXT_H__ diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 0c915921..64080752 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 4504eedd..69ed4cef 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef HTTP_PROXY_H__ #define HTTP_PROXY_H__ diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 2cea5098..fef5d6b6 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 08dbaa21..f4e83f06 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 7a30decd..83838106 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "Destination.h" #include "Identity.h" #include "ClientContext.h" diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index be935b93..e14f85c1 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2PSERVICE_H__ #define I2PSERVICE_H__ diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index b7a15c26..5b384bff 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "Base.h" #include "Log.h" diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 94f63e48..d4db80d8 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2PTUNNEL_H__ #define I2PTUNNEL_H__ diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index a4c82504..4ffa7442 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include "MatchedDestination.h" #include "Log.h" #include "ClientContext.h" diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 53cae203..30ad8942 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef MATCHED_DESTINATION_H_ #define MATCHED_DESTINATION_H_ #include "Destination.h" diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 086cbe69..2c6b711d 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #ifdef _MSC_VER diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 51a8bc57..ceda5253 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SAM_H__ #define SAM_H__ diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 272ac178..52d7799b 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include diff --git a/libi2pd_client/SOCKS.h b/libi2pd_client/SOCKS.h index fc43415a..f41cfd72 100644 --- a/libi2pd_client/SOCKS.h +++ b/libi2pd_client/SOCKS.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef SOCKS_H__ #define SOCKS_H__ From ead89c767ac6641c55ed70d1488ec8ee3461dea6 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 May 2020 18:32:44 -0400 Subject: [PATCH 133/189] compress longer RouterInfo --- libi2pd/I2NPProtocol.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a03ad7ed..53afbca4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -257,7 +257,14 @@ namespace i2p uint8_t * sizePtr = buf; buf += 2; m->len += (buf - payload); // payload size - size_t size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + size_t size = 0; + if (router->GetBufferLen () + (buf - payload) <= 940) // fits one tunnel message + size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + else + { + i2p::data::GzipDeflator deflator; + size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + } if (size) { htobe16buf (sizePtr, size); // size From 86e8614934d0111756cc521cbaf06832b38e48fe Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 May 2020 10:20:22 -0400 Subject: [PATCH 134/189] allow session restart after 2 minutes from creation --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +++- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 61e67339..2f43b554 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -467,7 +467,8 @@ namespace garlic return false; } m_State = eSessionStateNewSessionReplySent; - + m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); + return true; } @@ -559,6 +560,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; + m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } memcpy (m_H, h, 32); // restore m_H diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index dd958060..27ab9c71 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -131,7 +131,7 @@ namespace garlic } bool CheckExpired (uint64_t ts); // true is expired - bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsRatchets () const { return true; }; @@ -168,7 +168,7 @@ namespace garlic uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; - uint64_t m_LastActivityTimestamp = 0; // incoming + uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming std::shared_ptr m_SendTagset, m_NSRTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) From 45aa78d953dc0a42e8f63e52914dd6953862a86a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 23 May 2020 20:40:27 +0300 Subject: [PATCH 135/189] revert 7133a07 - it broke usage in some SOCKS implementations Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 52d7799b..6edd5677 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -256,9 +256,6 @@ namespace proxy size += (1 + addr.dns.size); /* name length + domain name */ m_response[4] = addr.dns.size; memcpy(m_response + 5, addr.dns.value, addr.dns.size); - // replace type to IPv4 for support socks5 clients - // without domain name resolving support (like netcat) - m_response[3] = ADDR_IPV4; break; } htobe16buf(m_response + size - 2, port); //Port From 5a32082624a2956be3ef36c1ef58ea96513e585b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 May 2020 15:58:11 -0400 Subject: [PATCH 136/189] recreate session after 90 seconds incativity --- libi2pd/Datagram.cpp | 3 ++- libi2pd/ECIESX25519AEADRatchetSession.h | 6 ++++-- libi2pd/Garlic.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 85b435d1..04792bc5 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -256,7 +256,8 @@ namespace datagram std::shared_ptr DatagramSession::GetSharedRoutingPath () { - if(!m_RoutingSession) { + if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) + { if(!m_RemoteLeaseSet) { m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 27ab9c71..108788d5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -25,8 +25,9 @@ namespace i2p { namespace garlic { - const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after + const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second since session creation we can restart session after const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of second we receive nothing and should restart if we can const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after @@ -132,7 +133,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } - + bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } + bool IsRatchets () const { return true; }; private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 7e717829..1170634d 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -719,7 +719,14 @@ namespace garlic destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) + { session = it->second; + if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ())) + { + LogPrint (eLogDebug, "Garlic: session restarted"); + session = nullptr; + } + } if (!session) { session = std::make_shared (this, true); @@ -1011,7 +1018,10 @@ namespace garlic if (it != m_ECIESx25519Sessions.end ()) { if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) + { + it->second->SetOwner (nullptr); // detach m_ECIESx25519Sessions.erase (it); + } else { LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); From 71564f0d10132c49f29e29b17a98cd83728465f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 May 2020 10:30:00 -0400 Subject: [PATCH 137/189] set default i2cp.leaseSetEncType=0,4 for http and socks proxy for android --- android/assets/i2pd.conf | 2 ++ libi2pd/Config.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/android/assets/i2pd.conf b/android/assets/i2pd.conf index 312a24ea..14254248 100644 --- a/android/assets/i2pd.conf +++ b/android/assets/i2pd.conf @@ -42,6 +42,8 @@ inbound.quantity = 5 outbound.length = 1 outbound.quantity = 5 signaturetype=7 +i2cp.leaseSetType=3 +i2cp.leaseSetEncType=0,4 keys = proxy-keys.dat # addresshelper = true # outproxy = http://false.i2p diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 19d72104..0358d3e9 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -107,6 +107,8 @@ namespace config { ("httpproxy.latency.max", value()->default_value("0"), "HTTP proxy max latency for tunnels") ("httpproxy.outproxy", value()->default_value(""), "HTTP proxy upstream out proxy url") ("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper") + ("httpproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") + ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") ; options_description socksproxy("SOCKS Proxy options"); @@ -126,6 +128,8 @@ namespace config { ("socksproxy.outproxy.enabled", value()->default_value(false), "Enable or disable SOCKS outproxy") ("socksproxy.outproxy", value()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy") ("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") + ("socksproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") + ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") ; options_description sam("SAM bridge options"); From 1975adc48f8ddd6ce618ea1150078c6f0e0ea385 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 May 2020 14:14:16 -0400 Subject: [PATCH 138/189] print remote peer for queues --- libi2pd/NTCP2.cpp | 3 ++- libi2pd/Transports.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index eec3a5a5..8b44a795 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1135,7 +1135,8 @@ namespace transport SendQueue (); else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) { - LogPrint (eLogWarning, "NTCP2: outgoing messages queue size exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); + LogPrint (eLogWarning, "NTCP2: outgoing messages queue size to ", + GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); Terminate (); } } diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 2f5e92f5..7157306d 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -389,7 +389,7 @@ namespace transport m_LoopbackHandler.Flush (); return; } - if(RoutesRestricted() && ! IsRestrictedPeer(ident)) return; + if(RoutesRestricted() && !IsRestrictedPeer(ident)) return; auto it = m_Peers.find (ident); if (it == m_Peers.end ()) { @@ -421,7 +421,8 @@ namespace transport } else { - LogPrint (eLogWarning, "Transports: delayed messages queue size exceeds ", MAX_NUM_DELAYED_MESSAGES); + LogPrint (eLogWarning, "Transports: delayed messages queue size to ", + ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES); std::unique_lock l(m_PeersMutex); m_Peers.erase (it); } From 50c8a84037d762551e200921f41e46ccd3250357 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 03:53:54 +0300 Subject: [PATCH 139/189] [SOCKS] overwrite connection info after establishing connection to i2p host (closes #1336) Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 6edd5677..c5428c86 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -227,38 +227,50 @@ namespace proxy boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS4Response(SOCKSHandler::errTypes error, uint32_t ip, uint16_t port) { assert(error >= SOCKS4_OK); - m_response[0] = '\x00'; //Version - m_response[1] = error; //Response code - htobe16buf(m_response + 2, port); //Port - htobe32buf(m_response + 4, ip); //IP + m_response[0] = '\x00'; // version + m_response[1] = error; // response code + htobe16buf(m_response + 2, port); // port + htobe32buf(m_response + 4, ip); // IP return boost::asio::const_buffers_1(m_response,8); } boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) { - size_t size = 6; // header + port + size_t size = 6; // header + port assert(error <= SOCKS5_ADDR_UNSUP); - m_response[0] = '\x05'; //Version - m_response[1] = error; //Response code - m_response[2] = '\x00'; //RSV - m_response[3] = type; //Address type + m_response[0] = '\x05'; // version + m_response[1] = error; // response code + m_response[2] = '\x00'; // reserved + m_response[3] = type; // address type switch (type) { case ADDR_IPV4: size += 4; htobe32buf(m_response + 4, addr.ip); + htobe16buf(m_response + size - 2, port); break; case ADDR_IPV6: size += 16; memcpy(m_response + 4, addr.ipv6, 16); + htobe16buf(m_response + size - 2, port); break; case ADDR_DNS: - size += (1 + addr.dns.size); /* name length + domain name */ - m_response[4] = addr.dns.size; - memcpy(m_response + 5, addr.dns.value, addr.dns.size); + std::string address(addr.dns.value, addr.dns.size); + if(address.substr(addr.dns.size - 4, 4) == ".i2p") // overwrite if requested address inside I2P + { + m_response[3] = ADDR_IPV4; + size += 4; + memset(m_response + 4, 0, 6); // six HEX zeros + } + else + { + size += (1 + addr.dns.size); /* name length + resolved address */ + m_response[4] = addr.dns.size; + memcpy(m_response + 5, addr.dns.value, addr.dns.size); + htobe16buf(m_response + size - 2, port); + } break; } - htobe16buf(m_response + size - 2, port); //Port return boost::asio::const_buffers_1(m_response, size); } From 0e0169d22be7227e36875038a51a1f69104726f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 May 2020 08:37:47 -0400 Subject: [PATCH 140/189] 2.32.0 --- ChangeLog | 24 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 930be261..69fa58b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,30 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.32.0] - 2020-05-25 +### Added +- Multiple encryption types for local destinations +- Next key and tagset for ECIES-X25519-AEAD-Ratchet +- NTCP2 through SOCKS proxy +- Throw error message if any port to bind is occupied +- gzip parameter for UDP tunnels +- Show ECIES-X25519-AEAD-Ratchet sessions and tags on the web console +- Simplified implementation of gzip for no compression mode +- Allow ECIES-X25519-AEAD-Ratchet session restart after 2 minutes +### Changed +- Select peers for client tunnels among routers >= 0.9.36 +- Check ECIES flag for encrypted lookup reply +- Streaming MTU size 1812 for ECIES-X25519-AEAD-Ratchet +- Don't calculate checksum for Data message send through ECIES-X25519-AEAD-Ratchet +- Catch network connectivity status for Windows +- Stop as soon as no more transit tunnels during graceful shutdown for Android +- RouterInfo gzip compression level depends on size +- Send response to received datagram from ECIES-X25519-AEAD-Ratchet session +- Reseeds list +### Fixed +- Correct timestamp check for LeaseSet2 +- Encrypted leaseset without authentication + ## [2.31.0] - 2020-04-10 ### Added - NTCP2 through HTTP proxy diff --git a/Win32/installer.iss b/Win32/installer.iss index 8e66c17a..88856558 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.31.0" +#define I2Pd_ver "2.32.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index d3c5c16b..ef6bf36e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2310 - versionName "2.31.0" + versionCode 2320 + versionName "2.32.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index 45a16dd8..a5ad1bfd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.31.0.{build} +version: 2.32.0.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/libi2pd/version.h b/libi2pd/version.h index d862f46e..346cf8a7 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -16,7 +16,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 31 +#define I2PD_VERSION_MINOR 32 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 45 +#define I2P_VERSION_MICRO 46 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 4c027bc0..da9627cc 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 1dcb8787963830396652c9cc56be93496d667357 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 12:43:16 +0000 Subject: [PATCH 141/189] update debian and rpm stuff to 2.32.0 Signed-off-by: r4sas --- contrib/debian/i2pd.tmpfile | 2 +- contrib/i2pd.logrotate | 14 +++++++------- contrib/rpm/i2pd-git.spec | 4 ++++ contrib/rpm/i2pd.spec | 4 ++++ debian/changelog | 9 +++++++++ debian/copyright | 6 +++--- debian/i2pd.logrotate | 10 +--------- debian/postrm | 2 +- 8 files changed, 30 insertions(+), 21 deletions(-) mode change 100644 => 120000 debian/i2pd.logrotate diff --git a/contrib/debian/i2pd.tmpfile b/contrib/debian/i2pd.tmpfile index 6cd19112..e9bfebc6 100644 --- a/contrib/debian/i2pd.tmpfile +++ b/contrib/debian/i2pd.tmpfile @@ -1,2 +1,2 @@ -d /var/run/i2pd 0755 i2pd i2pd - - +d /run/i2pd 0755 i2pd i2pd - - d /var/log/i2pd 0755 i2pd i2pd - - diff --git a/contrib/i2pd.logrotate b/contrib/i2pd.logrotate index 795280d4..d0ca70ad 100644 --- a/contrib/i2pd.logrotate +++ b/contrib/i2pd.logrotate @@ -1,9 +1,9 @@ "/var/log/i2pd/*.log" { - copytruncate - daily - rotate 5 - compress - delaycompress - missingok - notifempty + copytruncate + daily + rotate 5 + compress + delaycompress + missingok + notifempty } diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6967f949..22bbb505 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -121,6 +121,10 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 25 2020 r4sas - 2.32.0 +- update to 2.32.0 +- updated systemd service file (#1394) + * Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 49a5e666..646e4fb6 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -119,6 +119,10 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 25 2020 r4sas - 2.32.0 +- update to 2.32.0 +- updated systemd service file (#1394) + * Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config diff --git a/debian/changelog b/debian/changelog index 3824d4f8..43c3fc60 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +i2pd (2.32.0-1) unstable; urgency=high + + * updated to version 2.32.0/0.9.46 + * updated systemd service file (see #1394) + * updated apparmor profile (see 9318388007cff0495b4b360d0480f4fc1219a9dc) + * updated logrotate config and moved it to contrib + + -- r4sas Mon, 25 May 2020 12:45:00 +0000 + i2pd (2.31.0-1) unstable; urgency=medium * updated to version 2.31.0 diff --git a/debian/copyright b/debian/copyright index 3c513020..9f18f53a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,7 +3,7 @@ Upstream-Name: i2pd Source: https://github.com/PurpleI2P Files: * -Copyright: 2013-2017 PurpleI2P +Copyright: 2013-2020 PurpleI2P License: BSD-3-clause Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl @@ -16,8 +16,8 @@ License: BSD-2-Clause Files: debian/* Copyright: 2013-2015 Kill Your TV 2014-2016 hagen - 2016-2017 R4SAS - 2017-2018 Yangfl + 2016-2020 R4SAS + 2017-2020 Yangfl License: GPL-2+ License: BSD-3-clause diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate deleted file mode 100644 index 63c44270..00000000 --- a/debian/i2pd.logrotate +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/i2pd/i2pd.log { - rotate 6 - daily - missingok - notifempty - compress - delaycompress - copytruncate -} diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate new file mode 120000 index 00000000..2630046a --- /dev/null +++ b/debian/i2pd.logrotate @@ -0,0 +1 @@ +/opt/build/i2pd/contrib/i2pd.logrotate \ No newline at end of file diff --git a/debian/postrm b/debian/postrm index 53ab15e7..ba69785e 100755 --- a/debian/postrm +++ b/debian/postrm @@ -6,7 +6,7 @@ if [ "$1" = "purge" ]; then rm -rf /etc/i2pd rm -rf /var/lib/i2pd rm -rf /var/log/i2pd - rm -rf /var/run/i2pd + rm -rf /run/i2pd fi #DEBHELPER# From 6bd44f0e4b6804a5feb817c7487d9bfa05ee0f72 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 13:06:11 +0000 Subject: [PATCH 142/189] 2.32.0 Signed-off-by: r4sas --- ChangeLog | 17 +++++++++++------ qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69fa58b8..f080e1bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ - Show ECIES-X25519-AEAD-Ratchet sessions and tags on the web console - Simplified implementation of gzip for no compression mode - Allow ECIES-X25519-AEAD-Ratchet session restart after 2 minutes +- Added logrotate config for rpm package ### Changed - Select peers for client tunnels among routers >= 0.9.36 - Check ECIES flag for encrypted lookup reply @@ -20,10 +21,14 @@ - Stop as soon as no more transit tunnels during graceful shutdown for Android - RouterInfo gzip compression level depends on size - Send response to received datagram from ECIES-X25519-AEAD-Ratchet session +- Update webconsole functional +- Increased max transit tunnels limit - Reseeds list +- Dropped windows support in cmake ### Fixed -- Correct timestamp check for LeaseSet2 -- Encrypted leaseset without authentication +- Correct timestamp check for LeaseSet2 +- Encrypted leaseset without authentication +- Change SOCKS proxy connection response for clients without socks5h support (#1336) ## [2.31.0] - 2020-04-10 ### Added @@ -66,7 +71,7 @@ ### Added - Client auth flag for b33 address ### Changed -- Remove incoming NTCP2 session from pending list when established +- Remove incoming NTCP2 session from pending list when established - Handle errors for NTCP2 SessionConfrimed send ### Fixed - Failure to start on Windows XP @@ -115,7 +120,7 @@ ## [2.25.0] - 2019-05-09 ### Added - Create, publish and handle encrypted LeaseSet2 -- Support of b33 addresses +- Support of b33 addresses - RedDSA key blinding - .b32.i2p addresses in jump links - ntcp2.addressv6 parameter @@ -147,7 +152,7 @@ - Correct SAM response for invalid key - SAM crash on termination for Windows - Race condition for publishing - + ## [2.23.0] - 2019-01-21 ### Added - Standard LeaseSet2 support @@ -206,7 +211,7 @@ - NTCP2 is enabled by default - Show lease's expiration time in readable format in the web console ### Fixed -- Correct names for transports in the web console +- Correct names for transports in the web console ## [2.19.0] - 2018-06-26 ### Added diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index da9627cc..452d750f 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,7 +35,7 @@ - + From 2facf144438baa3e8822ab43bcd054372a028b93 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 13:09:02 +0000 Subject: [PATCH 143/189] fix symbolic link Signed-off-by: r4sas --- debian/i2pd.logrotate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate index 2630046a..40dea037 120000 --- a/debian/i2pd.logrotate +++ b/debian/i2pd.logrotate @@ -1 +1 @@ -/opt/build/i2pd/contrib/i2pd.logrotate \ No newline at end of file +../contrib/i2pd.logrotate \ No newline at end of file From d226834eef933b6b0b1ec051017463cb45bf62cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 13:33:02 +0000 Subject: [PATCH 144/189] update debian patch Signed-off-by: R4SAS --- debian/patches/01-tune-build-opts.patch | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch index dd2b4638..e06a8621 100644 --- a/debian/patches/01-tune-build-opts.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -1,17 +1,15 @@ -diff --git a/Makefile b/Makefile -index bdadfe0..2f71eec 100644 ---- a/Makefile -+++ b/Makefile -@@ -9,10 +9,10 @@ DEPS := obj/make.dep - +Index: i2pd/Makefile +=================================================================== +--- i2pd.orig/Makefile ++++ i2pd/Makefile +@@ -13,8 +13,8 @@ DAEMON_SRC_DIR := daemon + include filelist.mk - + -USE_AESNI := yes -+USE_AESNI := no -USE_AVX := yes ++USE_AESNI := no +USE_AVX := no USE_STATIC := no USE_MESHNET := no USE_UPNP := no - DEBUG := yes - From dba6d681083ebe271eb5b70bae0b206f9a218f28 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 13:42:26 +0000 Subject: [PATCH 145/189] update debian patch Signed-off-by: R4SAS --- debian/patches/02-fix-1210.patch | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/patches/02-fix-1210.patch b/debian/patches/02-fix-1210.patch index 6a4caf94..9ad9bb0f 100644 --- a/debian/patches/02-fix-1210.patch +++ b/debian/patches/02-fix-1210.patch @@ -4,10 +4,12 @@ Author: r4sas Bug: https://github.com/PurpleI2P/i2pd/issues/1210 Reviewed-By: r4sas -Last-Update: 2018-08-25 +Last-Update: 2020-05-25 ---- a/contrib/i2pd.service -+++ b/contrib/i2pd.service +Index: i2pd/contrib/i2pd.service +=================================================================== +--- i2pd.orig/contrib/i2pd.service ++++ i2pd/contrib/i2pd.service @@ -6,10 +6,10 @@ After=network.target [Service] User=i2pd @@ -21,5 +23,5 @@ Last-Update: 2018-08-25 +#LogsDirectory=i2pd +#LogsDirectoryMode=0700 Type=forking - ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service - ExecReload=/bin/kill -HUP $MAINPID + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/sh -c "kill -HUP $MAINPID" From 8e0f1de25a8e4aade51b8acbec0cd72622c507f1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 20:28:52 +0300 Subject: [PATCH 146/189] 2.32.0 - [RPM] fix build in fedora copr Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 4 +++- contrib/rpm/i2pd.spec | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 22bbb505..6cb09f0d 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.31.0 +Version: 2.32.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -111,6 +111,8 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* +%{_sysconfdir}/i2pd/subscriptions.txt %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 646e4fb6..62ef68e7 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd -Version: 2.31.0 -Release: 3%{?dist} +Version: 2.32.0 +Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -111,6 +111,7 @@ getent passwd i2pd >/dev/null || \ %{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* +%{_sysconfdir}/i2pd/subscriptions.txt /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd From 60b1b2ca4af37fde2858d2c711269036f715a3da Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 21:22:50 +0300 Subject: [PATCH 147/189] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 19 ++++++++++--------- contrib/rpm/i2pd.spec | 38 ++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6cb09f0d..1a557758 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -10,7 +10,7 @@ License: BSD URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz -%if 0%{?rhel} == 7 +%if 0%{?rhel} == 7 BuildRequires: cmake3 %else BuildRequires: cmake @@ -24,8 +24,8 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units -Requires: logrotate -Requires: systemd +Requires: logrotate +Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description @@ -74,17 +74,18 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd +%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 -%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd -%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/%{name} -%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/%{name}/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates @@ -117,7 +118,7 @@ getent passwd i2pd >/dev/null || \ %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd -%{_datadir}/%{name}/certificates +%{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates %{_sysconfdir}/logrotate.d/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 62ef68e7..b11f8b67 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.32.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -8,7 +8,7 @@ License: BSD URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz -%if 0%{?rhel} == 7 +%if 0%{?rhel} == 7 BuildRequires: cmake3 %else BuildRequires: cmake @@ -22,8 +22,8 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units -Requires: logrotate -Requires: systemd +Requires: logrotate +Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description @@ -71,19 +71,20 @@ pushd build %endif chrpath -d i2pd -install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd -install -d -m 755 %{buildroot}%{_datadir}/i2pd -install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd +%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service -install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd -install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates -ln -s %{_datadir}/i2pd/tunnels.conf.d %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d %pre @@ -106,15 +107,16 @@ getent passwd i2pd >/dev/null || \ %files -%doc LICENSE README.md +%doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd -%{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* %{_sysconfdir}/i2pd/subscriptions.txt -/%{_unitdir}/i2pd.service -%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd +%{_unitdir}/i2pd.service +%{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd +%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd +%{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates %{_sysconfdir}/logrotate.d/i2pd From a4c4bf4b584cd01633b570336adda383ce052761 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 22:30:18 +0300 Subject: [PATCH 148/189] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 46 +++++++++++++++++++-------------------- contrib/rpm/i2pd.spec | 46 +++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 1a557758..41a9dbe9 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,32 +1,32 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) -Name: i2pd-git -Version: 2.32.0 -Release: git%{git_hash}%{?dist} -Summary: I2P router written in C++ -Conflicts: i2pd +Name: i2pd-git +Version: 2.32.0 +Release: git%{git_hash}%{?dist} +Summary: I2P router written in C++ +Conflicts: i2pd -License: BSD -URL: https://github.com/PurpleI2P/i2pd -Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz +License: BSD +URL: https://github.com/PurpleI2P/i2pd +Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 +BuildRequires: cmake3 %else -BuildRequires: cmake +BuildRequires: cmake %endif -BuildRequires: chrpath -BuildRequires: gcc-c++ -BuildRequires: zlib-devel -BuildRequires: boost-devel -BuildRequires: openssl-devel -BuildRequires: miniupnpc-devel -BuildRequires: systemd-units +BuildRequires: chrpath +BuildRequires: gcc-c++ +BuildRequires: zlib-devel +BuildRequires: boost-devel +BuildRequires: openssl-devel +BuildRequires: miniupnpc-devel +BuildRequires: systemd-units -Requires: logrotate -Requires: systemd -Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd +Requires: logrotate +Requires: systemd +Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description C++ implementation of I2P. @@ -112,15 +112,15 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf -%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* -%{_sysconfdir}/i2pd/subscriptions.txt +%config %{_sysconfdir}/i2pd/subscriptions.txt +%doc %{_sysconfdir}/i2pd/tunnels.conf.d/README +%{_sysconfdir}/logrotate.d/i2pd %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates -%{_sysconfdir}/logrotate.d/i2pd %changelog diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index b11f8b67..cd9856cb 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,30 +1,30 @@ -Name: i2pd -Version: 2.32.0 -Release: 2%{?dist} -Summary: I2P router written in C++ -Conflicts: i2pd-git +Name: i2pd +Version: 2.32.0 +Release: 2%{?dist} +Summary: I2P router written in C++ +Conflicts: i2pd-git -License: BSD -URL: https://github.com/PurpleI2P/i2pd -Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz +License: BSD +URL: https://github.com/PurpleI2P/i2pd +Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 +BuildRequires: cmake3 %else -BuildRequires: cmake +BuildRequires: cmake %endif -BuildRequires: chrpath -BuildRequires: gcc-c++ -BuildRequires: zlib-devel -BuildRequires: boost-devel -BuildRequires: openssl-devel -BuildRequires: miniupnpc-devel -BuildRequires: systemd-units +BuildRequires: chrpath +BuildRequires: gcc-c++ +BuildRequires: zlib-devel +BuildRequires: boost-devel +BuildRequires: openssl-devel +BuildRequires: miniupnpc-devel +BuildRequires: systemd-units -Requires: logrotate -Requires: systemd -Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd +Requires: logrotate +Requires: systemd +Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description C++ implementation of I2P. @@ -110,15 +110,15 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf -%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* -%{_sysconfdir}/i2pd/subscriptions.txt +%config %{_sysconfdir}/i2pd/subscriptions.txt +%doc %{_sysconfdir}/i2pd/tunnels.conf.d/README +%{_sysconfdir}/logrotate.d/i2pd %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates -%{_sysconfdir}/logrotate.d/i2pd %changelog From 64c986ebbb5d11f6143ade4fbb3277f18a13c574 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 23:01:02 +0300 Subject: [PATCH 149/189] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 2 +- contrib/rpm/i2pd.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 41a9dbe9..3473a9d0 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -75,7 +75,6 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf @@ -112,6 +111,7 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config %{_sysconfdir}/i2pd/subscriptions.txt %doc %{_sysconfdir}/i2pd/tunnels.conf.d/README %{_sysconfdir}/logrotate.d/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index cd9856cb..588a6839 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -73,7 +73,6 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf @@ -110,6 +109,7 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config %{_sysconfdir}/i2pd/subscriptions.txt %doc %{_sysconfdir}/i2pd/tunnels.conf.d/README %{_sysconfdir}/logrotate.d/i2pd From bdb918cdb38057a1a7ce991dbbf2e7fc7e75fbdc Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 May 2020 21:40:46 -0400 Subject: [PATCH 150/189] honour explicitPeer param in tunnels --- libi2pd_client/ClientContext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 6a58d63c..54007c95 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -459,6 +459,8 @@ namespace client else if (authType == "2") // PSK ReadI2CPOptionsGroup (section, I2CP_PARAM_LEASESET_CLIENT_PSK, options); } + std::string explicitPeers = GetI2CPStringOption(section, I2CP_PARAM_EXPLICIT_PEERS, ""); + if (explicitPeers.length () > 0) options[I2CP_PARAM_EXPLICIT_PEERS] = explicitPeers; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const From 37ec90c436f2e34705d39ffd944cfab729028e89 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 May 2020 16:47:45 -0400 Subject: [PATCH 151/189] don't gererate more tags for detached session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2f43b554..310d263e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -612,7 +612,7 @@ namespace garlic int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; moreTags -= (receiveTagset->GetNextIndex () - index); - if (moreTags > 0) + if (moreTags > 0 && GetOwner ()) GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } From 45e8d5c50ecb9fdf8399d82c8f5a15d633741d77 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 27 May 2020 21:27:16 +0300 Subject: [PATCH 152/189] Return deprecated websocket config options for compatibility Closes #1523 Signed-off-by: R4SAS --- libi2pd/Config.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 0358d3e9..d11152dd 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -221,6 +221,14 @@ namespace config { ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?") ; + // Save deprecated websocket options for compatibility + options_description websocket("Websocket Options"); + websocket.add_options() + ("websockets.enabled", value()->default_value(false), "Deprecated option") + ("websockets.address", value()->default_value(""), "Deprecated option") + ("websockets.port", value()->default_value(0), "Deprecated option") + ; + options_description exploratory("Exploratory Options"); exploratory.add_options() ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") @@ -271,6 +279,7 @@ namespace config { .add(reseed) .add(addressbook) .add(trust) + .add(websocket) // deprecated .add(exploratory) .add(ntcp2) .add(nettime) From 0dc212d97c75ba1fa852af6889386f82f5ec289e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 May 2020 13:46:02 -0400 Subject: [PATCH 153/189] fixed non-updating LeaseSet1 --- libi2pd/LeaseSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 6b8b7545..b90d6d85 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -187,7 +187,7 @@ namespace data bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const { - return ExtractExpirationTimestamp (buf, len) > (m_ExpirationTime ? m_ExpirationTime : ExtractExpirationTimestamp (m_Buffer, m_BufferLen)); + return ExtractExpirationTimestamp (buf, len) > ExtractExpirationTimestamp (m_Buffer, m_BufferLen); } bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const From 9135772f8959c0a965085657dd8300a928304c64 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 2 Jun 2020 19:26:36 +0300 Subject: [PATCH 154/189] 2.32.1 Signed-off-by: R4SAS --- ChangeLog | 8 ++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 7 +++++-- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f080e1bc..33792a97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.32.1] - 2020-06-02 +### Added +- Read explicit peers in tunnels config +### Fixed +- Generation of tags for detached sessions +- Non-updating LeaseSet1 +- Start when deprecated websocket options present in i2pd.conf + ## [2.32.0] - 2020-05-25 ### Added - Multiple encryption types for local destinations diff --git a/Win32/installer.iss b/Win32/installer.iss index 88856558..40724d7a 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.32.0" +#define I2Pd_ver "2.32.1" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index ef6bf36e..c9e8429c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2320 - versionName "2.32.0" + versionCode 2321 + versionName "2.32.1" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index a5ad1bfd..0567127c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.32.0.{build} +version: 2.32.1.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 3473a9d0..7079ec23 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.32.0 +Version: 2.32.1 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -124,6 +124,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Jun 02 2020 r4sas - 2.32.1 +- update to 2.32.1 + * Mon May 25 2020 r4sas - 2.32.0 - update to 2.32.0 - updated systemd service file (#1394) diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 588a6839..5c0b8fbd 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd -Version: 2.32.0 -Release: 2%{?dist} +Version: 2.32.1 +Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -122,6 +122,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Jun 02 2020 r4sas - 2.32.1 +- update to 2.32.1 + * Mon May 25 2020 r4sas - 2.32.0 - update to 2.32.0 - updated systemd service file (#1394) diff --git a/debian/changelog b/debian/changelog index 43c3fc60..b01f9519 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.32.1-1) unstable; urgency=high + + * updated to version 2.32.1 + + -- r4sas Tue, 02 Jun 2020 16:30:00 +0000 + i2pd (2.32.0-1) unstable; urgency=high * updated to version 2.32.0/0.9.46 diff --git a/libi2pd/version.h b/libi2pd/version.h index 346cf8a7..c234516f 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -17,7 +17,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 32 -#define I2PD_VERSION_MICRO 0 +#define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define VERSION I2PD_VERSION diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 452d750f..75c57fb7 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From e1356965308b3554d001003b9bce737603030ffa Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jun 2020 16:05:19 -0400 Subject: [PATCH 155/189] support multiple encryption keys through the I2CP --- libi2pd/Crypto.cpp | 9 ++++++++- libi2pd/Crypto.h | 2 +- libi2pd/CryptoKey.cpp | 2 +- libi2pd/CryptoKey.h | 3 ++- libi2pd_client/I2CP.cpp | 44 +++++++++++++++++++++++++++-------------- libi2pd_client/I2CP.h | 9 +++++---- 6 files changed, 46 insertions(+), 23 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 6db124c0..2f10e91d 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -375,15 +375,22 @@ namespace crypto #endif } - void X25519Keys::SetPrivateKey (const uint8_t * priv) + void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic) { #if OPENSSL_X25519 if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Pkey) EVP_PKEY_free (m_Pkey); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); + if (calculatePublic) + { + size_t len = 32; + EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); + } #else memcpy (m_PrivateKey, priv, 32); + if (calculatePublic) + GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); #endif } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 56c8c10b..9ca3163f 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -88,7 +88,7 @@ namespace crypto void GenerateKeys (); const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; - void SetPrivateKey (const uint8_t * priv); // wihout calculating public + void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false); void Agree (const uint8_t * pub, uint8_t * shared); private: diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index d786e193..b8f66e4d 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -166,7 +166,7 @@ namespace crypto memcpy (pub, m_PublicKey, 32); } - ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) + ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic) { m_StaticKeys.SetPrivateKey (priv); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 1c8b0a71..fb69558f 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -145,11 +145,12 @@ namespace crypto { public: - ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); + ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const { return 32; }; + const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; private: diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index fef5d6b6..5a2f0901 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -55,12 +55,18 @@ namespace client void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { - memcpy (m_EncryptionPrivateKey, key, 256); - m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey); + m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key); } + void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key) + { + m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + } + bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { + if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor) + return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true); if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); else @@ -68,6 +74,19 @@ namespace client return false; } + const uint8_t * I2CPDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const + { + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor) + return m_ECIESx25519Decryptor->GetPubicKey (); + return nullptr; + } + + bool I2CPDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const + { + return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType; + } + + void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); @@ -77,7 +96,8 @@ namespace client void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) { - i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPrivateKey, tunnels); // we don't care about encryption key + uint8_t priv[256] = {0}; + i2p::data::LocalLeaseSet ls (m_Identity, priv, tunnels); // we don't care about encryption key, we need leases only m_LeaseSetExpirationTime = ls.GetExpirationTime (); uint8_t * leases = ls.GetLeases (); leases[-1] = tunnels.size (); @@ -572,28 +592,22 @@ namespace client offset += ls.GetBufferLen (); // private keys int numPrivateKeys = buf[offset]; offset++; - uint16_t currentKeyType = 0; - const uint8_t * currentKey = nullptr; for (int i = 0; i < numPrivateKeys; i++) { if (offset + 4 > len) return; uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length if (offset + keyLen > len) return; - if (!currentKey || keyType > currentKeyType) + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset); + else { - currentKeyType = keyType; - currentKey = buf + offset; + m_Destination->SetEncryptionType (keyType); + m_Destination->SetEncryptionPrivateKey (buf + offset); } offset += keyLen; } - // TODO: support multiple keys - if (currentKey) - { - m_Destination->SetEncryptionPrivateKey (currentKey); - m_Destination->SetEncryptionType (currentKeyType); - } - + m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index f4e83f06..db38ecdc 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -75,14 +75,15 @@ namespace client void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; + void SetECIESx25519EncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; - // TODO: implement GetEncryptionPublicKey + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; + const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only std::shared_ptr GetIdentity () const { return m_Identity; }; protected: @@ -101,9 +102,9 @@ namespace client std::shared_ptr m_Owner; std::shared_ptr m_Identity; - uint8_t m_EncryptionPrivateKey[256]; i2p::data::CryptoKeyType m_EncryptionKeyType; - std::shared_ptr m_Decryptor; + std::shared_ptr m_Decryptor; // standard + std::shared_ptr m_ECIESx25519Decryptor; uint64_t m_LeaseSetExpirationTime; }; From 438a225487d023f0f88905f0e1e1bbad07905801 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jun 2020 19:58:36 -0400 Subject: [PATCH 156/189] pass calculatePublic --- libi2pd/CryptoKey.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index b8f66e4d..4518a347 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -168,7 +168,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic) { - m_StaticKeys.SetPrivateKey (priv); + m_StaticKeys.SetPrivateKey (priv, calculatePublic); } bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) From 4ae41513acd14a370514e029ebf9c4a8b32af3f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Jun 2020 18:19:38 -0400 Subject: [PATCH 157/189] save new session with NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 11 ++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 14 +++++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 310d263e..a578131d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -150,7 +150,8 @@ namespace garlic uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) // Session Tag Ratchet - auto tagsetNsr = std::make_shared(shared_from_this ()); + auto tagsetNsr = (m_State == eSessionStateNewSessionReceived) ? std::make_shared(shared_from_this ()): + std::make_shared(shared_from_this ()); tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) tagsetNsr->NextSessionTagRatchet (); return tagsetNsr; @@ -416,8 +417,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - m_NSRTagset = CreateNewSessionTagset (); - uint64_t tag = m_NSRTagset->GetNextSessionTag (); + m_NSRSendTagset = CreateNewSessionTagset (); + uint64_t tag = m_NSRSendTagset->GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, &tag, 8); @@ -475,7 +476,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob and sent NSR already - uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + uint64_t tag = m_NSRSendTagset->GetNextSessionTag (); // next tag memcpy (out, &tag, 8); memcpy (out + 8, m_NSREncodedKey, 32); // recalculate h with new tag @@ -625,7 +626,7 @@ namespace garlic { case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; - m_NSRTagset = nullptr; + m_NSRSendTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 108788d5..d121842d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -79,6 +79,18 @@ namespace garlic uint64_t m_ExpirationTimestamp = 0; }; + class NSRatchetTagSet: public RatchetTagSet + { + public: + + NSRatchetTagSet (std::shared_ptr session): + RatchetTagSet (session), m_DummySession (session) {}; + + private: + + std::shared_ptr m_DummySession; // we need a strong pointer for NS + }; + enum ECIESx25519BlockType { eECIESx25519BlkDateTime = 0, @@ -171,7 +183,7 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset, m_NSRTagset; + std::shared_ptr m_SendTagset, m_NSRSendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; From 55ff6beb7d76f89c1ae7237ba6b8ab5fa5727a14 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2020 09:23:50 -0400 Subject: [PATCH 158/189] don't create ECIESx25519 again if key was not changed --- libi2pd_client/I2CP.cpp | 6 +++++- libi2pd_client/I2CP.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 5a2f0901..b0f334f5 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -60,7 +60,11 @@ namespace client void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key) { - m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + if (!m_ECIESx25519Decryptor || memcmp (m_ECIESx25519PrivateKey, key, 32)) // new key? + { + m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + memcpy (m_ECIESx25519PrivateKey, key, 32); + } } bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index db38ecdc..adb648f4 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -105,6 +105,7 @@ namespace client i2p::data::CryptoKeyType m_EncryptionKeyType; std::shared_ptr m_Decryptor; // standard std::shared_ptr m_ECIESx25519Decryptor; + uint8_t m_ECIESx25519PrivateKey[32]; uint64_t m_LeaseSetExpirationTime; }; From 6735b2686b6c13a36546dd794ee49b4d583565e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2020 15:41:30 -0400 Subject: [PATCH 159/189] set LeaseSet2 for ECIESx25519 --- libi2pd/Destination.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cd447773..6d5fb916 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -892,7 +892,11 @@ namespace client encryptionKey->GenerateKeys (); encryptionKey->CreateDecryptor (); if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + { m_ECIESx25519EncryptionKey.reset (encryptionKey); + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) + SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2 + } else m_StandardEncryptionKey.reset (encryptionKey); } From 221c14cf0e2ae481bbaa7edfd4257511e02ec9ac Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Jun 2020 16:24:11 -0400 Subject: [PATCH 160/189] don't lookup UDP session if port was not changed --- libi2pd_client/I2PTunnel.cpp | 28 ++++++++++++++++++---------- libi2pd_client/I2PTunnel.h | 5 +++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5b384bff..ea2517d7 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -634,7 +634,7 @@ namespace client uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); std::vector removePorts; for (const auto & s : m_Sessions) { - if (now - s.second.second >= delta) + if (now - s.second->second >= delta) removePorts.push_back(s.first); } for(auto port : removePorts) { @@ -761,7 +761,7 @@ namespace client m_RemoteIdent(nullptr), m_ResolveThread(nullptr), m_LocalSocket(localDestination->GetService(), localEndpoint), - RemotePort(remotePort), + RemotePort(remotePort), m_LastPort (0), m_cancel_resolve(false) { auto dgram = m_LocalDest->CreateDatagramDestination(gzip); @@ -796,16 +796,24 @@ namespace client return; // drop, remote not resolved } auto remotePort = m_RecvEndpoint.port(); - auto itr = m_Sessions.find(remotePort); - if (itr == m_Sessions.end()) { - // track new udp convo - m_Sessions[remotePort] = {boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0}; - } + if (!m_LastPort || m_LastPort != remotePort) + { + auto itr = m_Sessions.find(remotePort); + if (itr != m_Sessions.end()) + m_LastSession = itr->second; + else + { + m_LastSession = std::make_shared(boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0); + m_Sessions.emplace (remotePort, m_LastSession); + } + m_LastPort = remotePort; + } // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); // mark convo as active - m_Sessions[remotePort].second = i2p::util::GetMillisecondsSinceEpoch(); + if (m_LastSession) + m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); RecvFromLocal(); } @@ -851,9 +859,9 @@ namespace client // found convo if (len > 0) { LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); - m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second.first); + m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); // mark convo as active - itr->second.second = i2p::util::GetMillisecondsSinceEpoch(); + itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); } } else diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index d4db80d8..99934196 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -276,7 +276,7 @@ namespace client void TryResolving(); const std::string m_Name; std::mutex m_SessionsMutex; - std::map m_Sessions; // maps i2p port -> local udp convo + std::unordered_map > m_Sessions; // maps i2p port -> local udp convo const std::string m_RemoteDest; std::shared_ptr m_LocalDest; const boost::asio::ip::udp::endpoint m_LocalEndpoint; @@ -285,8 +285,9 @@ namespace client boost::asio::ip::udp::socket m_LocalSocket; boost::asio::ip::udp::endpoint m_RecvEndpoint; uint8_t m_RecvBuff[I2P_UDP_MAX_MTU]; - uint16_t RemotePort; + uint16_t RemotePort, m_LastPort; bool m_cancel_resolve; + std::shared_ptr m_LastSession; }; class I2PServerTunnel: public I2PService From 6d7847f2dfc2da364f5303207f3665533bfbbbbc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 16:26:45 -0400 Subject: [PATCH 161/189] send bulk datagrams --- libi2pd/Datagram.cpp | 14 ++++++++++++-- libi2pd/Datagram.h | 3 ++- libi2pd_client/I2PTunnel.cpp | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 04792bc5..5a6b8d90 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -56,6 +56,11 @@ namespace datagram session->SendMsg(msg); } + void DatagramDestination::FlushSendQueue (const i2p::data::IdentHash & ident) + { + ObtainSession(ident)->FlushSendQueue (); + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -366,6 +371,7 @@ namespace datagram void DatagramSession::FlushSendQueue () { + if (m_SendQueue.empty ()) return; std::vector send; auto routingPath = GetSharedRoutingPath(); // if we don't have a routing path we will drop all queued messages @@ -380,7 +386,6 @@ namespace datagram routingPath->outboundTunnel->SendTunnelDataMsg(send); } m_SendQueue.clear(); - ScheduleFlushSendQueue(); } void DatagramSession::ScheduleFlushSendQueue() @@ -388,7 +393,12 @@ namespace datagram boost::posix_time::milliseconds dlt(10); m_SendQueueTimer.expires_from_now(dlt); auto self = shared_from_this(); - m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) { if(ec) return; self->FlushSendQueue(); }); + m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) + { + if(ec) return; + self->FlushSendQueue(); + self->ScheduleFlushSendQueue(); + }); } } } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index e81f738a..b7abcc03 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -59,6 +59,7 @@ namespace datagram /** send an i2np message to remote endpoint for this session */ void SendMsg(std::shared_ptr msg); + void FlushSendQueue(); /** get the last time in milliseconds for when we used this datagram session */ uint64_t LastActivity() const { return m_LastUse; } @@ -84,7 +85,6 @@ namespace datagram private: - void FlushSendQueue(); void ScheduleFlushSendQueue(); void HandleSend(std::shared_ptr msg); @@ -122,6 +122,7 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + void FlushSendQueue (const i2p::data::IdentHash & ident); void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index ea2517d7..048c9962 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -811,6 +811,24 @@ namespace client // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + size_t numPackets = 0; + while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) + { + boost::system::error_code ec; + size_t moreBytes = m_LocalSocket.available(ec); + if (ec || !moreBytes) break; + transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); + remotePort = m_RecvEndpoint.port(); + // TODO: check remotePort + m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + numPackets++; + } + if (numPackets) + { + LogPrint(eLogDebug, "UDP Client: sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32()); + m_LocalDest->GetDatagramDestination()->FlushSendQueue (*m_RemoteIdent); + } + // mark convo as active if (m_LastSession) m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); From f077836bf5518d4fe19aea425dbaa7b5b12eaea1 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 19:20:24 -0400 Subject: [PATCH 162/189] store DatagramSession for bulk --- libi2pd/Datagram.cpp | 53 ++++++++++++++++++++++++------------ libi2pd/Datagram.h | 7 ++++- libi2pd_client/I2PTunnel.cpp | 9 +++--- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 5a6b8d90..c4877106 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -34,31 +34,48 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) - { - uint8_t hash[32]; - SHA256(payload, len, hash); - m_Owner->Sign (hash, 32, m_Signature.data ()); - } - else - m_Owner->Sign (payload, len, m_Signature.data ()); - - auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, - fromPort, toPort, false, !session->IsRatchets ()); // datagram - session->SendMsg(msg); + SendDatagram (ObtainSession(identity), payload, len, fromPort, toPort); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw - session->SendMsg(msg); + SendRawDatagram (ObtainSession(identity), payload, len, fromPort, toPort); } - void DatagramDestination::FlushSendQueue (const i2p::data::IdentHash & ident) + std::shared_ptr DatagramDestination::GetSession(const i2p::data::IdentHash & ident) { - ObtainSession(ident)->FlushSendQueue (); + return ObtainSession(ident); + } + + void DatagramDestination::SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) + { + if (session) + { + if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + { + uint8_t hash[32]; + SHA256(payload, len, hash); + m_Owner->Sign (hash, 32, m_Signature.data ()); + } + else + m_Owner->Sign (payload, len, m_Signature.data ()); + + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + fromPort, toPort, false, !session->IsRatchets ()); // datagram + session->SendMsg(msg); + } + } + + void DatagramDestination::SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) + { + if (session) + session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw + } + + void DatagramDestination::FlushSendQueue (std::shared_ptr session) + { + if (session) + session->FlushSendQueue (); } void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index b7abcc03..fa9d2371 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -122,7 +122,12 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); - void FlushSendQueue (const i2p::data::IdentHash & ident); + + std::shared_ptr GetSession(const i2p::data::IdentHash & ident); + void SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); + void SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); + void FlushSendQueue (std::shared_ptr session); + void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 048c9962..0b2bb7e0 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -810,7 +810,8 @@ namespace client } // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); - m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); + m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -820,14 +821,12 @@ namespace client transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); remotePort = m_RecvEndpoint.port(); // TODO: check remotePort - m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); numPackets++; } if (numPackets) - { LogPrint(eLogDebug, "UDP Client: sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32()); - m_LocalDest->GetDatagramDestination()->FlushSendQueue (*m_RemoteIdent); - } + m_LocalDest->GetDatagramDestination()->FlushSendQueue (session); // mark convo as active if (m_LastSession) From a8f227f7594ae827764d1e7445cfe1824da689bf Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 21:48:47 -0400 Subject: [PATCH 163/189] send raw follow-on datagrams --- libi2pd_client/I2PTunnel.cpp | 22 +++++++++++++++++----- libi2pd_client/I2PTunnel.h | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 0b2bb7e0..48b1e79d 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,12 +611,23 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - std::lock_guard lock(m_SessionsMutex); - auto session = ObtainUDPSession(from, toPort, fromPort); - session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); - session->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + { + std::lock_guard lock(m_SessionsMutex); + m_LastSession = ObtainUDPSession(from, toPort, fromPort); + } + m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); + m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); } + void I2PUDPServerTunnel::HandleRecvFromI2PRaw (uint16_t, uint16_t, const uint8_t * buf, size_t len) + { + if (m_LastSession) + { + m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); + m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + } + } + void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) { std::lock_guard lock(m_SessionsMutex); uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); @@ -714,6 +725,7 @@ namespace client m_LocalDest->Start(); auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + dgram->SetRawReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } I2PUDPServerTunnel::~I2PUDPServerTunnel() @@ -821,7 +833,7 @@ namespace client transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); remotePort = m_RecvEndpoint.port(); // TODO: check remotePort - m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); + m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); numPackets++; } if (numPackets) diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 99934196..19e44e79 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -237,6 +237,7 @@ namespace client private: void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); private: @@ -248,6 +249,7 @@ namespace client std::mutex m_SessionsMutex; std::vector m_Sessions; std::shared_ptr m_LocalDest; + UDPSessionPtr m_LastSession; }; class I2PUDPClientTunnel From 0639cce784a0506cff7be8fbc6b9edb2b9a420b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 10 Jun 2020 05:11:26 +0300 Subject: [PATCH 164/189] [SAM] fix ECDSA signatures names Signed-off-by: R4SAS --- libi2pd_client/SAM.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 2c6b711d..4723d168 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1015,8 +1015,8 @@ namespace client { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, {"ECDSA_SHA256_P256", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256}, - {"ECDSA_SHA256_P384", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384}, - {"ECDSA_SHA256_P521", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521}, + {"ECDSA_SHA384_P384", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384}, + {"ECDSA_SHA512_P521", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521}, {"EdDSA_SHA512_Ed25519", i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519}, {"GOST_GOSTR3411256_GOSTR3410CRYPTOPROA", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256}, {"GOST_GOSTR3411512_GOSTR3410TC26A512", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512}, From a33cad4b709fe62a488cbcd7447e3f35dd8ab3bf Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jun 2020 11:57:40 -0400 Subject: [PATCH 165/189] eliminate datagram send timer --- libi2pd/Datagram.cpp | 26 +++++++------------------- libi2pd/Datagram.h | 3 --- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index c4877106..99318ec9 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -34,12 +34,16 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - SendDatagram (ObtainSession(identity), payload, len, fromPort, toPort); + auto session = ObtainSession(identity); + SendDatagram (session, payload, len, fromPort, toPort); + FlushSendQueue (session); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - SendRawDatagram (ObtainSession(identity), payload, len, fromPort, toPort); + auto session = ObtainSession(identity); + SendRawDatagram (session, payload, len, fromPort, toPort); + FlushSendQueue (session); } std::shared_ptr DatagramDestination::GetSession(const i2p::data::IdentHash & ident) @@ -218,7 +222,6 @@ namespace datagram const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), - m_SendQueueTimer(localDestination->GetService()), m_RequestingLS(false) { } @@ -226,12 +229,10 @@ namespace datagram void DatagramSession::Start () { m_LastUse = i2p::util::GetMillisecondsSinceEpoch (); - ScheduleFlushSendQueue(); } void DatagramSession::Stop () { - m_SendQueueTimer.cancel (); } void DatagramSession::SendMsg(std::shared_ptr msg) @@ -383,7 +384,7 @@ namespace datagram if (msg || m_SendQueue.empty ()) m_SendQueue.push_back(msg); // flush queue right away if full - if(m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); + if(!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); } void DatagramSession::FlushSendQueue () @@ -404,18 +405,5 @@ namespace datagram } m_SendQueue.clear(); } - - void DatagramSession::ScheduleFlushSendQueue() - { - boost::posix_time::milliseconds dlt(10); - m_SendQueueTimer.expires_from_now(dlt); - auto self = shared_from_this(); - m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) - { - if(ec) return; - self->FlushSendQueue(); - self->ScheduleFlushSendQueue(); - }); - } } } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index fa9d2371..2aabcb1f 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -85,8 +85,6 @@ namespace datagram private: - void ScheduleFlushSendQueue(); - void HandleSend(std::shared_ptr msg); std::shared_ptr GetSharedRoutingPath(); @@ -101,7 +99,6 @@ namespace datagram std::shared_ptr m_RoutingSession; std::shared_ptr m_CurrentRemoteLease; std::shared_ptr m_CurrentOutboundTunnel; - boost::asio::deadline_timer m_SendQueueTimer; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 44bb8f6f1691176978390b753a325b92b42fbf00 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jun 2020 21:19:37 -0400 Subject: [PATCH 166/189] allocated datagram I2NP from memory pool --- libi2pd/Datagram.cpp | 18 ++++++------------ libi2pd/Datagram.h | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 99318ec9..5a196c3a 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -152,7 +152,7 @@ namespace datagram const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { - auto msg = NewI2NPMessage (); + auto msg = m_I2NPMsgsPool.AcquireShared (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : @@ -239,9 +239,11 @@ namespace datagram { // we used this session m_LastUse = i2p::util::GetMillisecondsSinceEpoch(); - // schedule send - auto self = shared_from_this(); - m_LocalDestination->GetService().post(std::bind(&DatagramSession::HandleSend, self, msg)); + if (msg || m_SendQueue.empty ()) + m_SendQueue.push_back(msg); + // flush queue right away if full + if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) + FlushSendQueue(); } DatagramSession::Info DatagramSession::GetSessionInfo() const @@ -379,14 +381,6 @@ namespace datagram if(ls && ls->GetExpirationTime() > oldExpire) m_RemoteLeaseSet = ls; } - void DatagramSession::HandleSend(std::shared_ptr msg) - { - if (msg || m_SendQueue.empty ()) - m_SendQueue.push_back(msg); - // flush queue right away if full - if(!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); - } - void DatagramSession::FlushSendQueue () { if (m_SendQueue.empty ()) return; diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 2aabcb1f..94fe422c 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -85,8 +85,6 @@ namespace datagram private: - void HandleSend(std::shared_ptr msg); - std::shared_ptr GetSharedRoutingPath(); void HandleLeaseSetUpdated(std::shared_ptr ls); @@ -119,6 +117,7 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + // TODO: implement calls from other thread from SAM std::shared_ptr GetSession(const i2p::data::IdentHash & ident); void SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); @@ -168,6 +167,7 @@ namespace datagram i2p::data::GzipInflator m_Inflator; i2p::data::GzipDeflator m_Deflator; std::vector m_From, m_Signature; + i2p::util::MemoryPool > m_I2NPMsgsPool; }; } } From 6a0174293e0e828d52b06cb5d261cdf183a865ec Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Jun 2020 22:04:32 -0400 Subject: [PATCH 167/189] send raw datagrams in opposite direction --- libi2pd_client/I2PTunnel.cpp | 61 ++++++++++++++++++++++++------------ libi2pd_client/I2PTunnel.h | 4 +++ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 48b1e79d..74175b14 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,6 +611,7 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { + if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0]) { std::lock_guard lock(m_SessionsMutex); m_LastSession = ObtainUDPSession(from, toPort, fromPort); @@ -658,7 +659,7 @@ namespace client auto ih = from.GetIdentHash(); for (auto & s : m_Sessions ) { - if ( s->Identity == ih) + if (s->Identity.GetLL()[0] == ih.GetLL()[0]) { /** found existing session */ LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); @@ -707,11 +708,25 @@ namespace client { LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); LastActivity = i2p::util::GetMillisecondsSinceEpoch(); - m_Destination->SendDatagramTo(m_Buffer, len, Identity, LocalPort, RemotePort); + auto session = m_Destination->GetSession (Identity); + m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + size_t numPackets = 0; + while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) + { + boost::system::error_code ec; + size_t moreBytes = IPSocket.available(ec); + if (ec || !moreBytes) break; + len = IPSocket.receive_from (boost::asio::buffer (m_Buffer, I2P_UDP_MAX_MTU), FromEndpoint, 0, ec); + m_Destination->SendRawDatagram (session, m_Buffer, len, LocalPort, RemotePort); + numPackets++; + } + if (numPackets > 0) + LogPrint(eLogDebug, "UDPSession: forward more ", numPackets, "packets B from ", FromEndpoint); + m_Destination->FlushSendQueue (session); Receive(); - } else { + } + else LogPrint(eLogError, "UDPSession: ", ecode.message()); - } } I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, @@ -781,6 +796,8 @@ namespace client std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + dgram->SetRawReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } void I2PUDPClientTunnel::Start() { @@ -880,26 +897,30 @@ namespace client void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { if(m_RemoteIdent && from.GetIdentHash() == *m_RemoteIdent) - { - auto itr = m_Sessions.find(toPort); - // found convo ? - if(itr != m_Sessions.end()) - { - // found convo - if (len > 0) { - LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); - m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); - // mark convo as active - itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); - } - } - else - LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); - } + HandleRecvFromI2PRaw (fromPort, toPort, buf, len); else LogPrint(eLogWarning, "UDP Client: unwarranted traffic from ", from.GetIdentHash().ToBase32()); } + void I2PUDPClientTunnel::HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + { + auto itr = m_Sessions.find(toPort); + // found convo ? + if(itr != m_Sessions.end()) + { + // found convo + if (len > 0) + { + LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", m_RemoteIdent ? m_RemoteIdent->ToBase32() : ""); + m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); + // mark convo as active + itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); + } + } + else + LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); + } + I2PUDPClientTunnel::~I2PUDPClientTunnel() { auto dgram = m_LocalDest->GetDatagramDestination(); if (dgram) dgram->ResetReceiver(); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 19e44e79..19d553da 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -275,7 +275,11 @@ namespace client void RecvFromLocal(); void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void TryResolving(); + + private: + const std::string m_Name; std::mutex m_SessionsMutex; std::unordered_map > m_Sessions; // maps i2p port -> local udp convo From 5993cc857a94abd10ebf05fbe7c1426719a1b9a4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 16:03:12 -0400 Subject: [PATCH 168/189] start new tunnel message if remining is too small --- libi2pd/TunnelGateway.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 8f01bc4e..317926ae 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -66,7 +66,7 @@ namespace tunnel // length of bytes doesn't fit full tunnel message // every follow-on fragment adds 7 bytes size_t nonFit = (fullMsgLen + numFollowOnFragments*7) % TUNNEL_DATA_MAX_PAYLOAD_SIZE; - if (!nonFit || nonFit > m_RemainingSize) + if (!nonFit || nonFit > m_RemainingSize || m_RemainingSize < fullMsgLen/5) { CompleteCurrentTunnelDataMessage (); CreateCurrentTunnelDataMessage (); From 5e0a8ed2324b4a6966fff0fe2b70a21e3c15dd14 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 16:06:07 -0400 Subject: [PATCH 169/189] set UDP receive buffer size --- libi2pd_client/I2PTunnel.cpp | 3 +++ libi2pd_client/I2PTunnel.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 74175b14..d05a97b7 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -692,6 +692,7 @@ namespace client LocalPort(ourPort), RemotePort(theirPort) { + IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU )); memcpy(Identity, to->data(), 32); Receive(); } @@ -791,6 +792,8 @@ namespace client RemotePort(remotePort), m_LastPort (0), m_cancel_resolve(false) { + m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU )); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 19d553da..eb1d8ed9 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -167,7 +167,7 @@ namespace client const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2; /** max size for i2p udp */ - const size_t I2P_UDP_MAX_MTU = i2p::datagram::MAX_DATAGRAM_SIZE; + const size_t I2P_UDP_MAX_MTU = 64*1024; struct UDPSession { From 61897ae16c151f67e73bb3f13c3c0e513acb05e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 20:42:54 -0400 Subject: [PATCH 170/189] crypto.ratchet.inboundTags --- libi2pd/Destination.cpp | 3 +++ libi2pd/Destination.h | 2 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 31 +++++++++++++++++------ libi2pd/Garlic.cpp | 3 ++- libi2pd/Garlic.h | 3 +++ libi2pd_client/ClientContext.cpp | 2 ++ 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6d5fb916..a764224c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -56,6 +56,9 @@ namespace client if (it != params->end ()) numTags = std::stoi(it->second); LogPrint (eLogInfo, "Destination: parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags"); + it = params->find (I2CP_PARAM_RATCHET_INBOUND_TAGS); + if (it != params->end ()) + SetNumRatchetInboundTags (std::stoi(it->second)); it = params->find (I2CP_PARAM_EXPLICIT_PEERS); if (it != params->end ()) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 139423c6..1d5c0a55 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -57,6 +57,8 @@ namespace client const int STREAM_REQUEST_TIMEOUT = 60; //in seconds const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend"; const int DEFAULT_TAGS_TO_SEND = 40; + const char I2CP_PARAM_RATCHET_INBOUND_TAGS[] = "crypto.ratchet.inboundTags"; + const char I2CP_PARAM_RATCHET_OUTBOUND_TAGS[] = "crypto.ratchet.outboundTags"; // not used yet const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname"; const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a578131d..ad91382f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -341,7 +341,8 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MAX_NUM_GENERATED_TAGS); receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } @@ -459,7 +460,8 @@ namespace garlic m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt @@ -548,7 +550,8 @@ namespace garlic auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload @@ -610,11 +613,23 @@ namespace garlic return false; } HandlePayload (payload, len - 16, receiveTagset, index); - int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 - if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; - moreTags -= (receiveTagset->GetNextIndex () - index); - if (moreTags > 0 && GetOwner ()) - GenerateMoreReceiveTags (receiveTagset, moreTags); + if (GetOwner ()) + { + int moreTags = 0; + if (GetOwner ()->GetNumRatchetInboundTags () > 0) // override in settings? + { + if (receiveTagset->GetNextIndex () - index < GetOwner ()->GetNumRatchetInboundTags ()/2) + moreTags = GetOwner ()->GetNumRatchetInboundTags (); + } + else + { + moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 + if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; + moreTags -= (receiveTagset->GetNextIndex () - index); + } + if (moreTags > 0) + GenerateMoreReceiveTags (receiveTagset, moreTags); + } return true; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1170634d..84a0519e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -432,7 +432,8 @@ namespace garlic return ret; } - GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default + GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default + m_NumRatchetInboundTags (0) // 0 means standard { m_Ctx = BN_CTX_new (); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6b34231a..70893bec 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -232,6 +232,8 @@ namespace garlic void CleanUp (); void SetNumTags (int numTags) { m_NumTags = numTags; }; int GetNumTags () const { return m_NumTags; }; + void SetNumRatchetInboundTags (int numTags) { m_NumRatchetInboundTags = numTags; }; + int GetNumRatchetInboundTags () const { return m_NumRatchetInboundTags; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); @@ -278,6 +280,7 @@ namespace garlic std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming + int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 54007c95..0348aeeb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -461,6 +461,8 @@ namespace client } std::string explicitPeers = GetI2CPStringOption(section, I2CP_PARAM_EXPLICIT_PEERS, ""); if (explicitPeers.length () > 0) options[I2CP_PARAM_EXPLICIT_PEERS] = explicitPeers; + std::string ratchetInboundTags = GetI2CPStringOption(section, I2CP_PARAM_RATCHET_INBOUND_TAGS, ""); + if (ratchetInboundTags.length () > 0) options[I2CP_PARAM_RATCHET_INBOUND_TAGS] = ratchetInboundTags; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const From 79858d4372f1754363ce61059208f5ba4c4329d5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 13 Jun 2020 18:19:24 +0300 Subject: [PATCH 171/189] [webconsole] adaptive styling Signed-off-by: R4SAS --- android/assets/tunnels.conf | 2 +- daemon/HTTPServer.cpp | 60 ++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/android/assets/tunnels.conf b/android/assets/tunnels.conf index e95fdf2e..c39a0220 100644 --- a/android/assets/tunnels.conf +++ b/android/assets/tunnels.conf @@ -1,4 +1,4 @@ -[IRC-IRC2P] +#[IRC-IRC2P] #type = client #address = 127.0.0.1 #port = 6668 diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7268ae01..a9588436 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -63,23 +63,40 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " a, .slide label { text-decoration: none; color: #894C84; }\r\n" " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n" - " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial; padding: 0 5px; }\r\n" - " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" - " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" - " .left { float: left; position: absolute; }\r\n" - " .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\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" + " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" + " .wrapper { margin: 0 auto; padding: 1em; max-width: 56em; }\r\n" + " .menu { float: left; } .menu a { display: block; padding: 2px; }\r\n" + " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" " .tunnel.expiring { color: #D3AE3F; }\r\n" " .tunnel.failed { color: #D33F3F; }\r\n" " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { display: table; border-collapse: collapse; text-align: center; }\r\n" - " table.extaddr { text-align: left; }\r\n table.services { width: 100%; }" + " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" + " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + " .menu { width: 100%; display: block; float: none; position: unset; font-size: 24px;\r\n" + " text-align: center; }\r\n" + " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%; font-size: 1.2em;\r\n" + " text-align: center; line-height: 28px; }\r\n" + " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" + " .header { margin: 0.5em 0; } small {display: block}\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" + " input { width: 35%; height: 50px; text-align: center; /* margin-top: 15px; */ padding: 5px;\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 35px; }\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: 22px; }\r\n" + " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n" + " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 50px; display: -webkit-inline-box; margin-top: 25px; }\r\n" + " }\r\n" /* adaptive style */ "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -181,30 +198,31 @@ namespace http { #else " \r\n" #endif + " \r\n" " \r\n" " Purple I2P " VERSION " Webconsole\r\n" << cssStyles << "\r\n"; s << "\r\n" - "
i2pd webconsole
\r\n" - "
\r\n" - "
\r\n" - " Main page
\r\n
\r\n" - " Router commands
\r\n" - " Local destinations
\r\n"; + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n" + " Router commands\r\n" + " Local destinations\r\n"; if (i2p::context.IsFloodfill ()) - s << " LeaseSets
\r\n"; + s << " LeaseSets\r\n"; s << - " Tunnels
\r\n" - " Transit tunnels
\r\n" - " Transports
\r\n" - " I2P tunnels
\r\n"; + " Tunnels\r\n" + " Transit tunnels\r\n" + " Transports\r\n" + " I2P tunnels\r\n"; if (i2p::client::context.GetSAMBridge ()) - s << " SAM sessions
\r\n"; + s << " SAM sessions\r\n"; s << "
\r\n" - "
"; + "
"; } static void ShowPageTail (std::stringstream& s) @@ -416,7 +434,7 @@ namespace http { out_tags += it.second->GetNumOutgoingTags (); } s << "
\r\n\r\n" - << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -432,7 +450,7 @@ namespace http { ecies_sessions++; } s << "
\r\n\r\n" - << "
\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; From a5fed64f38c7f0b21f31297161ef15fa50f1d79e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 13 Jun 2020 18:33:39 +0300 Subject: [PATCH 172/189] [webconsole] update sliders html and css Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a9588436..41f198c8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -66,7 +66,7 @@ namespace http { " 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" " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" - " .wrapper { margin: 0 auto; padding: 1em; max-width: 56em; }\r\n" + " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" " .menu { float: left; } .menu a { display: block; padding: 2px; }\r\n" " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" @@ -77,8 +77,8 @@ namespace http { " table { display: table; border-collapse: collapse; text-align: center; }\r\n" " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" - " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" - " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" + " .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n" + " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ @@ -284,7 +284,7 @@ namespace http { s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n
\r\n"; + s << "\r\n\r\n
\r\n"; } if(includeHiddenContent) { s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; @@ -391,7 +391,7 @@ namespace http { if (dest->IsEncryptedLeaseSet ()) { i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); - s << "
\r\n\r\n
\r\n"; + s << "
\r\n\r\n
\r\n"; s << blinded.ToB33 () << ".b32.i2p
\r\n"; s << "
\r\n
\r\n"; } @@ -399,7 +399,7 @@ namespace http { if(dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n
\r\n"; + << "\r\n\r\n
\r\n
AddressTypeEncType
"; for(auto& it: dest->GetLeaseSets ()) s << "\r\n"; s << "
AddressTypeEncType
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n
\r\n
\r\n
\r\n"; @@ -433,8 +433,8 @@ namespace http { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; out_tags += it.second->GetNumOutgoingTags (); } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -449,8 +449,8 @@ namespace http { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "" << it.second->GetState () << "\r\n"; ecies_sessions++; } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; @@ -549,7 +549,7 @@ namespace http { if (!ls->IsValid()) s << "
!! Invalid !!
\r\n"; s << "
\r\n"; - s << "\r\n
\r\n"; + s << "\r\n
\r\n"; s << "Store type: " << (int)storeType << "
\r\n"; s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) @@ -700,13 +700,13 @@ namespace http { if (!tmp_s.str ().empty ()) { s << "
\r\n\r\n
" + << " ( " << cnt << " )\r\n\r\n
" << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { s << "
\r\n\r\n
" + << "v6 ( " << cnt6 << " )\r\n\r\n
" << tmp_s6.str () << "
\r\n
\r\n"; } } @@ -734,7 +734,7 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -751,7 +751,7 @@ namespace http { auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions6) { auto endpoint = it.second->GetRemoteEndpoint (); From 1a39f7e5c608c6dd2443aef27534f05d9e56f4f9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 13 Jun 2020 16:18:12 -0400 Subject: [PATCH 173/189] GarlicRoutingPath per session --- libi2pd/Datagram.cpp | 118 +++++++++++++++++++------------------------ libi2pd/Datagram.h | 2 - 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 5a196c3a..ad679cc0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -281,94 +281,82 @@ namespace datagram std::shared_ptr DatagramSession::GetSharedRoutingPath () { - if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) + if (!m_RemoteLeaseSet || m_RemoteLeaseSet->IsExpired ()) { - if(!m_RemoteLeaseSet) { - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - } - if(!m_RemoteLeaseSet) { - // no remote lease set - if(!m_RequestingLS) { + m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); + if (!m_RemoteLeaseSet) + { + if(!m_RequestingLS) + { m_RequestingLS = true; m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1)); } return nullptr; - } + } + } + + if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); - } + auto path = m_RoutingSession->GetSharedRoutingPath(); - if(path) { - if (m_CurrentOutboundTunnel && !m_CurrentOutboundTunnel->IsEstablished()) { + if (path) + { + if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) // bad outbound tunnel, switch outbound tunnel - m_CurrentOutboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(m_CurrentOutboundTunnel); - path->outboundTunnel = m_CurrentOutboundTunnel; - } - if(m_CurrentRemoteLease && m_CurrentRemoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { + path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel); + + if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) + { // bad lease, switch to next one - if(m_RemoteLeaseSet && m_RemoteLeaseSet->IsExpired()) - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - if(m_RemoteLeaseSet) { - auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding([&](const i2p::data::Lease& l) -> bool { - return l.tunnelID == m_CurrentRemoteLease->tunnelID; - }); + if (m_RemoteLeaseSet) + { + auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding( + [&](const i2p::data::Lease& l) -> bool + { + return l.tunnelID == path->remoteLease->tunnelID; + }); auto sz = ls.size(); - if (sz) { + if (sz) + { auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; + path->remoteLease = ls[idx]; } - } else { + else + path->remoteLease = nullptr; + } + else // no remote lease set? LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32()); - } - path->remoteLease = m_CurrentRemoteLease; } - } else { + } + else + { // no current path, make one path = std::make_shared(); - // switch outbound tunnel if bad - if(m_CurrentOutboundTunnel == nullptr || ! m_CurrentOutboundTunnel->IsEstablished()) { - m_CurrentOutboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(m_CurrentOutboundTunnel); - } - // switch lease if bad - if(m_CurrentRemoteLease && m_CurrentRemoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { - if(!m_RemoteLeaseSet) { - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - } - if(m_RemoteLeaseSet) { - // pick random next good lease - auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding([&] (const i2p::data::Lease & l) -> bool { - if(m_CurrentRemoteLease) - return l.tunnelGateway == m_CurrentRemoteLease->tunnelGateway; - return false; - }); - auto sz = ls.size(); - if(sz) { - auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; - } - } else { - // no remote lease set currently, bail - LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32()); - return nullptr; - } - } else if (!m_CurrentRemoteLease) { - if(!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - if (m_RemoteLeaseSet) + path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(); + + if (m_RemoteLeaseSet) + { + // pick random next good lease + auto ls = m_RemoteLeaseSet->GetNonExpiredLeases(); + auto sz = ls.size(); + if (sz) { - auto ls = m_RemoteLeaseSet->GetNonExpiredLeases(); - auto sz = ls.size(); - if (sz) { - auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; - } + auto idx = rand() % sz; + path->remoteLease = ls[idx]; } + + + } + else + { + // no remote lease set currently, bail + LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32()); + return nullptr; } - path->outboundTunnel = m_CurrentOutboundTunnel; - path->remoteLease = m_CurrentRemoteLease; m_RoutingSession->SetSharedRoutingPath(path); } return path; - } void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr ls) diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 94fe422c..66e9e909 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -95,8 +95,6 @@ namespace datagram i2p::data::IdentHash m_RemoteIdent; std::shared_ptr m_RemoteLeaseSet; std::shared_ptr m_RoutingSession; - std::shared_ptr m_CurrentRemoteLease; - std::shared_ptr m_CurrentOutboundTunnel; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 0f309377ecf57c9edc23324da8368c22624fa5b1 Mon Sep 17 00:00:00 2001 From: Anton Nesterov Date: Sat, 13 Jun 2020 20:46:17 +0000 Subject: [PATCH 174/189] Improve AppArmor profile - give it a name - import needed abstractions - allow local additions - cleanup --- contrib/apparmor/usr.sbin.i2pd | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/contrib/apparmor/usr.sbin.i2pd b/contrib/apparmor/usr.sbin.i2pd index 6cc80609..1e47cd74 100644 --- a/contrib/apparmor/usr.sbin.i2pd +++ b/contrib/apparmor/usr.sbin.i2pd @@ -4,34 +4,22 @@ # #include -/usr/sbin/i2pd { +profile i2pd /{usr/,}sbin/i2pd { #include - - network inet dgram, - network inet stream, - network inet6 dgram, - network inet6 stream, - network netlink raw, - - /etc/gai.conf r, - /etc/host.conf r, - /etc/hosts r, - /etc/nsswitch.conf r, - /etc/resolv.conf r, - /run/resolvconf/resolv.conf r, - /run/systemd/resolve/resolv.conf r, - /run/systemd/resolve/stub-resolv.conf r, + #include + #include # path specific (feel free to modify if you have another paths) /etc/i2pd/** r, - /run/i2pd/i2pd.pid rwk, /var/lib/i2pd/** rw, /var/log/i2pd/i2pd.log w, - /var/run/i2pd/i2pd.pid rwk, - /usr/sbin/i2pd mr, - /usr/share/i2pd/** r, + /{var/,}run/i2pd/i2pd.pid rwk, + /{usr/,}sbin/i2pd mr, + @{system_share_dirs}/i2pd/** r, # user homedir (if started not by init.d or systemd) owner @{HOME}/.i2pd/ rw, owner @{HOME}/.i2pd/** rwk, + + #include if exists } From 69194118dfe3c6e0201efc3db6671bbf1d81e32e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 13 Jun 2020 21:24:16 -0400 Subject: [PATCH 175/189] generate random padding length in bulk --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 +++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ad91382f..87fd13ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -96,6 +96,7 @@ namespace garlic ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) { + RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0; ResetKeys (); } @@ -745,8 +746,12 @@ namespace garlic int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size { - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; // 0 - 15 + paddingSize = m_PaddingSizes[m_NextPaddingSize++] & 0x0F; // 0 - 15 + if (m_NextPaddingSize >= 32) + { + RAND_bytes (m_PaddingSizes, 32); + m_NextPaddingSize = 0; + } if (delta > 3) { delta -= 3; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index d121842d..727c48ac 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -188,7 +188,8 @@ namespace garlic std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; - + uint8_t m_PaddingSizes[32], m_NextPaddingSize; + public: // for HTTP only From 1e609acb035dba27116d3f3b4f3a63740aa52e3d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Jun 2020 11:16:08 -0400 Subject: [PATCH 176/189] keep sending through first successive routing path --- libi2pd/Datagram.cpp | 20 +++++++++++++++++--- libi2pd/Datagram.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index ad679cc0..844611d3 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -296,7 +296,23 @@ namespace datagram } if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) - m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); + { + bool found = false; + for (auto& it: m_PendingRoutingSessions) + if (it->GetOwner ()) // found established session + { + m_RoutingSession = it; + m_PendingRoutingSessions.clear (); + found = true; + break; + } + if (!found) + { + m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); + if (!m_RoutingSession->GetOwner ()) + m_PendingRoutingSessions.push_back (m_RoutingSession); + } + } auto path = m_RoutingSession->GetSharedRoutingPath(); if (path) @@ -345,8 +361,6 @@ namespace datagram auto idx = rand() % sz; path->remoteLease = ls[idx]; } - - } else { diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 66e9e909..5dd6c8b6 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -95,6 +95,7 @@ namespace datagram i2p::data::IdentHash m_RemoteIdent; std::shared_ptr m_RemoteLeaseSet; std::shared_ptr m_RoutingSession; + std::vector > m_PendingRoutingSessions; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 8d903a09e2a20d790fe287ca66eb4b4c458c8efa Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 14 Jun 2020 22:18:41 +0300 Subject: [PATCH 177/189] [Docker] drop boost-python2 --- contrib/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 6b6250d0..be3feea7 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -36,7 +36,7 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib && cd /usr/local/bin \ && strip i2pd \ && rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \ - boost-python3 python3 gdbm boost-unit_test_framework boost-python2 linux-headers boost-prg_exec_monitor \ + boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \ boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \ libtool g++ gcc From 70e4cbc0236d253b68d6747c0a3c046f9c095384 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 15 Jun 2020 20:10:47 -0400 Subject: [PATCH 178/189] differentiate UDP server sessions by port --- libi2pd_client/I2PTunnel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index d05a97b7..95f56873 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,7 +611,7 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0]) + if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0] || fromPort != m_LastSession->RemotePort) { std::lock_guard lock(m_SessionsMutex); m_LastSession = ObtainUDPSession(from, toPort, fromPort); @@ -659,7 +659,7 @@ namespace client auto ih = from.GetIdentHash(); for (auto & s : m_Sessions ) { - if (s->Identity.GetLL()[0] == ih.GetLL()[0]) + if (s->Identity.GetLL()[0] == ih.GetLL()[0] && remotePort == s->RemotePort) { /** found existing session */ LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); From 31494267e5856b0f685f323e6cfcbbd66dde16dd Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2020 14:24:25 -0400 Subject: [PATCH 179/189] fixed datagram idle crash --- libi2pd/Datagram.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 844611d3..b9938043 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -318,8 +318,12 @@ namespace datagram if (path) { if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) + { // bad outbound tunnel, switch outbound tunnel path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel); + if (!path->outboundTunnel) + m_RoutingSession->SetSharedRoutingPath (nullptr); + } if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { @@ -338,11 +342,14 @@ namespace datagram path->remoteLease = ls[idx]; } else - path->remoteLease = nullptr; + m_RoutingSession->SetSharedRoutingPath (nullptr); } else + { // no remote lease set? LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32()); + m_RoutingSession->SetSharedRoutingPath (nullptr); + } } } else @@ -350,7 +357,8 @@ namespace datagram // no current path, make one path = std::make_shared(); path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(); - + if (!path->outboundTunnel) return nullptr; + if (m_RemoteLeaseSet) { // pick random next good lease @@ -361,6 +369,8 @@ namespace datagram auto idx = rand() % sz; path->remoteLease = ls[idx]; } + else + return nullptr; } else { From 951ec567c7769e2f4b8adf1c5876052260821e89 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2020 21:06:35 -0400 Subject: [PATCH 180/189] don't try to connect though teminated local destination --- libi2pd_client/SAM.cpp | 23 +++++++++++++++-------- libi2pd_client/SAM.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 4723d168..63b9c7ed 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -494,7 +494,7 @@ namespace client context.GetAddressBook().InsertFullAddress(dest); auto leaseSet = session->localDestination->FindLeaseSet(dest->GetIdentHash()); if (leaseSet) - Connect(leaseSet); + Connect(leaseSet, session); else { session->localDestination->RequestDestination(dest->GetIdentHash(), @@ -509,18 +509,25 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } - void SAMSocket::Connect (std::shared_ptr remote) + void SAMSocket::Connect (std::shared_ptr remote, std::shared_ptr session) { - auto session = m_Owner.FindSession(m_ID); - if(session) + if (!session) session = m_Owner.FindSession(m_ID); + if (session) { m_SocketType = eSAMSocketTypeStream; m_Stream = session->localDestination->CreateStream (remote); - m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send - m_BufferOffset = 0; - I2PReceive (); - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + if (m_Stream) + { + m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send + m_BufferOffset = 0; + I2PReceive (); + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } void SAMSocket::HandleConnectLeaseSetRequestComplete (std::shared_ptr leaseSet) diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index ceda5253..7b1702f5 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -134,7 +134,7 @@ namespace client size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 void ExtractParams (char * buf, std::map& params); - void Connect (std::shared_ptr remote); + void Connect (std::shared_ptr remote, std::shared_ptr session = nullptr); void HandleConnectLeaseSetRequestComplete (std::shared_ptr leaseSet); void SendNamingLookupReply (std::shared_ptr identity); void HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name); From a0b35ebd3ef68dd4d4ccacf6cef218000e618c2f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 22 Jun 2020 22:32:18 -0400 Subject: [PATCH 181/189] mark NTCP2 unreachable routers --- libi2pd/NTCP2.cpp | 3 ++- libi2pd/Transports.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 8b44a795..60eab17c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1305,7 +1305,8 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - //i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + if (conn->GetRemoteIdentity ()) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); conn->Terminate (); } }); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7157306d..6f163e5f 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -440,7 +440,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address) + if (address && !peer.router->IsUnreachable ()) { auto s = std::make_shared (*m_NTCP2Server, peer.router); From 61e9c31f0dc3a3bda295fd4fdb0f80a3ac099ca9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jun 2020 11:29:54 -0400 Subject: [PATCH 182/189] don't hold RouterInfo after successive connect --- libi2pd/Transports.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 6f163e5f..7da0f63b 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -431,6 +431,8 @@ namespace transport bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer) { + if (!peer.router) // reconnect + peer.router = netdb.FindRouter (ident); // try to get new one from netdb if (peer.router) // we have RI already { if (!peer.numAttempts) // NTCP2 @@ -638,6 +640,7 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { + it->second.router = nullptr; // we don't need RouterInfo after successive connect bool sendDatabaseStore = true; if (it->second.delayedMessages.size () > 0) { From df9965e1295de377516cb3a15aa68ef1a86c71f6 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jun 2020 18:19:31 -0400 Subject: [PATCH 183/189] use unordered_map for peers --- libi2pd/Transports.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index cdfbfccf..95c7aedb 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -157,7 +157,7 @@ namespace transport SSUServer * m_SSUServer; NTCP2Server * m_NTCP2Server; mutable std::mutex m_PeersMutex; - std::map m_Peers; + std::unordered_map m_Peers; DHKeysPairSupplier m_DHKeysPairSupplier; From 1f31fdc257ec0a0f44fd263d0fb0ed9fa14464a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jun 2020 20:02:09 -0400 Subject: [PATCH 184/189] pre-calculate ephemeral keys for x25519 --- libi2pd/NTCP2.cpp | 8 +++---- libi2pd/NTCP2.h | 4 ++-- libi2pd/Transports.cpp | 52 +++++++++++++++++++++++++++++------------- libi2pd/Transports.h | 23 ++++++++++++------- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 60eab17c..f1f7e59f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -83,7 +83,7 @@ namespace transport void NTCP2Establisher::KDF1Alice () { - KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); + KeyDerivationFunction1 (m_RemoteStaticKey, *m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } void NTCP2Establisher::KDF1Bob () @@ -102,7 +102,7 @@ namespace transport // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; - m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); + m_EphemeralKeys->Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial); } @@ -127,13 +127,13 @@ namespace transport void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); + m_EphemeralKeys->Agree (m_RemoteStaticKey, inputKeyMaterial); MixKey (inputKeyMaterial); } void NTCP2Establisher::CreateEphemeralKey () { - m_EphemeralKeys.GenerateKeys (); + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); } void NTCP2Establisher::CreateSessionRequestMessage () diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 8b8c6acb..df72fed0 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -79,7 +79,7 @@ namespace transport NTCP2Establisher (); ~NTCP2Establisher (); - const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); }; + const uint8_t * GetPub () const { return m_EphemeralKeys->GetPublicKey (); }; const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set @@ -110,7 +110,7 @@ namespace transport bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); - i2p::crypto::X25519Keys m_EphemeralKeys; + std::shared_ptr m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; i2p::data::IdentHash m_RemoteIdentHash; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7da0f63b..edfe33fa 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -21,23 +21,27 @@ namespace i2p { namespace transport { - DHKeysPairSupplier::DHKeysPairSupplier (int size): + template + EphemeralKeysSupplier::EphemeralKeysSupplier (int size): m_QueueSize (size), m_IsRunning (false), m_Thread (nullptr) { } - DHKeysPairSupplier::~DHKeysPairSupplier () + template + EphemeralKeysSupplier::~EphemeralKeysSupplier () { Stop (); } - void DHKeysPairSupplier::Start () + template + void EphemeralKeysSupplier::Start () { m_IsRunning = true; - m_Thread = new std::thread (std::bind (&DHKeysPairSupplier::Run, this)); + m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier::Run, this)); } - void DHKeysPairSupplier::Stop () + template + void EphemeralKeysSupplier::Stop () { { std::unique_lock l(m_AcquiredMutex); @@ -52,19 +56,20 @@ namespace transport } } - void DHKeysPairSupplier::Run () + template + void EphemeralKeysSupplier::Run () { while (m_IsRunning) { int num, total = 0; while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 10) { - CreateDHKeysPairs (num); + CreateEphemeralKeys (num); total += num; } if (total >= 10) { - LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time"); + LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time"); std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break } else @@ -76,24 +81,26 @@ namespace transport } } - void DHKeysPairSupplier::CreateDHKeysPairs (int num) + template + void EphemeralKeysSupplier::CreateEphemeralKeys (int num) { if (num > 0) { for (int i = 0; i < num; i++) { - auto pair = std::make_shared (); + auto pair = std::make_shared (); pair->GenerateKeys (); - std::unique_lock l(m_AcquiredMutex); + std::unique_lock l(m_AcquiredMutex); m_Queue.push (pair); } } } - std::shared_ptr DHKeysPairSupplier::Acquire () + template + std::shared_ptr EphemeralKeysSupplier::Acquire () { { - std::unique_lock l(m_AcquiredMutex); + std::unique_lock l(m_AcquiredMutex); if (!m_Queue.empty ()) { auto pair = m_Queue.front (); @@ -103,12 +110,13 @@ namespace transport } } // queue is empty, create new - auto pair = std::make_shared (); + auto pair = std::make_shared (); pair->GenerateKeys (); return pair; } - void DHKeysPairSupplier::Return (std::shared_ptr pair) + template + void EphemeralKeysSupplier::Return (std::shared_ptr pair) { if (pair) { @@ -126,7 +134,7 @@ namespace transport m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), - m_DHKeysPairSupplier (5), // 5 pre-generated keys + m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), @@ -158,6 +166,7 @@ namespace transport i2p::config::GetOption("nat", m_IsNAT); m_DHKeysPairSupplier.Start (); + m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); @@ -312,6 +321,7 @@ namespace transport } m_DHKeysPairSupplier.Stop (); + m_X25519KeysPairSupplier.Stop (); m_IsRunning = false; if (m_Service) m_Service->stop (); if (m_Thread) @@ -630,6 +640,16 @@ namespace transport m_DHKeysPairSupplier.Return (pair); } + std::shared_ptr Transports::GetNextX25519KeysPair () + { + return m_X25519KeysPairSupplier.Acquire (); + } + + void Transports::ReuseX25519KeysPair (std::shared_ptr pair) + { + m_X25519KeysPairSupplier.Return (pair); + } + void Transports::PeerConnected (std::shared_ptr session) { m_Service->post([session, this]() diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 95c7aedb..48eee4b4 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -32,33 +32,37 @@ namespace i2p { namespace transport { - class DHKeysPairSupplier + template + class EphemeralKeysSupplier { + // called from this file only, so implementation is in Transports.cpp public: - DHKeysPairSupplier (int size); - ~DHKeysPairSupplier (); + EphemeralKeysSupplier (int size); + ~EphemeralKeysSupplier (); void Start (); void Stop (); - std::shared_ptr Acquire (); - void Return (std::shared_ptr pair); + std::shared_ptr Acquire (); + void Return (std::shared_ptr pair); private: void Run (); - void CreateDHKeysPairs (int num); + void CreateEphemeralKeys (int num); private: const int m_QueueSize; - std::queue > m_Queue; + std::queue > m_Queue; bool m_IsRunning; std::thread * m_Thread; std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; - + typedef EphemeralKeysSupplier DHKeysPairSupplier; + typedef EphemeralKeysSupplier X25519KeysPairSupplier; + struct Peer { int numAttempts; @@ -97,6 +101,8 @@ namespace transport boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr GetNextDHKeysPair (); void ReuseDHKeysPair (std::shared_ptr pair); + std::shared_ptr GetNextX25519KeysPair (); + void ReuseX25519KeysPair (std::shared_ptr pair); void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); void SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs); @@ -160,6 +166,7 @@ namespace transport std::unordered_map m_Peers; DHKeysPairSupplier m_DHKeysPairSupplier; + X25519KeysPairSupplier m_X25519KeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; // bytes per second From 5f1e66d64b2c92af5082f9b29b5e6d52ad4130d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jun 2020 13:00:41 -0400 Subject: [PATCH 185/189] use pre-calculated x25519 ephemeral keys for ratchets --- libi2pd/Crypto.h | 4 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 59 +++++++++++++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 4 +- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 9ca3163f..ab84e56a 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -91,6 +91,9 @@ namespace crypto void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false); void Agree (const uint8_t * pub, uint8_t * shared); + bool IsElligatorIneligible () const { return m_IsElligatorIneligible; } + void SetElligatorIneligible () { m_IsElligatorIneligible = true; } + private: uint8_t m_PublicKey[32]; @@ -101,6 +104,7 @@ namespace crypto BN_CTX * m_Ctx; uint8_t m_PrivateKey[32]; #endif + bool m_IsElligatorIneligible = false; // true if definitly ineligible }; // ElGamal diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 87fd13ed..8e0e743d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -16,6 +16,7 @@ #include "Timestamp.h" #include "Tunnel.h" #include "TunnelPool.h" +#include "Transports.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -137,12 +138,38 @@ namespace garlic bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) { + bool ineligible = false; + while (!ineligible) + { + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + ineligible = m_EphemeralKeys->IsElligatorIneligible (); + if (!ineligible) // we haven't tried it yet + { + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf)) + return true; // success + // otherwise return back + m_EphemeralKeys->SetElligatorIneligible (); + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } + else + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } + // we still didn't find elligator eligible pair for (int i = 0; i < 10; i++) { - m_EphemeralKeys.GenerateKeys (); - if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) + // create new + m_EphemeralKeys = std::make_shared(); + m_EphemeralKeys->GenerateKeys (); + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf)) return true; // success + else + { + // let NTCP2 use it + m_EphemeralKeys->SetElligatorIneligible (); + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } } + LogPrint (eLogError, "Garlic: Can't generate elligator eligible x25519 keys"); return false; } @@ -294,7 +321,7 @@ namespace garlic if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; - m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); + m_NextSendRatchet->key->Agree (m_NextSendRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared (shared_from_this ()); newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); @@ -326,7 +353,7 @@ namespace garlic int tagsetID = 2*keyID; if (newKey) { - m_NextReceiveRatchet->key.GenerateKeys (); + m_NextReceiveRatchet->key = i2p::transport::transports.GetNextX25519KeysPair (); m_NextReceiveRatchet->newKey = true; tagsetID++; } @@ -336,7 +363,7 @@ namespace garlic memcpy (m_NextReceiveRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; - m_NextReceiveRatchet->key.Agree (m_NextReceiveRatchet->remote, sharedSecret); + m_NextReceiveRatchet->key->Agree (m_NextReceiveRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared(shared_from_this ()); newTagset->SetTagSetID (tagsetID); @@ -364,7 +391,7 @@ namespace garlic else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) - m_NextSendRatchet->key.GenerateKeys (); + m_NextSendRatchet->key->GenerateKeys (); m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); @@ -384,9 +411,9 @@ namespace garlic // KDF1 MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) + m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt static key section uint8_t nonce[12]; @@ -435,11 +462,11 @@ namespace garlic offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + m_EphemeralKeys->Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) + m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); @@ -485,7 +512,7 @@ namespace garlic // recalculate h with new tag memcpy (m_H, m_NSRH, 32); MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) @@ -524,7 +551,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { // only fist time, we assume ephemeral keys the same - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) @@ -565,6 +592,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; + m_EphemeralKeys = nullptr; m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } @@ -643,6 +671,7 @@ namespace garlic case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; m_NSRSendTagset = nullptr; + m_EphemeralKeys = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif @@ -813,7 +842,7 @@ namespace garlic htobe16buf (v.data () + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) { - memcpy (v.data () + offset, m_NextReceiveRatchet->key.GetPublicKey (), 32); + memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); offset += 32; // public key } m_SendReverseKey = false; @@ -828,7 +857,7 @@ namespace garlic htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) { - memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32); offset += 32; // public key } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 727c48ac..2dccd865 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -122,7 +122,7 @@ namespace garlic struct DHRatchet { int keyID = 0; - i2p::crypto::X25519Keys key; + std::shared_ptr key; uint8_t remote[32]; // last remote public key bool newKey = true; }; @@ -180,7 +180,7 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only - i2p::crypto::X25519Keys m_EphemeralKeys; + std::shared_ptr m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming std::shared_ptr m_SendTagset, m_NSRSendTagset; From 6f2e6ed8873d68f8bdd9e626ed7ac5912beeffd0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jun 2020 15:05:17 -0400 Subject: [PATCH 186/189] key for next send ratchet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8e0e743d..d403c9bd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -391,7 +391,7 @@ namespace garlic else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) - m_NextSendRatchet->key->GenerateKeys (); + m_NextSendRatchet->key = i2p::transport::transports.GetNextX25519KeysPair (); m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); From 6f17624742b4af654b1c4c604172beb7b2c48787 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 5 Jul 2020 12:53:15 +0800 Subject: [PATCH 187/189] Android.mk : openssl-1.1.1d-clang instead of openssl-1.1.1a-clang --- android/jni/Android.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 2376509e..07dc7080 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -53,15 +53,15 @@ include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := crypto -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ssl -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include LOCAL_STATIC_LIBRARIES := crypto include $(PREBUILT_STATIC_LIBRARY) From e15b2cc5d6531037850b855b36b025ad371b962b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 15 Jun 2020 09:01:17 +0300 Subject: [PATCH 188/189] [webconsole] rework lists with tunnels, transit, etc Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 166 ++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 71 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 41f198c8..c387a402 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -67,35 +67,36 @@ namespace http { " 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" " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" - " .menu { float: left; } .menu a { display: block; padding: 2px; }\r\n" + " .menu { float: left; } .menu a, .commands a { display: block; }\r\n" + " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" - " .tunnel.established { color: #56B734; }\r\n" - " .tunnel.expiring { color: #D3AE3F; }\r\n" - " .tunnel.failed { color: #D33F3F; }\r\n" - " .tunnel.building { color: #434343; }\r\n" + " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n" + " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { display: table; border-collapse: collapse; text-align: center; }\r\n" " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" + " textarea { word-break: break-all; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" " .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n" " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ - " .menu { width: 100%; display: block; float: none; position: unset; font-size: 24px;\r\n" + " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" + " text-align: center; }\r\n" + " .menu a, .commands a { padding: 2px; }\r\n" + " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%;\r\n" " text-align: center; }\r\n" - " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%; font-size: 1.2em;\r\n" - " text-align: center; line-height: 28px; }\r\n" " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" - " .header { margin: 0.5em 0; } 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" " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" - " input { width: 35%; height: 50px; text-align: center; /* margin-top: 15px; */ padding: 5px;\r\n" - " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 35px; }\r\n" + " input { width: 35%; text-align: center; padding: 5px;\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 24px; }\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: 22px; }\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" - " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 50px; display: -webkit-inline-box; margin-top: 25px; }\r\n" + " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n" " }\r\n" /* adaptive style */ "\r\n"; @@ -228,7 +229,7 @@ namespace http { static void ShowPageTail (std::stringstream& s) { s << - "
\r\n" + "
\r\n
\r\n" "\r\n" "\r\n"; } @@ -358,18 +359,19 @@ namespace http { void ShowLocalDestinations (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Local Destinations:
\r\n
\r\n"; + s << "Local Destinations:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) { auto ident = it.second->GetIdentHash (); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; + s << "\r\n" << std::endl; } + s << "
\r\n"; auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer && !(i2cpServer->GetSessions ().empty ())) { - s << "
I2CP Local Destinations:
\r\n
\r\n"; + s << "
I2CP Local Destinations:
\r\n
\r\n"; for (auto& it: i2cpServer->GetSessions ()) { auto dest = it.second->GetDestination (); @@ -377,10 +379,11 @@ namespace http { { auto ident = dest->GetIdentHash (); auto& name = dest->GetNickname (); - s << "[ "; - s << name << " ] ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"
\r\n" << std::endl; + s << "
[ "; + s << name << " ] ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"
\r\n" << std::endl; } } + s << "
\r\n"; } } @@ -581,54 +584,59 @@ namespace http { void ShowTunnels (std::stringstream& s) { - s << "Tunnels:
\r\n
\r\n"; - s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; + s << "Tunnels:
\r\n"; + s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n
\r\n"; auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool (); - s << "Inbound tunnels:
\r\n"; + s << "Inbound tunnels:
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); + s << "
\r\n"; } - s << "
\r\n"; - s << "Outbound tunnels:
\r\n"; + s << "
\r\n
\r\n"; + s << "Outbound tunnels:
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ()); + s << "
\r\n"; } - s << "
\r\n"; + s << "
\r\n"; } static void ShowCommands (std::stringstream& s, uint32_t token) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); /* commands */ - s << "Router Commands
\r\n
\r\n"; - s << " Run peer test
\r\n"; + s << "Router Commands
\r\n
\r\n
\r\n"; + s << " Run peer test\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " Decline transit tunnels
\r\n"; + s << " Decline transit tunnels\r\n"; else - s << " Accept transit tunnels
\r\n"; + s << " Accept transit tunnels\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) - s << " Cancel graceful shutdown
"; + s << " Cancel graceful shutdown\r\n"; else s << " Start graceful shutdown
\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) - s << " Cancel graceful shutdown
"; + s << " Cancel graceful shutdown\r\n"; else - s << " Graceful shutdown
\r\n"; + s << " Graceful shutdown\r\n"; #endif - s << " Force shutdown
\r\n
\r\n"; + s << " Force shutdown\r\n"; + s << "
"; - s << "Note: any action done here are not persistent and not changes your config files.\r\n
\r\n"; + s << "
\r\nNote: any action done here are not persistent and not changes your config files.\r\n
\r\n"; s << "Logging level
\r\n"; s << " none \r\n"; @@ -651,17 +659,19 @@ namespace http { { if(i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "Transit tunnels:
\r\n
\r\n"; + s << "Transit tunnels:
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { + s << "
\r\n"; if (std::dynamic_pointer_cast(it)) s << it->GetTunnelID () << " ⇒ "; else if (std::dynamic_pointer_cast(it)) s << " ⇒ " << it->GetTunnelID (); else s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; } + s << "
\r\n"; } else { @@ -677,43 +687,44 @@ namespace http { { if (it.second && it.second->IsEstablished () && !it.second->GetSocket ().remote_endpoint ().address ().is_v6 ()) { - // incoming connection doesn't have remote RI + tmp_s << "
\r\n"; if (it.second->IsOutgoing ()) tmp_s << " ⇒ "; tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " << it.second->GetSocket ().remote_endpoint().address ().to_string (); if (!it.second->IsOutgoing ()) tmp_s << " ⇒ "; tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - tmp_s << "
\r\n" << std::endl; + tmp_s << "
\r\n" << std::endl; cnt++; } if (it.second && it.second->IsEstablished () && it.second->GetSocket ().remote_endpoint ().address ().is_v6 ()) { + tmp_s6 << "
\r\n"; if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " << "[" << it.second->GetSocket ().remote_endpoint().address ().to_string () << "]"; if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - tmp_s6 << "
\r\n" << std::endl; + tmp_s6 << "
\r\n" << std::endl; cnt6++; } } if (!tmp_s.str ().empty ()) { s << "
\r\n\r\n
" + << " ( " << cnt << " )\r\n\r\n
" << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { s << "
\r\n\r\n
" + << "v6 ( " << cnt6 << " )\r\n\r\n
" << tmp_s6.str () << "
\r\n
\r\n"; } } void ShowTransports (std::stringstream& s) { - s << "Transports:
\r\n
\r\n"; + s << "Transports:
\r\n"; auto ntcpServer = i2p::transport::transports.GetNTCPServer (); if (ntcpServer) { @@ -734,9 +745,10 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions) { + s << "
\r\n"; auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; s << endpoint.address ().to_string () << ":" << endpoint.port (); @@ -744,16 +756,17 @@ namespace http { s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; if (it.second->GetRelayTag ()) s << " [itag:" << it.second->GetRelayTag () << "]"; - s << "
\r\n" << std::endl; + s << "
\r\n" << std::endl; } s << "
\r\n
\r\n"; } auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions6) { + s << "
\r\n"; auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; s << "[" << endpoint.address ().to_string () << "]:" << endpoint.port (); @@ -761,7 +774,7 @@ namespace http { s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; if (it.second->GetRelayTag ()) s << " [itag:" << it.second->GetRelayTag () << "]"; - s << "
\r\n" << std::endl; + s << "
\r\n" << std::endl; } s << "
\r\n
\r\n"; } @@ -780,13 +793,14 @@ namespace http { if(sam->GetSessions ().size ()) { - s << "SAM Sessions:
\r\n
\r\n"; + s << "SAM Sessions:
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { auto& name = it.second->localDestination->GetNickname (); - s << ""; - s << name << " (" << it.first << ")
\r\n" << std::endl; + s << "\r\n" << std::endl; } + s << "
\r\n"; } else s << "SAM Sessions: no sessions currently running.
\r\n"; @@ -794,25 +808,28 @@ namespace http { static void ShowSAMSession (std::stringstream& s, const std::string& id) { - std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "SAM Session:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { ShowError(s, "SAM disabled"); return; } + auto session = sam->FindSession (id); if (!session) { ShowError(s, "SAM session not found"); return; } + + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + s << "SAM Session:
\r\n
\r\n"; auto& ident = session->localDestination->GetIdentHash(); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n"; + s << "\r\n"; s << "
\r\n"; - s << "Streams:
\r\n"; + s << "Streams:
\r\n
\r\n"; for (const auto& it: sam->ListSockets(id)) { + s << "
"; switch (it->GetSocketType ()) { case i2p::client::eSAMSocketTypeSession : s << "session"; break; @@ -821,78 +838,85 @@ namespace http { default: s << "unknown"; break; } s << " [" << it->GetSocket ().remote_endpoint() << "]"; - s << "
\r\n"; + s << "
\r\n"; } + s << "
\r\n"; } void ShowI2PTunnels (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Client Tunnels:
\r\n
\r\n"; + s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } auto httpProxy = i2p::client::context.GetHttpProxy (); if (httpProxy) { auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << "HTTP Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } auto socksProxy = i2p::client::context.GetSocksProxy (); if (socksProxy) { auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << "SOCKS Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; + auto& serverTunnels = i2p::client::context.GetServerTunnels (); if (!serverTunnels.empty ()) { - s << "
\r\nServer Tunnels:
\r\n
\r\n"; + s << "
\r\nServer Tunnels:
\r\n
\r\n"; for (auto& it: serverTunnels) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } + auto& clientForwards = i2p::client::context.GetClientForwards (); if (!clientForwards.empty ()) { - s << "
\r\nClient Forwards:
\r\n
\r\n"; + s << "
\r\nClient Forwards:
\r\n
\r\n"; for (auto& it: clientForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } auto& serverForwards = i2p::client::context.GetServerForwards (); if (!serverForwards.empty ()) { - s << "
\r\nServer Forwards:
\r\n
\r\n"; + s << "
\r\nServer Forwards:
\r\n
\r\n"; for (auto& it: serverForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } } From 2d65402cedf9d788609b47bbeac7faaab88c8591 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 15 Jun 2020 13:05:01 +0300 Subject: [PATCH 189/189] [webconsole] update styles Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c387a402..416cf1e4 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -69,6 +69,7 @@ namespace http { " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" " .menu { float: left; } .menu a, .commands a { display: block; }\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" " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n" " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n" @@ -172,7 +173,7 @@ namespace http { default: state = "unknown"; break; } s << " " << state << ((explr) ? " (exploratory)" : "") << ", "; - s << " " << (int) (bytes / 1024) << " KiB
\r\n"; + s << " " << (int) (bytes / 1024) << " KiB\r\n"; } static void SetLogLevel (const std::string& level) @@ -389,7 +390,7 @@ namespace http { static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest) { - s << "Base64:
\r\n
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { @@ -402,29 +403,34 @@ namespace http { if(dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n
\r\n"; + << "\r\n\r\n
\r\n
AddressTypeEncType
"; for(auto& it: dest->GetLeaseSets ()) s << "\r\n"; s << "
AddressTypeEncType
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n
\r\n
\r\n
\r\n"; } else s << "LeaseSets: 0
\r\n
\r\n"; + auto pool = dest->GetTunnelPool (); if (pool) { - s << "Inbound tunnels:
\r\n"; + s << "Inbound tunnels:
\r\n
\r\n"; for (auto & it : pool->GetInboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); + s << "
\r\n"; } s << "
\r\n"; - s << "Outbound tunnels:
\r\n"; + s << "Outbound tunnels:
\r\n
\r\n"; for (auto & it : pool->GetOutboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); + s << "
\r\n"; } } s << "
\r\n"; @@ -437,7 +443,7 @@ namespace http { out_tags += it.second->GetNumOutgoingTags (); } s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -453,7 +459,7 @@ namespace http { ecies_sessions++; } s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; @@ -483,11 +489,12 @@ namespace http { s << "RTT"; s << "Window"; s << "Status"; - s << "\r\n\r\n\r\n"; + s << "\r\n\r\n\r\n"; for (const auto& it: dest->GetAllStreams ()) { auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()); + std::string streamDestShort = streamDest.substr(0,12) + "….b32.i2p"; s << ""; s << "" << it->GetRecvStreamID () << ""; if (it->GetRecvStreamID ()) { @@ -496,7 +503,7 @@ namespace http { } else { s << ""; } - s << "" << streamDest << ""; + s << "" << streamDestShort << ""; s << "" << it->GetNumSentBytes () << ""; s << "" << it->GetNumReceivedBytes () << ""; s << "" << it->GetSendQueueSize () << ""; @@ -531,7 +538,7 @@ namespace http { { if (i2p::data::netdb.GetNumLeaseSets ()) { - s << "LeaseSets:
\r\n
\r\n"; + s << "LeaseSets:
\r\n
\r\n"; int counter = 1; // for each lease set i2p::data::netdb.VisitLeaseSets( @@ -545,13 +552,13 @@ namespace http { else ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); if (!ls) return; - s << "
\r\n"; + s << "\">\r\n"; if (!ls->IsValid()) - s << "
!! Invalid !!
\r\n"; - s << "
\r\n"; + s << "
!! Invalid !!
\r\n"; + s << "
\r\n"; s << "\r\n
\r\n"; s << "Store type: " << (int)storeType << "
\r\n"; s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; @@ -922,7 +929,7 @@ namespace http { std::string ConvertTime (uint64_t time) { - ldiv_t divTime = ldiv(time,1000); + lldiv_t divTime = lldiv(time, 1000); time_t t = divTime.quot; struct tm *tm = localtime(&t); char date[128];