From db88183a23ee277e63fe998cd2fae41b886121fa Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 29 Mar 2016 12:34:53 -0400 Subject: [PATCH 01/56] graceful shutdown by SIGINT --- Daemon.h | 31 ++++++++++++++++++------------- DaemonLinux.cpp | 29 +++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/Daemon.h b/Daemon.h index efbd5df4..031686f7 100644 --- a/Daemon.h +++ b/Daemon.h @@ -50,26 +50,31 @@ namespace i2p bool init(int argc, char* argv[]); bool start(); - bool stop(); + bool stop(); void run (); }; #else class DaemonLinux : public Daemon_Singleton { - public: - static DaemonLinux& Instance() - { - static DaemonLinux instance; - return instance; - } + public: + static DaemonLinux& Instance() + { + static DaemonLinux instance; + return instance; + } - bool start(); - bool stop(); -; void run (); + bool start(); + bool stop(); + void run (); - private: - std::string pidfile; - int pidFH; + private: + + std::string pidfile; + int pidFH; + + public: + + int gracefullShutdownInterval; // in seconds }; #endif diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index e760b4f5..d517ef79 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -17,14 +17,17 @@ void handle_signal(int sig) { switch (sig) { - case SIGHUP: - LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log..."); - i2p::log::Logger().Reopen (); - break; - case SIGABRT: - case SIGTERM: - case SIGINT: - Daemon.running = 0; // Exit loop + case SIGHUP: + LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log..."); + i2p::log::Logger().Reopen (); + break; + case SIGINT: + Daemon.gracefullShutdownInterval = 10*60; // 10 minutes + LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds"); + break; + case SIGABRT: + case SIGTERM: + Daemon.running = 0; // Exit loop break; } } @@ -96,6 +99,7 @@ namespace i2p return false; } } + gracefullShutdownInterval = 0; // not specified // Signal handler struct sigaction sa; @@ -122,6 +126,15 @@ namespace i2p while (running) { std::this_thread::sleep_for (std::chrono::seconds(1)); + if (gracefullShutdownInterval) + { + gracefullShutdownInterval--; // - 1 second + if (gracefullShutdownInterval <= 0) + { + LogPrint(eLogInfo, "Graceful shutdown"); + return; + } + } } } } From ac2e1709f80f08c5936faf9502eeec388a85cdb1 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 29 Mar 2016 12:50:34 -0400 Subject: [PATCH 02/56] graceful shutdown by SIGINT --- DaemonLinux.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index d517ef79..f91f782a 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -12,6 +12,7 @@ #include "Config.h" #include "FS.h" #include "Log.h" +#include "RouterContext.h" void handle_signal(int sig) { @@ -22,6 +23,7 @@ void handle_signal(int sig) i2p::log::Logger().Reopen (); break; case SIGINT: + i2p::context.SetAcceptsTunnels (false); Daemon.gracefullShutdownInterval = 10*60; // 10 minutes LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds"); break; From 6c628094ce9d57536859ef09f36221f701bc1dcc Mon Sep 17 00:00:00 2001 From: Mikal Villa Date: Tue, 29 Mar 2016 23:55:29 +0200 Subject: [PATCH 03/56] Adding exception handler on HTTP Proxy --- ClientContext.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index ccb8e0ad..88d90622 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -52,8 +52,12 @@ namespace client LoadPrivateKeys (keys, httpProxyKeys); localDestination = CreateNewLocalDestination (keys, false); } - m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination); - m_HttpProxy->Start(); + try { + m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination); + m_HttpProxy->Start(); + } catch (std::exception& e) { + LogPrint(eLogError, "Exception in HTTP Proxy: ", e.what()); + } } bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); From f1fb2651190bf02273489ab5ebf2e844556f3610 Mon Sep 17 00:00:00 2001 From: Mikal Villa Date: Wed, 30 Mar 2016 00:03:15 +0200 Subject: [PATCH 04/56] Adding exceptions for SOCKS, SAM and BOB proxy/briges --- ClientContext.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 88d90622..59f11f21 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -56,7 +56,7 @@ namespace client m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination); m_HttpProxy->Start(); } catch (std::exception& e) { - LogPrint(eLogError, "Exception in HTTP Proxy: ", e.what()); + LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); } } @@ -74,8 +74,12 @@ namespace client LoadPrivateKeys (keys, socksProxyKeys); localDestination = CreateNewLocalDestination (keys, false); } - m_SocksProxy = new i2p::proxy::SOCKSProxy(socksProxyAddr, socksProxyPort, socksOutProxyAddr, socksOutProxyPort, localDestination); - m_SocksProxy->Start(); + try { + m_SocksProxy = new i2p::proxy::SOCKSProxy(socksProxyAddr, socksProxyPort, socksOutProxyAddr, socksOutProxyPort, localDestination); + m_SocksProxy->Start(); + } catch (std::exception& e) { + LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); + } } // I2P tunnels @@ -87,8 +91,12 @@ namespace client std::string samAddr; i2p::config::GetOption("sam.address", samAddr); uint16_t samPort; i2p::config::GetOption("sam.port", samPort); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - m_SamBridge = new SAMBridge (samAddr, samPort); - m_SamBridge->Start (); + try { + m_SamBridge = new SAMBridge (samAddr, samPort); + m_SamBridge->Start (); + } catch (std::exception& e) { + LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); + } } // BOB @@ -97,8 +105,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); - m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); - m_BOBCommandChannel->Start (); + try { + m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); + m_BOBCommandChannel->Start (); + } catch (std::exception& e) { + LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); + } } m_AddressBook.StartResolvers (); From 8366c8d2a7cdf78e1abed05343fa413fa4adbdc5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 29 Mar 2016 21:37:30 -0400 Subject: [PATCH 05/56] don't initiate graceful shutdown twice --- DaemonLinux.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index f91f782a..b408fc70 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -23,9 +23,14 @@ void handle_signal(int sig) i2p::log::Logger().Reopen (); break; case SIGINT: - i2p::context.SetAcceptsTunnels (false); - Daemon.gracefullShutdownInterval = 10*60; // 10 minutes - LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds"); + if (i2p::context.AcceptsTunnels () && !Daemon.gracefullShutdownInterval) + { + i2p::context.SetAcceptsTunnels (false); + Daemon.gracefullShutdownInterval = 10*60; // 10 minutes + LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds"); + } + else + Daemon.running = 0; break; case SIGABRT: case SIGTERM: From e2a76056b8a095178fc3bd8e2d14a26d0f1e1f8f Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 06/56] * RouterInfo.h : add comments with bandwidth letter speed in KBps --- RouterInfo.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/RouterInfo.h b/RouterInfo.h index 5fa865b0..7648c6ba 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -24,13 +24,14 @@ namespace data const char CAPS_FLAG_HIDDEN = 'H'; const char CAPS_FLAG_REACHABLE = 'R'; const char CAPS_FLAG_UNREACHABLE = 'U'; - const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; - const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; - const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M'; - const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N'; - const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; - const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; - const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; + /* bandwidth flags */ + const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; /* < 12 KBps */ + const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; /* 12-48 KBps */ + const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M'; /* 48-64 KBps */ + const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N'; /* 64-128 KBps */ + const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */ + const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */ + const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */ const char CAPS_FLAG_SSU_TESTING = 'B'; const char CAPS_FLAG_SSU_INTRODUCER = 'C'; @@ -174,7 +175,6 @@ namespace data const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity->GetStandardIdentity ().publicKey; }; bool IsDestination () const { return false; }; - private: bool LoadFile (); From 5888ecbdcdee89136a3a4d5f1cda02a6f2ee79c9 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 07/56] * RouterInfo::UpdateCapsProperty() : add only one bw letter --- RouterInfo.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 22c5f2f8..c34087e5 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -333,16 +333,19 @@ namespace data void RouterInfo::UpdateCapsProperty () { std::string caps; - if (m_Caps & eFloodfill) - { - if (m_Caps & eExtraBandwidth) caps += CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' - caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' + if (m_Caps & eFloodfill) { caps += CAPS_FLAG_FLOODFILL; // floodfill - } - else - { - if (m_Caps & eExtraBandwidth) caps += CAPS_FLAG_EXTRA_BANDWIDTH1; - caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 : CAPS_FLAG_LOW_BANDWIDTH2; // bandwidth + caps += (m_Caps & eExtraBandwidth) + ? CAPS_FLAG_EXTRA_BANDWIDTH1 // 'P' + : CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' + } else { + if (m_Caps & eExtraBandwidth) { + caps += CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' + } else if (m_Caps & eHighBandwidth) { + caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' + } else { + caps += CAPS_FLAG_LOW_BANDWIDTH2; // 'L' + } } if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable From e625d8aabc074e0e3e965485d3d176493c1048a0 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 08/56] * RouterInfo.cpp : remove .c_str() --- RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index c34087e5..dfd54059 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -77,7 +77,7 @@ namespace data bool RouterInfo::LoadFile () { - std::ifstream s(m_FullPath.c_str (), std::ifstream::binary); + std::ifstream s(m_FullPath, std::ifstream::binary); if (s.is_open ()) { s.seekg (0,std::ios::end); From 642bcfcdeab395d5e155124400b0d038a2b64cf0 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 09/56] * RouterContext : replace Set(Low|High|Extra)Bandwidth with SetBandwidth() --- RouterContext.cpp | 62 +++++++++++++++++++++++++++++------------------ RouterContext.h | 7 +++--- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index 2157a81e..9a1749d0 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -165,34 +165,50 @@ namespace i2p m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG); } } - - void RouterContext::SetHighBandwidth () - { - if (!m_RouterInfo.IsHighBandwidth () || m_RouterInfo.IsExtraBandwidth ()) - { - m_RouterInfo.SetCaps ((m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eHighBandwidth) & ~i2p::data::RouterInfo::eExtraBandwidth); - UpdateRouterInfo (); + + void RouterContext::SetBandwidth (char L) { + uint16_t limit = 0; + enum { low, high, extra } type = high; + /* detect parameters */ + switch (L) { + case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; + case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = 48; type = low; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 64; type = high; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; + default: + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break; + case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; + case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 9999; type = extra; break; } + /* floodfill requires 'extra' bandwidth */ + if (m_IsFloodfill && limit < 2048) { + limit = 2048, type = extra; + LogPrint(eLogInfo, "Daemon: bandwidth set to 'extra' due to floodfill"); + } + /* update caps & flags in RI */ + auto caps = m_RouterInfo.GetCaps (); + caps &= ~i2p::data::RouterInfo::eHighBandwidth; + caps &= ~i2p::data::RouterInfo::eExtraBandwidth; + switch (type) { + case low : /* not set */; break; + case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; + case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; + } + m_RouterInfo.SetCaps (caps); + UpdateRouterInfo (); + m_BandwidthLimit = limit; } - void RouterContext::SetLowBandwidth () - { - if (m_RouterInfo.IsHighBandwidth () || m_RouterInfo.IsExtraBandwidth ()) - { - m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eHighBandwidth & ~i2p::data::RouterInfo::eExtraBandwidth); - UpdateRouterInfo (); - } + void RouterContext::SetBandwidth (int limit) { + if (limit > 2000) { SetBandwidth('X'); } + else if (limit > 256) { SetBandwidth('P'); } + else if (limit > 128) { SetBandwidth('O'); } + else if (limit > 64) { SetBandwidth('N'); } + else if (limit > 48) { SetBandwidth('M'); } + else if (limit > 12) { SetBandwidth('L'); } + else { SetBandwidth('K'); } } - void RouterContext::SetExtraBandwidth () - { - if (!m_RouterInfo.IsExtraBandwidth () || !m_RouterInfo.IsHighBandwidth ()) - { - m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eExtraBandwidth | i2p::data::RouterInfo::eHighBandwidth); - UpdateRouterInfo (); - } - } - bool RouterContext::IsUnreachable () const { return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; diff --git a/RouterContext.h b/RouterContext.h index 0679a038..9766c66e 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -45,6 +45,7 @@ namespace i2p uint32_t GetUptime () const; uint32_t GetStartupTime () const { return m_StartupTime; }; uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; + uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; RouterStatus GetStatus () const { return m_Status; }; void SetStatus (RouterStatus status); @@ -58,9 +59,8 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); - void SetHighBandwidth (); - void SetLowBandwidth (); - void SetExtraBandwidth (); + void SetBandwidth (int limit); /* in kilobytes */ + void SetBandwidth (char L); /* by letter */ bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; @@ -101,6 +101,7 @@ namespace i2p uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; uint64_t m_StartupTime; // in seconds since epoch + uint32_t m_BandwidthLimit; // allowed bandwidth RouterStatus m_Status; std::mutex m_GarlicMutex; }; From aef6b7712c0f8682111dc1ec6d0639a60873bb98 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 10/56] * Transports: update IsBandwidthExceeded() and comments in header --- Transports.cpp | 4 ++-- Transports.h | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Transports.cpp b/Transports.cpp index 275c6f90..0fdfce3d 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -200,9 +200,9 @@ namespace transport bool Transports::IsBandwidthExceeded () const { - if (i2p::context.GetRouterInfo ().IsExtraBandwidth ()) return false; + auto limit = i2p::context.GetBandwidthLimit() * 1024; // convert to bytes auto bw = std::max (m_InBandwidth, m_OutBandwidth); - return bw > (i2p::context.GetRouterInfo ().IsHighBandwidth () ? HIGH_BANDWIDTH_LIMIT : LOW_BANDWIDTH_LIMIT); + return bw > limit; } void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) diff --git a/Transports.h b/Transports.h index 9b603963..3bfe1f8b 100644 --- a/Transports.h +++ b/Transports.h @@ -66,8 +66,6 @@ namespace transport }; const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds - const uint32_t LOW_BANDWIDTH_LIMIT = 32*1024; // 32KBs - const uint32_t HIGH_BANDWIDTH_LIMIT = 256*1024; // 256KBs class Transports { public: @@ -94,8 +92,8 @@ namespace transport void UpdateReceivedBytes (uint64_t numBytes) { m_TotalReceivedBytes += numBytes; }; uint64_t GetTotalSentBytes () const { return m_TotalSentBytes; }; uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; }; - uint32_t GetInBandwidth () const { return m_InBandwidth; }; // bytes per second - uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; // bytes per second + uint32_t GetInBandwidth () const { return m_InBandwidth; }; + uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; bool IsBandwidthExceeded () const; size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer () const; @@ -138,7 +136,7 @@ namespace transport DHKeysPairSupplier m_DHKeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes; - uint32_t m_InBandwidth, m_OutBandwidth; + uint32_t m_InBandwidth, m_OutBandwidth; // bytes per second uint64_t m_LastInBandwidthUpdateBytes, m_LastOutBandwidthUpdateBytes; uint64_t m_LastBandwidthUpdateTime; From 350dea622835b3c4752e33bda935e3ae19b59da1 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 11/56] * update --bandwidth option handling --- Config.cpp | 2 +- Daemon.cpp | 35 +++++++++++------------------------ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/Config.cpp b/Config.cpp index 1dc1207f..fab986f5 100644 --- a/Config.cpp +++ b/Config.cpp @@ -123,7 +123,7 @@ namespace config { ("service", value()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'") ("notransit", value()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup") ("floodfill", value()->zero_tokens()->default_value(false), "Router will be floodfill") - ("bandwidth", value()->default_value('-'), "Bandwidth limiting: L - 32kbps, O - 256Kbps, P - unlimited") + ("bandwidth", value()->default_value("256"), "Bandwidth limit: integer in kbps or letters: L (32), O (256), P (2048), X (>9000)") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") diff --git a/Daemon.cpp b/Daemon.cpp index 3adfdb71..13cdc075 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -142,34 +142,21 @@ namespace i2p i2p::context.SetAcceptsTunnels (!transit); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - char bandwidth; i2p::config::GetOption("bandwidth", bandwidth); - - if (isFloodfill) - { + if (isFloodfill) { LogPrint(eLogInfo, "Daemon: router will be floodfill"); i2p::context.SetFloodfill (true); - } - else + } else { i2p::context.SetFloodfill (false); - if (bandwidth != '-') - { - LogPrint(eLogInfo, "Daemon: bandwidth set to ", bandwidth); - if (bandwidth > 'O') - i2p::context.SetExtraBandwidth (); - else if (bandwidth > 'L') - i2p::context.SetHighBandwidth (); - else - i2p::context.SetLowBandwidth (); } - else if (isFloodfill) - { - LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); - i2p::context.SetExtraBandwidth (); - } - else - { - LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'"); - i2p::context.SetLowBandwidth (); + + /* this section also honors 'floodfill' flag, if set above */ + std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); + if (bandwidth[0] > 'K' && bandwidth[0] < 'Z') { + i2p::context.SetBandwidth (bandwidth[0]); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); + } else if (bandwidth[0] >= '0' && bandwidth[0] <= '9') { + i2p::context.SetBandwidth (std::atoi(bandwidth.c_str())); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); } std::string family; i2p::config::GetOption("family", family); From 27649f7d4c54b7b47a357697ae1492cb613f2165 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 31 Mar 2016 00:00:00 +0000 Subject: [PATCH 12/56] * update docs --- Config.cpp | 2 +- docs/configuration.md | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Config.cpp b/Config.cpp index fab986f5..73124ae4 100644 --- a/Config.cpp +++ b/Config.cpp @@ -127,7 +127,7 @@ namespace config { #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") - ("close", value()->default_value("ask"), "On close action") // minimize, exit, ask TODO: add custom validator or something + ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; diff --git a/docs/configuration.md b/docs/configuration.md index 1a45716d..f3e9f98c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -23,9 +23,14 @@ If you are upgrading your very old router (< 2.3.0) see also [this](config_opts_ * --ipv6 - Enable communication through ipv6. false by default * --notransit - Router will not accept transit tunnels at startup. false by default * --floodfill - Router will be floodfill. false by default -* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited +* --bandwidth= - Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000) * --family= - Name of a family, router belongs to + +Windows-specific options: + * --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove") +* --insomnia - Prevent system from sleeping +* --close= - Action on close: minimize, exit, ask All options below still possible in cmdline, but better write it in config file: From df5b7c7d0d9ed26bb964ed5bb5e42c62e1ed2270 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Mar 2016 21:31:17 -0400 Subject: [PATCH 13/56] specify bandwidth for floodfill --- Config.cpp | 2 +- Daemon.cpp | 39 ++++++++++++++++++++++++++++++++------- RouterContext.cpp | 17 ++++++++--------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Config.cpp b/Config.cpp index 73124ae4..8d42895a 100644 --- a/Config.cpp +++ b/Config.cpp @@ -123,7 +123,7 @@ namespace config { ("service", value()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'") ("notransit", value()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup") ("floodfill", value()->zero_tokens()->default_value(false), "Router will be floodfill") - ("bandwidth", value()->default_value("256"), "Bandwidth limit: integer in kbps or letters: L (32), O (256), P (2048), X (>9000)") + ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in kbps or letters: L (32), O (256), P (2048), X (>9000)") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") diff --git a/Daemon.cpp b/Daemon.cpp index 13cdc075..f15fe3e3 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -151,13 +151,38 @@ namespace i2p /* this section also honors 'floodfill' flag, if set above */ std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); - if (bandwidth[0] > 'K' && bandwidth[0] < 'Z') { - i2p::context.SetBandwidth (bandwidth[0]); - LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); - } else if (bandwidth[0] >= '0' && bandwidth[0] <= '9') { - i2p::context.SetBandwidth (std::atoi(bandwidth.c_str())); - LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); - } + if (bandwidth.length () > 0) + { + if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X') + { + i2p::context.SetBandwidth (bandwidth[0]); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); + } + else + { + auto value = std::atoi(bandwidth.c_str()); + if (value > 0) + { + i2p::context.SetBandwidth (value); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); + } + else + { + LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); + } + } + } + else if (isFloodfill) + { + LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1); + } + else + { + LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); + } std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); diff --git a/RouterContext.cpp b/RouterContext.cpp index 9a1749d0..e50681d9 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -170,26 +170,24 @@ namespace i2p uint16_t limit = 0; enum { low, high, extra } type = high; /* detect parameters */ - switch (L) { + switch (L) + { case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = 48; type = low; break; case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 64; type = high; break; case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; - default: case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 9999; type = extra; break; - } - /* floodfill requires 'extra' bandwidth */ - if (m_IsFloodfill && limit < 2048) { - limit = 2048, type = extra; - LogPrint(eLogInfo, "Daemon: bandwidth set to 'extra' due to floodfill"); + default: + limit = 48; type = low; } /* update caps & flags in RI */ auto caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eHighBandwidth; caps &= ~i2p::data::RouterInfo::eExtraBandwidth; - switch (type) { + switch (type) + { case low : /* not set */; break; case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; @@ -199,7 +197,8 @@ namespace i2p m_BandwidthLimit = limit; } - void RouterContext::SetBandwidth (int limit) { + void RouterContext::SetBandwidth (int limit) + { if (limit > 2000) { SetBandwidth('X'); } else if (limit > 256) { SetBandwidth('P'); } else if (limit > 128) { SetBandwidth('O'); } From e5fac08d1d509998aa84785ecdd05cdf9007c02c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 31 Mar 2016 09:12:21 -0400 Subject: [PATCH 14/56] release 2.6.0 --- version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/version.h b/version.h index e7414de3..c5177d30 100644 --- a/version.h +++ b/version.h @@ -1,14 +1,14 @@ #ifndef _VERSION_H_ #define _VERSION_H_ -#define CODENAME "Purple" +#define CODENAME "Bora Bora" #define STRINGIZE(x) #x #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 5 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MINOR 6 +#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define VERSION I2PD_VERSION From 751b95d4af16f8b70033b365e13fc48df03f0947 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 1 Apr 2016 11:36:56 -0400 Subject: [PATCH 15/56] add locking to SAM when adding/removing sockets --- HTTPServer.cpp | 2 +- SAM.cpp | 32 ++++++++++++++++++-------------- SAM.h | 25 ++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index b6ec3522..f7efcba9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -749,7 +749,7 @@ namespace util s << "&" << HTTP_PARAM_BASE32_ADDRESS << "=" << ident.ToBase32 () << ">"; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; s << "Streams:
\r\n"; - for (auto it: session->sockets) + for (auto it: session->ListSockets()) { switch (it->GetSocketType ()) { diff --git a/SAM.cpp b/SAM.cpp index 7b493eb3..ecdd513d 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -47,16 +47,19 @@ namespace client break; case eSAMSocketTypeStream: { - if (m_Session) - m_Session->sockets.remove (shared_from_this ()); + if (m_Session) { + m_Session->DelSocket (shared_from_this ()); + m_Session = nullptr; + } break; } case eSAMSocketTypeAcceptor: { if (m_Session) { - m_Session->sockets.remove (shared_from_this ()); + m_Session->DelSocket (shared_from_this ()); m_Session->localDestination->StopAcceptingStreams (); + m_Session = nullptr; } break; } @@ -64,7 +67,7 @@ namespace client ; } m_SocketType = eSAMSocketTypeTerminated; - m_Socket.close (); + if (m_Socket.is_open()) m_Socket.close (); } void SAMSocket::ReceiveHandshake () @@ -369,7 +372,7 @@ namespace client void SAMSocket::Connect (std::shared_ptr remote) { m_SocketType = eSAMSocketTypeStream; - m_Session->sockets.push_back (shared_from_this ()); + m_Session->AddSocket (shared_from_this ()); m_Stream = m_Session->localDestination->CreateStream (remote); m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect I2PReceive (); @@ -402,7 +405,7 @@ namespace client if (!m_Session->localDestination->IsAcceptingStreams ()) { m_SocketType = eSAMSocketTypeAcceptor; - m_Session->sockets.push_back (shared_from_this ()); + m_Session->AddSocket (shared_from_this ()); m_Session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } @@ -676,19 +679,20 @@ namespace client SAMSession::~SAMSession () { - for (auto it: sockets) - it->SetSocketType (eSAMSocketTypeTerminated); + CloseStreams(); i2p::client::context.DeleteLocalDestination (localDestination); } void SAMSession::CloseStreams () { - for (auto it: sockets) - { - it->CloseStream (); - it->SetSocketType (eSAMSocketTypeTerminated); - } - sockets.clear (); + { + std::lock_guard lock(m_SocketsMutex); + for (auto sock : m_Sockets) { + sock->CloseStream(); + } + } + // XXX: should this be done inside locked parts? + m_Sockets.clear(); } SAMBridge::SAMBridge (const std::string& address, int port): diff --git a/SAM.h b/SAM.h index 07142c8c..4cdea686 100644 --- a/SAM.h +++ b/SAM.h @@ -134,7 +134,30 @@ namespace client struct SAMSession { std::shared_ptr localDestination; - std::list > sockets; + std::list > m_Sockets; + std::mutex m_SocketsMutex; + + /** safely add a socket to this session */ + void AddSocket(std::shared_ptr sock) { + std::lock_guard lock(m_SocketsMutex); + m_Sockets.push_back(sock); + } + + /** safely remove a socket from this session */ + void DelSocket(std::shared_ptr sock) { + std::lock_guard lock(m_SocketsMutex); + m_Sockets.remove(sock); + } + + /** get a list holding a copy of all sam sockets from this session */ + std::list > ListSockets() { + std::list > l; + { + std::lock_guard lock(m_SocketsMutex); + for( auto & sock : m_Sockets ) l.push_back(sock); + } + return l; + } SAMSession (std::shared_ptr dest); ~SAMSession (); From 5c877de2c2f954c27471092fff73443a1c9af9d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 Apr 2016 12:51:34 -0400 Subject: [PATCH 16/56] check if hosts is incomplete --- AddressBook.cpp | 18 ++++++++++++------ AddressBook.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index ad2d0c32..766d8c95 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -343,10 +343,11 @@ namespace client } } - void AddressBook::LoadHostsFromStream (std::istream& f) + bool AddressBook::LoadHostsFromStream (std::istream& f) { std::unique_lock l(m_AddressBookMutex); int numAddresses = 0; + bool incomplete = false; std::string s; while (!f.eof ()) { @@ -370,15 +371,21 @@ namespace client numAddresses++; } else + { LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name); - } + incomplete = f.eof (); + } + } + else + incomplete = f.eof (); } LogPrint (eLogInfo, "Addressbook: ", numAddresses, " addresses processed"); if (numAddresses > 0) { - m_IsLoaded = true; + if (!incomplete) m_IsLoaded = true; m_Storage->Save (m_Addresses); } + return !incomplete; } void AddressBook::LoadSubscriptions () @@ -776,13 +783,12 @@ namespace client i2p::data::GzipInflator inflator; inflator.Inflate (s, uncompressed); if (!uncompressed.fail ()) - m_Book.LoadHostsFromStream (uncompressed); + return m_Book.LoadHostsFromStream (uncompressed); else return false; } else - m_Book.LoadHostsFromStream (s); - return true; + return m_Book.LoadHostsFromStream (s); } AddressResolver::AddressResolver (std::shared_ptr destination): diff --git a/AddressBook.h b/AddressBook.h index 56f8145c..61b82f4b 100644 --- a/AddressBook.h +++ b/AddressBook.h @@ -66,7 +66,7 @@ namespace client void InsertAddress (const std::string& address, const std::string& base64); // for jump service void InsertAddress (std::shared_ptr address); - void LoadHostsFromStream (std::istream& f); + bool LoadHostsFromStream (std::istream& f); void DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified); //This method returns the ".b32.i2p" address std::string ToAddress(const i2p::data::IdentHash& ident) { return GetB32Address(ident); } From 0bf2abaa4c4c40775a9b8d3f4b852158cc8f840e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 Apr 2016 08:57:35 -0400 Subject: [PATCH 17/56] fixed race condition at startup --- Signature.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Signature.cpp b/Signature.cpp index 13612327..11fc8600 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -435,8 +435,13 @@ namespace crypto std::unique_ptr& GetEd25519 () { if (!g_Ed25519) - g_Ed25519.reset (new Ed25519()); - + { + auto c = new Ed25519(); + if (!g_Ed25519) // make sure it was not created already + g_Ed25519.reset (c); + else + delete c; + } return g_Ed25519; } From 97afa502c52fde5c5b265884ae916050c2dd249d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 Apr 2016 22:16:49 -0400 Subject: [PATCH 18/56] shard_ptr for SAMSession --- SAM.cpp | 36 ++++++++++++++++++++---------------- SAM.h | 8 ++++---- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index ecdd513d..dea3614e 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -47,19 +47,16 @@ namespace client break; case eSAMSocketTypeStream: { - if (m_Session) { + if (m_Session) m_Session->DelSocket (shared_from_this ()); - m_Session = nullptr; - } break; } case eSAMSocketTypeAcceptor: { if (m_Session) - { + { m_Session->DelSocket (shared_from_this ()); - m_Session->localDestination->StopAcceptingStreams (); - m_Session = nullptr; + m_Session->localDestination->StopAcceptingStreams (); } break; } @@ -68,6 +65,7 @@ namespace client } m_SocketType = eSAMSocketTypeTerminated; if (m_Socket.is_open()) m_Socket.close (); + m_Session = nullptr; } void SAMSocket::ReceiveHandshake () @@ -721,7 +719,7 @@ namespace client m_IsRunning = false; m_Acceptor.cancel (); for (auto it: m_Sessions) - delete it.second; + it.second->CloseStreams (); m_Sessions.clear (); m_Service.stop (); if (m_Thread) @@ -775,7 +773,7 @@ namespace client Accept (); } - SAMSession * SAMBridge::CreateSession (const std::string& id, const std::string& destination, + std::shared_ptr SAMBridge::CreateSession (const std::string& id, const std::string& destination, const std::map * params) { std::shared_ptr localDestination = nullptr; @@ -800,8 +798,9 @@ namespace client } if (localDestination) { + auto session = std::make_shared(localDestination); std::unique_lock l(m_SessionsMutex); - auto ret = m_Sessions.insert (std::pair(id, new SAMSession (localDestination))); + auto ret = m_Sessions.insert (std::make_pair(id, session)); if (!ret.second) LogPrint (eLogWarning, "SAM: Session ", id, " already exists"); return ret.first->second; @@ -811,19 +810,24 @@ namespace client void SAMBridge::CloseSession (const std::string& id) { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (id); - if (it != m_Sessions.end ()) + std::shared_ptr session; { - auto session = it->second; + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (id); + if (it != m_Sessions.end ()) + { + session = it->second; + m_Sessions.erase (it); + } + } + if (session) + { session->localDestination->StopAcceptingStreams (); session->CloseStreams (); - m_Sessions.erase (it); - delete session; } } - SAMSession * SAMBridge::FindSession (const std::string& id) const + std::shared_ptr SAMBridge::FindSession (const std::string& id) const { std::unique_lock l(m_SessionsMutex); auto it = m_Sessions.find (id); diff --git a/SAM.h b/SAM.h index 4cdea686..ef36f285 100644 --- a/SAM.h +++ b/SAM.h @@ -128,7 +128,7 @@ namespace client std::string m_ID; // nickname bool m_IsSilent; std::shared_ptr m_Stream; - SAMSession * m_Session; + std::shared_ptr m_Session; }; struct SAMSession @@ -176,10 +176,10 @@ namespace client void Stop (); boost::asio::io_service& GetService () { return m_Service; }; - SAMSession * CreateSession (const std::string& id, const std::string& destination, // empty string means transient + std::shared_ptr CreateSession (const std::string& id, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); - SAMSession * FindSession (const std::string& id) const; + std::shared_ptr FindSession (const std::string& id) const; private: @@ -200,7 +200,7 @@ namespace client boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket; mutable std::mutex m_SessionsMutex; - std::map m_Sessions; + std::map > m_Sessions; uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1]; public: From 941f30d1ea17c8bf63b856ee8d91e949804d11d7 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 4 Apr 2016 22:17:04 -0400 Subject: [PATCH 19/56] show streams from all streaming destinations --- Destination.cpp | 14 ++++++++++++++ Destination.h | 1 + HTTPServer.cpp | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index c53c4ee6..5893caff 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -780,5 +780,19 @@ namespace client } LogPrint(eLogError, "Destinations: Can't save keys to ", path); } + + std::vector > ClientDestination::GetAllStreams () const + { + std::vector > ret; + if (m_StreamingDestination) + { + for (auto& it: m_StreamingDestination->GetStreams ()) + ret.push_back (it.second); + } + for (auto& it: m_StreamingDestinationsByPorts) + for (auto& it1: it.second->GetStreams ()) + ret.push_back (it1.second); + return ret; + } } } diff --git a/Destination.h b/Destination.h index 44cb7424..3011b4cb 100644 --- a/Destination.h +++ b/Destination.h @@ -159,6 +159,7 @@ namespace client // for HTTP only int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; + std::vector > GetAllStreams () const; }; } } diff --git a/HTTPServer.cpp b/HTTPServer.cpp index f7efcba9..8db9d330 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -609,19 +609,19 @@ namespace util s << "Status"; s << ""; - for (auto it: dest->GetStreamingDestination ()->GetStreams ()) + for (auto it: dest->GetAllStreams ()) { s << ""; - s << "" << it.first << ""; - s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetRemoteIdentity ()) << ""; - s << "" << it.second->GetNumSentBytes () << ""; - s << "" << it.second->GetNumReceivedBytes () << ""; - s << "" << it.second->GetSendQueueSize () << ""; - s << "" << it.second->GetReceiveQueueSize () << ""; - s << "" << it.second->GetSendBufferSize () << ""; - s << "" << it.second->GetRTT () << ""; - s << "" << it.second->GetWindowSize () << ""; - s << "" << (int)it.second->GetStatus () << ""; + s << "" << it->GetSendStreamID () << ""; + s << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << ""; + s << "" << it->GetNumSentBytes () << ""; + s << "" << it->GetNumReceivedBytes () << ""; + s << "" << it->GetSendQueueSize () << ""; + s << "" << it->GetReceiveQueueSize () << ""; + s << "" << it->GetSendBufferSize () << ""; + s << "" << it->GetRTT () << ""; + s << "" << it->GetWindowSize () << ""; + s << "" << (int)it->GetStatus () << ""; s << "
\r\n" << std::endl; } } From f412f4ca883dd69839e3df8299b937774c4d6644 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 20/56] * use commented i2pd.conf as default --- debian/i2pd.conf | 19 ------------------- debian/i2pd.install | 2 +- docs/i2pd.conf | 4 ++-- 3 files changed, 3 insertions(+), 22 deletions(-) delete mode 100644 debian/i2pd.conf diff --git a/debian/i2pd.conf b/debian/i2pd.conf deleted file mode 100644 index 4a518916..00000000 --- a/debian/i2pd.conf +++ /dev/null @@ -1,19 +0,0 @@ -ipv6 - -[httpproxy] -address = 127.0.0.1 -port = 4444 - -# other services (disabled by default) -# -#[sam] -#address = 127.0.0.1 -#port = 7656 -# -#[bob] -#address = 127.0.0.1 -#port = 2827 -# -#[i2pcontrol] -#address = 127.0.0.1 -#port = 7650 diff --git a/debian/i2pd.install b/debian/i2pd.install index f4e7e4f1..2e3c93cd 100644 --- a/debian/i2pd.install +++ b/debian/i2pd.install @@ -1,5 +1,5 @@ i2pd usr/sbin/ -debian/i2pd.conf etc/i2pd/ +docs/i2pd.conf etc/i2pd/ debian/tunnels.conf etc/i2pd/ debian/subscriptions.txt etc/i2pd/ contrib/certificates/ usr/share/i2pd/ diff --git a/docs/i2pd.conf b/docs/i2pd.conf index e85eaa17..d4ea226a 100644 --- a/docs/i2pd.conf +++ b/docs/i2pd.conf @@ -69,8 +69,8 @@ port = 7070 ## Uncomment and set to 'false' to disable HTTP Proxy # enabled = true ## Address and port service will listen on -# address = 127.0.0.1 -# port = 4444 +address = 127.0.0.1 +port = 4444 ## Optional keys file for proxy local destination # keys = http-proxy-keys.dat From cb8333a48f0441bf553ce70b8b8436d0a51659ff Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 21/56] * update manpage --- debian/i2pd.1 | 107 +++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/debian/i2pd.1 b/debian/i2pd.1 index 2a1e7f88..f61e243e 100644 --- a/debian/i2pd.1 +++ b/debian/i2pd.1 @@ -5,7 +5,7 @@ i2pd \- Load-balanced unspoofable packet switching network .SH SYNOPSIS .B i2pd -[\fIOPTION1\fR) [\fIOPTION2\fR]... +[\fIOPTION1\fR] [\fIOPTION2\fR]... .SH DESCRIPTION i2pd @@ -18,59 +18,58 @@ network is both distributed and dynamic, with no trusted parties. Any of the configuration options below can be used in the \fBDAEMON_ARGS\fR variable in \fI/etc/default/i2pd\fR. .BR .TP -\fB\-\-host=\fR -The external IP (deprecated) -.TP -\fB\-\-port=\fR -The external port to listen on -.TP -\fB\-\-httpport=\fR -The HTTP port to listen on -.TP -\fB\-\-log=\fR[\fI1\fR|\fI0\fR] -.br -Enable of disable logging to a file. \fI1\fR for yes, \fI0\fR for no. (default: \fI0\fR, off) -.TP -\fB\-\-daemon=\fR[\fI1\fR|\fI0\fR] -Enable or disable daemon mode. Daemon mode is enabled with \fI1\fR and disabled with \fI0\fR. (default: \fI0\fR, off) -.TP -\fB\-\-service=\fR[\fI1\fR|\fI0\fR] -If enabled, system folders (\fB/var/run/i2pd.pid\fR, \fB/var/log/i2pd.log\fR, \fB/var/lib/i2pd\fR) will be used. If off, \fB$HOME/.i2pd\fR will be used instead. (default: \fI0\fR, off). -.TP -\fB\-\-unreachable=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if router is declared as unreachable and works through introducers. (default: \fI0\fR, off) -.TP -\fB\-\-v6=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if \fBi2pd\fR should communicate via IPv6. (default: \fI0\fR, off) -.TP -\fB\-\-floodfill=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if \fBi2pd\fR should become a floodfill. (default: \fI0\fR, off) -.TP -\fB\-\-bandwidth=\fR[\fI1\fR|\fI0\fR] -\fIL\fR if \fBi2pd\fR should be limited to 32KiB/s. Enabling floodfill will automatically set this to \fI0\fR (default: \fI0\fR, no limit) -.TP -\fB\-\-httpproxyport=\fR -The local port for the HTTP Proxy to listen on (default: \fI4446\fR) -.TP -\fB\-\-socksproxyport=\fR -The local port for the SOCKS proxy to listen on (default: \fI4447\fR) -.TP -\fB\-\-proxykeys=\fR -An optional keys file for tunnel local destination (both HTTP and SOCKS) -.TP -\fB\-\-samport=\fR -Port of SAM bridge. Usually \fI7656\fR. SAM will not be enabled if this is not set. (default: unset) -.TP -\fB\-\-bobport=\fR -Port of BOB command channel. Usually \fI2827\fR. BOB will not be enabled if this is not set. (default: unset) -.TP -\fB\-\-i2pcontrolport=\fR -Port of I2P control service. Usually \fI7650\fR. I2PControl will not be enabled if this is not set. (default: unset) +\fB\-\-help\fR +Show available options. .TP \fB\-\-conf=\fR Config file (default: \fI~/.i2pd/i2pd.conf\fR or \fI/var/lib/i2pd/i2pd.conf\fR) +.BR This parameter will be silently ignored if the specified config file does not exist. Options specified on the command line take precedence over those in the config file. +.TP +\fB\-\-tunconf=\fR +Tunnels config file (default: \fI~/.i2pd/tunnels.conf\fR or \fI/var/lib/i2pd/tunnels.conf\fR) +.TP +\fB\-\-pidfile=\fR +Where to write pidfile (don\'t write by default) +.TP +\fB\-\-log=\fR +Logs destination: \fIstdout\fR, \fIfile\fR, \fIsyslog\fR (\fIstdout\fR if not set, \fIfile\fR - otherwise, for compatibility) +.TP +\fB\-\-loglevel=\fR +Log messages above this level (\fIdebug\fR, \fBinfo\fR, \fIwarn\fR, \fIerror\fR) +.TP +\fB\-\-datadir=\fR +Path to storage of i2pd data (RI, keys, peer profiles, ...) +.TP +\fB\-\-host=\fR +The external IP address +.TP +\fB\-\-port=\fR +The port to listen on for incoming connections +.TP +\fB\-\-daemon\fR +Router will go to background after start +.TP +\fB\-\-service\fR +Router will use system folders like \fI/var/lib/i2pd\fR +.TP +\fB\-\-ipv6\fR +Enable communication through ipv6. false by default +.TP +\fB\-\-notransit\fR +Router will not accept transit tunnels at startup +.TP +\fB\-\-floodfill\fR +Router will be floodfill +.TP +\fB\-\-bandwidth=\fR +Bandwidth limit: integer in KBps or letter aliases: \fIL (32KBps)\fR, O (256), P (2048), X (>9000) +.TP +\fB\-\-family=\fR +Name of a family, router belongs to. +.PP +See service-specific parameters in page \fIdocs/configuration.md\fR or in example config file \fIdocs/i2pd.conf\fR .SH FILES .PP @@ -82,10 +81,10 @@ i2pd configuration files (when running as a system service) .PP /var/lib/i2pd/ .RS 4 -i2pd profile directory (when running as a system service, see \fB\-\-service=\fR above) +i2pd profile directory (when running as a system service, see \fB\-\-service\fR above) .RE .PP -$HOME/.i2pd +$HOME/.i2pd/ .RS 4 i2pd profile directory (when running as a normal user) .RE @@ -95,7 +94,9 @@ i2pd profile directory (when running as a normal user) default I2P hosts file .SH AUTHOR This manual page was written by kytv for the Debian system (but may be used by others). -.BR +.PP +Updated by hagen in 2016. +.PP Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation .BR -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL +On Debian systems, the complete text of the GNU General Public License can be found in \fI/usr/share/common-licenses/GPL\fR From b5875f3a0a9ab0efe64e46e5f1e3b4ade2c89e2c Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 22/56] * update year in copyrights --- debian/copyright | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/copyright b/debian/copyright index 117fcffd..606d059b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,9 +3,9 @@ Upstream-Name: i2pd Source: https://github.com/PurpleI2P Files: * -Copyright: 2013-2015 PurpleI2P +Copyright: 2013-2016 PurpleI2P License: BSD-3-clause - Copyright (c) 2013-2015, The PurpleI2P Project + Copyright (c) 2013-2016, The PurpleI2P Project . All rights reserved. . @@ -34,7 +34,7 @@ License: BSD-3-clause SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files: debian/* -Copyright: 2014-2015 hagen +Copyright: 2014-2016 hagen 2013-2015 Kill Your TV License: GPL-2.0+ This package is free software; you can redistribute it and/or modify From cc55335a8dc982dad2f951bcf5e025f9b76a5de2 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 23/56] * docs/configuration.md --- docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index f3e9f98c..ac5c4684 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -16,8 +16,8 @@ If you are upgrading your very old router (< 2.3.0) see also [this](config_opts_ * --logfile= - Path to logfile (default - autodetect) * --loglevel= - Log messages above this level (debug, *info, warn, error) * --datadir= - Path to storage of i2pd data (RI, keys, peer profiles, ...) -* --host= - The external IP -* --port= - The port to listen on +* --host= - Router external IP for incoming connections +* --port= - Port to listen for incoming connections (default: auto) * --daemon - Router will go to background after start * --service - Router will use system folders like '/var/lib/i2pd' * --ipv6 - Enable communication through ipv6. false by default From f63dd75f0876eb32c021041465108c31acda4748 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 24/56] * set bw limits thru i2pcontrol (#461) (experimental) --- I2PControl.cpp | 20 ++++++++++++++++++++ I2PControl.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/I2PControl.cpp b/I2PControl.cpp index 907fa2fd..1ef56c2d 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -83,6 +83,10 @@ namespace client m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler; m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler; m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler; + + // NetworkSetting + m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit; + m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit; } I2PControlService::~I2PControlService () @@ -496,6 +500,22 @@ namespace client } } + void I2PControlService::InboundBandwidthLimit (const std::string& value, std::ostringstream& results) + { + if (value != "null") + i2p::context.SetBandwidth (std::atoi(value.c_str())); + int bw = i2p::context.GetBandwidthLimit(); + InsertParam (results, "i2p.router.net.bw.in", bw); + } + + void I2PControlService::OutboundBandwidthLimit (const std::string& value, std::ostringstream& results) + { + if (value != "null") + i2p::context.SetBandwidth (std::atoi(value.c_str())); + int bw = i2p::context.GetBandwidthLimit(); + InsertParam (results, "i2p.router.net.bw.out", bw); + } + // certificate void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path) { diff --git a/I2PControl.h b/I2PControl.h index 714d3aa5..728c9925 100644 --- a/I2PControl.h +++ b/I2PControl.h @@ -94,6 +94,8 @@ namespace client // NetworkSetting typedef void (I2PControlService::*NetworkSettingRequestHandler)(const std::string& value, std::ostringstream& results); + void InboundBandwidthLimit (const std::string& value, std::ostringstream& results); + void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results); private: From 5f73f09836e04d83fd126cbf4c6b74925b7e0a71 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 25/56] * RouterInfo::SaveToFile() now returns bool --- RouterInfo.cpp | 21 +++++++++++---------- RouterInfo.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index dfd54059..8b12f591 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -514,19 +514,20 @@ namespace data m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen (); } - void RouterInfo::SaveToFile (const std::string& fullPath) + bool RouterInfo::SaveToFile (const std::string& fullPath) { m_FullPath = fullPath; - if (m_Buffer) - { - std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); - if (f.is_open ()) - f.write ((char *)m_Buffer, m_BufferLen); - else - LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); - } - else + if (!m_Buffer) { LogPrint (eLogError, "RouterInfo: Can't save, m_Buffer == NULL"); + return false; + } + std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); + if (!f.is_open ()) { + LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); + return false; + } + f.write ((char *)m_Buffer, m_BufferLen); + return true; } size_t RouterInfo::ReadString (char * str, std::istream& s) diff --git a/RouterInfo.h b/RouterInfo.h index 7648c6ba..c9881dd2 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -161,7 +161,7 @@ namespace data bool IsUpdated () const { return m_IsUpdated; }; void SetUpdated (bool updated) { m_IsUpdated = updated; }; - void SaveToFile (const std::string& fullPath); + bool SaveToFile (const std::string& fullPath); std::shared_ptr GetProfile () const; void SaveProfile () { if (m_Profile) m_Profile->Save (); }; From f48a7df80fc413e543822ddf20164488cd3d96e3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Apr 2016 10:22:32 -0400 Subject: [PATCH 26/56] recreate router.info if missing or malformed --- RouterContext.cpp | 24 ++++++++++++++++-------- RouterInfo.cpp | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index e50681d9..f35d8426 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -356,16 +356,24 @@ namespace i2p delete[] buf; } - i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); // TODO m_RouterInfo.SetRouterIdentity (GetIdentity ()); - m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); - m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION); - m_RouterInfo.SetProperty ("router.version", I2P_VERSION); + i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); + if (!routerInfo.IsUnreachable ()) // router.info looks good + { + m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); + m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION); + m_RouterInfo.SetProperty ("router.version", I2P_VERSION); + + // Migration to 0.9.24. TODO: remove later + m_RouterInfo.DeleteProperty ("coreVersion"); + m_RouterInfo.DeleteProperty ("stat_uptime"); + } + else + { + LogPrint (eLogError, ROUTER_INFO, " is malformed. Creating new"); + NewRouterInfo (); + } - // Migration to 0.9.24. TODO: remove later - m_RouterInfo.DeleteProperty ("coreVersion"); - m_RouterInfo.DeleteProperty ("stat_uptime"); - if (IsUnreachable ()) SetReachable (); // we assume reachable until we discover firewall through peer tests diff --git a/RouterInfo.cpp b/RouterInfo.cpp index dfd54059..9f590d74 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -104,6 +104,8 @@ namespace data { if (LoadFile ()) ReadFromBuffer (false); + else + m_IsUnreachable = true; } void RouterInfo::ReadFromBuffer (bool verifySignature) From 405aa906c5cffb3d7aba8da58ae7a28473806d6c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Apr 2016 13:18:25 -0400 Subject: [PATCH 27/56] short exponent for non-x64 --- Crypto.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 8416a337..b42dafa6 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -200,8 +200,11 @@ namespace crypto ctx = BN_CTX_new (); // select random k BIGNUM * k = BN_new (); - BN_rand_range (k, elgp); - if (BN_is_zero (k)) BN_one (k); +#if defined(__x86_64__) + BN_rand (k, 2048, -1, 1); // full exponent for x64 +#else + BN_rand (k, 226, -1, 1); // short exponent of 226 bits +#endif // caulculate a a = BN_new (); BN_mod_exp (a, elgg, k, elgp, ctx); From 86572265945b6ef2ea2d5bb8e60765d47cf663b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 15:49:46 -0400 Subject: [PATCH 28/56] use 226 bits private keys for non-x64 --- Crypto.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index b42dafa6..1dc8a2e5 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -146,6 +146,10 @@ namespace crypto } // DH/ElGamal + + const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; + const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg @@ -169,6 +173,10 @@ namespace crypto { if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; }; if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; }; +#if !defined(__x86_64__) // use short exponent for non x64 + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); +#endif DH_generate_key (m_DH); if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); @@ -201,9 +209,9 @@ namespace crypto // select random k BIGNUM * k = BN_new (); #if defined(__x86_64__) - BN_rand (k, 2048, -1, 1); // full exponent for x64 + BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 #else - BN_rand (k, 226, -1, 1); // short exponent of 226 bits + BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits #endif // caulculate a a = BN_new (); @@ -282,6 +290,14 @@ namespace crypto { #if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) RAND_bytes (priv, 256); +#else + // lower 226 bits (28 bytes and 2 bits) only. short exponent + auto numBytes = (ELGAMAL_SHORT_EXPONENT_NUM_BITS)/8 + 1; // 29 + auto numZeroBytes = 256 - numBytes; + RAND_bytes (priv + numZeroBytes, numBytes); + memset (priv, 0, numZeroBytes); + priv[numZeroBytes] &= 0x04; +#endif BN_CTX * ctx = BN_CTX_new (); BIGNUM * p = BN_new (); BN_bin2bn (priv, 256, p); @@ -289,11 +305,6 @@ namespace crypto bn2buf (p, pub, 256); BN_free (p); BN_CTX_free (ctx); -#else - DHKeys dh; - dh.GenerateKeys (priv, pub); - -#endif } // HMAC From 380c7b7720bb00aaa6670541462660fb0323b568 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 16:11:18 -0400 Subject: [PATCH 29/56] use 226 bits private keys for non-x64 --- Crypto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Crypto.cpp b/Crypto.cpp index 1dc8a2e5..0ec0f020 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -296,7 +296,7 @@ namespace crypto auto numZeroBytes = 256 - numBytes; RAND_bytes (priv + numZeroBytes, numBytes); memset (priv, 0, numZeroBytes); - priv[numZeroBytes] &= 0x04; + priv[numZeroBytes] &= 0x03; #endif BN_CTX * ctx = BN_CTX_new (); BIGNUM * p = BN_new (); From afe2935c9db67d62b1dd6e2694db9ac8e1f7fa52 Mon Sep 17 00:00:00 2001 From: xcps Date: Wed, 6 Apr 2016 16:33:23 -0400 Subject: [PATCH 30/56] webconsole update --- HTTPServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8db9d330..06fabc31 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -777,20 +777,20 @@ namespace util s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { - s << it.second->GetName () << " ⇐ "; 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\nServer Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetServerTunnels ()) { - s << it.second->GetName () << " ⇒ "; auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; + s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); s << "
\r\n"<< std::endl; From 2ebb2d8f0e7ec783e188645a96c4d252c60b671e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 21:02:58 -0400 Subject: [PATCH 31/56] fixed race condition --- Identity.cpp | 26 +++++++++++++++++--------- Identity.h | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index 0ca9567a..f221dd04 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -311,18 +311,18 @@ namespace data switch (keyType) { case SIGNING_KEY_TYPE_DSA_SHA1: - m_Verifier.reset (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); + UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); break; case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64 - m_Verifier.reset (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA384_P384: { size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96 - m_Verifier.reset (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: @@ -331,7 +331,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto::ECDSAP521Verifier (signingKey)); + UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA256_2048: @@ -340,7 +340,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA384_3072: @@ -349,7 +349,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA512_4096: @@ -358,20 +358,28 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 - m_Verifier.reset (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); break; } default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } } - + + void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const + { + if (!m_Verifier || !verifier) + m_Verifier.reset (verifier); + else + delete verifier; + } + void IdentityEx::DropVerifier () const { // TODO: potential race condition with Verify diff --git a/Identity.h b/Identity.h index 27da190d..d8abd6f4 100644 --- a/Identity.h +++ b/Identity.h @@ -95,6 +95,7 @@ namespace data private: void CreateVerifier () const; + void UpdateVerifier (i2p::crypto::Verifier * verifier) const; private: From c45aab7cefb75ee5b7f3802bd0b3a0b9a317a791 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 8 Apr 2016 15:45:23 -0400 Subject: [PATCH 32/56] precalculate g^x mod p table --- Crypto.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Crypto.cpp b/Crypto.cpp index 0ec0f020..9858d6fd 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -153,6 +153,32 @@ namespace crypto #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg + void PrecalculateElggTable (BIGNUM * table[][256], int len) // table is len's array of array of 256 bignums + { + if (len <= 0) return; + BN_CTX * ctx = BN_CTX_new (); + BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (montCtx, elgp, ctx); + BIGNUM * elggMont = BN_new (); + BN_from_montgomery(elggMont, elgg, montCtx, ctx); + for (int i = 0; i < len; i++) + { + table[i][0] = BN_new (); + if (!i) + BN_from_montgomery (table[0][0], BN_value_one (), montCtx, ctx); // 2^0 = 1 + else + BN_mod_mul_montgomery (table[i][0], table[i-1][255], elggMont, montCtx, ctx); + for (int j = 1; j < 256; j++) + { + table[i][j] = BN_new (); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], elggMont, montCtx, ctx); + } + } + BN_free (elggMont); + BN_MONT_CTX_free (montCtx); + BN_CTX_free (ctx); + } + // DH DHKeys::DHKeys (): m_IsUpdated (true) From ffc666eaaa5390019809f957412427b4d740f8e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 9 Apr 2016 22:44:13 -0400 Subject: [PATCH 33/56] g^x mod p using precalculated table --- Crypto.cpp | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 9858d6fd..6891e776 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -153,32 +153,62 @@ namespace crypto #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg - void PrecalculateElggTable (BIGNUM * table[][256], int len) // table is len's array of array of 256 bignums + void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); - BIGNUM * elggMont = BN_new (); - BN_from_montgomery(elggMont, elgg, montCtx, ctx); + BN_MONT_CTX_set (montCtx, elgp, ctx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_from_montgomery (table[0][0], BN_value_one (), montCtx, ctx); // 2^0 = 1 + BN_to_montgomery (table[0][0], elgg, montCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][255], elggMont, montCtx, ctx); - for (int j = 1; j < 256; j++) + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); + for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], elggMont, montCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); } } - BN_free (elggMont); BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } + BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) + // exp is in Big Endian + { + if (len <= 0) return nullptr; + BIGNUM * res = nullptr; + BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (montCtx, elgp, ctx); + for (int i = 0; i < len; i++) + { + if (res) + { + if (exp[i]) + BN_mod_mul_montgomery (res, res, table[len-1-i][exp[i]-1], montCtx, ctx); + } + else if (exp[i]) + res = BN_dup (table[len-i-1][exp[i]-1]); + } + if (res) + BN_from_montgomery (res, res, montCtx, ctx); + BN_MONT_CTX_free (montCtx); + return res; + } + + BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) + { + auto len = BN_num_bytes (exp); + uint8_t * buf = new uint8_t[len]; + BN_bn2bin (exp, buf); + auto ret = ElggPow (buf, len, table, ctx); + delete[] buf; + return ret; + } + // DH DHKeys::DHKeys (): m_IsUpdated (true) From 34a8d4a57d8d6cccf0fc6f40999f74b57eb30f2f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Apr 2016 17:06:02 -0400 Subject: [PATCH 34/56] use precalculated table for ElGamal encryption --- Crypto.cpp | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 6891e776..0523f55f 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -148,12 +148,15 @@ namespace crypto // DH/ElGamal const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; + const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg - void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums +#if !defined(__x86_64__) // use precalculated table + + static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); @@ -176,7 +179,17 @@ namespace crypto BN_CTX_free (ctx); } - BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) + static void DestroyElggTable (BIGNUM * table[][255], int len) + { + for (int i = 0; i < len; i++) + for (int j = 0; j < 255; j++) + { + BN_free (table[i][j]); + table[i][j] = nullptr; + } + } + + static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) // exp is in Big Endian { if (len <= 0) return nullptr; @@ -199,7 +212,7 @@ namespace crypto return res; } - BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) + static BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) { auto len = BN_num_bytes (exp); uint8_t * buf = new uint8_t[len]; @@ -208,6 +221,10 @@ namespace crypto delete[] buf; return ret; } + + BIGNUM * g_ElggTable[ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; + +#endif // DH @@ -229,9 +246,9 @@ namespace crypto { if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; }; if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; }; -#if !defined(__x86_64__) // use short exponent for non x64 +#if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); - BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); + BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); #endif DH_generate_key (m_DH); if (priv) bn2buf (m_DH->priv_key, priv, 256); @@ -266,12 +283,14 @@ namespace crypto BIGNUM * k = BN_new (); #if defined(__x86_64__) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 -#else - BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits -#endif - // caulculate a + // calculate a a = BN_new (); BN_mod_exp (a, elgg, k, elgp, ctx); +#else + BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits + // calculate a + a = ElggPow (k, g_ElggTable, ctx); +#endif BIGNUM * y = BN_new (); BN_bin2bn (key, 256, y); // calculate b1 @@ -772,10 +791,16 @@ namespace crypto for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); CRYPTO_set_locking_callback (OpensslLockingCallback);*/ +#if !defined(__x86_64__) + PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); +#endif } void TerminateCrypto () { +#if !defined(__x86_64__) + DestroyElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); +#endif /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } From 6a9d2ba653e1f99e4591908bed5f01c2baaeb4a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Apr 2016 21:16:18 -0400 Subject: [PATCH 35/56] use precalculated table for DH --- Crypto.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 0523f55f..fbd3e139 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -155,27 +155,27 @@ namespace crypto #define elgg GetCryptoConstants ().elgg #if !defined(__x86_64__) // use precalculated table - + + static BN_MONT_CTX * g_MontCtx = nullptr; static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); - BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); + g_MontCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (g_MontCtx, elgp, ctx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_to_montgomery (table[0][0], elgg, montCtx, ctx); + BN_to_montgomery (table[0][0], elgg, g_MontCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], g_MontCtx, ctx); for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], g_MontCtx, ctx); } } - BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } @@ -187,15 +187,16 @@ namespace crypto BN_free (table[i][j]); table[i][j] = nullptr; } + BN_MONT_CTX_free (g_MontCtx); } static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) // exp is in Big Endian { if (len <= 0) return nullptr; + auto montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_copy (montCtx, g_MontCtx); BIGNUM * res = nullptr; - BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); for (int i = 0; i < len; i++) { if (res) @@ -249,8 +250,12 @@ namespace crypto #if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); -#endif + auto ctx = BN_CTX_new (); + m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); + BN_CTX_free (ctx); +#else DH_generate_key (m_DH); +#endif if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); m_IsUpdated = true; From 6336d38a3ea14bafdb5d34f36b9dd2cd80838aa5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 11 Apr 2016 12:04:15 -0400 Subject: [PATCH 36/56] Removed downloads. Added Docimentation --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4f167754..b985abf4 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,11 @@ Donations BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59 ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z +DOGE: DNXLQKziRPAsD9H3DFNjk4fLQrdaSX893Y -Downloads ------------- - -Official binary releases could be found at: -http://i2pd.website/releases/ -older releases -http://download.i2p.io/purplei2p/i2pd/releases/ +Documentation: +-------------- +http://i2pd.readthedocs.org Supported OS ------------ From d15cc7cc4766e766fe56b3f41b4ea9817a0cfeaa Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 11 Apr 2016 12:39:32 -0400 Subject: [PATCH 37/56] changed tray icon back to ictoopie --- Win32/Resource.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Win32/Resource.rc b/Win32/Resource.rc index bdc532e9..c885c044 100644 --- a/Win32/Resource.rc +++ b/Win32/Resource.rc @@ -52,8 +52,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -//MAINICON ICON "ictoopie.ico" -MAINICON ICON "anke.ico" +MAINICON ICON "ictoopie.ico" +//MAINICON ICON "anke.ico" MASCOT BITMAP "Anke_700px.bmp" From c0b0df34d2817034b4775b6626198a966f543432 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Apr 2016 19:07:11 -0400 Subject: [PATCH 38/56] clean montgomery context --- Crypto.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index fbd3e139..fe6dfa8f 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -163,19 +163,22 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); g_MontCtx = BN_MONT_CTX_new (); BN_MONT_CTX_set (g_MontCtx, elgp, ctx); + auto montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_copy (montCtx, g_MontCtx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_to_montgomery (table[0][0], elgg, g_MontCtx, ctx); + BN_to_montgomery (table[0][0], elgg, montCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], g_MontCtx, ctx); + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], g_MontCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); } } + BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } From ef106f3232ed1bb99994c61e7b10edb1a3e0870a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 13 Apr 2016 11:22:08 -0400 Subject: [PATCH 39/56] fixed typo --- TunnelEndpoint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index a3907ce5..842b624f 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -119,7 +119,7 @@ namespace tunnel if (ret.second) HandleOutOfSequenceFragment (msgID, ret.first->second); else - LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, "already exists"); + LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists"); } else { From a4773d259da5d61c39ea1539d61634e0a2a02b6f Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 40/56] * use std::to_string() instead boost's function --- HTTPServer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 06fabc31..7a15eaa4 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "Base.h" #include "FS.h" @@ -911,7 +910,7 @@ namespace util m_Reply.headers[0].name = "Date"; m_Reply.headers[0].value = std::string(time_buff); m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = boost::lexical_cast(m_Reply.content.size()); + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); m_Reply.headers[2].name = "Content-Type"; m_Reply.headers[2].value = "text/html"; } From 5d38693b4dd7456b0e88c63f4f907db75e3ec526 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 41/56] * HTTPServer : fold namespace to two constants --- HTTPServer.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7a15eaa4..86808e25 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -23,7 +23,6 @@ namespace i2p { namespace util { - const std::string HTTPConnection::itoopieImage = "\"ICToopie HTTPConnection::reply::to_buffers(int status) { std::vector buffers; @@ -236,17 +228,17 @@ namespace util default: status_string += "WTF"; } buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); for (std::size_t i = 0; i < headers.size(); ++i) { header& h = headers[i]; buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); + buffers.push_back(boost::asio::buffer(HTTP_HEADER_KV_SEP)); buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); } - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); } buffers.push_back(boost::asio::buffer(content)); return buffers; @@ -977,6 +969,3 @@ namespace util } } } - - - From a5c0b48b575f99a648885bd85b960092cf7d5877 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 42/56] * HandleDestinationRequestTimeout() : readable code --- HTTPServer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 86808e25..2d69ae7a 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -846,11 +846,13 @@ namespace util if (ecode != boost::asio::error::operation_aborted) { auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination); - if (leaseSet && !leaseSet->IsExpired ()) + if (leaseSet && !leaseSet->IsExpired ()) { SendToDestination (leaseSet, port, buf, len); - else - // still no LeaseSet - SendReply (leaseSet ? "" + itoopieImage + "
\r\nLeases expired" : "" + itoopieImage + "LeaseSet not found", 504); + } else if (leaseSet) { + SendReply ("" + itoopieImage + "
\r\nLeaseSet expired", 504); + } else { + SendReply ("" + itoopieImage + "
\r\nLeaseSet not found", 504); + } } } From 87dd890eb054aabee7e6082d9dc50c91180b95d0 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 43/56] * HTTPConnection::reply : to_buffers() -> to_string() --- HTTPServer.cpp | 49 ++++++++++++++++++++----------------------------- HTTPServer.h | 2 +- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 2d69ae7a..4b426aa9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -206,42 +206,33 @@ namespace util const char HTTP_HEADER_KV_SEP[] = ": "; const char HTTP_CRLF[] = "\r\n"; - std::vector HTTPConnection::reply::to_buffers(int status) + std::string HTTPConnection::reply::to_string(int code) { - std::vector buffers; + std::stringstream ss(""); if (headers.size () > 0) { - status_string = "HTTP/1.1 "; - status_string += std::to_string (status); - status_string += " "; - switch (status) + const char *status; + switch (code) { - case 105: status_string += "Name Not Resolved"; break; - case 200: status_string += "OK"; break; - case 400: status_string += "Bad Request"; break; - case 404: status_string += "Not Found"; break; - case 408: status_string += "Request Timeout"; break; - case 500: status_string += "Internal Server Error"; break; - case 502: status_string += "Bad Gateway"; break; - case 503: status_string += "Not Implemented"; break; - case 504: status_string += "Gateway Timeout"; break; - default: status_string += "WTF"; + case 105: status = "Name Not Resolved"; break; + case 200: status = "OK"; break; + case 400: status = "Bad Request"; break; + case 404: status = "Not Found"; break; + case 408: status = "Request Timeout"; break; + case 500: status = "Internal Server Error"; break; + case 502: status = "Bad Gateway"; break; + case 503: status = "Not Implemented"; break; + case 504: status = "Gateway Timeout"; break; + default: status = "WTF"; } - buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); - - for (std::size_t i = 0; i < headers.size(); ++i) - { - header& h = headers[i]; - buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(HTTP_HEADER_KV_SEP)); - buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); + ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; + for (header & h : headers) { + ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; } - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); + ss << HTTP_CRLF; /* end of headers */ } - buffers.push_back(boost::asio::buffer(content)); - return buffers; + ss << content; + return ss.str(); } void HTTPConnection::Terminate () diff --git a/HTTPServer.h b/HTTPServer.h index f70e27dc..8dd40dea 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -40,7 +40,7 @@ namespace util { std::vector
headers; std::string status_string, content; - std::vector to_buffers (int status); + std::string to_string (int status); }; public: From 04bfd52fba8107bec4c5438c2bfc649f96ced768 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 44/56] * HTTPConnection::SendReply() : cleaner code --- HTTPServer.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 4b426aa9..b54f55e8 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -885,22 +885,23 @@ namespace util void HTTPConnection::SendReply (const std::string& content, int status) { - m_Reply.content = content; + // we need the date header to be complaint with http 1.1 + std::time_t time_now = std::time(nullptr); + char time_buff[128]; + std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); + /* fill reply with headers */ m_Reply.headers.resize(3); - // we need the date header to be complaint with http 1.1 - std::time_t time_now = std::time(nullptr); - char time_buff[128]; - if (std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now))) - { - m_Reply.headers[0].name = "Date"; - m_Reply.headers[0].value = std::string(time_buff); - m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); - m_Reply.headers[2].name = "Content-Type"; - m_Reply.headers[2].value = "text/html"; - } - - boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), + m_Reply.headers[0].name = "Date"; + m_Reply.headers[0].value = std::string(time_buff); + m_Reply.headers[1].name = "Content-Length"; + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); + m_Reply.headers[2].name = "Content-Type"; + m_Reply.headers[2].value = "text/html"; + + std::vector buffers; + buffers.push_back(boost::asio::buffer(m_Reply.to_string(status))); + buffers.push_back(boost::asio::buffer(content)); + boost::asio::async_write (*m_Socket, buffers, std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } From 3f9d2601b41a95e4630e2e538602503a8e76a726 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 45/56] + HTTPConnection::SendError() --- HTTPServer.cpp | 13 +++++++++---- HTTPServer.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index b54f55e8..66506908 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -813,7 +813,7 @@ namespace util if (!i2p::client::context.GetAddressBook ().GetIdentHash (address, destination)) { LogPrint (eLogWarning, "HTTPServer: Unknown address ", address); - SendReply ("" + itoopieImage + "
\r\nUnknown address " + address + "", 404); + SendError ("Unknown address " + address); return; } @@ -840,9 +840,9 @@ namespace util if (leaseSet && !leaseSet->IsExpired ()) { SendToDestination (leaseSet, port, buf, len); } else if (leaseSet) { - SendReply ("" + itoopieImage + "
\r\nLeaseSet expired", 504); + SendError ("LeaseSet expired"); } else { - SendReply ("" + itoopieImage + "
\r\nLeaseSet not found", 504); + SendError ("LeaseSet not found"); } } } @@ -877,7 +877,7 @@ namespace util else { if (ecode == boost::asio::error::timed_out) - SendReply ("" + itoopieImage + "
\r\nNot responding", 504); + SendError ("Host not responding"); else if (ecode != boost::asio::error::operation_aborted) Terminate (); } @@ -905,6 +905,11 @@ namespace util std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } + void HTTPConnection::SendError(const std::string& content) + { + SendReply ("" + itoopieImage + "
\r\n" + content + "", 504); + } + HTTPServer::HTTPServer (const std::string& address, int port): m_Thread (nullptr), m_Work (m_Service), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)) diff --git a/HTTPServer.h b/HTTPServer.h index 8dd40dea..d5cef8ad 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -59,6 +59,7 @@ namespace util void HandleWriteReply(const boost::system::error_code& ecode); void HandleWrite (const boost::system::error_code& ecode); void SendReply (const std::string& content, int status = 200); + void SendError (const std::string& message); void HandleRequest (const std::string& address); void HandleCommand (const std::string& command, std::stringstream& s); From bce2a63772532d15de617c059f24bbe86c333cbf Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 14 Apr 2016 14:05:25 -0400 Subject: [PATCH 46/56] rollback some changes --- HTTPServer.cpp | 90 +++++++++++++++++++++++++++++--------------------- HTTPServer.h | 2 +- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 66506908..6c2c6112 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -203,36 +203,51 @@ namespace util const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels"; const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices="; const char HTTP_PARAM_ADDRESS[] = "address"; - const char HTTP_HEADER_KV_SEP[] = ": "; - const char HTTP_CRLF[] = "\r\n"; - std::string HTTPConnection::reply::to_string(int code) + namespace misc_strings { - std::stringstream ss(""); + + const char name_value_separator[] = { ':', ' ' }; + const char crlf[] = { '\r', '\n' }; + + } // namespace misc_strings + + std::vector HTTPConnection::reply::to_buffers(int status) + { + std::vector buffers; if (headers.size () > 0) { - const char *status; - switch (code) + status_string = "HTTP/1.1 "; + status_string += std::to_string (status); + status_string += " "; + switch (status) { - case 105: status = "Name Not Resolved"; break; - case 200: status = "OK"; break; - case 400: status = "Bad Request"; break; - case 404: status = "Not Found"; break; - case 408: status = "Request Timeout"; break; - case 500: status = "Internal Server Error"; break; - case 502: status = "Bad Gateway"; break; - case 503: status = "Not Implemented"; break; - case 504: status = "Gateway Timeout"; break; - default: status = "WTF"; + case 105: status_string += "Name Not Resolved"; break; + case 200: status_string += "OK"; break; + case 400: status_string += "Bad Request"; break; + case 404: status_string += "Not Found"; break; + case 408: status_string += "Request Timeout"; break; + case 500: status_string += "Internal Server Error"; break; + case 502: status_string += "Bad Gateway"; break; + case 503: status_string += "Not Implemented"; break; + case 504: status_string += "Gateway Timeout"; break; + default: status_string += "WTF"; } - ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; - for (header & h : headers) { - ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; + buffers.push_back(boost::asio::buffer(status_string, status_string.size())); + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + + for (std::size_t i = 0; i < headers.size(); ++i) + { + header& h = headers[i]; + buffers.push_back(boost::asio::buffer(h.name)); + buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); + buffers.push_back(boost::asio::buffer(h.value)); + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } - ss << HTTP_CRLF; /* end of headers */ + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } - ss << content; - return ss.str(); + buffers.push_back(boost::asio::buffer(content)); + return buffers; } void HTTPConnection::Terminate () @@ -885,23 +900,22 @@ namespace util void HTTPConnection::SendReply (const std::string& content, int status) { - // we need the date header to be complaint with http 1.1 - std::time_t time_now = std::time(nullptr); - char time_buff[128]; - std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); - /* fill reply with headers */ + m_Reply.content = content; m_Reply.headers.resize(3); - m_Reply.headers[0].name = "Date"; - m_Reply.headers[0].value = std::string(time_buff); - m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); - m_Reply.headers[2].name = "Content-Type"; - m_Reply.headers[2].value = "text/html"; - - std::vector buffers; - buffers.push_back(boost::asio::buffer(m_Reply.to_string(status))); - buffers.push_back(boost::asio::buffer(content)); - boost::asio::async_write (*m_Socket, buffers, + // we need the date header to be complaint with http 1.1 + std::time_t time_now = std::time(nullptr); + char time_buff[128]; + if (std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now))) + { + m_Reply.headers[0].name = "Date"; + m_Reply.headers[0].value = std::string(time_buff); + m_Reply.headers[1].name = "Content-Length"; + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); + m_Reply.headers[2].name = "Content-Type"; + m_Reply.headers[2].value = "text/html"; + } + + boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } diff --git a/HTTPServer.h b/HTTPServer.h index d5cef8ad..66083d85 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -40,7 +40,7 @@ namespace util { std::vector
headers; std::string status_string, content; - std::string to_string (int status); + std::vector to_buffers (int status); }; public: From aff8cd478c6318dadf594acf9cfe408c869e108c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Apr 2016 16:57:58 -0400 Subject: [PATCH 47/56] optional elgamal precomputation for x64 --- Config.cpp | 12 ++++++++++ Crypto.cpp | 65 ++++++++++++++++++++++++++++++++++++------------------ Crypto.h | 2 +- Daemon.cpp | 3 ++- api.cpp | 6 ++++- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Config.cpp b/Config.cpp index 8d42895a..d5ff2a46 100644 --- a/Config.cpp +++ b/Config.cpp @@ -180,6 +180,17 @@ namespace config { ("i2pcontrol.key", value()->default_value("i2pcontrol.key.pem"), "I2PCP connection cerificate key") ; + options_description precomputation("Precomputation options"); + precomputation.add_options() + ("precomputation.elgamal", +#if defined(__x86_64__) + value()->default_value(false), +#else + value()->default_value(true), +#endif + "Enable or disable elgamal precomputation table") + ; + m_OptionsDesc .add(general) .add(httpserver) @@ -188,6 +199,7 @@ namespace config { .add(sam) .add(bob) .add(i2pcontrol) + .add(precomputation) ; } diff --git a/Crypto.cpp b/Crypto.cpp index fe6dfa8f..f7c00595 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -150,12 +150,11 @@ namespace crypto const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; - + const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg -#if !defined(__x86_64__) // use precalculated table - static BN_MONT_CTX * g_MontCtx = nullptr; static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { @@ -226,9 +225,7 @@ namespace crypto return ret; } - BIGNUM * g_ElggTable[ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; - -#endif + static BIGNUM * (* g_ElggTable)[255] = nullptr; // DH @@ -253,12 +250,20 @@ namespace crypto #if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); - auto ctx = BN_CTX_new (); - m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); - BN_CTX_free (ctx); -#else - DH_generate_key (m_DH); #endif + if (g_ElggTable) + { +#if defined(__x86_64__) + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1); +#endif + auto ctx = BN_CTX_new (); + m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); + BN_CTX_free (ctx); + } + else + DH_generate_key (m_DH); + if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); m_IsUpdated = true; @@ -291,14 +296,16 @@ namespace crypto BIGNUM * k = BN_new (); #if defined(__x86_64__) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 - // calculate a - a = BN_new (); - BN_mod_exp (a, elgg, k, elgp, ctx); #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits +#endif // calculate a - a = ElggPow (k, g_ElggTable, ctx); -#endif + a = BN_new (); + if (g_ElggTable) + a = ElggPow (k, g_ElggTable, ctx); + else + BN_mod_exp (a, elgg, k, elgp, ctx); + BIGNUM * y = BN_new (); BN_bin2bn (key, 256, y); // calculate b1 @@ -792,23 +799,37 @@ namespace crypto } }*/ - void InitCrypto () + void InitCrypto (bool precomputation) { SSL_library_init (); /* auto numLocks = CRYPTO_num_locks(); for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); CRYPTO_set_locking_callback (OpensslLockingCallback);*/ -#if !defined(__x86_64__) - PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); + if (precomputation) + { +#if defined(__x86_64__) + g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); +#else + g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); #endif + } } void TerminateCrypto () { -#if !defined(__x86_64__) - DestroyElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); -#endif + if (g_ElggTable) + { + DestroyElggTable (g_ElggTable, +#if defined(__x86_64__) + ELGAMAL_FULL_EXPONENT_NUM_BYTES +#else + ELGAMAL_SHORT_EXPONENT_NUM_BYTES +#endif + ); + } /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } diff --git a/Crypto.h b/Crypto.h index e633f8bf..e333940e 100644 --- a/Crypto.h +++ b/Crypto.h @@ -273,7 +273,7 @@ namespace crypto #endif }; - void InitCrypto (); + void InitCrypto (bool precomputation); void TerminateCrypto (); } } diff --git a/Daemon.cpp b/Daemon.cpp index f15fe3e3..0924b236 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -117,7 +117,8 @@ namespace i2p LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); - i2p::crypto::InitCrypto (); + bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); + i2p::crypto::InitCrypto (precomputation); i2p::context.Init (); uint16_t port; i2p::config::GetOption("port", port); diff --git a/api.cpp b/api.cpp index 64648743..1828901b 100644 --- a/api.cpp +++ b/api.cpp @@ -28,7 +28,11 @@ namespace api i2p::fs::DetectDataDir(datadir, false); i2p::fs::Init(); - i2p::crypto::InitCrypto (); +#if defined(__x86_64__) + i2p::crypto::InitCrypto (false); +#else + i2p::crypto::InitCrypto (true); +#endif i2p::context.Init (); } From aff65083cc779dec6847bc900c65d27dc1cf39cc Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Apr 2016 17:03:56 -0400 Subject: [PATCH 48/56] precomputation.elgamal --- docs/configuration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index ac5c4684..14db728a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -59,7 +59,9 @@ All options below still possible in cmdline, but better write it in config file: * --i2pcontrol.address= - The address to listen on (I2P control service) * --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified -* --i2pcontrol.enabled= - If I2P control is enabled. false by default +* --i2pcontrol.enabled= - If I2P control is enabled. false by default + +* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default Config files ------------ From c265bd6c4d455b89e443542571cbf3f9e5043dd5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Apr 2016 21:07:45 -0400 Subject: [PATCH 49/56] delete pre-calculated tablle upon termination --- Crypto.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Crypto.cpp b/Crypto.cpp index f7c00595..742296f5 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -828,7 +828,8 @@ namespace crypto #else ELGAMAL_SHORT_EXPONENT_NUM_BYTES #endif - ); + ); + delete[] g_ElggTable; g_ElggTable = nullptr; } /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ From bb656ce44b638dd3e7822dacba4d840793329bb3 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:12:14 +0200 Subject: [PATCH 50/56] added some limits options --- Config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Config.cpp b/Config.cpp index d5ff2a46..41236014 100644 --- a/Config.cpp +++ b/Config.cpp @@ -130,6 +130,13 @@ namespace config { ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; + options_description limits("Limits options"); + limits.add_options() + ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") + ("limits.router", value()->default_value(4096), "Maximum active router sessions (default:4096)") + ("limits.client", value()->default_value(1024), "Maximum active client sessions (default:1024)") + ("limits.floodfill", value()->default_value(1024), "Maximum active floodfill sessions (default:1024)") + ; options_description httpserver("HTTP Server options"); httpserver.add_options() From 8456c8b47b56e37d655660c5d8c0e16a79aa19bc Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:22:04 +0200 Subject: [PATCH 51/56] limits options --- Config.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Config.cpp b/Config.cpp index 41236014..af399bd4 100644 --- a/Config.cpp +++ b/Config.cpp @@ -133,9 +133,6 @@ namespace config { options_description limits("Limits options"); limits.add_options() ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") - ("limits.router", value()->default_value(4096), "Maximum active router sessions (default:4096)") - ("limits.client", value()->default_value(1024), "Maximum active client sessions (default:1024)") - ("limits.floodfill", value()->default_value(1024), "Maximum active floodfill sessions (default:1024)") ; options_description httpserver("HTTP Server options"); From 9a860341626462d5c725bb14e4da0f57ffc33777 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:24:50 +0200 Subject: [PATCH 52/56] limits options --- Config.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Config.cpp b/Config.cpp index af399bd4..922ce236 100644 --- a/Config.cpp +++ b/Config.cpp @@ -130,9 +130,10 @@ namespace config { ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; + options_description limits("Limits options"); limits.add_options() - ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") + ("limits.transittunnels", value()->default_value(2500), "Maximum active transit sessions (default:2500)") ; options_description httpserver("HTTP Server options"); From e120e9a78eb9eba3914f4e28e90006705c82703e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Apr 2016 14:53:50 -0400 Subject: [PATCH 53/56] configurable transit tunnels limit --- Config.cpp | 1 + Daemon.cpp | 2 ++ I2NPProtocol.cpp | 12 +++++++++++- I2NPProtocol.h | 5 +++-- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Config.cpp b/Config.cpp index 922ce236..d7cef879 100644 --- a/Config.cpp +++ b/Config.cpp @@ -198,6 +198,7 @@ namespace config { m_OptionsDesc .add(general) + .add(limits) .add(httpserver) .add(httpproxy) .add(socksproxy) diff --git a/Daemon.cpp b/Daemon.cpp index 0924b236..81bbcdd5 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -141,6 +141,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); i2p::context.SetAcceptsTunnels (!transit); + uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); + SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); if (isFloodfill) { diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 7cebf96a..9674fdca 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -286,6 +286,16 @@ namespace i2p return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo } + static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO: + void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) + { + if (maxNumTransitTunnels > 0 && maxNumTransitTunnels <= 10000 && g_MaxNumTransitTunnels != maxNumTransitTunnels) + { + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + g_MaxNumTransitTunnels = maxNumTransitTunnels; + } + } + bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) @@ -298,7 +308,7 @@ namespace i2p i2p::crypto::ElGamalDecrypt (i2p::context.GetEncryptionPrivateKey (), record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText); // replace record to reply if (i2p::context.AcceptsTunnels () && - i2p::tunnel::tunnels.GetTransitTunnels ().size () <= MAX_NUM_TRANSIT_TUNNELS && + i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && !i2p::transport::transports.IsBandwidthExceeded ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 6450e958..cf8f4266 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -97,8 +97,6 @@ namespace i2p const uint8_t DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP = 0x08; // 1000 const uint8_t DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP = 0x0C; // 1100 - const unsigned int MAX_NUM_TRANSIT_TUNNELS = 2500; - namespace tunnel { class InboundTunnel; @@ -259,6 +257,9 @@ namespace tunnel std::vector > m_TunnelMsgs, m_TunnelGatewayMsgs; }; + + const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500; + void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); } #endif From 4431d5063541451258cf19bd8886f6107efb74a4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Apr 2016 15:02:11 -0400 Subject: [PATCH 54/56] limits.transittunnels --- docs/configuration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 14db728a..2a639be3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -61,7 +61,9 @@ All options below still possible in cmdline, but better write it in config file: * --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified * --i2pcontrol.enabled= - If I2P control is enabled. false by default -* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default +* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default + +* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default Config files ------------ From d582c30f6e45f6a47bfcdc1e7608bb03ecd2dc6d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Apr 2016 17:32:24 -0400 Subject: [PATCH 55/56] allow same port at different interfaces --- ClientContext.cpp | 5 +++-- ClientContext.h | 6 +++--- I2PService.h | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 59f11f21..2eb81af2 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -328,7 +328,8 @@ namespace client localDestination = CreateNewLocalDestination (k, false, &options); } auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); - if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr(clientTunnel))).second) + if (m_ClientTunnels.insert (std::make_pair (clientTunnel->GetAcceptor ().local_endpoint (), + std::unique_ptr(clientTunnel))).second) clientTunnel->Start (); else LogPrint (eLogError, "Clients: I2P client tunnel with port ", port, " already exists"); @@ -382,7 +383,7 @@ namespace client serverTunnel->SetAccessList (idents); } if (m_ServerTunnels.insert (std::make_pair ( - std::make_tuple (localDestination->GetIdentHash (), inPort), + std::make_pair (localDestination->GetIdentHash (), inPort), std::unique_ptr(serverTunnel))).second) serverTunnel->Start (); else diff --git a/ClientContext.h b/ClientContext.h index a05c2161..3381228b 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -2,9 +2,9 @@ #define CLIENT_CONTEXT_H__ #include -#include #include #include +#include #include "Destination.h" #include "HTTPProxy.h" #include "SOCKS.h" @@ -78,8 +78,8 @@ namespace client i2p::proxy::HTTPProxy * m_HttpProxy; i2p::proxy::SOCKSProxy * m_SocksProxy; - std::map > m_ClientTunnels; // port->tunnel - std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel + std::map > m_ClientTunnels; // local endpoint->tunnel + std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel SAMBridge * m_SamBridge; BOBCommandChannel * m_BOBCommandChannel; diff --git a/I2PService.h b/I2PService.h index 251a379a..2df11909 100644 --- a/I2PService.h +++ b/I2PService.h @@ -118,6 +118,9 @@ namespace client void Start (); //If you override this make sure you call it from the children void Stop (); + + const boost::asio::ip::tcp::acceptor& GetAcceptor () const { return m_Acceptor; }; + protected: virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } From 85840872ab50fe7e1af312d51912a3ebba3362f9 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Tue, 26 Apr 2016 19:39:10 +0200 Subject: [PATCH 56/56] family: volatile.crt --- contrib/certificates/family/volatile.crt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 contrib/certificates/family/volatile.crt diff --git a/contrib/certificates/family/volatile.crt b/contrib/certificates/family/volatile.crt new file mode 100644 index 00000000..928c7f39 --- /dev/null +++ b/contrib/certificates/family/volatile.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxDCCAWmgAwIBAgIJAJnJIdKHYwWcMAoGCCqGSM49BAMCMGcxCzAJBgNVBAYT +AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn +aXRzIFB0eSBMdGQxIDAeBgNVBAMMF3ZvbGF0aWxlLmZhbWlseS5pMnAubmV0MB4X +DTE2MDQyNjE1MjAyNloXDTI2MDQyNDE1MjAyNlowZzELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDEgMB4GA1UEAwwXdm9sYXRpbGUuZmFtaWx5LmkycC5uZXQwWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAARf6LBfbbfL6HInvC/4wAGaN3rj0eeLE/OdBpA93R3L +s8EUp0YTEJHWPo9APiKMmAwQSsMJfjhNrbp+UWEnnx2LMAoGCCqGSM49BAMCA0kA +MEYCIQDpQu2KPV5G1JOFLoZvdj+rcvEnjxM/FxkaqikwkVx8FAIhANP7DkUal+GT +SuiCtcqM4QyIBsfsCJBWEMzovft164Bo +-----END CERTIFICATE-----