From 63f4cf3d07d392f18a63ee2cfd008eae49a1e75e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Jul 2016 11:10:10 -0400 Subject: [PATCH 01/34] graceful shutdown for windows --- Win32/Win32App.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 01432381..cd9837ba 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -2,6 +2,7 @@ #include #include #include "../Config.h" +#include "../RouterContext.h" #include "../version.h" #include "resource.h" #include "Win32App.h" @@ -15,10 +16,13 @@ #define ID_EXIT 2001 #define ID_CONSOLE 2002 #define ID_APP 2003 +#define ID_GRACEFUL_SHUTDOWN 2004 #define ID_TRAY_ICON 2050 #define WM_TRAYICON (WM_USER + 1) +#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100 + namespace i2p { namespace win32 @@ -30,6 +34,7 @@ namespace win32 InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); @@ -82,6 +87,7 @@ namespace win32 case WM_CLOSE: { RemoveTrayIcon (hWnd); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); PostQuitMessage (0); break; } @@ -101,6 +107,12 @@ namespace win32 PostMessage (hWnd, WM_CLOSE, 0, 0); return 0; } + case ID_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (false); + SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes + return 0; + } case ID_CONSOLE: { char buf[30]; @@ -167,6 +179,15 @@ namespace win32 } break; } + case WM_TIMER: + { + if (wParam == IDT_GRACEFUL_SHUTDOWN_TIMER) + { + PostMessage (hWnd, WM_CLOSE, 0, 0); // exit + return 0; + } + break; + } } return DefWindowProc( hWnd, uMsg, wParam, lParam); } From 183c22cc848ec8f08b1505a76aeeb6b8e7b7c863 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Jul 2016 11:22:53 -0400 Subject: [PATCH 02/34] rollback --- Makefile.mingw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.mingw b/Makefile.mingw index 5cf16bf5..85b6b455 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -9,7 +9,7 @@ LDFLAGS = -Wl,-rpath,/usr/local/lib \ -L/usr/local/lib # UPNP Support -ifeq ($(USE_UPNP),yes) +ifeq ($(USE_UPNP),yes) CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB LDLIBS = -Wl,-Bstatic -lminiupnpc endif @@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) endif -ifeq ($(USE_AESNI),yes) +ifeq ($(USE_AESNI),1) CPU_FLAGS = -maes -DAESNI else CPU_FLAGS = -msse From 36aa2485564678ba23c871e9666719cc169c62cf Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Jul 2016 11:52:44 -0400 Subject: [PATCH 03/34] Graceful shutdown --- Win32/Win32App.cpp | 8 ++++++++ Win32/Win32App.h | 1 + 2 files changed, 9 insertions(+) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index cd9837ba..7da8f882 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -239,5 +239,13 @@ namespace win32 { UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); } + + bool GracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } } } diff --git a/Win32/Win32App.h b/Win32/Win32App.h index 7d35ec1e..3babffa9 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -10,6 +10,7 @@ namespace win32 bool StartWin32App (); void StopWin32App (); int RunWin32App (); + bool GracefulShutdown (); } } #endif // WIN32APP_H__ From 10be15050344d31bfe997c6ba71e4934bb3e0fbc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Jul 2016 12:11:52 -0400 Subject: [PATCH 04/34] invoke GracefulShutdown for Win32 --- HTTPServer.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 566ad53e..b4f90466 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -22,6 +22,9 @@ #include "HTTPServer.h" #include "Daemon.h" #include "util.h" +#ifdef WIN32_APP +#include "Win32/Win32App.h" +#endif // For image and info #include "version.h" @@ -409,15 +412,21 @@ namespace http { else s << " Accept transit tunnels
\r\n"; #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) - if (Daemon.gracefullShutdownInterval) { + if (Daemon.gracefullShutdownInterval) + { s << " Cancel gracefull shutdown ("; s << Daemon.gracefullShutdownInterval; s << " seconds remains)
\r\n"; - } else { + } + else + { s << " Start gracefull shutdown
\r\n"; } - s << " Force shutdown
\r\n"; #endif +#ifdef WIN32_APP + s << " Gracefull shutdown
\r\n"; +#endif + s << " Force shutdown
\r\n"; } void ShowTransitTunnels (std::stringstream& s) @@ -723,6 +732,9 @@ namespace http { i2p::context.SetAcceptsTunnels (false); #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) Daemon.gracefullShutdownInterval = 10*60; +#endif +#ifdef WIN32_APP + i2p::win32::GracefulShutdown (); #endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { i2p::context.SetAcceptsTunnels (true); From 97da8e2f2e72d4ed96cf6828aac77741ccebf7f2 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Jul 2016 02:00:00 +0000 Subject: [PATCH 05/34] * HTTPServer.cpp : true random password --- HTTPServer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index b4f90466..a811ad45 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -782,12 +782,14 @@ namespace http { std::string pass; i2p::config::GetOption("http.pass", pass); /* generate pass if needed */ if (needAuth && pass == "") { + uint8_t random[16]; char alnum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; - pass.resize(16); - for (size_t i = 0; i < pass.size(); i++) { - pass[i] = alnum[rand() % (sizeof(alnum) - 1)]; + pass.resize(sizeof(random)); + RAND_bytes(random, sizeof(random)); + for (size_t i = 0; i < sizeof(random); i++) { + pass[i] = alnum[random[i] % (sizeof(alnum) - 1)]; } i2p::config::SetOption("http.pass", pass); LogPrint(eLogInfo, "HTTPServer: password set to ", pass); From 5a6bd38d22a6df75c29835f44ed79c150990b693 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Jul 2016 02:00:00 +0000 Subject: [PATCH 06/34] * docs/configuration.md --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index e6ac74d2..8bd072b9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -109,7 +109,7 @@ tunnels.conf: # * keys -- our identity, if unset, will be generated on every startup, # if set and file missing, keys will be generated and placed to this file # * address -- local interface to bind - # * signaturetype -- signature type for new destination. 0,1 or 7 + # * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512) [IRC] type = client address = 127.0.0.1 From b1aeae6772f7440a913f4d1102bd5043468e2700 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Jul 2016 02:00:00 +0000 Subject: [PATCH 07/34] * util.{cpp,h} : kill with fire i2p::util::http (#314, closes #432) --- NetDb.cpp | 1 - UPnP.h | 2 - util.cpp | 159 +----------------------------------------------------- util.h | 29 ---------- 4 files changed, 1 insertion(+), 190 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index f5b51064..1752f1a9 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -14,7 +14,6 @@ #include "RouterContext.h" #include "Garlic.h" #include "NetDb.h" -#include "util.h" using namespace i2p::transport; diff --git a/UPnP.h b/UPnP.h index 4013b3df..f62ce402 100644 --- a/UPnP.h +++ b/UPnP.h @@ -13,8 +13,6 @@ #include -#include "util.h" - namespace i2p { namespace transport diff --git a/util.cpp b/util.cpp index 08ee6672..ca2b61c2 100644 --- a/util.cpp +++ b/util.cpp @@ -1,12 +1,7 @@ #include #include -#include -#include -#include -#include -#include #include -#include + #include "util.h" #include "Log.h" @@ -60,158 +55,6 @@ namespace i2p { namespace util { -namespace http -{ - std::string GetHttpContent (std::istream& response) - { - std::string version, statusMessage; - response >> version; // HTTP version - int status; - response >> status; // status - std::getline (response, statusMessage); - if (status == 200) // OK - { - bool isChunked = false; - std::string header; - while (!response.eof () && header != "\r") - { - std::getline(response, header); - auto colon = header.find (':'); - if (colon != std::string::npos) - { - std::string field = header.substr (0, colon); - std::transform(field.begin(), field.end(), field.begin(), ::tolower); - if (field == i2p::util::http::TRANSFER_ENCODING) - isChunked = (header.find ("chunked", colon + 1) != std::string::npos); - } - } - - std::stringstream ss; - if (isChunked) - MergeChunkedResponse (response, ss); - else - ss << response.rdbuf(); - return ss.str(); - } - else - { - LogPrint (eLogError, "HTTPClient: error, server responds ", status); - return ""; - } - } - - void MergeChunkedResponse (std::istream& response, std::ostream& merged) - { - while (!response.eof ()) - { - std::string hexLen; - size_t len; - std::getline (response, hexLen); - std::istringstream iss (hexLen); - iss >> std::hex >> len; - if (!len || len > 10000000L) // 10M - { - LogPrint (eLogError, "Unexpected chunk length ", len); - break; - } - char * buf = new char[len]; - response.read (buf, len); - merged.write (buf, len); - delete[] buf; - std::getline (response, hexLen); // read \r\n after chunk - } - } - - url::url(const std::string& url_s) - { - portstr_ = "80"; - port_ = 80; - user_ = ""; - pass_ = ""; - - parse(url_s); - } - - - // code for parser tests - //{ - // i2p::util::http::url u_0("http://127.0.0.1:7070/asdasd?qqqqqqqqqqqq"); - // i2p::util::http::url u_1("http://user:password@site.com:8080/asdasd?qqqqqqqqqqqqq"); - // i2p::util::http::url u_2("http://user:password@site.com/asdasd?qqqqqqqqqqqqqq"); - // i2p::util::http::url u_3("http://user:@site.com/asdasd?qqqqqqqqqqqqq"); - // i2p::util::http::url u_4("http://user@site.com/asdasd?qqqqqqqqqqqq"); - // i2p::util::http::url u_5("http://@site.com:800/asdasd?qqqqqqqqqqqq"); - // i2p::util::http::url u_6("http://@site.com:err_port/asdasd?qqqqqqqqqqqq"); - // i2p::util::http::url u_7("http://user:password@site.com:err_port/asdasd?qqqqqqqqqqqq"); - //} - void url::parse(const std::string& url_s) - { - const std::string prot_end("://"); - std::string::const_iterator prot_i = search(url_s.begin(), url_s.end(), - prot_end.begin(), prot_end.end()); - protocol_.reserve(distance(url_s.begin(), prot_i)); - transform(url_s.begin(), prot_i, - back_inserter(protocol_), - std::ptr_fun(tolower)); // protocol is icase - if( prot_i == url_s.end() ) - return; - advance(prot_i, prot_end.length()); - std::string::const_iterator path_i = find(prot_i, url_s.end(), '/'); - host_.reserve(distance(prot_i, path_i)); - transform(prot_i, path_i, - back_inserter(host_), - std::ptr_fun(tolower)); // host is icase - - // parse user/password - auto user_pass_i = find(host_.begin(), host_.end(), '@'); - if (user_pass_i != host_.end()) - { - std::string user_pass = std::string(host_.begin(), user_pass_i); - auto pass_i = find(user_pass.begin(), user_pass.end(), ':'); - if (pass_i != user_pass.end()) - { - user_ = std::string(user_pass.begin(), pass_i); - pass_ = std::string(pass_i + 1, user_pass.end()); - } - else - user_ = user_pass; - - host_.assign(user_pass_i + 1, host_.end()); - } - - // parse port - auto port_i = find(host_.begin(), host_.end(), ':'); - if (port_i != host_.end()) - { - portstr_ = std::string(port_i + 1, host_.end()); - host_.assign(host_.begin(), port_i); - try{ - port_ = boost::lexical_cast(portstr_); - } - catch (std::exception e) { - port_ = 80; - } - } - - std::string::const_iterator query_i = find(path_i, url_s.end(), '?'); - path_.assign(path_i, query_i); - if( query_i != url_s.end() ) - ++query_i; - query_.assign(query_i, url_s.end()); - } - - std::string urlDecode(const std::string& data) - { - std::string res(data); - for (size_t pos = res.find('%'); pos != std::string::npos; pos = res.find('%',pos+1)) - { - char c = strtol(res.substr(pos+1,2).c_str(), NULL, 16); - res.replace(pos,3,1,c); - } - return res; - } -} - namespace net { #ifdef WIN32 diff --git a/util.h b/util.h index 642ecc9b..77b94995 100644 --- a/util.h +++ b/util.h @@ -22,7 +22,6 @@ namespace i2p { namespace util { - /** wrapper arround boost::lexical_cast that "never" fails */ @@ -34,34 +33,6 @@ namespace util return fallback; } } - - namespace http - { - // in (lower case) - const char ETAG[] = "etag"; // ETag - const char LAST_MODIFIED[] = "last-modified"; // Last-Modified - const char TRANSFER_ENCODING[] = "transfer-encoding"; // Transfer-Encoding - const char CONTENT_ENCODING[] = "content-encoding"; // Content-Encoding - // out - const char IF_NONE_MATCH[] = "If-None-Match"; - const char IF_MODIFIED_SINCE[] = "If-Modified-Since"; - - std::string GetHttpContent (std::istream& response); - void MergeChunkedResponse (std::istream& response, std::ostream& merged); - std::string urlDecode(const std::string& data); - - struct url { - url(const std::string& url_s); // omitted copy, ==, accessors, ... - private: - void parse(const std::string& url_s); - public: - std::string protocol_, host_, path_, query_; - std::string portstr_; - unsigned int port_; - std::string user_; - std::string pass_; - }; - } namespace net { From 1062776762636950d6a0d8a21c2ff1ff639e3357 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Jul 2016 13:24:25 -0400 Subject: [PATCH 08/34] cleanup router's tags --- NetDb.cpp | 8 ++++++-- RouterContext.cpp | 6 ++++++ RouterContext.h | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 1752f1a9..6ef5df7f 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -71,7 +71,7 @@ namespace data void NetDb::Run () { - uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0; + uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; while (m_IsRunning) { try @@ -121,7 +121,11 @@ namespace data } lastSave = ts; } - + if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT) + { + i2p::context.CleanupDestination (); + lastDestinationCleanup = ts; + } // if we're in hidden mode don't publish or explore // if (m_HiddenMode) continue; diff --git a/RouterContext.cpp b/RouterContext.cpp index f2c2bc48..3b16d81a 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -439,6 +439,12 @@ namespace i2p std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); } + + void RouterContext::CleanupDestination () + { + std::unique_lock l(m_GarlicMutex); + i2p::garlic::GarlicDestination::CleanupExpiredTags (); + } uint32_t RouterContext::GetUptime () const { diff --git a/RouterContext.h b/RouterContext.h index 05339847..27e0947d 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -71,7 +71,8 @@ namespace i2p void SetSupportsV4 (bool supportsV4); void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session - void UpdateStats (); + void UpdateStats (); + void CleanupDestination (); // garlic destination // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; From 0899eeddc0f881b78dd7d9240e0350d9dd107762 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Jul 2016 10:59:44 -0400 Subject: [PATCH 09/34] UPnP for x86_64 --- docs/build_notes_windows.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/build_notes_windows.md b/docs/build_notes_windows.md index 8ba36131..827d0123 100644 --- a/docs/build_notes_windows.md +++ b/docs/build_notes_windows.md @@ -161,15 +161,17 @@ support for this. Unpack client source code in a sibling folder, e.g. C:\dev\miniupnpc . You may want to remove version number from folder name included in downloaded archive. -Note that you might need to build DLL yourself for 64-bit systems -using msys2 as 64-bit DLLs are not provided by the project. - You can also install it through the MSYS2 and build with USE_UPNP key. ```bash pacman -S mingw-w64-i686-miniupnpc -make USE_UPNP=1 +make USE_UPNP=yes +``` +or +```bash +pacman -S mingw-x86_64-miniupnpc +make USE_UPNP=yes ``` ### Creating Visual Studio project From ebc132ea6504da112c9aed09fb163d2a1a696ceb Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Sat, 30 Jul 2016 21:27:17 +0300 Subject: [PATCH 10/34] Update 01-tune-build-opts.patch --- debian/patches/01-tune-build-opts.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch index e0e24408..2a09b07b 100644 --- a/debian/patches/01-tune-build-opts.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -1,14 +1,15 @@ diff --git a/Makefile b/Makefile -index fe8ae7e..fc8abda 100644 +index 7d04ba0..33ee184 100644 --- a/Makefile +++ b/Makefile -@@ -9,9 +9,9 @@ DEPS := obj/make.dep +@@ -9,10 +9,10 @@ DEPS := obj/make.dep include filelist.mk -USE_AESNI := yes +USE_AESNI := no USE_STATIC := no + USE_MESHNET := no -USE_UPNP := no +USE_UPNP := yes From 47b562b032a362d1860f5c3b900bbc2f4392970a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Jul 2016 18:22:14 -0400 Subject: [PATCH 11/34] temporary disable OS X --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d83cdbc0..819c75f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ cache: apt: true os: - linux - - osx sudo: required dist: trusty addons: From 5698ff9c4cd7f7faf0512786f685b8fe1e4cdd3c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Jul 2016 10:22:41 -0400 Subject: [PATCH 12/34] wait for UPnP discovery during startup --- UPnP.cpp | 9 ++++++++- UPnP.h | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/UPnP.cpp b/UPnP.cpp index 41b49e00..db0d3683 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -49,7 +49,9 @@ namespace transport m_IsRunning = true; LogPrint(eLogInfo, "UPnP: starting"); m_Service.post (std::bind (&UPnP::Discover, this)); + std::unique_lock l(m_StartedMutex); m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this))); + m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum } UPnP::~UPnP () @@ -80,7 +82,12 @@ namespace transport #else m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); #endif - + { + // notify satrting thread + std::unique_lock l(m_StartedMutex); + m_Started.notify_all (); + } + int r; r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); if (r == 1) diff --git a/UPnP.h b/UPnP.h index f62ce402..7d67fdbf 100644 --- a/UPnP.h +++ b/UPnP.h @@ -4,6 +4,8 @@ #ifdef USE_UPNP #include #include +#include +#include #include #include @@ -43,8 +45,10 @@ namespace transport bool m_IsRunning; std::unique_ptr m_Thread; + std::condition_variable m_Started; + std::mutex m_StartedMutex; boost::asio::io_service m_Service; - boost::asio::deadline_timer m_Timer; + boost::asio::deadline_timer m_Timer; struct UPNPUrls m_upnpUrls; struct IGDdatas m_upnpData; From 94b3bb23914af2a6b37ccc440cdeec53fb4b9bc4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Aug 2016 10:26:50 -0400 Subject: [PATCH 13/34] adjust termination timeout --- NTCPSession.cpp | 7 ++++--- SSUSession.cpp | 7 ++++--- TransportSession.h | 8 ++++++-- Transports.cpp | 2 ++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index d2c03857..8475cd50 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -19,7 +19,8 @@ namespace i2p namespace transport { NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): - TransportSession (in_RemoteRouter), m_Server (server), m_Socket (m_Server.GetService ()), + TransportSession (in_RemoteRouter, NTCP_TERMINATION_TIMEOUT), + m_Server (server), m_Socket (m_Server.GetService ()), m_TerminationTimer (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false) { @@ -731,7 +732,7 @@ namespace transport void NTCPSession::ScheduleTermination () { m_TerminationTimer.cancel (); - m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_TIMEOUT)); + m_TerminationTimer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ())); m_TerminationTimer.async_wait (std::bind (&NTCPSession::HandleTerminationTimer, shared_from_this (), std::placeholders::_1)); } @@ -740,7 +741,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogDebug, "NTCP: No activity for ", NTCP_TERMINATION_TIMEOUT, " seconds"); + LogPrint (eLogDebug, "NTCP: No activity for ", GetTerminationTimeout (), " seconds"); //Terminate (); m_Socket.close ();// invoke Terminate () from HandleReceive } diff --git a/SSUSession.cpp b/SSUSession.cpp index 3aae06ba..4e095deb 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -12,7 +12,8 @@ namespace i2p namespace transport { SSUSession::SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint, - std::shared_ptr router, bool peerTest ): TransportSession (router), + std::shared_ptr router, bool peerTest ): + TransportSession (router, SSU_TERMINATION_TIMEOUT), m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_Timer (GetService ()), m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false), m_RelayTag (0),m_Data (*this), m_IsDataReceived (false) @@ -882,7 +883,7 @@ namespace transport void SSUSession::ScheduleTermination () { m_Timer.cancel (); - m_Timer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_TIMEOUT)); + m_Timer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ())); m_Timer.async_wait (std::bind (&SSUSession::HandleTerminationTimer, shared_from_this (), std::placeholders::_1)); } @@ -891,7 +892,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", SSU_TERMINATION_TIMEOUT, " seconds"); + LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", GetTerminationTimeout (), " seconds"); Failed (); } } diff --git a/TransportSession.h b/TransportSession.h index 608e72d1..1b057bc7 100644 --- a/TransportSession.h +++ b/TransportSession.h @@ -53,8 +53,8 @@ namespace transport { public: - TransportSession (std::shared_ptr router): - m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router) + TransportSession (std::shared_ptr router, int terminationTimeout): + m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout) { if (router) m_RemoteIdentity = router->GetRouterIdentity (); @@ -70,6 +70,9 @@ namespace transport size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; bool IsOutgoing () const { return m_IsOutgoing; }; + int GetTerminationTimeout () const { return m_TerminationTimeout; }; + void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; }; + virtual void SendI2NPMessages (const std::vector >& msgs) = 0; protected: @@ -78,6 +81,7 @@ namespace transport std::shared_ptr m_DHKeysPair; // X - for client and Y - for server size_t m_NumSentBytes, m_NumReceivedBytes; bool m_IsOutgoing; + int m_TerminationTimeout; }; } } diff --git a/Transports.cpp b/Transports.cpp index a54455cc..4ad53d7f 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -569,6 +569,8 @@ namespace transport } if (sendDatabaseStore) session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); + else + session->SetTerminationTimeout (10); // most likely it's publishing, no follow-up messages expected, set timeout to 10 seconds it->second.sessions.push_back (session); session->SendI2NPMessages (it->second.delayedMessages); it->second.delayedMessages.clear (); From 8f58886a21cd2d24c1b7a0256c04e30dd03acc64 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Thu, 4 Aug 2016 23:27:07 +0300 Subject: [PATCH 14/34] tiny commit to check pulling --- SOCKS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SOCKS.cpp b/SOCKS.cpp index 73833191..9d85963b 100644 --- a/SOCKS.cpp +++ b/SOCKS.cpp @@ -26,7 +26,7 @@ namespace proxy { uint8_t size; char value[max_socks_hostname_size]; - void FromString (std::string str) + void FromString (const std::string& str) { size = str.length(); if (str.length() > max_socks_hostname_size) size = max_socks_hostname_size; From 4b9afdf53a733be28e66604a4f7c4865f53f73a4 Mon Sep 17 00:00:00 2001 From: l-n-s Date: Fri, 5 Aug 2016 18:06:06 +0000 Subject: [PATCH 15/34] fix typo --- docs/build_notes_unix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index 795e408a..228333c8 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -23,7 +23,7 @@ After successfull build i2pd could be installed with: ```bash make install ``` -or you can just use 'make' once you have all dependacies (boost and openssl) installed +or you can just use 'make' once you have all dependencies (boost and openssl) installed ```bash git clone https://github.com/PurpleI2P/i2pd.git From b8ec63cf8c936d184f68da6ea0813d36676843d2 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Fri, 5 Aug 2016 21:23:54 +0300 Subject: [PATCH 16/34] copy ellimination for ranges #part1 --- AddressBook.cpp | 8 ++++---- BOB.cpp | 8 ++++---- ClientContext.cpp | 2 +- Destination.cpp | 8 ++++---- Garlic.cpp | 20 ++++++++++---------- HTTP.cpp | 2 +- HTTPProxy.cpp | 10 +++++----- HTTPServer.cpp | 16 ++++++++-------- I2CP.cpp | 2 +- I2NPProtocol.cpp | 2 +- I2PControl.cpp | 6 +++--- LeaseSet.cpp | 12 ++++++------ NetDb.cpp | 26 +++++++++++++------------- NetDbRequests.cpp | 2 +- Profiling.cpp | 2 +- Queue.h | 5 +++-- Tunnel.h | 2 +- 17 files changed, 67 insertions(+), 66 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index cd15d68d..6fdde4eb 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -173,7 +173,7 @@ namespace client return 0; } - for (auto it: addresses) { + for (const auto& it: addresses) { f << it.first << "," << it.second.ToBase32 () << std::endl; num++; } @@ -252,7 +252,7 @@ namespace client } LogPrint (eLogError, "Addressbook: subscription download timeout"); m_IsDownloading = false; - } + } if (m_Storage) { m_Storage->Save (m_Addresses); @@ -260,7 +260,7 @@ namespace client m_Storage = nullptr; } m_DefaultSubscription = nullptr; - for (auto it: m_Subscriptions) + for (auto& it: m_Subscriptions) delete it; m_Subscriptions.clear (); } @@ -418,7 +418,7 @@ namespace client { std::map localAddresses; m_Storage->LoadLocal (localAddresses); - for (auto it: localAddresses) + for (const auto& it: localAddresses) { auto dot = it.first.find ('.'); if (dot != std::string::npos) diff --git a/BOB.cpp b/BOB.cpp index caf766af..8ffffba6 100644 --- a/BOB.cpp +++ b/BOB.cpp @@ -536,8 +536,8 @@ namespace client void BOBCommandSession::ListCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: list"); - auto& destinations = m_Owner.GetDestinations (); - for (auto it: destinations) + const auto& destinations = m_Owner.GetDestinations (); + for (const auto& it: destinations) SendData (it.first.c_str ()); SendReplyOK ("Listing done"); } @@ -619,7 +619,7 @@ namespace client BOBCommandChannel::~BOBCommandChannel () { Stop (); - for (auto it: m_Destinations) + for (const auto& it: m_Destinations) delete it.second; } @@ -633,7 +633,7 @@ namespace client void BOBCommandChannel::Stop () { m_IsRunning = false; - for (auto it: m_Destinations) + for (auto& it: m_Destinations) it.second->Stop (); m_Acceptor.cancel (); m_Service.stop (); diff --git a/ClientContext.cpp b/ClientContext.cpp index 2bc13969..aa18ecdf 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -194,7 +194,7 @@ namespace client LogPrint(eLogInfo, "Clients: stopping AddressBook"); m_AddressBook.Stop (); - for (auto it: m_Destinations) + for (auto& it: m_Destinations) it.second->Stop (); m_Destinations.clear (); m_SharedLocalDestination = nullptr; diff --git a/Destination.cpp b/Destination.cpp index 2df14a9f..b1ab2a6c 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -103,7 +103,7 @@ namespace client { if (m_IsRunning) Stop (); - for (auto it: m_LeaseSetRequests) + for (auto& it: m_LeaseSetRequests) if (it.second->requestComplete) it.second->requestComplete (nullptr); m_LeaseSetRequests.clear (); if (m_Pool) @@ -635,7 +635,7 @@ namespace client it = m_RemoteLeaseSets.erase (it); } else - it++; + ++it; } } @@ -663,7 +663,7 @@ namespace client { m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: m_StreamingDestination->Start (); - for (auto it: m_StreamingDestinationsByPorts) + for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); return true; } @@ -677,7 +677,7 @@ namespace client { m_StreamingDestination->Stop (); m_StreamingDestination = nullptr; - for (auto it: m_StreamingDestinationsByPorts) + for (auto& it: m_StreamingDestinationsByPorts) it.second->Stop (); if (m_DatagramDestination) { diff --git a/Garlic.cpp b/Garlic.cpp index d48e9d94..c3c0e045 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -111,7 +111,7 @@ namespace garlic it = m_UnconfirmedTagsMsgs.erase (it); } else - it++; + ++it; } } @@ -123,7 +123,7 @@ namespace garlic if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) it = m_SessionTags.erase (it); else - it++; + ++it; } CleanupUnconfirmedTags (); return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); @@ -144,7 +144,7 @@ namespace garlic ret = true; } else - it++; + ++it; } return ret; } @@ -615,7 +615,7 @@ namespace garlic it = m_Tags.erase (it); } else - it++; + ++it; } if (numExpiredTags > 0) LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ()); @@ -631,7 +631,7 @@ namespace garlic it = m_Sessions.erase (it); } else - it++; + ++it; } } @@ -643,26 +643,26 @@ namespace garlic void GarlicDestination::DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID) { m_DeliveryStatusSessions[msgID] = session; - } + } void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload ()); { auto it = m_DeliveryStatusSessions.find (msgID); - if (it != m_DeliveryStatusSessions.end ()) + if (it != m_DeliveryStatusSessions.end ()) { it->second->MessageConfirmed (msgID); m_DeliveryStatusSessions.erase (it); LogPrint (eLogDebug, "Garlic: message ", msgID, " acknowledged"); - } + } } } void GarlicDestination::SetLeaseSetUpdated () { - std::unique_lock l(m_SessionsMutex); - for (auto it: m_Sessions) + std::unique_lock l(m_SessionsMutex); + for (auto& it: m_Sessions) it.second->SetLeaseSetUpdated (); } diff --git a/HTTP.cpp b/HTTP.cpp index 4a0286a7..08615e5b 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -160,7 +160,7 @@ namespace http { strsplit(query, tokens, '&'); params.clear(); - for (auto it : tokens) { + for (const auto& it : tokens) { std::size_t eq = it.find ('='); if (eq != std::string::npos) { auto e = std::pair(it.substr(0, eq), it.substr(eq + 1)); diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index b35c3b4a..60b6bc33 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -105,7 +105,7 @@ namespace proxy { ss << "

" << description << "

\r\n"; std::string content = ss.str(); SendProxyError(content); - } + } void HTTPReqHandler::HostNotFound(std::string & host) { std::stringstream ss; @@ -113,13 +113,13 @@ namespace proxy { << "

Remote host not found in router's addressbook

\r\n" << "

You may try to find this host on jumpservices below:

\r\n" << "
    \r\n"; - for (auto & js : jumpservices) { + for (const auto& js : jumpservices) { ss << "
  • " << js.first << "
  • \r\n"; } ss << "
\r\n"; std::string content = ss.str(); SendProxyError(content); - } + } void HTTPReqHandler::SendProxyError(std::string & content) { @@ -164,7 +164,7 @@ namespace proxy { req.del_header("Forwarded"); /* drop proxy-disclosing headers */ std::vector toErase; - for (auto it : req.headers) { + for (const auto& it : req.headers) { if (it.first.compare(0, 12, "X-Forwarded-") == 0) { toErase.push_back(it.first); } else if (it.first.compare(0, 6, "Proxy-") == 0) { @@ -173,7 +173,7 @@ namespace proxy { /* allow */ } } - for (auto header : toErase) { + for (const auto& header : toErase) { req.headers.erase(header); } /* replace headers */ diff --git a/HTTPServer.cpp b/HTTPServer.cpp index a811ad45..8ca35100 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -210,7 +210,7 @@ namespace http { s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; s << "Our external address:" << "
\r\n" ; - for (auto address : i2p::context.GetRouterInfo().GetAddresses()) + for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) { switch (address->transportStyle) { @@ -283,7 +283,7 @@ namespace http { } s << "
\r\n"; s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
Outgoing:
" << std::endl; - for (auto it: dest->GetSessions ()) + for (const auto& it: dest->GetSessions ()) { s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " "; s << it.second->GetNumOutgoingTags () << "
" << std::endl; @@ -314,7 +314,7 @@ namespace http { s << "Status"; s << ""; - for (auto it: dest->GetAllStreams ()) + for (const auto& it: dest->GetAllStreams ()) { s << ""; s << "" << it->GetSendStreamID () << ""; @@ -432,7 +432,7 @@ namespace http { void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; - for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) + for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { if (std::dynamic_pointer_cast(it)) s << it->GetTunnelID () << " ⇒ "; @@ -451,7 +451,7 @@ namespace http { if (ntcpServer) { s << "NTCP
\r\n"; - for (auto it: ntcpServer->GetNTCPSessions ()) + for (const auto& it: ntcpServer->GetNTCPSessions ()) { if (it.second && it.second->IsEstablished ()) { @@ -469,7 +469,7 @@ namespace http { if (ssuServer) { s << "
\r\nSSU
\r\n"; - for (auto it: ssuServer->GetSessions ()) + for (const auto& it: ssuServer->GetSessions ()) { auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; @@ -481,7 +481,7 @@ namespace http { s << "
\r\n" << std::endl; } s << "
\r\nSSU6
\r\n"; - for (auto it: ssuServer->GetSessionsV6 ()) + for (const auto& it: ssuServer->GetSessionsV6 ()) { auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; @@ -526,7 +526,7 @@ namespace http { s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n"; s << "
\r\n"; s << "Streams:
\r\n"; - for (auto it: session->ListSockets()) + for (const auto& it: session->ListSockets()) { switch (it->GetSocketType ()) { diff --git a/I2CP.cpp b/I2CP.cpp index 0867d719..0352cd15 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -659,7 +659,7 @@ namespace client { m_IsRunning = false; m_Acceptor.cancel (); - for (auto it: m_Sessions) + for (auto& it: m_Sessions) it.second->Stop (); m_Sessions.clear (); m_Service.stop (); diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 92ab8281..cbd4c3fc 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -202,7 +202,7 @@ namespace i2p len += 32; buf[len] = routers.size (); len++; - for (auto it: routers) + for (const auto& it: routers) { memcpy (buf + len, it, 32); len += 32; diff --git a/I2PControl.cpp b/I2PControl.cpp index a55871a3..3e2e3997 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -358,7 +358,7 @@ namespace client void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) { - for (auto it = params.begin (); it != params.end (); it++) + for (auto it = params.begin (); it != params.end (); ++it) { LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first); auto it1 = m_RouterInfoHandlers.find (it->first); @@ -434,7 +434,7 @@ namespace client void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results) { - for (auto it = params.begin (); it != params.end (); it++) + for (auto it = params.begin (); it != params.end (); ++it) { if (it != params.begin ()) results << ","; LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first); @@ -483,7 +483,7 @@ namespace client // network setting void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results) { - for (auto it = params.begin (); it != params.end (); it++) + for (auto it = params.begin (); it != params.end (); ++it) { if (it != params.begin ()) results << ","; LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first); diff --git a/LeaseSet.cpp b/LeaseSet.cpp index fafe14b7..89cad0df 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -64,10 +64,10 @@ namespace data return; } - // reset existing leases + // reset existing leases if (m_StoreLeases) - for (auto it: m_Leases) - it->isUpdated = false; + for (auto& it: m_Leases) + it->isUpdated = false; else m_Leases.clear (); @@ -123,7 +123,7 @@ namespace data m_Leases.erase (it++); } else - it++; + ++it; } } @@ -167,7 +167,7 @@ namespace data { auto ts = i2p::util::GetMillisecondsSinceEpoch (); std::vector > leases; - for (auto it: m_Leases) + for (const auto& it: m_Leases) { auto endDate = it->endDate; if (withThreshold) @@ -183,7 +183,7 @@ namespace data bool LeaseSet::HasExpiredLeases () const { auto ts = i2p::util::GetMillisecondsSinceEpoch (); - for (auto it: m_Leases) + for (const auto& it: m_Leases) if (ts >= it->endDate) return true; return false; } diff --git a/NetDb.cpp b/NetDb.cpp index 6ef5df7f..dc018326 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -51,7 +51,7 @@ namespace data { if (m_IsRunning) { - for (auto it: m_RouterInfos) + for (auto& it: m_RouterInfos) it.second->SaveProfile (); DeleteObsoleteProfiles (); m_RouterInfos.clear (); @@ -339,7 +339,7 @@ namespace data m_LastLoad = i2p::util::GetSecondsSinceEpoch(); std::vector files; m_Storage.Traverse(files); - for (auto path : files) + for (const auto& path : files) LoadRouterInfo(path); LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)"); @@ -357,7 +357,7 @@ namespace data expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL : NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; - for (auto it: m_RouterInfos) + for (auto& it: m_RouterInfos) { std::string ident = it.second->GetIdentHashBase64(); std::string path = m_Storage.Path(ident); @@ -405,7 +405,7 @@ namespace data it = m_RouterInfos.erase (it); continue; } - it++; + ++it; } } // clean up expired floodfiils @@ -415,7 +415,7 @@ namespace data if ((*it)->IsUnreachable ()) it = m_Floodfills.erase (it); else - it++; + ++it; } } } @@ -901,7 +901,7 @@ namespace data { uint32_t i = 0; std::unique_lock l(m_RouterInfosMutex); - for (auto it: m_RouterInfos) + for (const auto& it: m_RouterInfos) { if (i >= ind) { @@ -933,7 +933,7 @@ namespace data else minMetric.SetMax (); std::unique_lock l(m_FloodfillsMutex); - for (auto it: m_Floodfills) + for (const auto& it: m_Floodfills) { if (!it->IsUnreachable ()) { @@ -964,7 +964,7 @@ namespace data if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); { std::unique_lock l(m_FloodfillsMutex); - for (auto it: m_Floodfills) + for (const auto& it: m_Floodfills) { if (!it->IsUnreachable ()) { @@ -983,11 +983,11 @@ namespace data std::vector res; size_t i = 0; - for (auto it: sorted) + for (const auto& it: sorted) { if (i < num) { - auto& ident = it.r->GetIdentHash (); + const auto& ident = it.r->GetIdentHash (); if (!excluded.count (ident)) { res.push_back (ident); @@ -1016,7 +1016,7 @@ namespace data IdentHash destKey = CreateRoutingKey (destination); minMetric.SetMax (); // must be called from NetDb thread only - for (auto it: m_RouterInfos) + for (const auto& it: m_RouterInfos) { if (!it.second->IsFloodfill ()) { @@ -1042,7 +1042,7 @@ namespace data it = m_LeaseSets.erase (it); } else - it++; + ++it; } } @@ -1054,7 +1054,7 @@ namespace data if (ts > it->second.second + 180) // 3 minutes it = m_LookupResponses.erase (it); else - it++; + ++it; } } } diff --git a/NetDbRequests.cpp b/NetDbRequests.cpp index e1ea2872..c3966597 100644 --- a/NetDbRequests.cpp +++ b/NetDbRequests.cpp @@ -141,7 +141,7 @@ namespace data if (done) it = m_RequestedDestinations.erase (it); else - it++; + ++it; } } } diff --git a/Profiling.cpp b/Profiling.cpp index be675502..890a2620 100644 --- a/Profiling.cpp +++ b/Profiling.cpp @@ -167,7 +167,7 @@ namespace data std::vector files; m_ProfilesStorage.Traverse(files); - for (auto path: files) { + for (const auto& path: files) { if (stat(path.c_str(), &st) != 0) { LogPrint(eLogWarning, "Profiling: Can't stat(): ", path); continue; diff --git a/Queue.h b/Queue.h index b47a19c8..39d139b9 100644 --- a/Queue.h +++ b/Queue.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace i2p { @@ -20,7 +21,7 @@ namespace util void Put (Element e) { std::unique_lock l(m_QueueMutex); - m_Queue.push (e); + m_Queue.push (std::move(e)); m_NonEmpty.notify_one (); } @@ -29,7 +30,7 @@ namespace util if (!vec.empty ()) { std::unique_lock l(m_QueueMutex); - for (auto it: vec) + for (const auto& it: vec) m_Queue.push (it); m_NonEmpty.notify_one (); } diff --git a/Tunnel.h b/Tunnel.h index 0d35b682..5bc8b195 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -224,7 +224,7 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; - + // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; From d5075d706c2888169ade77770f72239ac08ad58c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Aug 2016 16:27:36 -0400 Subject: [PATCH 17/34] eliminate decay timer --- SSUData.cpp | 30 ++++++++---------------------- SSUData.h | 10 ++++------ 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/SSUData.cpp b/SSUData.cpp index 2bd65682..e802791d 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -25,10 +25,10 @@ namespace transport } SSUData::SSUData (SSUSession& session): - m_Session (session), m_ResendTimer (session.GetService ()), m_DecayTimer (session.GetService ()), + m_Session (session), m_ResendTimer (session.GetService ()), m_IncompleteMessagesCleanupTimer (session.GetService ()), m_MaxPacketSize (session.IsV6 () ? SSU_V6_MAX_PACKET_SIZE : SSU_V4_MAX_PACKET_SIZE), - m_PacketSize (m_MaxPacketSize) + m_PacketSize (m_MaxPacketSize), m_LastMessageReceivedTime (0) { } @@ -44,7 +44,6 @@ namespace transport void SSUData::Stop () { m_ResendTimer.cancel (); - m_DecayTimer.cancel (); m_IncompleteMessagesCleanupTimer.cancel (); } @@ -233,11 +232,8 @@ namespace transport { if (!m_ReceivedMessages.count (msgID)) { - if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES) - m_ReceivedMessages.clear (); - else - ScheduleDecay (); m_ReceivedMessages.insert (msgID); + m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); if (!msg->IsExpired ()) m_Handler.PutNextMessage (msg); else @@ -469,21 +465,6 @@ namespace transport } } - void SSUData::ScheduleDecay () - { - m_DecayTimer.cancel (); - m_DecayTimer.expires_from_now (boost::posix_time::seconds(DECAY_INTERVAL)); - auto s = m_Session.shared_from_this(); - m_ResendTimer.async_wait ([s](const boost::system::error_code& ecode) - { s->m_Data.HandleDecayTimer (ecode); }); - } - - void SSUData::HandleDecayTimer (const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - m_ReceivedMessages.clear (); - } - void SSUData::ScheduleIncompleteMessagesCleanup () { m_IncompleteMessagesCleanupTimer.cancel (); @@ -508,6 +489,11 @@ namespace transport else it++; } + // decay + if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || + i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) + m_ReceivedMessages.clear (); + ScheduleIncompleteMessagesCleanup (); } } diff --git a/SSUData.h b/SSUData.h index bfc75128..f3ad9ea8 100644 --- a/SSUData.h +++ b/SSUData.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include "I2NPProtocol.h" @@ -109,9 +109,6 @@ namespace transport void ScheduleResend (); void HandleResendTimer (const boost::system::error_code& ecode); - void ScheduleDecay (); - void HandleDecayTimer (const boost::system::error_code& ecode); - void ScheduleIncompleteMessagesCleanup (); void HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode); @@ -121,10 +118,11 @@ namespace transport SSUSession& m_Session; std::map > m_IncompleteMessages; std::map > m_SentMessages; - std::set m_ReceivedMessages; - boost::asio::deadline_timer m_ResendTimer, m_DecayTimer, m_IncompleteMessagesCleanupTimer; + std::unordered_set m_ReceivedMessages; + boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; + uint32_t m_LastMessageReceivedTime; // in second }; } } From 8b53ded53a9f728d70d5f84c3160a34940a6b7e9 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Mon, 8 Aug 2016 00:52:18 +0300 Subject: [PATCH 18/34] copy elimination for ranges #part2 --- NTCPSession.cpp | 6 +++--- RouterContext.cpp | 14 ++++++------- RouterInfo.cpp | 52 +++++++++++++++++++++++------------------------ RouterInfo.h | 6 +++--- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 8475cd50..b22b0f3c 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -666,7 +666,7 @@ namespace transport { m_IsSending = true; std::vector bufs; - for (auto it: msgs) + for (const auto& it: msgs) bufs.push_back (CreateMsgBuffer (it)); boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); @@ -716,7 +716,7 @@ namespace transport { if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE) { - for (auto it: msgs) + for (const auto& it: msgs) m_SendQueue.push_back (it); } else @@ -767,7 +767,7 @@ namespace transport m_Thread = new std::thread (std::bind (&NTCPServer::Run, this)); // create acceptors auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (auto address: addresses) + for (const auto& address: addresses) { if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { diff --git a/RouterContext.cpp b/RouterContext.cpp index 3b16d81a..c92b575b 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -112,7 +112,7 @@ namespace i2p void RouterContext::UpdatePort (int port) { bool updated = false; - for (auto address : m_RouterInfo.GetAddresses ()) + for (auto& address : m_RouterInfo.GetAddresses ()) { if (address->port != port) { @@ -127,7 +127,7 @@ namespace i2p void RouterContext::UpdateAddress (const boost::asio::ip::address& host) { bool updated = false; - for (auto address : m_RouterInfo.GetAddresses ()) + for (auto& address : m_RouterInfo.GetAddresses ()) { if (address->host != host && address->IsCompatible (host)) { @@ -244,7 +244,7 @@ namespace i2p m_RouterInfo.SetCaps (i2p::data::RouterInfo::eUnreachable | i2p::data::RouterInfo::eSSUTesting); // LU, B // remove NTCP address auto& addresses = m_RouterInfo.GetAddresses (); - for (auto it = addresses.begin (); it != addresses.end (); it++) + for (auto it = addresses.begin (); it != addresses.end (); ++it) { if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && (*it)->host.is_v4 ()) @@ -254,7 +254,7 @@ namespace i2p } } // delete previous introducers - for (auto addr : addresses) + for (auto& addr : addresses) addr->introducers.clear (); // update @@ -274,7 +274,7 @@ namespace i2p // insert NTCP back auto& addresses = m_RouterInfo.GetAddresses (); - for (auto addr : addresses) + for (const auto& addr : addresses) { if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && addr->host.is_v4 ()) @@ -285,7 +285,7 @@ namespace i2p } } // delete previous introducers - for (auto addr : addresses) + for (auto& addr : addresses) addr->introducers.clear (); // update @@ -316,7 +316,7 @@ namespace i2p bool updated = false, found = false; int port = 0; auto& addresses = m_RouterInfo.GetAddresses (); - for (auto addr: addresses) + for (auto& addr: addresses) { if (addr->host.is_v6 () && addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { diff --git a/RouterInfo.cpp b/RouterInfo.cpp index f497c30e..b594cb7a 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -369,19 +369,19 @@ namespace data SetProperty ("caps", caps); } - void RouterInfo::WriteToStream (std::ostream& s) + void RouterInfo::WriteToStream (std::ostream& s) const { uint64_t ts = htobe64 (m_Timestamp); - s.write ((char *)&ts, sizeof (ts)); + s.write ((const char *)&ts, sizeof (ts)); // addresses uint8_t numAddresses = m_Addresses->size (); s.write ((char *)&numAddresses, sizeof (numAddresses)); - for (auto addr : *m_Addresses) + for (const auto& addr_ptr : *m_Addresses) { - Address& address = *addr; - s.write ((char *)&address.cost, sizeof (address.cost)); - s.write ((char *)&address.date, sizeof (address.date)); + const Address& address = *addr_ptr; + s.write ((const char *)&address.cost, sizeof (address.cost)); + s.write ((const char *)&address.date, sizeof (address.date)); std::stringstream properties; if (address.transportStyle == eTransportNTCP) WriteString ("NTCP", s); @@ -410,7 +410,7 @@ namespace data if (address.introducers.size () > 0) { int i = 0; - for (auto introducer: address.introducers) + for (const auto& introducer: address.introducers) { WriteString ("ihost" + boost::lexical_cast(i), properties); properties << '='; @@ -419,7 +419,7 @@ namespace data i++; } i = 0; - for (auto introducer: address.introducers) + for (const auto& introducer: address.introducers) { WriteString ("ikey" + boost::lexical_cast(i), properties); properties << '='; @@ -431,7 +431,7 @@ namespace data i++; } i = 0; - for (auto introducer: address.introducers) + for (const auto& introducer: address.introducers) { WriteString ("iport" + boost::lexical_cast(i), properties); properties << '='; @@ -440,7 +440,7 @@ namespace data i++; } i = 0; - for (auto introducer: address.introducers) + for (const auto& introducer: address.introducers) { WriteString ("itag" + boost::lexical_cast(i), properties); properties << '='; @@ -482,7 +482,7 @@ namespace data // properties std::stringstream properties; - for (auto& p : m_Properties) + for (const auto& p : m_Properties) { WriteString (p.first, properties); properties << '='; @@ -570,10 +570,10 @@ namespace data addr->cost = 2; addr->date = 0; addr->mtu = 0; - for (auto it: *m_Addresses) // don't insert same address twice + for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; - m_Addresses->push_back(addr); m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4; + m_Addresses->push_back(std::move(addr)); } void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu) @@ -586,21 +586,22 @@ namespace data addr->date = 0; addr->mtu = mtu; memcpy (addr->key, key, 32); - for (auto it: *m_Addresses) // don't insert same address twice + for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; - m_Addresses->push_back(addr); m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; - m_Caps |= eSSUTesting; - m_Caps |= eSSUIntroducer; + m_Addresses->push_back(std::move(addr)); + + m_Caps |= eSSUTesting; + m_Caps |= eSSUIntroducer; } bool RouterInfo::AddIntroducer (const Introducer& introducer) { - for (auto addr : *m_Addresses) + for (auto& addr : *m_Addresses) { if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) { - for (auto intro: addr->introducers) + for (auto& intro: addr->introducers) if (intro.iTag == introducer.iTag) return false; // already presented addr->introducers.push_back (introducer); return true; @@ -611,16 +612,16 @@ namespace data bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e) { - for (auto addr: *m_Addresses) + for (auto& addr: *m_Addresses) { if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) { - for (std::vector::iterator it = addr->introducers.begin (); it != addr->introducers.end (); it++) + for (auto it = addr->introducers.begin (); it != addr->introducers.end (); ++it) if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) { addr->introducers.erase (it); return true; - } + } } } return false; @@ -707,7 +708,7 @@ namespace data if (addr->host.is_v6 ()) it = m_Addresses->erase (it); else - it++; + ++it; } } } @@ -723,7 +724,7 @@ namespace data if (addr->host.is_v4 ()) it = m_Addresses->erase (it); else - it++; + ++it; } } } @@ -751,8 +752,7 @@ namespace data std::shared_ptr RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const { - auto addresses = m_Addresses; - for (auto address : *addresses) + for (const auto& address : *m_Addresses) { if (address->transportStyle == s) { diff --git a/RouterInfo.h b/RouterInfo.h index 8c99d245..16937b5b 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -187,9 +187,9 @@ namespace data void ReadFromFile (); void ReadFromStream (std::istream& s); void ReadFromBuffer (bool verifySignature); - void WriteToStream (std::ostream& s); - size_t ReadString (char * str, std::istream& s); - void WriteString (const std::string& str, std::ostream& s); + void WriteToStream (std::ostream& s) const; + static size_t ReadString (char* str, std::istream& s); + static void WriteString (const std::string& str, std::ostream& s); void ExtractCaps (const char * value); std::shared_ptr GetAddress (TransportStyle s, bool v4only, bool v6only = false) const; void UpdateCapsProperty (); From 56a60772a412c4b350b8beffc6198a00db7694c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 8 Aug 2016 11:53:38 -0400 Subject: [PATCH 19/34] fixed potential deadlock --- AddressBook.cpp | 17 ++++++++++++----- Destination.cpp | 6 +++--- Destination.h | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index 6fdde4eb..f778fff6 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -658,16 +658,23 @@ namespace client if (!leaseSet) { std::unique_lock l(newDataReceivedMutex); - i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident, + if (i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident, [&newDataReceived, &leaseSet](std::shared_ptr ls) { leaseSet = ls; newDataReceived.notify_all (); - }); - if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) + })) { - LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired"); - i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident); + if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) + { + LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired"); + i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident, false); // don't notify, because we know it already + return false; + } + } + else + { + LogPrint (eLogError, "Addressbook: Destination is not ready"); return false; } } diff --git a/Destination.cpp b/Destination.cpp index b1ab2a6c..05216d18 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -486,17 +486,17 @@ namespace client return true; } - void LeaseSetDestination::CancelDestinationRequest (const i2p::data::IdentHash& dest) + void LeaseSetDestination::CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify) { auto s = shared_from_this (); - m_Service.post ([dest, s](void) + m_Service.post ([dest, notify, s](void) { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) { auto requestComplete = it->second->requestComplete; s->m_LeaseSetRequests.erase (it); - if (requestComplete) requestComplete (nullptr); + if (notify && requestComplete) requestComplete (nullptr); } }); } diff --git a/Destination.h b/Destination.h index e64508c9..ac7ef7c9 100644 --- a/Destination.h +++ b/Destination.h @@ -79,7 +79,7 @@ namespace client bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr); - void CancelDestinationRequest (const i2p::data::IdentHash& dest); + void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true); // implements GarlicDestination std::shared_ptr GetLeaseSet (); From ab1df3a1d08d6ce06a76b63a85867502cc990c9f Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Mon, 8 Aug 2016 23:37:16 +0300 Subject: [PATCH 20/34] Update HTTPServer.cpp --- HTTPServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8ca35100..228023d9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -149,7 +149,8 @@ namespace http { " Transit tunnels
\r\n" " Transports
\r\n" " I2P tunnels
\r\n" - " SAM sessions
\r\n" + if (i2p::client::context.GetSAMBridge ()) + " SAM sessions
\r\n" "\r\n" "
"; } From 7ba4af7e2e9b6a75cddbb4c48da178cd1a6f5ec3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 8 Aug 2016 17:31:32 -0400 Subject: [PATCH 21/34] fixed build error --- HTTPServer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 228023d9..8ca35100 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -149,8 +149,7 @@ namespace http { " Transit tunnels
\r\n" " Transports
\r\n" " I2P tunnels
\r\n" - if (i2p::client::context.GetSAMBridge ()) - " SAM sessions
\r\n" + " SAM sessions
\r\n" "
\r\n" "
"; } From a530503c0c0ec1d7e01723abee074c5596c14bcb Mon Sep 17 00:00:00 2001 From: brain5lug Date: Tue, 9 Aug 2016 01:53:37 +0300 Subject: [PATCH 22/34] copy elimination for ranges #part3 --- SAM.cpp | 4 ++-- SAM.h | 2 +- SSU.cpp | 42 +++++++++++++++++++----------------------- SSUData.cpp | 14 +++++++------- SSUSession.cpp | 2 +- Streaming.cpp | 16 ++++++++-------- Transports.cpp | 10 +++++----- Transports.h | 2 +- TunnelConfig.h | 2 +- 9 files changed, 45 insertions(+), 49 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index 55eae222..2864cd6f 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -686,7 +686,7 @@ namespace client { { std::lock_guard lock(m_SocketsMutex); - for (auto sock : m_Sockets) { + for (auto& sock : m_Sockets) { sock->CloseStream(); } } @@ -719,7 +719,7 @@ namespace client { m_IsRunning = false; m_Acceptor.cancel (); - for (auto it: m_Sessions) + for (auto& it: m_Sessions) it.second->CloseStreams (); m_Sessions.clear (); m_Service.stop (); diff --git a/SAM.h b/SAM.h index ef36f285..db08c5a0 100644 --- a/SAM.h +++ b/SAM.h @@ -154,7 +154,7 @@ namespace client std::list > l; { std::lock_guard lock(m_SocketsMutex); - for( auto & sock : m_Sockets ) l.push_back(sock); + for(const auto& sock : m_Sockets ) l.push_back(sock); } return l; } diff --git a/SSU.cpp b/SSU.cpp index f4277a5a..0c3662d3 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -237,9 +237,8 @@ namespace transport std::map > * sessions) { std::shared_ptr session; - for (auto it1: packets) + for (auto& packet: packets) { - auto packet = it1; try { if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous @@ -431,11 +430,11 @@ namespace transport void SSUServer::DeleteAllSessions () { - for (auto it: m_Sessions) + for (auto& it: m_Sessions) it.second->Close (); m_Sessions.clear (); - for (auto it: m_SessionsV6) + for (auto& it: m_SessionsV6) it.second->Close (); m_SessionsV6.clear (); } @@ -444,7 +443,7 @@ namespace transport std::shared_ptr SSUServer::GetRandomV4Session (Filter filter) // v4 only { std::vector > filteredSessions; - for (auto s :m_Sessions) + for (const auto& s :m_Sessions) if (filter (s.second)) filteredSessions.push_back (s.second); if (filteredSessions.size () > 0) { @@ -468,7 +467,7 @@ namespace transport std::shared_ptr SSUServer::GetRandomV6Session (Filter filter) // v6 only { std::vector > filteredSessions; - for (auto s :m_SessionsV6) + for (const auto& s :m_SessionsV6) if (filter (s.second)) filteredSessions.push_back (s.second); if (filteredSessions.size () > 0) { @@ -535,7 +534,7 @@ namespace transport std::list newList; size_t numIntroducers = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it :m_Introducers) + for (const auto& it : m_Introducers) { auto session = FindSession (it); if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) @@ -552,23 +551,20 @@ namespace transport { // create new auto introducers = FindIntroducers (SSU_MAX_NUM_INTRODUCERS); - if (introducers.size () > 0) + for (const auto& it1: introducers) { - for (auto it1: introducers) + const auto& ep = it1->GetRemoteEndpoint (); + i2p::data::RouterInfo::Introducer introducer; + introducer.iHost = ep.address (); + introducer.iPort = ep.port (); + introducer.iTag = it1->GetRelayTag (); + introducer.iKey = it1->GetIntroKey (); + if (i2p::context.AddIntroducer (introducer)) { - auto& ep = it1->GetRemoteEndpoint (); - i2p::data::RouterInfo::Introducer introducer; - introducer.iHost = ep.address (); - introducer.iPort = ep.port (); - introducer.iTag = it1->GetRelayTag (); - introducer.iKey = it1->GetIntroKey (); - if (i2p::context.AddIntroducer (introducer)) - { - newList.push_back (ep); - if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break; - } - } - } + newList.push_back (ep); + if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break; + } + } } m_Introducers = newList; if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS) @@ -637,7 +633,7 @@ namespace transport it = m_PeerTests.erase (it); } else - it++; + ++it; } if (numDeleted > 0) LogPrint (eLogDebug, "SSU: ", numDeleted, " peer tests have been expired"); diff --git a/SSUData.cpp b/SSUData.cpp index e802791d..e5abfd54 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -427,12 +427,12 @@ namespace transport if (ts >= it->second->nextResendTime) { if (it->second->numResends < MAX_NUM_RESENDS) - { + { for (auto& f: it->second->fragments) - if (f) + if (f) { try - { + { m_Session.Send (f->buf, f->len); // resend numResent++; } @@ -440,11 +440,11 @@ namespace transport { LogPrint (eLogWarning, "SSU: Can't resend data fragment ", ec.what ()); } - } + } it->second->numResends++; it->second->nextResendTime += it->second->numResends*RESEND_INTERVAL; - it++; + ++it; } else { @@ -453,7 +453,7 @@ namespace transport } } else - it++; + ++it; } if (numResent < MAX_OUTGOING_WINDOW_SIZE) ScheduleResend (); @@ -487,7 +487,7 @@ namespace transport it = m_IncompleteMessages.erase (it); } else - it++; + ++it; } // decay if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || diff --git a/SSUSession.cpp b/SSUSession.cpp index 4e095deb..bf4058a5 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -907,7 +907,7 @@ namespace transport { if (m_State == eSessionStateEstablished) { - for (auto it: msgs) + for (const auto& it: msgs) if (it) m_Data.Send (it); } } diff --git a/Streaming.cpp b/Streaming.cpp index 3806d97d..90c363ea 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -247,7 +247,7 @@ namespace stream } int nackCount = packet->GetNACKCount (); for (auto it = m_SentPackets.begin (); it != m_SentPackets.end ();) - { + { auto seqn = (*it)->GetSeqn (); if (seqn <= ackThrough) { @@ -263,7 +263,7 @@ namespace stream if (nacked) { LogPrint (eLogDebug, "Streaming: Packet ", seqn, " NACK"); - it++; + ++it; continue; } } @@ -412,7 +412,7 @@ namespace stream } bool isEmpty = m_SentPackets.empty (); auto ts = i2p::util::GetMillisecondsSinceEpoch (); - for (auto it: packets) + for (auto& it: packets) { it->sendTime = ts; m_SentPackets.insert (it); @@ -762,7 +762,7 @@ namespace stream bool updated = false; if (expired && m_CurrentRemoteLease) { - for (auto it: leases) + for (const auto& it: leases) if ((it->tunnelGateway == m_CurrentRemoteLease->tunnelGateway) && (it->tunnelID != m_CurrentRemoteLease->tunnelID)) { m_CurrentRemoteLease = it; @@ -798,7 +798,7 @@ namespace stream StreamingDestination::~StreamingDestination () { - for (auto it: m_SavedPackets) + for (auto& it: m_SavedPackets) { for (auto it1: it.second) delete it1; it.second.clear (); @@ -877,7 +877,7 @@ namespace stream else // follow on packet without SYN { uint32_t receiveStreamID = packet->GetReceiveStreamID (); - for (auto it: m_Streams) + for (auto& it: m_Streams) if (it.second->GetSendStreamID () == receiveStreamID) { // found @@ -944,7 +944,7 @@ namespace stream m_Owner->GetService ().post([acceptor, this](void) { m_Acceptor = acceptor; - for (auto it: m_PendingIncomingStreams) + for (auto& it: m_PendingIncomingStreams) if (it->GetStatus () == eStreamStatusOpen) // still open? m_Acceptor (it); m_PendingIncomingStreams.clear (); @@ -963,7 +963,7 @@ namespace stream if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogWarning, "Streaming: Pending incoming timeout expired"); - for (auto it: m_PendingIncomingStreams) + for (auto& it: m_PendingIncomingStreams) it->Close (); m_PendingIncomingStreams.clear (); } diff --git a/Transports.cpp b/Transports.cpp index 4ad53d7f..b1c174f6 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -112,7 +112,7 @@ namespace transport m_Thread = new std::thread (std::bind (&Transports::Run, this)); // create acceptors auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (auto address : addresses) + for (const auto& address : addresses) { if (m_NTCPServer == nullptr && enableNTCP) { @@ -236,7 +236,7 @@ namespace transport if (ident == i2p::context.GetRouterInfo ().GetIdentHash ()) { // we send it to ourself - for (auto it: msgs) + for (auto& it: msgs) i2p::HandleI2NPMessage (it); return; } @@ -266,7 +266,7 @@ namespace transport { if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES) { - for (auto it1: msgs) + for (auto& it1: msgs) it->second.delayedMessages.push_back (it1); } else @@ -636,7 +636,7 @@ namespace transport it = m_Peers.erase (it); } else - it++; + ++it; } UpdateBandwidth (); // TODO: use separate timer(s) for it if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test @@ -658,7 +658,7 @@ namespace transport { std::lock_guard lock(m_FamilyMutex); m_TrustedFamilies.clear(); - for ( auto fam : families ) + for ( const auto& fam : families ) m_TrustedFamilies.push_back(fam); } diff --git a/Transports.h b/Transports.h index 708c55e2..81063916 100644 --- a/Transports.h +++ b/Transports.h @@ -60,7 +60,7 @@ namespace transport void Done () { - for (auto it: sessions) + for (auto& it: sessions) it->Done (); } }; diff --git a/TunnelConfig.h b/TunnelConfig.h index 7546c9b2..23417ed9 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -213,7 +213,7 @@ namespace tunnel void CreatePeers (const Peers& peers) { TunnelHopConfig * prev = nullptr; - for (auto it: peers) + for (const auto& it: peers) { auto hop = new TunnelHopConfig (it); if (prev) From 32466e3804ee52afeca9d644c31373e4d7165cec Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 8 Aug 2016 22:15:09 -0400 Subject: [PATCH 23/34] don't notify before wait --- AddressBook.cpp | 20 +++++++------------- Destination.cpp | 3 ++- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index f778fff6..e996b5f0 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -658,23 +658,17 @@ namespace client if (!leaseSet) { std::unique_lock l(newDataReceivedMutex); - if (i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident, - [&newDataReceived, &leaseSet](std::shared_ptr ls) + i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident, + [&newDataReceived, &leaseSet, &newDataReceivedMutex](std::shared_ptr ls) { leaseSet = ls; + std::unique_lock l1(newDataReceivedMutex); newDataReceived.notify_all (); - })) + }); + if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) { - if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) - { - LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired"); - i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident, false); // don't notify, because we know it already - return false; - } - } - else - { - LogPrint (eLogError, "Addressbook: Destination is not ready"); + LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired"); + i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident, false); // don't notify, because we know it already return false; } } diff --git a/Destination.cpp b/Destination.cpp index 05216d18..42351787 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -479,7 +479,8 @@ namespace client { if (!m_Pool || !IsReady ()) { - if (requestComplete) requestComplete (nullptr); + if (requestComplete) + m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; } m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete)); From 6a752a56ff33d9778444d6802b3177cfdf7901b5 Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Tue, 9 Aug 2016 13:54:47 +0300 Subject: [PATCH 24/34] Update HTTPServer.cpp --- HTTPServer.cpp | 84 ++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8ca35100..f10289ef 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -68,7 +68,7 @@ namespace http { const char HTTP_PAGE_TUNNELS[] = "tunnels"; const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels"; - const char HTTP_PAGE_TRANSPORTS[] = "transports"; + const char HTTP_PAGE_TRANSPORTS[] = "transports"; const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations"; const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination"; const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions"; @@ -82,7 +82,7 @@ namespace http { const char HTTP_COMMAND_SHUTDOWN_CANCEL[] = "shutdown_cancel"; const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; - const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; + const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; @@ -144,12 +144,14 @@ namespace http { " Main page
\r\n
\r\n" " Router commands
\r\n" " Local destinations
\r\n" - " Lease Sets
\r\n" + " LeaseSets
\r\n" " Tunnels
\r\n" " Transit tunnels
\r\n" " Transports
\r\n" - " I2P tunnels
\r\n" - " SAM sessions
\r\n" + " I2P tunnels
\r\n"; + if (i2p::client::context.GetSAMBridge ()) + s << " SAM sessions
\r\n"; + s << "
\r\n" "
"; } @@ -239,9 +241,9 @@ namespace http { size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); - - s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; - s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; + + s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; + s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } void ShowLocalDestinations (std::stringstream& s) @@ -280,18 +282,18 @@ namespace http { it->Print(s); ShowTunnelDetails(s, it->GetState (), it->GetNumSentBytes ()); } - } + } s << "
\r\n"; s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
Outgoing:
" << std::endl; for (const auto& it: dest->GetSessions ()) { s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " "; s << it.second->GetNumOutgoingTags () << "
" << std::endl; - } + } s << "
" << std::endl; // s << "
\r\nStreams:
\r\n"; // for (auto it: dest->GetStreamingDestination ()->GetStreams ()) - // { + // { // s << it.first << "->" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetRemoteIdentity ()) << " "; // s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; // s << " [out:" << it.second->GetSendQueueSize () << "][in:" << it.second->GetReceiveQueueSize () << "]"; @@ -300,7 +302,7 @@ namespace http { // s << "[Window:" << it.second->GetWindowSize () << "]"; // s << "[Status:" << (int)it.second->GetStatus () << "]"; // s << "
\r\n"<< std::endl; - // } + // } s << "
\r\n"; s << ""; s << ""; @@ -315,7 +317,7 @@ namespace http { s << ""; for (const auto& it: dest->GetAllStreams ()) - { + { s << ""; s << ""; s << ""; @@ -329,12 +331,12 @@ namespace http { s << ""; s << "
\r\n" << std::endl; } - } + } } void ShowLeasesSets(std::stringstream& s) { - s << "
LeaseSets

"; + s << "
LeaseSets:

"; // for each lease set i2p::data::netdb.VisitLeaseSets( [&s](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) @@ -382,7 +384,7 @@ namespace http { ); // end for each lease set } - + void ShowTunnels (std::stringstream& s) { s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; @@ -399,7 +401,7 @@ namespace http { ShowTunnelDetails(s, it->GetState (), it->GetNumSentBytes ()); } s << "
\r\n"; - } + } void ShowCommands (std::stringstream& s) { @@ -409,7 +411,7 @@ namespace http { //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) s << " Decline transit tunnels
\r\n"; - else + else s << " Accept transit tunnels
\r\n"; #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) if (Daemon.gracefullShutdownInterval) @@ -435,11 +437,11 @@ namespace http { for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { if (std::dynamic_pointer_cast(it)) - s << it->GetTunnelID () << " ⇒ "; + s << it->GetTunnelID () << " ⇒ "; else if (std::dynamic_pointer_cast(it)) - s << " ⇒ " << it->GetTunnelID (); + s << " ⇒ " << it->GetTunnelID (); else - s << " ⇒ " << it->GetTunnelID () << " ⇒ "; + s << " ⇒ " << it->GetTunnelID () << " ⇒ "; s << " " << it->GetNumTransmittedBytes () << "
\r\n"; } } @@ -449,22 +451,22 @@ namespace http { s << "Transports:
\r\n
\r\n"; auto ntcpServer = i2p::transport::transports.GetNTCPServer (); if (ntcpServer) - { + { s << "NTCP
\r\n"; for (const auto& it: ntcpServer->GetNTCPSessions ()) { if (it.second && it.second->IsEstablished ()) { // incoming connection doesn't have remote RI - if (it.second->IsOutgoing ()) s << " ⇒ "; + if (it.second->IsOutgoing ()) s << " ⇒ "; s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " << it.second->GetSocket ().remote_endpoint().address ().to_string (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; + if (!it.second->IsOutgoing ()) s << " ⇒ "; s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; s << "
\r\n" << std::endl; } } - } + } auto ssuServer = i2p::transport::transports.GetSSUServer (); if (ssuServer) { @@ -472,9 +474,9 @@ namespace http { for (const auto& it: ssuServer->GetSessions ()) { auto endpoint = it.second->GetRemoteEndpoint (); - if (it.second->IsOutgoing ()) s << " ⇒ "; + if (it.second->IsOutgoing ()) s << " ⇒ "; s << endpoint.address ().to_string () << ":" << endpoint.port (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; + if (!it.second->IsOutgoing ()) s << " ⇒ "; s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; if (it.second->GetRelayTag ()) s << " [itag:" << it.second->GetRelayTag () << "]"; @@ -484,15 +486,15 @@ namespace http { for (const auto& it: ssuServer->GetSessionsV6 ()) { auto endpoint = it.second->GetRemoteEndpoint (); - if (it.second->IsOutgoing ()) s << " ⇒ "; + if (it.second->IsOutgoing ()) s << " ⇒ "; s << endpoint.address ().to_string () << ":" << endpoint.port (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; + if (!it.second->IsOutgoing ()) s << " ⇒ "; s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; s << "
\r\n" << std::endl; } } } - + void ShowSAMSessions (std::stringstream& s) { auto sam = i2p::client::context.GetSAMBridge (); @@ -505,8 +507,8 @@ namespace http { { s << ""; s << it.first << "
\r\n" << std::endl; - } - } + } + } void ShowSAMSession (std::stringstream& s, const std::string& id) { @@ -537,8 +539,8 @@ namespace http { } s << " [" << it->GetSocket ().remote_endpoint() << "]"; s << "
\r\n"; - } - } + } + } void ShowI2PTunnels (std::stringstream& s) { @@ -547,21 +549,21 @@ namespace http { { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; - s << it.second->GetName () << " ⇐ "; + s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; - } + } s << "
\r\nServer Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetServerTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; - s << it.second->GetName () << " ⇒ "; + s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); s << "
\r\n"<< std::endl; - } - } + } + } HTTPConnection::HTTPConnection (std::shared_ptr socket): m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0) @@ -734,7 +736,7 @@ namespace http { Daemon.gracefullShutdownInterval = 10*60; #endif #ifdef WIN32_APP - i2p::win32::GracefulShutdown (); + i2p::win32::GracefulShutdown (); #endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { i2p::context.SetAcceptsTunnels (true); @@ -752,7 +754,7 @@ namespace http { s << "Back to commands list
\r\n"; s << "

You will be redirected in 5 seconds"; res.add_header("Refresh", "5; url=/?page=commands"); - } + } void HTTPConnection::SendReply (HTTPRes& reply, std::string& content) { From 2dd5de4373b5303ad29ec7bfc2bddbfe28fd7c80 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Aug 2016 10:17:40 -0400 Subject: [PATCH 25/34] handle default subscription in separate thread --- AddressBook.cpp | 13 ++++++------- AddressBook.h | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index e996b5f0..b3f0f1ce 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -260,8 +260,6 @@ namespace client m_Storage = nullptr; } m_DefaultSubscription = nullptr; - for (auto& it: m_Subscriptions) - delete it; m_Subscriptions.clear (); } @@ -403,7 +401,7 @@ namespace client { getline(f, s); if (!s.length()) continue; // skip empty line - m_Subscriptions.push_back (new AddressBookSubscription (*this, s)); + m_Subscriptions.push_back (std::make_shared (*this, s)); } LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); } @@ -462,7 +460,7 @@ namespace client int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT; if (success) { - if (m_DefaultSubscription) m_DefaultSubscription.reset (nullptr); + if (m_DefaultSubscription) m_DefaultSubscription = nullptr; if (m_IsLoaded) nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT; else @@ -516,16 +514,17 @@ namespace client // download it from http://i2p-projekt.i2p/hosts.txt LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription."); if (!m_DefaultSubscription) - m_DefaultSubscription.reset (new AddressBookSubscription (*this, DEFAULT_SUBSCRIPTION_ADDRESS)); + m_DefaultSubscription = std::make_shared(*this, DEFAULT_SUBSCRIPTION_ADDRESS); m_IsDownloading = true; - m_DefaultSubscription->CheckUpdates (); + std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_DefaultSubscription)); + load_hosts.detach(); // TODO: use join } else if (!m_Subscriptions.empty ()) { // pick random subscription auto ind = rand () % m_Subscriptions.size(); m_IsDownloading = true; - std::thread load_hosts(&AddressBookSubscription::CheckUpdates, m_Subscriptions[ind]); + std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_Subscriptions[ind])); load_hosts.detach(); // TODO: use join } } diff --git a/AddressBook.h b/AddressBook.h index fd852907..7f559cd0 100644 --- a/AddressBook.h +++ b/AddressBook.h @@ -102,8 +102,8 @@ namespace client std::map m_Lookups; // nonce -> address AddressBookStorage * m_Storage; volatile bool m_IsLoaded, m_IsDownloading; - std::vector m_Subscriptions; - std::unique_ptr m_DefaultSubscription; // in case if we don't know any addresses yet + std::vector > m_Subscriptions; + std::shared_ptr m_DefaultSubscription; // in case if we don't know any addresses yet boost::asio::deadline_timer * m_SubscriptionsUpdateTimer; }; From 94642f90666feacb5d49bb5e423e40d2e1b7cb50 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Wed, 10 Aug 2016 01:16:24 +0300 Subject: [PATCH 26/34] copy elimination for ranges #part4 --- Tunnel.cpp | 15 +++++++-------- TunnelGateway.cpp | 2 +- TunnelPool.cpp | 29 ++++++++++++++--------------- UPnP.cpp | 8 ++++---- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index fd971628..6a6accd6 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -345,7 +345,7 @@ namespace tunnel { std::shared_ptr tunnel; size_t minReceived = 0; - for (auto it : m_InboundTunnels) + for (const auto& it : m_InboundTunnels) { if (!it->IsEstablished ()) continue; if (!tunnel || it->GetNumReceivedBytes () < minReceived) @@ -362,7 +362,7 @@ namespace tunnel if (m_OutboundTunnels.empty ()) return nullptr; uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0; std::shared_ptr tunnel; - for (auto it: m_OutboundTunnels) + for (const auto& it: m_OutboundTunnels) { if (it->IsEstablished ()) { @@ -586,7 +586,7 @@ namespace tunnel m_NumFailedTunnelCreations++; } else - it++; + ++it; break; case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted"); @@ -595,7 +595,7 @@ namespace tunnel break; case eTunnelStateBuildReplyReceived: // intermediate state, will be either established of build failed - it++; + ++it; break; default: // success @@ -635,7 +635,7 @@ namespace tunnel if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) tunnel->SetState (eTunnelStateExpiring); } - it++; + ++it; } } } @@ -738,9 +738,8 @@ namespace tunnel void Tunnels::ManageTunnelPools () { std::unique_lock l(m_PoolsMutex); - for (auto it: m_Pools) + for (auto& pool : m_Pools) { - auto pool = it; if (pool && pool->IsActive ()) { pool->CreateTunnels (); @@ -856,7 +855,7 @@ namespace tunnel int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // TODO: possible race condition with I2PControl - for (auto it: m_TransitTunnels) + for (const auto& it : m_TransitTunnels) { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; if (t > timeout) timeout = t; diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index d701e24b..ad423fc0 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -197,7 +197,7 @@ namespace tunnel { m_Buffer.CompleteCurrentTunnelDataMessage (); auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (); - for (auto tunnelMsg : tunnelMsgs) + for (auto& tunnelMsg : tunnelMsgs) { m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg); tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData); diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 4bd116cb..119556aa 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -49,13 +49,13 @@ namespace tunnel { { std::unique_lock l(m_InboundTunnelsMutex); - for (auto it: m_InboundTunnels) + for (auto& it: m_InboundTunnels) it->SetTunnelPool (nullptr); m_InboundTunnels.clear (); } { std::unique_lock l(m_OutboundTunnelsMutex); - for (auto it: m_OutboundTunnels) + for (auto& it: m_OutboundTunnels) it->SetTunnelPool (nullptr); m_OutboundTunnels.clear (); } @@ -78,7 +78,7 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - for (auto it: m_Tests) + for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; std::unique_lock l(m_InboundTunnelsMutex); @@ -101,7 +101,7 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - for (auto it: m_Tests) + for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; std::unique_lock l(m_OutboundTunnelsMutex); @@ -114,7 +114,7 @@ namespace tunnel std::vector > v; int i = 0; std::unique_lock l(m_InboundTunnelsMutex); - for (auto it : m_InboundTunnels) + for (const auto& it : m_InboundTunnels) { if (i >= num) break; if (it->IsEstablished ()) @@ -144,7 +144,7 @@ namespace tunnel if (tunnels.empty ()) return nullptr; uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0; typename TTunnels::value_type tunnel = nullptr; - for (auto it: tunnels) + for (const auto& it: tunnels) { if (it->IsEstablished () && it != excluded) { @@ -164,7 +164,7 @@ namespace tunnel if (old) { std::unique_lock l(m_OutboundTunnelsMutex); - for (auto it: m_OutboundTunnels) + for (const auto& it: m_OutboundTunnels) if (it->IsEstablished () && old->GetEndpointIdentHash () == it->GetEndpointIdentHash ()) { tunnel = it; @@ -182,7 +182,7 @@ namespace tunnel int num = 0; { std::unique_lock l(m_InboundTunnelsMutex); - for (auto it : m_InboundTunnels) + for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } for (int i = num; i < m_NumInboundTunnels; i++) @@ -191,7 +191,7 @@ namespace tunnel num = 0; { std::unique_lock l(m_OutboundTunnelsMutex); - for (auto it : m_OutboundTunnels) + for (const auto& it : m_OutboundTunnels) if (it->IsEstablished ()) num++; } for (int i = num; i < m_NumOutboundTunnels; i++) @@ -203,11 +203,10 @@ namespace tunnel decltype(m_Tests) tests; { std::unique_lock l(m_TestsMutex); - tests = m_Tests; - m_Tests.clear (); + tests.swap(m_Tests); } - for (auto it: tests) + for (auto& it: tests) { LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed"); // if test failed again with another tunnel we consider it failed @@ -248,12 +247,12 @@ namespace tunnel if ((*it1)->IsFailed ()) { failed = true; - it1++; + ++it1; } if ((*it2)->IsFailed ()) { failed = true; - it2++; + ++it2; } if (!failed) { @@ -265,7 +264,7 @@ namespace tunnel } (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), CreateDeliveryStatusMsg (msgID)); - it1++; it2++; + ++it1; ++it2; } } } diff --git a/UPnP.cpp b/UPnP.cpp index db0d3683..612b1441 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -122,8 +122,8 @@ namespace transport void UPnP::PortMapping () { - auto a = context.GetRouterInfo().GetAddresses(); - for (auto address : a) + const auto& a = context.GetRouterInfo().GetAddresses(); + for (const auto& address : a) { if (!address->host.is_v6 ()) TryPortMapping (address); @@ -139,8 +139,8 @@ namespace transport void UPnP::CloseMapping () { - auto a = context.GetRouterInfo().GetAddresses(); - for (auto address : a) + const auto& a = context.GetRouterInfo().GetAddresses(); + for (const auto& address : a) { if (!address->host.is_v6 ()) CloseMapping (address); From 8e835f2f6b03d6ab563a8575a964007283e3d5b4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Aug 2016 20:51:54 -0400 Subject: [PATCH 27/34] fixed race condition --- RouterInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index b594cb7a..90cf5e44 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -752,7 +752,8 @@ namespace data std::shared_ptr RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const { - for (const auto& address : *m_Addresses) + auto addresses = m_Addresses; + for (const auto& address : *addresses) { if (address->transportStyle == s) { From c27f8a5c1e9eba348e8b4b5e5dca74bbf7e6bafa Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Thu, 11 Aug 2016 12:25:26 +0300 Subject: [PATCH 28/34] Replaced arrows to HTML code. Deleted tab spaces. --- Tunnel.cpp | 317 ++++++++++++++++++++++++++--------------------------- 1 file changed, 158 insertions(+), 159 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 6a6accd6..7d2e6735 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -13,19 +13,19 @@ #include "Tunnel.h" namespace i2p -{ +{ namespace tunnel -{ - +{ + Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false) { - } + } Tunnel::~Tunnel () { - } + } void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { @@ -33,7 +33,7 @@ namespace tunnel int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops; auto msg = NewI2NPShortMessage (); *msg->GetPayload () = numRecords; - msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; + msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; // shuffle records std::vector recordIndicies; @@ -56,13 +56,13 @@ namespace tunnel hop->recordIndex = idx; i++; hop = hop->next; - } - // fill up fake records with random data + } + // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { int idx = recordIndicies[i]; RAND_bytes (records + idx*TUNNEL_BUILD_RECORD_SIZE, TUNNEL_BUILD_RECORD_SIZE); - } + } // decrypt real records i2p::crypto::CBCDecryption decryption; @@ -73,31 +73,31 @@ namespace tunnel // decrypt records after current hop TunnelHopConfig * hop1 = hop->next; while (hop1) - { + { decryption.SetIV (hop->replyIV); uint8_t * record = records + hop1->recordIndex*TUNNEL_BUILD_RECORD_SIZE; decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); hop1 = hop1->next; - } + } hop = hop->prev; - } + } msg->FillI2NPMessageHeader (eI2NPVariableTunnelBuild); // send message if (outboundTunnel) - outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); + outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); else i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); - } - + } + bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len) { LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); - + i2p::crypto::CBCDecryption decryption; TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) - { + { decryption.SetKey (hop->replyKey); // decrypt records before and including current hop TunnelHopConfig * hop1 = hop; @@ -105,22 +105,22 @@ namespace tunnel { auto idx = hop1->recordIndex; if (idx >= 0 && idx < msg[0]) - { + { uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; decryption.SetIV (hop->replyIV); decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); - } + } else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); hop1 = hop1->prev; - } + } hop = hop->prev; } bool established = true; hop = m_Config->GetFirstHop (); while (hop) - { + { const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; uint8_t ret = record[BUILD_RESPONSE_RECORD_RET_OFFSET]; LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret); @@ -143,12 +143,12 @@ namespace tunnel tunnelHop->decryption.SetKeys (hop->layerKey, hop->ivKey); m_Hops.push_back (std::unique_ptr(tunnelHop)); hop = hop->prev; - } + } m_Config = nullptr; - } + } if (established) m_State = eTunnelStateEstablished; return established; - } + } void Tunnel::EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) { @@ -158,20 +158,20 @@ namespace tunnel { it->decryption.Decrypt (inPayload, outPayload); inPayload = outPayload; - } - } + } + } void Tunnel::SendTunnelDataMsg (std::shared_ptr msg) { LogPrint (eLogWarning, "Tunnel: Can't send I2NP messages without delivery instructions"); - } + } std::vector > Tunnel::GetPeers () const { auto peers = GetInvertedPeers (); - std::reverse (peers.begin (), peers.end ()); + std::reverse (peers.begin (), peers.end ()); return peers; - } + } std::vector > Tunnel::GetInvertedPeers () const { @@ -179,54 +179,54 @@ namespace tunnel std::vector > ret; for (auto& it: m_Hops) ret.push_back (it->ident); - return ret; - } + return ret; + } void Tunnel::PrintHops (std::stringstream& s) const { for (auto& it: m_Hops) - { - s << " ⇒ "; + { + s << " ⇒ "; s << i2p::data::GetIdentHashAbbreviation (it->ident->GetIdentHash ()); - } - } - + } + } + void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) { - if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive + if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive auto newMsg = CreateEmptyTunnelDataMsg (); EncryptTunnelMsg (msg, newMsg); newMsg->from = shared_from_this (); - m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); - } + m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); + } void InboundTunnel::Print (std::stringstream& s) const { PrintHops (s); - s << " ⇒ " << GetTunnelID () << ":me"; - } + s << " ⇒ " << GetTunnelID () << ":me"; + } ZeroHopsInboundTunnel::ZeroHopsInboundTunnel (): InboundTunnel (std::make_shared ()), m_NumReceivedBytes (0) { - } - + } + void ZeroHopsInboundTunnel::SendTunnelDataMsg (std::shared_ptr msg) { if (msg) - { + { m_NumReceivedBytes += msg->GetLength (); msg->from = shared_from_this (); HandleI2NPMessage (msg); - } - } + } + } void ZeroHopsInboundTunnel::Print (std::stringstream& s) const { - s << " ⇒ " << GetTunnelID () << ":me"; - } - + s << " ⇒ " << GetTunnelID () << ":me"; + } + void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg) { TunnelMessageBlock block; @@ -234,28 +234,28 @@ namespace tunnel { block.hash = gwHash; if (gwTunnel) - { + { block.deliveryType = eDeliveryTypeTunnel; block.tunnelID = gwTunnel; - } + } else block.deliveryType = eDeliveryTypeRouter; - } - else + } + else block.deliveryType = eDeliveryTypeLocal; block.data = msg; - + SendTunnelDataMsg ({block}); } - + void OutboundTunnel::SendTunnelDataMsg (const std::vector& msgs) { std::unique_lock l(m_SendMutex); for (auto& it : msgs) m_Gateway.PutTunnelDataMsg (it); m_Gateway.SendBuffer (); - } - + } + void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { LogPrint (eLogError, "Tunnel: incoming message for outbound tunnel ", GetTunnelID ()); @@ -265,9 +265,9 @@ namespace tunnel { s << GetTunnelID () << ":me"; PrintHops (s); - s << " ⇒ "; - } - + s << " ⇒ "; + } + ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel (): OutboundTunnel (std::make_shared ()), m_NumSentBytes (0) @@ -286,30 +286,30 @@ namespace tunnel case eDeliveryTypeTunnel: i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data)); break; - case eDeliveryTypeRouter: + case eDeliveryTypeRouter: i2p::transport::transports.SendMessage (msg.hash, msg.data); break; default: LogPrint (eLogError, "Tunnel: Unknown delivery type ", (int)msg.deliveryType); - } + } } } void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const { - s << GetTunnelID () << ":me ⇒ "; + s << GetTunnelID () << ":me ⇒ "; } Tunnels tunnels; - + Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_NumSuccesiveTunnelCreations (0), m_NumFailedTunnelCreations (0) { } - - Tunnels::~Tunnels () + + Tunnels::~Tunnels () { - } + } std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { @@ -317,29 +317,29 @@ namespace tunnel if (it != m_Tunnels.end ()) return it->second; return nullptr; - } - + } + std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { - return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); + return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); } std::shared_ptr Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) { - return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); - } + return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); + } - template + template std::shared_ptr Tunnels::GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels) { auto it = pendingTunnels.find(replyMsgID); if (it != pendingTunnels.end () && it->second->GetState () == eTunnelStatePending) - { - it->second->SetState (eTunnelStateBuildReplyReceived); + { + it->second->SetState (eTunnelStateBuildReplyReceived); return it->second; } return nullptr; - } + } std::shared_ptr Tunnels::GetNextInboundTunnel () { @@ -353,26 +353,26 @@ namespace tunnel tunnel = it; minReceived = it->GetNumReceivedBytes (); } - } + } return tunnel; } - + std::shared_ptr Tunnels::GetNextOutboundTunnel () { if (m_OutboundTunnels.empty ()) return nullptr; uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0; std::shared_ptr tunnel; for (const auto& it: m_OutboundTunnels) - { + { if (it->IsEstablished ()) { tunnel = it; i++; } if (i > ind && tunnel) break; - } + } return tunnel; - } + } std::shared_ptr Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels) @@ -381,19 +381,19 @@ namespace tunnel std::unique_lock l(m_PoolsMutex); m_Pools.push_back (pool); return pool; - } + } void Tunnels::DeleteTunnelPool (std::shared_ptr pool) { if (pool) - { + { StopTunnelPool (pool); { std::unique_lock l(m_PoolsMutex); m_Pools.remove (pool); - } - } - } + } + } + } void Tunnels::StopTunnelPool (std::shared_ptr pool) { @@ -401,47 +401,47 @@ namespace tunnel { pool->SetActive (false); pool->DetachTunnels (); - } - } - + } + } + void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) m_TransitTunnels.push_back (tunnel); else LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); - } + } void Tunnels::Start () { m_IsRunning = true; m_Thread = new std::thread (std::bind (&Tunnels::Run, this)); } - + void Tunnels::Stop () { m_IsRunning = false; m_Queue.WakeUp (); if (m_Thread) - { + { m_Thread->join (); delete m_Thread; m_Thread = 0; - } - } + } + } void Tunnels::Run () { std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready - + uint64_t lastTs = 0; while (m_IsRunning) { try - { + { auto msg = m_Queue.GetNextWithTimeout (1000); // 1 sec if (msg) - { + { uint32_t prevTunnelID = 0, tunnelID = 0; std::shared_ptr prevTunnel; do @@ -449,16 +449,16 @@ namespace tunnel std::shared_ptr tunnel; uint8_t typeID = msg->GetTypeID (); switch (typeID) - { + { case eI2NPTunnelData: case eI2NPTunnelGateway: - { + { tunnelID = bufbe32toh (msg->GetPayload ()); if (tunnelID == prevTunnelID) tunnel = prevTunnel; else if (prevTunnel) prevTunnel->FlushTunnelDataMsgs (); - + if (!tunnel) tunnel = GetTunnel (tunnelID); if (tunnel) @@ -472,17 +472,17 @@ namespace tunnel LogPrint (eLogWarning, "Tunnel: tunnel not found, tunnelID=", tunnelID, " previousTunnelID=", prevTunnelID, " type=", (int)typeID); break; - } - case eI2NPVariableTunnelBuild: + } + case eI2NPVariableTunnelBuild: case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: - case eI2NPTunnelBuildReply: + case eI2NPTunnelBuildReply: HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); - break; + break; default: LogPrint (eLogWarning, "Tunnel: unexpected messsage type ", (int) typeID); } - + msg = m_Queue.Get (); if (msg) { @@ -493,8 +493,8 @@ namespace tunnel tunnel->FlushTunnelDataMsgs (); } while (msg); - } - + } + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); if (ts - lastTs >= 15) // manage tunnels every 15 seconds { @@ -505,9 +505,9 @@ namespace tunnel catch (std::exception& ex) { LogPrint (eLogError, "Tunnel: runtime exception: ", ex.what ()); - } - } - } + } + } + } void Tunnels::HandleTunnelGatewayMsg (std::shared_ptr tunnel, std::shared_ptr msg) { @@ -528,7 +528,7 @@ namespace tunnel msg->len = msg->offset + len; auto typeID = msg->GetTypeID (); LogPrint (eLogDebug, "Tunnel: gateway of ", (int) len, " bytes for tunnel ", tunnel->GetTunnelID (), ", msg type ", (int)typeID); - + if (IsRouterInfoMsg (msg) || typeID == eI2NPDatabaseSearchReply) // transit DatabaseStore my contain new/updated RI // or DatabaseSearchReply with new routers @@ -543,7 +543,7 @@ namespace tunnel ManageOutboundTunnels (); ManageTransitTunnels (); ManageTunnelPools (); - } + } void Tunnels::ManagePendingTunnels () { @@ -557,7 +557,7 @@ namespace tunnel // check pending tunnel. delete failed or timeout uint64_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) - { + { auto tunnel = it->second; switch (tunnel->GetState ()) { @@ -579,8 +579,8 @@ namespace tunnel profile->TunnelNonReplied (); } hop = hop->next; - } - } + } + } // delete it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; @@ -596,13 +596,13 @@ namespace tunnel case eTunnelStateBuildReplyReceived: // intermediate state, will be either established of build failed ++it; - break; + break; default: // success it = pendingTunnels.erase (it); m_NumSuccesiveTunnelCreations++; - } - } + } + } } void Tunnels::ManageOutboundTunnels () @@ -620,26 +620,26 @@ namespace tunnel pool->TunnelExpired (tunnel); // we don't have outbound tunnels in m_Tunnels it = m_OutboundTunnels.erase (it); - } + } else { if (tunnel->IsEstablished ()) - { + { if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - tunnel->SetIsRecreated (); + tunnel->SetIsRecreated (); auto pool = tunnel->GetTunnelPool (); if (pool) pool->RecreateOutboundTunnel (tunnel); } if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) tunnel->SetState (eTunnelStateExpiring); - } + } ++it; } } - } - + } + if (m_OutboundTunnels.size () < 5) { // trying to create one more oubound tunnel @@ -648,12 +648,12 @@ namespace tunnel if (!inboundTunnel || !router) return; LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); CreateTunnel ( - std::make_shared (std::vector > { router->GetRouterIdentity () }, - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) - ); + std::make_shared (std::vector > { router->GetRouterIdentity () }, + inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) + ); } } - + void Tunnels::ManageInboundTunnels () { uint64_t ts = i2p::util::GetSecondsSinceEpoch (); @@ -669,26 +669,26 @@ namespace tunnel pool->TunnelExpired (tunnel); m_Tunnels.erase (tunnel->GetTunnelID ()); it = m_InboundTunnels.erase (it); - } + } else { if (tunnel->IsEstablished ()) - { + { if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - tunnel->SetIsRecreated (); + tunnel->SetIsRecreated (); auto pool = tunnel->GetTunnelPool (); if (pool) pool->RecreateInboundTunnel (tunnel); } - + if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) tunnel->SetState (eTunnelStateExpiring); - } + } it++; } } - } + } if (m_InboundTunnels.empty ()) { @@ -702,10 +702,10 @@ namespace tunnel } return; } - + if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 5) { - // trying to create one more inbound tunnel + // trying to create one more inbound tunnel auto router = i2p::data::netdb.GetRandomRouter (); if (!router) { LogPrint (eLogWarning, "Tunnel: can't find any router, skip creating tunnel"); @@ -714,9 +714,9 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel"); CreateTunnel ( std::make_shared (std::vector > { router->GetRouterIdentity () }) - ); + ); } - } + } void Tunnels::ManageTransitTunnels () { @@ -729,35 +729,35 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired"); m_Tunnels.erase (tunnel->GetTunnelID ()); it = m_TransitTunnels.erase (it); - } + } else it++; } - } + } void Tunnels::ManageTunnelPools () { std::unique_lock l(m_PoolsMutex); for (auto& pool : m_Pools) - { + { if (pool && pool->IsActive ()) - { + { pool->CreateTunnels (); pool->TestTunnels (); - } + } } - } - + } + void Tunnels::PostTunnelData (std::shared_ptr msg) { - if (msg) m_Queue.Put (msg); - } + if (msg) m_Queue.Put (msg); + } void Tunnels::PostTunnelData (const std::vector >& msgs) { m_Queue.Put (msgs); - } - + } + template std::shared_ptr Tunnels::CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) { @@ -767,7 +767,7 @@ namespace tunnel AddPendingTunnel (replyMsgID, newTunnel); newTunnel->Build (replyMsgID, outboundTunnel); return newTunnel; - } + } std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) { @@ -804,20 +804,20 @@ namespace tunnel pool->TunnelCreated (newTunnel); else newTunnel->SetTunnelPool (nullptr); - } + } void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) - { + { m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) - { + { // build symmetric outbound tunnel CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), - GetNextOutboundTunnel ()); + GetNextOutboundTunnel ()); } else { @@ -829,9 +829,9 @@ namespace tunnel } else LogPrint (eLogError, "Tunnel: tunnel with id ", newTunnel->GetTunnelID (), " already exists"); - } + } + - std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel () { auto inboundTunnel = std::make_shared (); @@ -839,7 +839,7 @@ namespace tunnel m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; - } + } std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel () { @@ -859,7 +859,7 @@ namespace tunnel { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; if (t > timeout) timeout = t; - } + } return timeout; } @@ -882,4 +882,3 @@ namespace tunnel } } } - From 702e6c8080e3f7a936a0e9c5f7e7f0bd4703c6cb Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 09:30:35 -0400 Subject: [PATCH 29/34] buld instruction without QT --- docs/build_notes_android.md | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/docs/build_notes_android.md b/docs/build_notes_android.md index 71f0b2bc..b6cbd978 100644 --- a/docs/build_notes_android.md +++ b/docs/build_notes_android.md @@ -1,6 +1,8 @@ Building on Android =================== +There are two versions: with QT and without QT. + Pre-requesties -------------- @@ -8,12 +10,12 @@ You need to install Android SDK, NDK and QT with android support. - [SDK](https://developer.android.com/studio/index.html) (choose command line tools only) - [NDK](https://developer.android.com/ndk/downloads/index.html) -- [QT](https://www.qt.io/download-open-source/). Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run ) +- [QT](https://www.qt.io/download-open-source/).(for QT only) Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run ) You also need Java JDK and Ant. -QT-Creator ----------- +QT-Creator (for QT only) +------------------------ Open QT-creator that should be installed with QT. Go to Settings/Anndroid and specify correct paths to SDK and NDK. If everything is correct you will see two set avaiable: @@ -30,11 +32,26 @@ git clone https://github.com/PurpleI2P/android-ifaddrs.git ``` -Building the app ----------------- -- Open qt/i2pd_qt/i2pd_qt.pro in the QT-creator. -- Change line MAIN_PATH = /path/to/libraries to actual path where did you put the dependancies to. -- Select appropriate project (usually armeabi-v7a) and build. -- You will find an .apk file in android-build/bin folder. +Building the app with QT +------------------------ +- Open qt/i2pd_qt/i2pd_qt.pro in the QT-creator +- Change line MAIN_PATH = /path/to/libraries to an actual path where you put the dependancies to +- Select appropriate project (usually armeabi-v7a) and build +- You will find an .apk file in android-build/bin folder +Building the app without QT +--------------------------- +- Change line I2PD_LIBS_PATH in android/jni/Application.mk to an actual path where you put the dependancies to +- Run 'ndk-build -j4' from andorid folder +- Create or edit file 'local.properties'. Place 'sdk.dir=' and 'ndk.dir=' +- Run 'ant clean debug' +Creating release .apk +---------------------- +In order to create release .apk you must obtain a Java keystore file(.jks). Either you have in already, or you can generate it yourself using keytool, or from one of you existing well-know ceritificates. For example, i2pd release are signed with this [certificate](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/certificates/router/orignal_at_mail.i2p.crt). +Create file 'ant.propeties' +key.store= +key.alias= +key.store.password= +key.alias.password= +Run 'ant clean release' From a5da55d0f7e46c6bf60b0e8b46e7dab144e35adb Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 09:38:31 -0400 Subject: [PATCH 30/34] Update build_notes_android.md --- docs/build_notes_android.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/build_notes_android.md b/docs/build_notes_android.md index b6cbd978..93b8b77e 100644 --- a/docs/build_notes_android.md +++ b/docs/build_notes_android.md @@ -10,7 +10,7 @@ You need to install Android SDK, NDK and QT with android support. - [SDK](https://developer.android.com/studio/index.html) (choose command line tools only) - [NDK](https://developer.android.com/ndk/downloads/index.html) -- [QT](https://www.qt.io/download-open-source/).(for QT only) Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run ) +- [QT](https://www.qt.io/download-open-source/)(for QT only). Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run ) You also need Java JDK and Ant. @@ -50,8 +50,8 @@ Creating release .apk ---------------------- In order to create release .apk you must obtain a Java keystore file(.jks). Either you have in already, or you can generate it yourself using keytool, or from one of you existing well-know ceritificates. For example, i2pd release are signed with this [certificate](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/certificates/router/orignal_at_mail.i2p.crt). Create file 'ant.propeties' -key.store= -key.alias= -key.store.password= -key.alias.password= +key.store='path to keystore file' +key.alias='alias name' +key.store.password='keystore password' +key.alias.password='alias password' Run 'ant clean release' From 82d80d2ead0e188ebc9215f6fcdf97b6a0d37b78 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 10:28:36 -0400 Subject: [PATCH 31/34] moved Config.cpp to libi2pd --- filelist.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filelist.mk b/filelist.mk index d8d74252..f2f4937e 100644 --- a/filelist.mk +++ b/filelist.mk @@ -5,7 +5,7 @@ LIB_SRC = \ SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ - util.cpp api.cpp + Config.cpp util.cpp api.cpp LIB_CLIENT_SRC = \ AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \ @@ -13,5 +13,5 @@ LIB_CLIENT_SRC = \ # also: Daemon{Linux,Win32}.cpp will be added later DAEMON_SRC = \ - HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp Config.cpp i2pd.cpp + HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp From 8e849ea6f8c250a69d4c48970b9c4abd29ad0912 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 10:33:53 -0400 Subject: [PATCH 32/34] reseed from file --- Config.cpp | 18 ++++++++++++------ Reseed.cpp | 8 ++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Config.cpp b/Config.cpp index 2a35ce7e..a629f2d4 100644 --- a/Config.cpp +++ b/Config.cpp @@ -147,12 +147,17 @@ namespace config { #endif "Enable or disable elgamal precomputation table") ; + + options_description reseed("Reseed options"); + reseed.add_options() + ("reseed.file", value()->default_value(""), "Path to .su3 file") + ; - options_description trust("Trust options"); - trust.add_options() - ("trust.enabled", value()->default_value(false), "enable explicit trust options") - ("trust.family", value()->default_value(""), "Router Familiy to trust for first hops") - ("trust.hidden", value()->default_value(false), "should we hide our router from other routers?"); + options_description trust("Trust options"); + trust.add_options() + ("trust.enabled", value()->default_value(false), "enable explicit trust options") + ("trust.family", value()->default_value(""), "Router Familiy to trust for first hops") + ("trust.hidden", value()->default_value(false), "should we hide our router from other routers?"); m_OptionsDesc .add(general) @@ -166,7 +171,8 @@ namespace config { .add(i2pcontrol) .add(upnp) .add(precomputation) - .add(trust) + .add(reseed) + .add(trust) ; } diff --git a/Reseed.cpp b/Reseed.cpp index 236531f9..bac381b1 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -16,6 +16,7 @@ #include "NetDb.h" #include "HTTP.h" #include "util.h" +#include "Config.h" namespace i2p { @@ -51,6 +52,13 @@ namespace data int Reseeder::ReseedNowSU3 () { + std::string filename; i2p::config::GetOption("reseed.file", filename); + if (filename.length() > 0) // reseed file is specified + { + auto num = ProcessSU3File (filename.c_str ()); + if (num > 0) return num; // success + LogPrint (eLogWarning, "Can't reseed from ", filename, " . Trying from hosts"); + } auto ind = rand () % httpsReseedHostList.size (); std::string& reseedHost = httpsReseedHostList[ind]; return ReseedFromSU3 (reseedHost); From 4c96106666ddb8d86191ea9acfb3a06031e2421c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 10:37:03 -0400 Subject: [PATCH 33/34] reseed.file added --- docs/configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 8bd072b9..32cd7f49 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -70,7 +70,9 @@ All options below still possible in cmdline, but better write it in config file: * --upnp.enabled= - Enable or disable UPnP, false by default for CLI and true for GUI (Windows, Android) * --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default + * --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default +* --reseed.file - Full path to SU3 file to reseed from * --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default From db8d93d3085bf2e85c22b2368d2ff35abbdfd364 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Aug 2016 10:43:06 -0400 Subject: [PATCH 34/34] 2.9.0 --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 54fc295f..00064c00 100644 --- a/version.h +++ b/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 8 +#define I2PD_VERSION_MINOR 9 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)

Streams
StreamIDDestination
" << it->GetSendStreamID () << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << "" << (int)it->GetStatus () << "