From 48d9a03aa894169aab777917a9f8b7bace87909c Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Mon, 7 Jun 2021 12:58:57 -0400 Subject: [PATCH 001/383] tbytes in WinApp --- Win32/Win32App.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index db5a1f3d..133b57b6 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -132,7 +132,11 @@ namespace win32 auto mbytes = transfer & 0x03ff; transfer >>= 10; auto gbytes = transfer & 0x03ff; + transfer >>= 10; + auto tbytes = transfer & 0x03ff; + if (tbytes) + s << tbytes << " TB, "; if (gbytes) s << gbytes << " GB, "; if (mbytes) From d599502b1a31c45095e545f84de4f90c3fc88a4a Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Mon, 7 Jun 2021 23:49:56 -0400 Subject: [PATCH 002/383] 1000Gb+ display --- Win32/Win32App.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 133b57b6..7104ec7f 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -131,12 +131,8 @@ namespace win32 transfer >>= 10; auto mbytes = transfer & 0x03ff; transfer >>= 10; - auto gbytes = transfer & 0x03ff; - transfer >>= 10; - auto tbytes = transfer & 0x03ff; + auto gbytes = transfer; - if (tbytes) - s << tbytes << " TB, "; if (gbytes) s << gbytes << " GB, "; if (mbytes) From 1af9117b80ec0461d32eb7229d81ba57f2ed8775 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 15 Oct 2021 14:01:41 -0400 Subject: [PATCH 003/383] don't create new tunnel message for encryption/decryption --- libi2pd/TransitTunnel.cpp | 17 ++++++++--------- libi2pd/TransitTunnel.h | 8 ++++---- libi2pd/Tunnel.cpp | 13 ++++++------- libi2pd/Tunnel.h | 4 ++-- libi2pd/TunnelBase.h | 2 +- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index dc7655d1..c4f3fa19 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -37,15 +37,14 @@ namespace tunnel { } - void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (false); - EncryptTunnelMsg (tunnelMsg, newMsg); + EncryptTunnelMsg (tunnelMsg, tunnelMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); - htobe32buf (newMsg->GetPayload (), GetNextTunnelID ()); - newMsg->FillI2NPMessageHeader (eI2NPTunnelData); - m_TunnelDataMsgs.push_back (newMsg); + htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); + tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData); + m_TunnelDataMsgs.push_back (tunnelMsg); } void TransitTunnelParticipant::FlushTunnelDataMsgs () @@ -65,7 +64,7 @@ namespace tunnel LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ()); } - void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ()); } @@ -85,7 +84,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (tunnelMsg, newMsg); diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index e71ec750..bce90958 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -35,7 +35,7 @@ namespace tunnel // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); private: @@ -54,7 +54,7 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); void FlushTunnelDataMsgs (); private: @@ -95,7 +95,7 @@ namespace tunnel void Cleanup () { m_Endpoint.Cleanup (); } - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } private: diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 1f69470c..c8a1cc99 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -243,13 +243,12 @@ namespace tunnel } } - void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) + void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr&& msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive - auto newMsg = CreateEmptyTunnelDataMsg (true); - EncryptTunnelMsg (msg, newMsg); - newMsg->from = shared_from_this (); - m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); + EncryptTunnelMsg (msg, msg); + msg->from = shared_from_this (); + m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } void InboundTunnel::Print (std::stringstream& s) const @@ -308,7 +307,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { LogPrint (eLogError, "Tunnel: incoming message for outbound tunnel ", GetTunnelID ()); } @@ -519,7 +518,7 @@ namespace tunnel if (tunnel) { if (typeID == eI2NPTunnelData) - tunnel->HandleTunnelDataMsg (msg); + tunnel->HandleTunnelDataMsg (std::move (msg)); else // tunnel gateway assumed HandleTunnelGatewayMsg (tunnel, msg); } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 2e1c9534..930d0c58 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -132,7 +132,7 @@ namespace tunnel void Print (std::stringstream& s) const; // implements TunnelBase - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); bool IsInbound() const { return false; } @@ -148,7 +148,7 @@ namespace tunnel public: InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; - void HandleTunnelDataMsg (std::shared_ptr msg); + void HandleTunnelDataMsg (std::shared_ptr&& msg); virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; void Print (std::stringstream& s) const; bool IsInbound() const { return true; } diff --git a/libi2pd/TunnelBase.h b/libi2pd/TunnelBase.h index f98066d3..8d0edff1 100644 --- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -47,7 +47,7 @@ namespace tunnel virtual ~TunnelBase () {}; virtual void Cleanup () {}; - virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; + virtual void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) = 0; virtual void SendTunnelDataMsg (std::shared_ptr msg) = 0; virtual void FlushTunnelDataMsgs () {}; virtual void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) = 0; From d310efcb5cbe5f81cbd1b5705109b8f9caf14294 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Oct 2021 11:31:37 -0400 Subject: [PATCH 004/383] pass I2NPMessage by move --- libi2pd/I2NPProtocol.cpp | 2 +- libi2pd/I2NPProtocol.h | 2 +- libi2pd/NTCP2.cpp | 5 +++-- libi2pd/SSUData.cpp | 2 +- libi2pd/Transports.cpp | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 29d68b3c..0bc721ec 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -860,7 +860,7 @@ namespace i2p Flush (); } - void I2NPMessagesHandler::PutNextMessage (std::shared_ptr msg) + void I2NPMessagesHandler::PutNextMessage (std::shared_ptr&& msg) { if (msg) { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index f0777ac2..c8bf1697 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -301,7 +301,7 @@ namespace tunnel public: ~I2NPMessagesHandler (); - void PutNextMessage (std::shared_ptr msg); + void PutNextMessage (std::shared_ptr&& msg); void Flush (); private: diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 05d68203..296139a3 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -876,11 +876,12 @@ namespace transport break; } auto nextMsg = NewI2NPMessage (size); - nextMsg->Align (12); // for possible tunnel msg + nextMsg->Align (6); // for possible tunnel msg + nextMsg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); nextMsg->FromNTCP2 (); - m_Handler.PutNextMessage (nextMsg); + m_Handler.PutNextMessage (std::move (nextMsg)); break; } case eNTCP2BlkTermination: diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index ccc89b41..18b471e2 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -247,7 +247,7 @@ namespace transport m_ReceivedMessages.emplace (msgID, m_LastMessageReceivedTime); if (!msg->IsExpired ()) { - m_Handler.PutNextMessage (msg); + m_Handler.PutNextMessage (std::move (msg)); } else LogPrint (eLogDebug, "SSU: message expired"); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 181c3663..6fd5fad9 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -389,7 +389,7 @@ namespace transport { // we send it to ourself for (auto& it: msgs) - m_LoopbackHandler.PutNextMessage (it); + m_LoopbackHandler.PutNextMessage (std::move (it)); m_LoopbackHandler.Flush (); return; } From 197882a4c9e15ab6b3a40f4c658c3e6720019417 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Oct 2021 15:30:24 -0400 Subject: [PATCH 005/383] create I2NP depending on type in I2NP block --- libi2pd/NTCP2.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 296139a3..9e18c81e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -875,13 +875,16 @@ namespace transport LogPrint (eLogError, "NTCP2: I2NP block is too long ", size); break; } - auto nextMsg = NewI2NPMessage (size); - nextMsg->Align (6); // for possible tunnel msg - nextMsg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + auto nextMsg = (frame[offset] == eI2NPTunnelData) ? NewI2NPTunnelMessage (true) : NewI2NPMessage (size); nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header - memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); - nextMsg->FromNTCP2 (); - m_Handler.PutNextMessage (std::move (nextMsg)); + if (nextMsg->len <= nextMsg->maxLen) + { + memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); + nextMsg->FromNTCP2 (); + m_Handler.PutNextMessage (std::move (nextMsg)); + } + else + LogPrint (eLogError, "NTCP2: I2NP block is too long for I2NP message"); break; } case eNTCP2BlkTermination: From 278fd2d8d58210a126abfbbe4eb6a3b7d4b2063b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Oct 2021 19:03:08 -0400 Subject: [PATCH 006/383] create tunnel I2NP message for tunnel data --- libi2pd/SSUData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 18b471e2..6bf01778 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -176,7 +176,8 @@ namespace transport if (it == m_IncompleteMessages.end ()) { // create new message - auto msg = NewI2NPShortMessage (); + auto msg = (!fragmentNum && fragmentSize > 0 && buf[I2NP_SHORT_HEADER_TYPEID_OFFSET] == eI2NPTunnelData) ? + NewI2NPTunnelMessage (true) : NewI2NPShortMessage (); msg->len -= I2NP_SHORT_HEADER_SIZE; it = m_IncompleteMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (msg))).first; From efd84a240483de954c688cc12ebdf78e03968b24 Mon Sep 17 00:00:00 2001 From: xanoni <77220130+xanoni@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:10:17 -0400 Subject: [PATCH 007/383] Makefile: set default target ("all") Fixes compilation on Darwin, see: https://github.com/PurpleI2P/i2pd/pull/1698#issuecomment-946304938 --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index d7765af7..59b1df1a 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.DEFAULT_GOAL := all + SYS := $(shell $(CXX) -dumpmachine) ifneq (, $(findstring darwin, $(SYS))) From ff3d2db85e4c49600adf38c6de9087881b57247e Mon Sep 17 00:00:00 2001 From: xanoni <77220130+xanoni@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:29:30 -0400 Subject: [PATCH 008/383] Darwin: allow calling make install more than once This commit ensures that `gzip` does not overwrite any of the repo files, because that prevents `make install` from executing more than once. --- .gitignore | 1 + Makefile.homebrew | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bafe2e18..75bd6abb 100644 --- a/.gitignore +++ b/.gitignore @@ -260,6 +260,7 @@ docs/generated build/Makefile # debian stuff +debian/i2pd.1.gz .pc/ # qt diff --git a/Makefile.homebrew b/Makefile.homebrew index c1992296..8d6dd7a3 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -44,7 +44,7 @@ install: all install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd @cp -R contrib/certificates ${PREFIX}/share/i2pd/ install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd - @gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 + @gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 @ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/ @ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf @ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt From 0c25e8f1eb0f90089c8f95158cfa147672d28af8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 6 Oct 2021 21:35:23 +0300 Subject: [PATCH 009/383] [build] changes in windows build script Signed-off-by: R4SAS --- build/build_mingw.cmd | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index e8f1378b..a4e6d8de 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -34,13 +34,19 @@ del /S build_*.log >> nul 2>&1 echo Receiving latest commit and cleaning up... %xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1 -echo. REM set to variable current commit hash -FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO ( +FOR /F "usebackq" %%a IN (`%xSH% "git describe --tags"`) DO ( set tag=%%a ) +REM set to variable latest released tag +FOR /F "usebackq" %%b IN (`%xSH% "git describe --abbrev=0"`) DO ( + set reltag=%%b +) + +echo Preparing configuration files and README for packaging... + %xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul REM converting configuration files to DOS format (usable in default notepad) @@ -64,8 +70,9 @@ call :BUILDING_XP echo. REM compile installer -C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%tag%.0" build\win_installer.iss >> build\build.log 2>&1 +C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1 +%xSH% "git checkout contrib/*" >> build\build.log 2>&1 del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul echo Build complete... @@ -74,13 +81,13 @@ exit /b 0 :BUILDING %xSH% "make clean" >> nul -echo Building i2pd %tag% for win%bitness% +echo Building i2pd %tag% for win%bitness%... %xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build\build_win%bitness%_%tag%.log 2>&1 goto EOF :BUILDING_XP %xSH% "make clean" >> nul -echo Building i2pd %tag% for winxp +echo Building i2pd %tag% for winxp... %xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1 :EOF \ No newline at end of file From 8a58572b342449b1e6c90cb9bfb201b9c6614be3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 19 Oct 2021 18:24:49 +0300 Subject: [PATCH 010/383] [webconsole] upload example dark style Signed-off-by: R4SAS --- contrib/webconsole/style-dark.css | 272 ++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 contrib/webconsole/style-dark.css diff --git a/contrib/webconsole/style-dark.css b/contrib/webconsole/style-dark.css new file mode 100644 index 00000000..6ec19023 --- /dev/null +++ b/contrib/webconsole/style-dark.css @@ -0,0 +1,272 @@ +:root { + --main-bg-color: #121212; + --main-text-color: #156A3D; + --main-link-color: #894C84; +} + +body { + font: 100%/1.5em sans-serif; + margin: 0; + padding: 1.5em; + background: var(--main-bg-color); + color: var(--main-text-color); +} + +a, .slide label { + text-decoration: none; + color: var(--main-link-color); +} + +a:hover, .slide label:hover, button[type=submit]:hover { + color: #FAFAFA; + background: var(--main-link-color); +} + +a.button { + appearance: button; + text-decoration: none; + padding: 0 5px; + border: 1px solid var(--main-link-color); +} + +.header { + font-size: 2.5em; + text-align: center; + margin: 1em 0; + color: var(--main-link-color); +} + +.wrapper { + margin: 0 auto; + padding: 1em; + max-width: 64em; +} + +.menu { + display: block; + float: left; + overflow: hidden; + max-width: 12em; + white-space: nowrap; + text-overflow: ellipsis; +} + +.listitem { + display: block; + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.tableitem { + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.content { + float: left; + font-size: 1em; + margin-left: 4em; + max-width: 48em; + overflow: auto; +} + +.tunnel.established { + color: #56B734; +} + +.tunnel.expiring { + color: #D3AE3F; +} + +.tunnel.failed { + color: #D33F3F; +} + +.tunnel.building { + color: #434343; +} + +caption { + font-size: 1.5em; + text-align: center; + color: var(--main-link-color); +} + +table { + display: table; + border-collapse: collapse; + text-align: center; +} + +table.extaddr { + text-align: left; +} + +table.services { + width: 100%; +} + +textarea { + background-color: var(--main-bg-color); + color: var(--main-text-color); + word-break: break-all; +} + +.streamdest { + width: 120px; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; +} + +.slide div.slidecontent, .slide [type="checkbox"] { + display: none; +} + +.slide [type="checkbox"]:checked ~ div.slidecontent { + display: block; + margin-top: 0; + padding: 0; +} + +.disabled { + color: #D33F3F; +} + +.enabled { + color: #56B734; +} + +button[type=submit] { + background-color: transparent; + color: var(--main-link-color); + text-decoration: none; + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input, select, select option { + background-color: var(--main-bg-color); + color: var(--main-link-color); + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input:focus, select:focus, select option:focus { + outline: none; +} + +input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +@media screen and (max-width: 1150px) { /* adaptive style */ + .wrapper { + max-width: 58em; + } + + .menu { + max-width: 10em; + } + + .content { + margin-left: 2em; + max-width: 42em; + } +} + +@media screen and (max-width: 980px) { + body { + font: 100%/1.2em sans-serif; + padding: 1.2em 0 0 0; + } + + .menu { + width: 100%; + max-width: unset; + display: block; + float: none; + position: unset; + font-size: 16px; + text-align: center; + } + + .menu a, .commands a { + display: inline-block; + padding: 4px; + } + + .content { + float: none; + margin-left: unset; + margin-top: 16px; + max-width: 100%; + width: 100%; + text-align: center; + } + + a, .slide label { + /* margin-right: 10px; */ + display: block; + /* font-size: 18px; */ + } + + .header { + margin: unset; + font-size: 1.5em; + } + + small { + display: block + } + + a.button { + appearance: button; + text-decoration: none; + margin-top: 10px; + padding: 6px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + width: -webkit-fill-available; + } + + input, select { + width: 35%; + text-align: center; + padding: 5px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + font-size: 18px; + } + + table.extaddr { + margin: auto; + text-align: unset; + } + + textarea { + width: -webkit-fill-available; + height: auto; + padding: 5px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + font-size: 12px; + } + + button[type=submit] { + padding: 5px 15px; + background: transparent; + border: 2px solid var(--main-link-color); + cursor: pointer; + -webkit-border-radius: 5px; + border-radius: 5px; + position: relative; + height: 36px; + display: -webkit-inline-box; + margin-top: 10px; + } +} \ No newline at end of file From af794f901f5b4474de41168873d1cadc674b2988 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Fri, 8 Oct 2021 11:31:47 +0200 Subject: [PATCH 011/383] libi2pd: minor logging fixes --- libi2pd/SSUSession.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 3e4eecb8..b28f324b 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -303,7 +303,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: Wrong external address ", ourIP.to_string ()); + LogPrint (eLogError, "SSU: External address ", ourIP.to_string (), " is in reserved range"); Failed (); } } @@ -609,7 +609,7 @@ namespace transport { *payload = 16; payload++; // size - memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6 + memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Charlie's IP V6 payload += 16; // address } htobe16buf (payload, to.port ()); // Charlie's port @@ -703,7 +703,7 @@ namespace transport if (!i2p::util::net::IsInReservedRange (ourIP)) i2p::context.UpdateAddress (ourIP); else - LogPrint (eLogWarning, "SSU: Wrong external address ", ourIP.to_string ()); + LogPrint (eLogError, "SSU: External address ", ourIP.to_string (), " is in reserved range"); if (ourIP.is_v4 ()) { if (ourPort != m_Server.GetPort ()) @@ -1301,7 +1301,7 @@ namespace transport ip = boost::asio::ip::address_v6 (bytes); } else - LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported"); + LogPrint (eLogWarning, "SSU: Address size ", int(size), " is not supported"); buf += size; port = bufbe16toh (buf); return s; From a348e106206a1871d33e01cb381eaff50b0ad29c Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Mon, 18 Oct 2021 12:09:56 +0200 Subject: [PATCH 012/383] libi2pd: fix undefined behaviour and memory overruns This fixes the following issues (flagged by cppcheck): [libi2pd/ECIESX25519AEADRatchetSession.cpp:537]: (error) Buffer is accessed out of bounds: m_NSREncodedKey [libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: keys.publicKey [libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: publicKey [libi2pd/NetDb.cpp:70] -> [libi2pd/NetDb.cpp:69]: (error) Iterator 'it' used after element has been erased [libi2pd/SSUData.cpp:186] -> [libi2pd/SSUData.cpp:187]: (warning) Shifting 32-bit value by 63 bits is undefined behaviour. --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/Identity.cpp | 3 ++- libi2pd/NetDb.cpp | 2 +- libi2pd/SSUData.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c9671a7e..88d59c33 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -534,7 +534,7 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; } - memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR + memcpy (m_NSREncodedKey, out + offset, 32); // for possible next NSR memcpy (m_NSRH, m_H, 32); offset += 32; // KDF for Reply Key Section diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index aa03bfb7..fe876997 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -19,7 +19,8 @@ namespace data Identity& Identity::operator=(const Keys& keys) { // copy public and signing keys together - memcpy (publicKey, keys.publicKey, sizeof (publicKey) + sizeof (signingKey)); + memcpy (publicKey, keys.publicKey, sizeof (publicKey)); + memcpy (signingKey, keys.signingKey, sizeof (signingKey)); memset (certificate, 0, sizeof (certificate)); return *this; } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 8d0025ec..b4ffe2bd 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -66,8 +66,8 @@ namespace data if (it != m_RouterInfos.end ()) { // remove own router - m_RouterInfos.erase (it); m_Floodfills.remove (it->second); + m_RouterInfos.erase (it); } // insert own router m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 6bf01778..2f93218e 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -185,7 +185,7 @@ namespace transport auto& incompleteMessage = it->second; // mark fragment as received if (fragmentNum < 64) - incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum); + incompleteMessage->receivedFragmentsBits |= (uint64_t(0x01) << fragmentNum); else LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); From ae0cf2e8311cd2b8cdaa5a0c9f33907a6b82bfeb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Oct 2021 21:05:22 -0400 Subject: [PATCH 013/383] use memory pool for tunnel messages --- libi2pd/I2NPProtocol.cpp | 12 +++--------- libi2pd/Tunnel.cpp | 16 +++++++++++++++- libi2pd/Tunnel.h | 6 ++++++ libi2pd/util.h | 38 ++++++++++++++++++++++++++++++++------ 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 0bc721ec..fa4fa7a6 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,20 +38,14 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - I2NPMessage * msg = nullptr; if (endpoint) - { - // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet - msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 - msg->Align (6); - msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - } + return i2p::tunnel::tunnels.NewI2NPTunnelMessage (); else { - msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); + return std::shared_ptr(msg); } - return std::shared_ptr(msg); } std::shared_ptr NewI2NPMessage (size_t len) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index c8a1cc99..3de91940 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -488,7 +488,7 @@ namespace tunnel i2p::util::SetThreadName("Tunnels"); std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready - uint64_t lastTs = 0, lastPoolsTs = 0; + uint64_t lastTs = 0, lastPoolsTs = 0, lastMemoryPoolTs = 0; while (m_IsRunning) { try @@ -564,6 +564,11 @@ namespace tunnel ManageTunnelPools (ts); lastPoolsTs = ts; } + if (ts - lastMemoryPoolTs >= 120) // manage memory pool every 2 minutes + { + m_I2NPTunnelMessagesMemoryPool.CleanUpMt (); + lastMemoryPoolTs = ts; + } } } catch (std::exception& ex) @@ -935,6 +940,15 @@ namespace tunnel return outboundTunnel; } + std::shared_ptr Tunnels::NewI2NPTunnelMessage () + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + return msg; + } + int Tunnels::GetTransitTunnelsExpirationTimeout () { int timeout = 0; diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 930d0c58..30d9d565 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -18,6 +18,7 @@ #include #include #include +#include "util.h" #include "Queue.h" #include "Crypto.h" #include "TunnelConfig.h" @@ -40,6 +41,8 @@ namespace tunnel const int MAX_NUM_RECORDS = 8; const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds + const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6 + enum TunnelState { eTunnelStatePending, @@ -219,6 +222,8 @@ namespace tunnel void DeleteTunnelPool (std::shared_ptr pool); void StopTunnelPool (std::shared_ptr pool); + std::shared_ptr NewI2NPTunnelMessage (); + private: template @@ -257,6 +262,7 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; + i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; diff --git a/libi2pd/util.h b/libi2pd/util.h index 282ce7aa..d681829c 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -56,12 +56,8 @@ namespace util void CleanUp () { - while (m_Head) - { - auto tmp = m_Head; - m_Head = static_cast(*(void * *)m_Head); // next - ::operator delete ((void *)tmp); - } + CleanUp (m_Head); + m_Head = nullptr; } template @@ -98,6 +94,18 @@ namespace util std::bind (&MemoryPool::Release, this, std::placeholders::_1)); } + protected: + + void CleanUp (T * head) + { + while (head) + { + auto tmp = head; + head = static_cast(*(void * *)head); // next + ::operator delete ((void *)tmp); + } + } + protected: T * m_Head; @@ -131,6 +139,24 @@ namespace util this->Release (it); } + template + std::shared_ptr AcquireSharedMt (TArgs&&... args) + { + return std::shared_ptr(AcquireMt (std::forward(args)...), + std::bind::*)(T *)> (&MemoryPoolMt::ReleaseMt, this, std::placeholders::_1)); + } + + void CleanUpMt () + { + T * head; + { + std::lock_guard l(m_Mutex); + head = this->m_Head; + this->m_Head = nullptr; + } + if (head) this->CleanUp (head); + } + private: std::mutex m_Mutex; From b0f043ec863cfe48332afc5edffc37a949e4ae5c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 Oct 2021 05:28:59 +0300 Subject: [PATCH 014/383] [make] USE_GIT_VERSION option to use commit info in version (closes #1702) Signed-off-by: R4SAS --- Makefile | 21 ++++++++++++++++----- daemon/Daemon.cpp | 2 +- libi2pd/version.h | 7 ++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 59b1df1a..f1258874 100644 --- a/Makefile +++ b/Makefile @@ -29,11 +29,17 @@ DAEMON_SRC_DIR := daemon # import source files lists include filelist.mk -USE_AESNI := $(or $(USE_AESNI),yes) -USE_STATIC := $(or $(USE_STATIC),no) -USE_MESHNET := $(or $(USE_MESHNET),no) -USE_UPNP := $(or $(USE_UPNP),no) -DEBUG := $(or $(DEBUG),yes) +USE_AESNI := $(or $(USE_AESNI),yes) +USE_STATIC := $(or $(USE_STATIC),no) +USE_MESHNET := $(or $(USE_MESHNET),no) +USE_UPNP := $(or $(USE_UPNP),no) +DEBUG := $(or $(DEBUG),yes) + +# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string +USE_GIT_VERSION := $(or $(USE_GIT_VERSION),no) + +# for MacOS only, waiting for "1", not "yes" +HOMEBREW := $(or $(HOMEBREW),0) ifeq ($(DEBUG),yes) CXX_DEBUG = -g @@ -66,6 +72,11 @@ ifeq ($(USE_MESHNET),yes) NEEDED_CXXFLAGS += -DMESHNET endif +ifeq ($(USE_GIT_VERSION),yes) + GIT_VERSION := $(shell git describe --tags) + NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\" +endif + NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 445c4dfd..8cee7852 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -134,7 +134,7 @@ namespace util // use stdout -- default } - LogPrint(eLogNone, "i2pd v", VERSION, " starting"); + LogPrint(eLogNone, "i2pd v", VERSION, " (", I2P_VERSION, ") starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); LogPrint(eLogDebug, "FS: certificates directory: ", certsdir); diff --git a/libi2pd/version.h b/libi2pd/version.h index 97351c40..5aba36bd 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -19,7 +19,12 @@ #define I2PD_VERSION_MINOR 39 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 -#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) +#ifdef GITVER + #define I2PD_VERSION GITVER +#else + #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) +#endif + #define VERSION I2PD_VERSION #ifdef MESHNET From 0a62a962d7d702d66acab122902521ae41d734b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 Oct 2021 05:57:04 +0300 Subject: [PATCH 015/383] [debian] update upnp patch Signed-off-by: R4SAS --- debian/patches/02-upnp.patch | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 75ea2bfa..99698737 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -2,16 +2,16 @@ Description: Enable UPnP usage in package Author: r4sas Reviewed-By: r4sas -Last-Update: 2021-01-16 +Last-Update: 2021-10-22 --- i2pd.orig/Makefile +++ i2pd/Makefile -@@ -21,7 +21,7 @@ include filelist.mk - USE_AESNI := $(or $(USE_AESNI),yes) - USE_STATIC := $(or $(USE_STATIC),no) - USE_MESHNET := $(or $(USE_MESHNET),no) --USE_UPNP := $(or $(USE_UPNP),no) -+USE_UPNP := $(or $(USE_UPNP),yes) - DEBUG := $(or $(DEBUG),yes) +@@ -32,7 +32,7 @@ include filelist.mk + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) - ifeq ($(DEBUG),yes) + # for debugging purposes only, when commit hash needed in trunk builds in i2pd version string From cdc8e463b7e393458921d2d3788b0dd99feabc6d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Oct 2021 19:18:45 -0400 Subject: [PATCH 016/383] use memory pool for outgoing tunnel gateway messages --- libi2pd/I2NPProtocol.cpp | 9 +-------- libi2pd/Tunnel.cpp | 22 ++++++++++++++++------ libi2pd/Tunnel.h | 6 ++++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index fa4fa7a6..bdd65d30 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,14 +38,7 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - if (endpoint) - return i2p::tunnel::tunnels.NewI2NPTunnelMessage (); - else - { - auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 - msg->Align (12); - return std::shared_ptr(msg); - } + return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint); } std::shared_ptr NewI2NPMessage (size_t len) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 3de91940..a315ff49 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -566,6 +566,7 @@ namespace tunnel } if (ts - lastMemoryPoolTs >= 120) // manage memory pool every 2 minutes { + m_I2NPTunnelEndpointMessagesMemoryPool.CleanUpMt (); m_I2NPTunnelMessagesMemoryPool.CleanUpMt (); lastMemoryPoolTs = ts; } @@ -940,13 +941,22 @@ namespace tunnel return outboundTunnel; } - std::shared_ptr Tunnels::NewI2NPTunnelMessage () + std::shared_ptr Tunnels::NewI2NPTunnelMessage (bool endpoint) { - // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet - auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); - msg->Align (6); - msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - return msg; + if (endpoint) + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + auto msg = m_I2NPTunnelEndpointMessagesMemoryPool.AcquireSharedMt (); + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + return msg; + } + else + { + auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); + msg->Align (12); + return msg; + } } int Tunnels::GetTransitTunnelsExpirationTimeout () diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 30d9d565..56166e0b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -41,6 +41,7 @@ namespace tunnel const int MAX_NUM_RECORDS = 8; const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds + const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12 const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6 enum TunnelState @@ -222,7 +223,7 @@ namespace tunnel void DeleteTunnelPool (std::shared_ptr pool); void StopTunnelPool (std::shared_ptr pool); - std::shared_ptr NewI2NPTunnelMessage (); + std::shared_ptr NewI2NPTunnelMessage (bool endpoint); private: @@ -262,7 +263,8 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; - i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; + i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; + i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; From f1990bc2ab1c6b9cc32c5f7a07b7a9d08ae0c8f1 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Oct 2021 21:08:20 -0400 Subject: [PATCH 017/383] use tunnel endpoint memroy pool to split to tunnel messages at gateway --- libi2pd/TunnelGateway.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 08df569c..c9ad0357 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -158,8 +158,7 @@ namespace tunnel void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage () { m_CurrentTunnelDataMsg = nullptr; - m_CurrentTunnelDataMsg = NewI2NPShortMessage (); - m_CurrentTunnelDataMsg->Align (12); + m_CurrentTunnelDataMsg = NewI2NPTunnelMessage (true); // tunnel endpoint is at least of two tunnel messages size // we reserve space for padding m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE; m_CurrentTunnelDataMsg->len = m_CurrentTunnelDataMsg->offset; From 921ec9ec12ead861994c98d96087b93a31051ef5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 Oct 2021 18:10:02 -0400 Subject: [PATCH 018/383] fix build with openssl 3.0.0 --- libi2pd/Crypto.cpp | 2 +- libi2pd/Reseed.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 427bbbd6..d38d489a 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1277,7 +1277,7 @@ namespace crypto EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len); } if (info.length () > 0) - EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ()); + EVP_PKEY_CTX_add1_hkdf_info (pctx, (const uint8_t *)info.c_str (), info.length ()); EVP_PKEY_derive (pctx, out, &outLen); EVP_PKEY_CTX_free (pctx); #else diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index aec683d4..2e8eccf7 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -478,7 +478,7 @@ namespace data if (terminator) terminator[0] = 0; } // extract RSA key (we need n only, e = 65537) - RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert)); + const RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert)); const BIGNUM * n, * e, * d; RSA_get0_key(key, &n, &e, &d); PublicKey value; From 9965d72990b704a8c724fb6f5d3a951fce8ca4aa Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Oct 2021 21:36:34 -0400 Subject: [PATCH 019/383] don't store EVP_PKEY with EdDSA signer and verifier --- libi2pd/Signature.cpp | 27 +++++++++++---------------- libi2pd/Signature.h | 5 ++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 88ee4060..28ae5fa6 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,8 +15,7 @@ namespace i2p namespace crypto { #if OPENSSL_EDDSA - EDDSA25519Verifier::EDDSA25519Verifier (): - m_Pkey (nullptr) + EDDSA25519Verifier::EDDSA25519Verifier () { m_MDCtx = EVP_MD_CTX_create (); } @@ -24,13 +23,13 @@ namespace crypto EDDSA25519Verifier::~EDDSA25519Verifier () { EVP_MD_CTX_destroy (m_MDCtx); - if (m_Pkey) EVP_PKEY_free (m_Pkey); } void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) { - m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); - EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + EVP_PKEY * pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); + EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, pkey); + EVP_PKEY_free (pkey); } bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const @@ -100,33 +99,29 @@ namespace crypto #if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): - m_Fallback (nullptr) + m_MDCtx (nullptr), m_Fallback (nullptr) { - m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + EVP_PKEY * pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; - EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); + EVP_PKEY_get_raw_public_key (pkey, publicKey, &len); if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) { LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); - EVP_PKEY_free (m_Pkey); m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); } else { m_MDCtx = EVP_MD_CTX_create (); - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, pkey); } + EVP_PKEY_free (pkey); } EDDSA25519Signer::~EDDSA25519Signer () { if (m_Fallback) delete m_Fallback; - else - { - EVP_MD_CTX_destroy (m_MDCtx); - EVP_PKEY_free (m_Pkey); - } + EVP_MD_CTX_destroy (m_MDCtx); } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 18084603..caf9b274 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -304,7 +304,6 @@ namespace crypto private: #if OPENSSL_EDDSA - EVP_PKEY * m_Pkey; EVP_MD_CTX * m_MDCtx; #else EDDSAPoint m_PublicKey; @@ -341,7 +340,7 @@ namespace crypto void Sign (const uint8_t * buf, int len, uint8_t * signature) const; private: - EVP_PKEY * m_Pkey; + EVP_MD_CTX * m_MDCtx; EDDSA25519SignerCompat * m_Fallback; }; From bb8dc679421ae8e116ebc4a1bc4648e6887d4c62 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 19:05:16 -0400 Subject: [PATCH 020/383] don't use openssl's SipHash from 3.0.0 due regression --- libi2pd/Crypto.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 5f42b527..75942905 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -39,7 +39,9 @@ # define OPENSSL_HKDF 1 # define OPENSSL_EDDSA 1 # define OPENSSL_X25519 1 -# define OPENSSL_SIPHASH 1 +# if (OPENSSL_VERSION_NUMBER < 0x030000000) // 3.0.0, regression in SipHash +# define OPENSSL_SIPHASH 1 +# endif # endif # if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them # define OPENSSL_AEAD_CHACHA20_POLY1305 1 From 8566f6c127eb54825cdbabefa32c25a611c5f241 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 21:18:21 -0400 Subject: [PATCH 021/383] don't store EVP_PKEY sip keys --- libi2pd/NTCP2.cpp | 19 ++++++++++--------- libi2pd/NTCP2.h | 1 - 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 9e18c81e..b4f290dd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -323,9 +323,10 @@ namespace transport m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_Establisher (new NTCP2Establisher), - m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), #if OPENSSL_SIPHASH m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), +#else + m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), m_NextReceivedBufferSize (0), m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), @@ -352,8 +353,6 @@ namespace transport delete[] m_NextReceivedBuffer; delete[] m_NextSendBuffer; #if OPENSSL_SIPHASH - if (m_SendSipKey) EVP_PKEY_free (m_SendSipKey); - if (m_ReceiveSipKey) EVP_PKEY_free (m_ReceiveSipKey); if (m_SendMDCtx) EVP_MD_CTX_destroy (m_SendMDCtx); if (m_ReceiveMDCtx) EVP_MD_CTX_destroy (m_ReceiveMDCtx); #endif @@ -711,17 +710,19 @@ namespace transport void NTCP2Session::SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey) { #if OPENSSL_SIPHASH - m_SendSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); + EVP_PKEY * sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); m_SendMDCtx = EVP_MD_CTX_create (); EVP_PKEY_CTX *ctx = nullptr; - EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, m_SendSipKey); + EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, sipKey); EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); - - m_ReceiveSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, receiveSipKey, 16); + EVP_PKEY_free (sipKey); + + sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, receiveSipKey, 16); m_ReceiveMDCtx = EVP_MD_CTX_create (); ctx = nullptr; - EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, m_ReceiveSipKey); + EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, sipKey); EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); + EVP_PKEY_free (sipKey); #else m_SendSipKey = sendSipKey; m_ReceiveSipKey = receiveSipKey; @@ -1114,7 +1115,7 @@ namespace transport void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { - if (!m_SendKey || !m_SendSipKey) return; + if (!m_SendKey) return; m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block // termination block m_NextSendBuffer[2] = eNTCP2BlkTermination; diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index f9f3e751..3516ce6a 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -205,7 +205,6 @@ namespace transport uint8_t m_Kab[32], m_Kba[32], m_Sipkeysab[32], m_Sipkeysba[32]; const uint8_t * m_SendKey, * m_ReceiveKey; #if OPENSSL_SIPHASH - EVP_PKEY * m_SendSipKey, * m_ReceiveSipKey; EVP_MD_CTX * m_SendMDCtx, * m_ReceiveMDCtx; #else const uint8_t * m_SendSipKey, * m_ReceiveSipKey; From 876e98d91e2cf75f1c856e1d8ec2e3efac401ba9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 22:23:32 -0400 Subject: [PATCH 022/383] check if sip key is available --- libi2pd/NTCP2.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index b4f290dd..03aac04d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -910,12 +910,14 @@ namespace transport void NTCP2Session::SetNextSentFrameLength (size_t frameLen, uint8_t * lengthBuf) { - #if OPENSSL_SIPHASH +#if OPENSSL_SIPHASH + if (!m_SendMDCtx) return; EVP_DigestSignInit (m_SendMDCtx, nullptr, nullptr, nullptr, nullptr); EVP_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); size_t l = 8; - EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); + EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); #else + if (!m_SendSipKey) return; i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); #endif // length must be in BigEndian From 26db88d89be2cd9cba842593c8d597e768b5fa05 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 22:33:37 -0400 Subject: [PATCH 023/383] check if sip key is available --- libi2pd/NTCP2.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 03aac04d..e592a7f2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -911,13 +911,11 @@ namespace transport void NTCP2Session::SetNextSentFrameLength (size_t frameLen, uint8_t * lengthBuf) { #if OPENSSL_SIPHASH - if (!m_SendMDCtx) return; EVP_DigestSignInit (m_SendMDCtx, nullptr, nullptr, nullptr, nullptr); EVP_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); size_t l = 8; EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); #else - if (!m_SendSipKey) return; i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); #endif // length must be in BigEndian @@ -1117,7 +1115,13 @@ namespace transport void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { - if (!m_SendKey) return; + if (!m_SendKey || +#if OPENSSL_SIPHASH + !m_SendMDCtx +#else + !m_SendSipKey +#endif + ) return; m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block // termination block m_NextSendBuffer[2] = eNTCP2BlkTermination; From 7073a6bf384e763b46dc891d0091f69d295bca58 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Thu, 28 Oct 2021 21:59:27 +0200 Subject: [PATCH 024/383] libi2pd: make Tunnel and TunnelConfig destructors virtual --- libi2pd/Tunnel.h | 2 +- libi2pd/TunnelConfig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 56166e0b..80d29a15 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -68,7 +68,7 @@ namespace tunnel public: Tunnel (std::shared_ptr config); - ~Tunnel (); + virtual ~Tunnel (); void Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel = nullptr); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f198dffd..ae924ba6 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - ~TunnelConfig () + virtual ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; From 1de1c79d4f72a1c7aa3ad51e6a582df5c8302c39 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Sun, 31 Oct 2021 14:51:41 +0100 Subject: [PATCH 025/383] libi2pd: add missing locks to i2p::tunnel::Tunnels m_InboundTunnelsMutex, m_OutboundTunnelsMutex and m_PoolsMutex have been changed to recursive_mutexes since they can be acquired multiple times by the same thread. --- libi2pd/Tunnel.cpp | 33 ++++++++++++++++++++++++++++----- libi2pd/Tunnel.h | 8 +++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a315ff49..f3cdd432 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -366,6 +366,7 @@ namespace tunnel std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { + std::unique_lock l(m_TunnelsMutex); auto it = m_Tunnels.find(tunnelID); if (it != m_Tunnels.end ()) return it->second; @@ -374,11 +375,13 @@ namespace tunnel std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { + std::unique_lock l(m_PendingInboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); } std::shared_ptr Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) { + std::unique_lock l(m_PendingOutboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); } @@ -459,9 +462,11 @@ namespace tunnel void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { - if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) + std::unique_lock l(m_TunnelsMutex); + if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) { + std::unique_lock l(m_TransitTunnelsMutex); m_TransitTunnels.push_back (tunnel); - else + } else LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); } @@ -616,7 +621,10 @@ namespace tunnel void Tunnels::ManagePendingTunnels () { + std::unique_lock li(m_PendingInboundTunnelsMutex); ManagePendingTunnels (m_PendingInboundTunnels); + li.unlock(); + std::unique_lock lo(m_PendingOutboundTunnelsMutex); ManagePendingTunnels (m_PendingOutboundTunnels); } @@ -676,6 +684,7 @@ namespace tunnel void Tunnels::ManageOutboundTunnels () { + std::unique_lock l(m_OutboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) @@ -730,6 +739,8 @@ namespace tunnel void Tunnels::ManageInboundTunnels () { + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) @@ -786,6 +797,7 @@ namespace tunnel return; } + std::unique_lock lo(m_OutboundTunnelsMutex); if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3) { // trying to create one more inbound tunnel @@ -806,6 +818,8 @@ namespace tunnel void Tunnels::ManageTransitTunnels () { + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock l(m_TransitTunnelsMutex); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { @@ -876,17 +890,20 @@ namespace tunnel void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { + std::unique_lock l(m_PendingInboundTunnelsMutex); m_PendingInboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { + std::unique_lock l(m_PendingOutboundTunnelsMutex); m_PendingOutboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddOutboundTunnel (std::shared_ptr newTunnel) { // we don't need to insert it to m_Tunnels + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (pool && pool->IsActive ()) @@ -897,8 +914,10 @@ namespace tunnel void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { + std::unique_lock l(m_TunnelsMutex); if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) { + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) @@ -926,6 +945,8 @@ namespace tunnel auto inboundTunnel = std::make_shared (); inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; @@ -936,6 +957,7 @@ namespace tunnel auto outboundTunnel = std::make_shared (); outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels return outboundTunnel; @@ -964,6 +986,7 @@ namespace tunnel int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // TODO: possible race condition with I2PControl + std::unique_lock l(m_TransitTunnelsMutex); for (const auto& it : m_TransitTunnels) { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; @@ -974,19 +997,19 @@ namespace tunnel size_t Tunnels::CountTransitTunnels() const { - // TODO: locking + std::unique_lock l(m_TransitTunnelsMutex); return m_TransitTunnels.size(); } size_t Tunnels::CountInboundTunnels() const { - // TODO: locking + std::unique_lock l(m_InboundTunnelsMutex); return m_InboundTunnels.size(); } size_t Tunnels::CountOutboundTunnels() const { - // TODO: locking + std::unique_lock l(m_OutboundTunnelsMutex); return m_OutboundTunnels.size(); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 80d29a15..640a9ca7 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -254,12 +254,18 @@ namespace tunnel bool m_IsRunning; std::thread * m_Thread; std::map > m_PendingInboundTunnels; // by replyMsgID + mutable std::mutex m_PendingInboundTunnelsMutex; std::map > m_PendingOutboundTunnels; // by replyMsgID + mutable std::mutex m_PendingOutboundTunnelsMutex; std::list > m_InboundTunnels; + mutable std::recursive_mutex m_InboundTunnelsMutex; std::list > m_OutboundTunnels; + mutable std::recursive_mutex m_OutboundTunnelsMutex; std::list > m_TransitTunnels; + mutable std::mutex m_TransitTunnelsMutex; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id - std::mutex m_PoolsMutex; + mutable std::recursive_mutex m_TunnelsMutex; + mutable std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; From 58b7b7d7317df28a40a6bc620761eb218d551a02 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Sat, 30 Oct 2021 23:14:48 +0200 Subject: [PATCH 026/383] libi2pd: add missing locks to i2p::tunnel::TunnelPool --- libi2pd/TunnelPool.cpp | 46 +++++++++++++++++++++++++++++++++--------- libi2pd/TunnelPool.h | 6 ++++-- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5ed330c8..4d00ad6f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -59,6 +59,7 @@ namespace tunnel void TunnelPool::SetExplicitPeers (std::shared_ptr > explicitPeers) { + std::unique_lock l(m_ExplicitPeersMutex); m_ExplicitPeers = explicitPeers; if (m_ExplicitPeers) { @@ -92,6 +93,7 @@ namespace tunnel it->SetTunnelPool (nullptr); m_OutboundTunnels.clear (); } + std::unique_lock l(m_TestsMutex); m_Tests.clear (); } @@ -126,6 +128,7 @@ namespace tunnel } m_InboundTunnels.insert (createdTunnel); } + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -135,10 +138,11 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); + std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (expiredTunnel); } } @@ -157,10 +161,11 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); + std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (expiredTunnel); } } @@ -261,11 +266,21 @@ namespace tunnel return tunnel; } + std::shared_ptr TunnelPool::GetLocalDestination () const { + std::unique_lock l(m_LocalDestinationMutex); + return m_LocalDestination; + } + + void TunnelPool::SetLocalDestination (std::shared_ptr destination) { + std::unique_lock l(m_LocalDestinationMutex); + m_LocalDestination = destination; + } + void TunnelPool::CreateTunnels () { int num = 0; { - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); for (const auto& it : m_OutboundTunnels) if (it->IsEstablished ()) num++; } @@ -274,10 +289,11 @@ namespace tunnel num = 0; { - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } + std::unique_lock lo(m_OutboundTunnelsMutex); if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) { for (auto it: m_OutboundTunnels) @@ -287,9 +303,11 @@ namespace tunnel if (num >= m_NumInboundTunnels) break; } } + lo.unlock(); for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); + std::unique_lock l(m_LocalDestinationMutex); if (num < m_NumInboundTunnels && m_NumInboundHops <= 0 && m_LocalDestination) // zero hops IB m_LocalDestination->SetLeaseSetUpdated (); // update LeaseSet immediately } @@ -311,7 +329,7 @@ namespace tunnel if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else @@ -323,9 +341,10 @@ namespace tunnel { it.second.second->SetState (eTunnelStateFailed); { - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } + std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -335,7 +354,10 @@ namespace tunnel } // new tests + std::unique_lock lt(m_TestsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); + std::unique_lock li(m_InboundTunnelsMutex); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { @@ -355,7 +377,6 @@ namespace tunnel uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); { - std::unique_lock l(m_TestsMutex); m_Tests[msgID] = std::make_pair (*it1, *it2); } (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), @@ -377,10 +398,11 @@ namespace tunnel void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else - LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, dropped"); + LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, garlic message dropped"); } void TunnelPool::ProcessDeliveryStatus (std::shared_ptr msg) @@ -425,10 +447,11 @@ namespace tunnel } else { + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, delivery status message dropped"); } } @@ -512,13 +535,16 @@ namespace tunnel if (m_CustomPeerSelector) return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } + // explicit peers in use + std::lock_guard lock(m_ExplicitPeersMutex); if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { + std::unique_lock l(m_ExplicitPeersMutex); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); if (!numHops) return false; @@ -610,8 +636,10 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { + std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) path.isShort = false; // because can't handle ECIES encrypted reply + ld.unlock(); std::shared_ptr config; if (m_NumOutboundHops > 0) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 875a9955..1069e1b9 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -64,8 +64,8 @@ namespace tunnel TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels); ~TunnelPool (); - std::shared_ptr GetLocalDestination () const { return m_LocalDestination; }; - void SetLocalDestination (std::shared_ptr destination) { m_LocalDestination = destination; }; + std::shared_ptr GetLocalDestination () const; + void SetLocalDestination (std::shared_ptr destination); void SetExplicitPeers (std::shared_ptr > explicitPeers); void CreateTunnels (); @@ -126,8 +126,10 @@ namespace tunnel private: + mutable std::mutex m_LocalDestinationMutex; std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; + mutable std::mutex m_ExplicitPeersMutex; std::shared_ptr > m_ExplicitPeers; mutable std::mutex m_InboundTunnelsMutex; std::set, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first From 4c5ec68ff14ea9f144b0cad792956315d4969233 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 1 Nov 2021 02:40:54 +0300 Subject: [PATCH 027/383] [win] add menu item for opening datadir Signed-off-by: R4SAS --- Win32/Win32App.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 7104ec7f..377e1076 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -31,6 +31,7 @@ #define ID_RELOAD 2006 #define ID_ACCEPT_TRANSIT 2007 #define ID_DECLINE_TRANSIT 2008 +#define ID_DATADIR 2009 #define ID_TRAY_ICON 2050 #define WM_TRAYICON (WM_USER + 1) @@ -49,7 +50,8 @@ namespace win32 { HMENU hPopup = CreatePopupMenu(); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DATADIR, "Open &datadir"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "&Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); if(!i2p::context.AcceptsTunnels()) @@ -303,6 +305,12 @@ namespace win32 SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); return 0; } + case ID_DATADIR: + { + std::string datadir(i2p::fs::GetUTF8DataDir()); + ShellExecute(NULL, "explore", datadir.c_str(), NULL, NULL, SW_SHOWNORMAL); + return 0; + } } break; } From 56ec8fe95b5490e4773ac6b90d1bdacc89884ad7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Oct 2021 21:20:16 -0400 Subject: [PATCH 028/383] eliminate local destination mutex --- libi2pd/TunnelPool.cpp | 17 ----------------- libi2pd/TunnelPool.h | 5 ++--- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 4d00ad6f..051ecdc6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -128,7 +128,6 @@ namespace tunnel } m_InboundTunnels.insert (createdTunnel); } - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -266,16 +265,6 @@ namespace tunnel return tunnel; } - std::shared_ptr TunnelPool::GetLocalDestination () const { - std::unique_lock l(m_LocalDestinationMutex); - return m_LocalDestination; - } - - void TunnelPool::SetLocalDestination (std::shared_ptr destination) { - std::unique_lock l(m_LocalDestinationMutex); - m_LocalDestination = destination; - } - void TunnelPool::CreateTunnels () { int num = 0; @@ -307,7 +296,6 @@ namespace tunnel for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); - std::unique_lock l(m_LocalDestinationMutex); if (num < m_NumInboundTunnels && m_NumInboundHops <= 0 && m_LocalDestination) // zero hops IB m_LocalDestination->SetLeaseSetUpdated (); // update LeaseSet immediately } @@ -344,7 +332,6 @@ namespace tunnel std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } - std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -398,7 +385,6 @@ namespace tunnel void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else @@ -447,7 +433,6 @@ namespace tunnel } else { - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else @@ -636,10 +621,8 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { - std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) path.isShort = false; // because can't handle ECIES encrypted reply - ld.unlock(); std::shared_ptr config; if (m_NumOutboundHops > 0) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 1069e1b9..b32bafa3 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -64,8 +64,8 @@ namespace tunnel TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels); ~TunnelPool (); - std::shared_ptr GetLocalDestination () const; - void SetLocalDestination (std::shared_ptr destination); + std::shared_ptr GetLocalDestination () const { return m_LocalDestination; }; + void SetLocalDestination (std::shared_ptr destination) { m_LocalDestination = destination; }; void SetExplicitPeers (std::shared_ptr > explicitPeers); void CreateTunnels (); @@ -126,7 +126,6 @@ namespace tunnel private: - mutable std::mutex m_LocalDestinationMutex; std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; mutable std::mutex m_ExplicitPeersMutex; From c6e47581877e6f61ed3293b0f0b9c24eae161bb6 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 1 Nov 2021 05:03:34 +0300 Subject: [PATCH 029/383] Revert "Merge pull request #1703 from simonvetter/simon/memory-and-multithreading-fixes" This reverts commit 67863cfcf9784dd638f505b8052abb8070ed8a90, reversing changes made to 4c5ec68ff14ea9f144b0cad792956315d4969233. That change completly bloking transports thread on windows. Signed-off-by: R4SAS --- libi2pd/Tunnel.cpp | 33 +++++---------------------------- libi2pd/Tunnel.h | 10 ++-------- libi2pd/TunnelConfig.h | 2 +- libi2pd/TunnelPool.cpp | 29 +++++++++-------------------- libi2pd/TunnelPool.h | 1 - 5 files changed, 17 insertions(+), 58 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f3cdd432..a315ff49 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -366,7 +366,6 @@ namespace tunnel std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { - std::unique_lock l(m_TunnelsMutex); auto it = m_Tunnels.find(tunnelID); if (it != m_Tunnels.end ()) return it->second; @@ -375,13 +374,11 @@ namespace tunnel std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { - std::unique_lock l(m_PendingInboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); } std::shared_ptr Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) { - std::unique_lock l(m_PendingOutboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); } @@ -462,11 +459,9 @@ namespace tunnel void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { - std::unique_lock l(m_TunnelsMutex); - if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) { - std::unique_lock l(m_TransitTunnelsMutex); + if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) m_TransitTunnels.push_back (tunnel); - } else + else LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); } @@ -621,10 +616,7 @@ namespace tunnel void Tunnels::ManagePendingTunnels () { - std::unique_lock li(m_PendingInboundTunnelsMutex); ManagePendingTunnels (m_PendingInboundTunnels); - li.unlock(); - std::unique_lock lo(m_PendingOutboundTunnelsMutex); ManagePendingTunnels (m_PendingOutboundTunnels); } @@ -684,7 +676,6 @@ namespace tunnel void Tunnels::ManageOutboundTunnels () { - std::unique_lock l(m_OutboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) @@ -739,8 +730,6 @@ namespace tunnel void Tunnels::ManageInboundTunnels () { - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock li(m_InboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) @@ -797,7 +786,6 @@ namespace tunnel return; } - std::unique_lock lo(m_OutboundTunnelsMutex); if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3) { // trying to create one more inbound tunnel @@ -818,8 +806,6 @@ namespace tunnel void Tunnels::ManageTransitTunnels () { - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock l(m_TransitTunnelsMutex); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { @@ -890,20 +876,17 @@ namespace tunnel void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { - std::unique_lock l(m_PendingInboundTunnelsMutex); m_PendingInboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { - std::unique_lock l(m_PendingOutboundTunnelsMutex); m_PendingOutboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddOutboundTunnel (std::shared_ptr newTunnel) { // we don't need to insert it to m_Tunnels - std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (pool && pool->IsActive ()) @@ -914,10 +897,8 @@ namespace tunnel void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { - std::unique_lock l(m_TunnelsMutex); if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) { - std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) @@ -945,8 +926,6 @@ namespace tunnel auto inboundTunnel = std::make_shared (); inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; @@ -957,7 +936,6 @@ namespace tunnel auto outboundTunnel = std::make_shared (); outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); - std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels return outboundTunnel; @@ -986,7 +964,6 @@ namespace tunnel int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // TODO: possible race condition with I2PControl - std::unique_lock l(m_TransitTunnelsMutex); for (const auto& it : m_TransitTunnels) { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; @@ -997,19 +974,19 @@ namespace tunnel size_t Tunnels::CountTransitTunnels() const { - std::unique_lock l(m_TransitTunnelsMutex); + // TODO: locking return m_TransitTunnels.size(); } size_t Tunnels::CountInboundTunnels() const { - std::unique_lock l(m_InboundTunnelsMutex); + // TODO: locking return m_InboundTunnels.size(); } size_t Tunnels::CountOutboundTunnels() const { - std::unique_lock l(m_OutboundTunnelsMutex); + // TODO: locking return m_OutboundTunnels.size(); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 640a9ca7..56166e0b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -68,7 +68,7 @@ namespace tunnel public: Tunnel (std::shared_ptr config); - virtual ~Tunnel (); + ~Tunnel (); void Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel = nullptr); @@ -254,18 +254,12 @@ namespace tunnel bool m_IsRunning; std::thread * m_Thread; std::map > m_PendingInboundTunnels; // by replyMsgID - mutable std::mutex m_PendingInboundTunnelsMutex; std::map > m_PendingOutboundTunnels; // by replyMsgID - mutable std::mutex m_PendingOutboundTunnelsMutex; std::list > m_InboundTunnels; - mutable std::recursive_mutex m_InboundTunnelsMutex; std::list > m_OutboundTunnels; - mutable std::recursive_mutex m_OutboundTunnelsMutex; std::list > m_TransitTunnels; - mutable std::mutex m_TransitTunnelsMutex; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id - mutable std::recursive_mutex m_TunnelsMutex; - mutable std::mutex m_PoolsMutex; + std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index ae924ba6..f198dffd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - virtual ~TunnelConfig () + ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 051ecdc6..5ed330c8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -59,7 +59,6 @@ namespace tunnel void TunnelPool::SetExplicitPeers (std::shared_ptr > explicitPeers) { - std::unique_lock l(m_ExplicitPeersMutex); m_ExplicitPeers = explicitPeers; if (m_ExplicitPeers) { @@ -93,7 +92,6 @@ namespace tunnel it->SetTunnelPool (nullptr); m_OutboundTunnels.clear (); } - std::unique_lock l(m_TestsMutex); m_Tests.clear (); } @@ -137,11 +135,10 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.erase (expiredTunnel); } } @@ -160,11 +157,10 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (expiredTunnel); } } @@ -269,7 +265,7 @@ namespace tunnel { int num = 0; { - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); for (const auto& it : m_OutboundTunnels) if (it->IsEstablished ()) num++; } @@ -278,11 +274,10 @@ namespace tunnel num = 0; { - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } - std::unique_lock lo(m_OutboundTunnelsMutex); if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) { for (auto it: m_OutboundTunnels) @@ -292,7 +287,6 @@ namespace tunnel if (num >= m_NumInboundTunnels) break; } } - lo.unlock(); for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); @@ -317,7 +311,7 @@ namespace tunnel if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else @@ -329,7 +323,7 @@ namespace tunnel { it.second.second->SetState (eTunnelStateFailed); { - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } if (m_LocalDestination) @@ -341,10 +335,7 @@ namespace tunnel } // new tests - std::unique_lock lt(m_TestsMutex); - std::unique_lock lo(m_OutboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); - std::unique_lock li(m_InboundTunnelsMutex); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { @@ -364,6 +355,7 @@ namespace tunnel uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); { + std::unique_lock l(m_TestsMutex); m_Tests[msgID] = std::make_pair (*it1, *it2); } (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), @@ -388,7 +380,7 @@ namespace tunnel if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else - LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, garlic message dropped"); + LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, dropped"); } void TunnelPool::ProcessDeliveryStatus (std::shared_ptr msg) @@ -436,7 +428,7 @@ namespace tunnel if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, delivery status message dropped"); + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); } } @@ -520,16 +512,13 @@ namespace tunnel if (m_CustomPeerSelector) return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } - // explicit peers in use - std::lock_guard lock(m_ExplicitPeersMutex); if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { - std::unique_lock l(m_ExplicitPeersMutex); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); if (!numHops) return false; diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index b32bafa3..875a9955 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -128,7 +128,6 @@ namespace tunnel std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; - mutable std::mutex m_ExplicitPeersMutex; std::shared_ptr > m_ExplicitPeers; mutable std::mutex m_InboundTunnelsMutex; std::set, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first From c0400bfd0789940b118e444cca7d4d8f3d87b9de Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Oct 2021 22:14:59 -0400 Subject: [PATCH 030/383] virtual destructor for TunnelConfig --- libi2pd/TunnelConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f198dffd..ae924ba6 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - ~TunnelConfig () + virtual ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; From 1a8a32a773deffa80ccd03102cfa687eb1622a9e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Nov 2021 14:51:24 -0400 Subject: [PATCH 031/383] select next tunnel with compatible transports --- libi2pd/Destination.cpp | 28 ++++++++++++++-------------- libi2pd/RouterInfo.h | 3 ++- libi2pd/Tunnel.cpp | 2 +- libi2pd/Tunnel.h | 1 + libi2pd/TunnelConfig.h | 4 ++-- libi2pd/TunnelPool.cpp | 15 +++++++++------ libi2pd/TunnelPool.h | 9 ++++++--- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 54137664..f523243a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -555,18 +555,6 @@ namespace client shared_from_this (), std::placeholders::_1)); return; } - auto outbound = m_Pool->GetNextOutboundTunnel (); - if (!outbound) - { - LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); - return; - } - auto inbound = m_Pool->GetNextInboundTunnel (); - if (!inbound) - { - LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); - return; - } auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills); if (!floodfill) { @@ -575,6 +563,18 @@ namespace client return; } m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); + auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); + if (!outbound) + { + LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); + return; + } + auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)); + if (!inbound) + { + LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); + return; + } LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); @@ -751,10 +751,10 @@ namespace client std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) - request->replyTunnel = m_Pool->GetNextInboundTunnel (); + request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) - request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); + request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); if (request->replyTunnel && request->outboundTunnel) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b2b883dc..de1fe235 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -64,7 +64,8 @@ namespace data eNTCP2V6 = 0x02, eSSUV4 = 0x04, eSSUV6 = 0x08, - eNTCP2V6Mesh = 0x10 + eNTCP2V6Mesh = 0x10, + eAllTransports = 0xFF }; typedef uint8_t CompatibleTransports; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a315ff49..ad048bb8 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -32,7 +32,7 @@ namespace tunnel Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), m_Config (config), m_IsShortBuildMessage (false), m_Pool (nullptr), - m_State (eTunnelStatePending), m_FarEndTransports (0), + m_State (eTunnelStatePending), m_FarEndTransports (i2p::data::RouterInfo::eAllTransports), m_IsRecreated (false), m_Latency (0) { } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 56166e0b..3ab366c8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -76,6 +76,7 @@ namespace tunnel std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; bool IsShortBuildMessage () const { return m_IsShortBuildMessage; }; + i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const { return m_FarEndTransports; }; TunnelState GetState () const { return m_State; }; void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index ae924ba6..c514a404 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -82,7 +82,7 @@ namespace tunnel public: TunnelConfig (const std::vector >& peers, - bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // inbound + bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // inbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); @@ -91,7 +91,7 @@ namespace tunnel TunnelConfig (const std::vector >& peers, uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, - i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // outbound + i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5ed330c8..c9897b29 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -190,20 +190,23 @@ namespace tunnel return v; } - std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_OutboundTunnelsMutex); - return GetNextTunnel (m_OutboundTunnels, excluded); + return GetNextTunnel (m_OutboundTunnels, excluded, compatible); } - std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_InboundTunnelsMutex); - return GetNextTunnel (m_InboundTunnels, excluded); + return GetNextTunnel (m_InboundTunnels, excluded, compatible); } template - typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const + typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const { if (tunnels.empty ()) return nullptr; uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0; @@ -211,7 +214,7 @@ namespace tunnel typename TTunnels::value_type tunnel = nullptr; for (const auto& it: tunnels) { - if (it->IsEstablished () && it != excluded) + if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ())) { if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() && !it->LatencyFitsRange(m_MinLatency, m_MaxLatency))) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 875a9955..2f4018ce 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -76,8 +76,10 @@ namespace tunnel void RecreateInboundTunnel (std::shared_ptr tunnel); void RecreateOutboundTunnel (std::shared_ptr tunnel); std::vector > GetInboundTunnels (int num) const; - std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr) const; - std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr) const; + std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; + std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; std::shared_ptr GetNewOutboundTunnel (std::shared_ptr old) const; void TestTunnels (); void ManageTunnels (uint64_t ts); @@ -120,7 +122,8 @@ namespace tunnel void CreateOutboundTunnel (); void CreatePairedInboundTunnel (std::shared_ptr outboundTunnel); template - typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; + typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const; bool SelectPeers (Path& path, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound); From 8f0978cfd6439559803b5e6ba6c22dcd20f59dff Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 10:49:18 -0400 Subject: [PATCH 032/383] all transports by default --- libi2pd/TunnelConfig.h | 2 +- libi2pd/TunnelPool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index c514a404..7934bc6b 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -185,7 +185,7 @@ namespace tunnel // this constructor can't be called from outside TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false), - m_FarEndTransports (0) + m_FarEndTransports (i2p::data::RouterInfo::eAllTransports) { } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 2f4018ce..41cc400f 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -40,7 +40,7 @@ namespace tunnel { std::vector peers; bool isShort = true; - i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0; + i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports; void Add (std::shared_ptr r); void Reverse (); From f8c390cdd3a4b9f375f97b9ed1c7c15b8f8cc11a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 15:44:56 -0400 Subject: [PATCH 033/383] pick compatible tunnels --- libi2pd/Destination.cpp | 2 +- libi2pd/NetDb.cpp | 8 ++--- libi2pd/TunnelPool.cpp | 72 ++++++++++++++++++++--------------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f523243a..9341baa4 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -562,7 +562,6 @@ namespace client m_ExcludedFloodfills.clear (); return; } - m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); if (!outbound) { @@ -575,6 +574,7 @@ namespace client LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } + m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b4ffe2bd..7123741a 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -681,8 +681,8 @@ namespace data else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; - auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr; + auto outbound = pool ? pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; + auto inbound = pool ? pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (outbound && inbound) outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); else @@ -1129,8 +1129,8 @@ namespace data { // otherwise through exploratory auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; - auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr; + auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; + auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (inbound && outbound) outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound)); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index c9897b29..a67b6618 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -498,9 +498,8 @@ namespace tunnel } prevHop = hop; path.Add (hop); - if (i == numHops - 1) - path.farEndTransports = hop->GetCompatibleTransports (inbound); } + path.farEndTransports = prevHop->GetCompatibleTransports (inbound); // last hop return true; } @@ -555,13 +554,13 @@ namespace tunnel void TunnelPool::CreateInboundTunnel () { - auto outboundTunnel = GetNextOutboundTunnel (); - if (!outboundTunnel) - outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); Path path; if (SelectPeers (path, true)) { + auto outboundTunnel = GetNextOutboundTunnel (nullptr, path.farEndTransports); + if (!outboundTunnel) + outboundTunnel = tunnels.GetNextOutboundTunnel (); std::shared_ptr config; if (m_NumInboundHops > 0) { @@ -583,7 +582,7 @@ namespace tunnel CreateInboundTunnel (); return; } - auto outboundTunnel = GetNextOutboundTunnel (); + auto outboundTunnel = GetNextOutboundTunnel (nullptr, tunnel->GetFarEndTransports ()); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); @@ -604,40 +603,41 @@ namespace tunnel void TunnelPool::CreateOutboundTunnel () { - auto inboundTunnel = GetNextInboundTunnel (); - if (!inboundTunnel) - inboundTunnel = tunnels.GetNextInboundTunnel (); - if (inboundTunnel) + LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); + Path path; + if (SelectPeers (path, false)) { - LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); - Path path; - if (SelectPeers (path, false)) + auto inboundTunnel = GetNextInboundTunnel (nullptr, path.farEndTransports); + if (!inboundTunnel) + inboundTunnel = tunnels.GetNextInboundTunnel (); + if (!inboundTunnel) { - if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - path.isShort = false; // because can't handle ECIES encrypted reply - - std::shared_ptr config; - if (m_NumOutboundHops > 0) - config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), - inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); + LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no inbound tunnels found"); + return; + } + + if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + path.isShort = false; // because can't handle ECIES encrypted reply + + std::shared_ptr config; + if (m_NumOutboundHops > 0) + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); - std::shared_ptr tunnel; - if (path.isShort) - { - // TODO: implement it better - tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); - tunnel->SetTunnelPool (shared_from_this ()); - } - else - tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); - if (tunnel && tunnel->IsEstablished ()) // zero hops - TunnelCreated (tunnel); - } - else - LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); + std::shared_ptr tunnel; + if (path.isShort) + { + // TODO: implement it better + tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); + tunnel->SetTunnelPool (shared_from_this ()); + } + else + tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); + if (tunnel && tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else - LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no inbound tunnels found"); + LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); } void TunnelPool::RecreateOutboundTunnel (std::shared_ptr tunnel) @@ -647,7 +647,7 @@ namespace tunnel CreateOutboundTunnel (); return; } - auto inboundTunnel = GetNextInboundTunnel (); + auto inboundTunnel = GetNextInboundTunnel (nullptr, tunnel->GetFarEndTransports ()); if (!inboundTunnel) inboundTunnel = tunnels.GetNextInboundTunnel (); if (inboundTunnel) From 3f63f15b16e8c512e5dda777f1266d6a50d11409 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 19:16:45 -0400 Subject: [PATCH 034/383] copy compatible transports to new tunnel --- libi2pd/TunnelPool.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a67b6618..7bce0519 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -588,9 +588,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); std::shared_ptr config; if (m_NumInboundHops > 0 && tunnel->GetPeers().size()) - { - config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage ()); - } + config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); if (!m_NumInboundHops || config) { auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); @@ -657,7 +655,7 @@ namespace tunnel if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) { config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), - inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage ()); + inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); } if (!m_NumOutboundHops || config) { From d798faa1cad7a80dc7cc98d7ea9cc95e211c2a44 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Nov 2021 17:18:31 -0500 Subject: [PATCH 035/383] pick compatible ooutbound tunnel --- libi2pd/Streaming.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index be3d09d8..8be6811b 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -828,13 +828,6 @@ namespace stream m_RTO = m_RTT*1.5; // TODO: implement it better } } - if (!m_CurrentOutboundTunnel || !m_CurrentOutboundTunnel->IsEstablished ()) - m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel); - if (!m_CurrentOutboundTunnel) - { - LogPrint (eLogError, "Streaming: No outbound tunnels in the pool, sSID=", m_SendStreamID); - return; - } auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet @@ -842,6 +835,21 @@ namespace stream UpdateCurrentRemoteLease (true); if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { + if (!m_CurrentOutboundTunnel) + { + auto leaseRouter = i2p::data::netdb.FindRouter (m_CurrentRemoteLease->tunnelGateway); + m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNextOutboundTunnel (nullptr, + leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports); + } + else if (!m_CurrentOutboundTunnel->IsEstablished ()) + m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel); + if (!m_CurrentOutboundTunnel) + { + LogPrint (eLogError, "Streaming: No outbound tunnels in the pool, sSID=", m_SendStreamID); + m_CurrentRemoteLease = nullptr; + return; + } + std::vector msgs; for (const auto& it: packets) { From 49883dc3ac43054ed1090107ed761d95074ef2eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Nov 2021 07:02:11 +0300 Subject: [PATCH 036/383] [webconsole] update stylesheet (closes #1699) Signed-off-by: R4SAS --- contrib/webconsole/style-dark.css | 272 ------------------------------ contrib/webconsole/style.css | 107 +++++++++--- daemon/HTTPServerResources.h | 97 ++++++----- 3 files changed, 133 insertions(+), 343 deletions(-) delete mode 100644 contrib/webconsole/style-dark.css diff --git a/contrib/webconsole/style-dark.css b/contrib/webconsole/style-dark.css deleted file mode 100644 index 6ec19023..00000000 --- a/contrib/webconsole/style-dark.css +++ /dev/null @@ -1,272 +0,0 @@ -:root { - --main-bg-color: #121212; - --main-text-color: #156A3D; - --main-link-color: #894C84; -} - -body { - font: 100%/1.5em sans-serif; - margin: 0; - padding: 1.5em; - background: var(--main-bg-color); - color: var(--main-text-color); -} - -a, .slide label { - text-decoration: none; - color: var(--main-link-color); -} - -a:hover, .slide label:hover, button[type=submit]:hover { - color: #FAFAFA; - background: var(--main-link-color); -} - -a.button { - appearance: button; - text-decoration: none; - padding: 0 5px; - border: 1px solid var(--main-link-color); -} - -.header { - font-size: 2.5em; - text-align: center; - margin: 1em 0; - color: var(--main-link-color); -} - -.wrapper { - margin: 0 auto; - padding: 1em; - max-width: 64em; -} - -.menu { - display: block; - float: left; - overflow: hidden; - max-width: 12em; - white-space: nowrap; - text-overflow: ellipsis; -} - -.listitem { - display: block; - font-family: monospace; - font-size: 1.2em; - white-space: nowrap; -} - -.tableitem { - font-family: monospace; - font-size: 1.2em; - white-space: nowrap; -} - -.content { - float: left; - font-size: 1em; - margin-left: 4em; - max-width: 48em; - overflow: auto; -} - -.tunnel.established { - color: #56B734; -} - -.tunnel.expiring { - color: #D3AE3F; -} - -.tunnel.failed { - color: #D33F3F; -} - -.tunnel.building { - color: #434343; -} - -caption { - font-size: 1.5em; - text-align: center; - color: var(--main-link-color); -} - -table { - display: table; - border-collapse: collapse; - text-align: center; -} - -table.extaddr { - text-align: left; -} - -table.services { - width: 100%; -} - -textarea { - background-color: var(--main-bg-color); - color: var(--main-text-color); - word-break: break-all; -} - -.streamdest { - width: 120px; - max-width: 240px; - overflow: hidden; - text-overflow: ellipsis; -} - -.slide div.slidecontent, .slide [type="checkbox"] { - display: none; -} - -.slide [type="checkbox"]:checked ~ div.slidecontent { - display: block; - margin-top: 0; - padding: 0; -} - -.disabled { - color: #D33F3F; -} - -.enabled { - color: #56B734; -} - -button[type=submit] { - background-color: transparent; - color: var(--main-link-color); - text-decoration: none; - padding: 5px; - border: 1px solid var(--main-link-color); - font-size: 14px; -} - -input, select, select option { - background-color: var(--main-bg-color); - color: var(--main-link-color); - padding: 5px; - border: 1px solid var(--main-link-color); - font-size: 14px; -} - -input:focus, select:focus, select option:focus { - outline: none; -} - -input[type=number]::-webkit-inner-spin-button { - -webkit-appearance: none; -} - -@media screen and (max-width: 1150px) { /* adaptive style */ - .wrapper { - max-width: 58em; - } - - .menu { - max-width: 10em; - } - - .content { - margin-left: 2em; - max-width: 42em; - } -} - -@media screen and (max-width: 980px) { - body { - font: 100%/1.2em sans-serif; - padding: 1.2em 0 0 0; - } - - .menu { - width: 100%; - max-width: unset; - display: block; - float: none; - position: unset; - font-size: 16px; - text-align: center; - } - - .menu a, .commands a { - display: inline-block; - padding: 4px; - } - - .content { - float: none; - margin-left: unset; - margin-top: 16px; - max-width: 100%; - width: 100%; - text-align: center; - } - - a, .slide label { - /* margin-right: 10px; */ - display: block; - /* font-size: 18px; */ - } - - .header { - margin: unset; - font-size: 1.5em; - } - - small { - display: block - } - - a.button { - appearance: button; - text-decoration: none; - margin-top: 10px; - padding: 6px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - width: -webkit-fill-available; - } - - input, select { - width: 35%; - text-align: center; - padding: 5px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - font-size: 18px; - } - - table.extaddr { - margin: auto; - text-align: unset; - } - - textarea { - width: -webkit-fill-available; - height: auto; - padding: 5px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - font-size: 12px; - } - - button[type=submit] { - padding: 5px 15px; - background: transparent; - border: 2px solid var(--main-link-color); - cursor: pointer; - -webkit-border-radius: 5px; - border-radius: 5px; - position: relative; - height: 36px; - display: -webkit-inline-box; - margin-top: 10px; - } -} \ No newline at end of file diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index 047839a6..3a6ab059 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -1,35 +1,63 @@ +/* + * Copyright (c) 2013-2021, The PurpleI2P Project + * + * This file is part of Purple i2pd project and licensed under BSD3 + * + * See full license text in LICENSE file at top of project tree + * + ****************************************************************** + * + * This is styles heet for webconsole, with @media selectors for adaptive + * view on desktop and mobile devices, respecting preferred user's color + * scheme used in system/browser. + * + * Minified copy of that style sheet is bundled inside i2pd sources. +*/ + +:root { + --main-bg-color: #FAFAFA; + --main-text-color: #103456; + --main-link-color: #894C84; +} + +@media (prefers-color-scheme: dark) { + :root { + --main-bg-color: #121212; + --main-text-color: #156A3D; + --main-link-color: #894C84; + } +} + body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; - background: #FAFAFA; - color: #103456; + background: var(--main-bg-color); + color: var(--main-text-color); } a, .slide label { text-decoration: none; - color: #894C84; + color: var(--main-link-color); } -a:hover, .slide label:hover { +a:hover, .slide label:hover, button[type=submit]:hover { color: #FAFAFA; - background: #894C84; + background: var(--main-link-color); } a.button { - -webkit-appearance: button; - -moz-appearance: button; appearance: button; text-decoration: none; padding: 0 5px; - border: 1px solid #894C84; + border: 1px solid var(--main-link-color); } .header { font-size: 2.5em; text-align: center; margin: 1em 0; - color: #894C84; + color: var(--main-link-color); } .wrapper { @@ -42,6 +70,7 @@ a.button { display: block; float: left; overflow: hidden; + padding: 4px; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; @@ -63,8 +92,9 @@ a.button { .content { float: left; font-size: 1em; - margin-left: 4em; - max-width: 48em; + margin-left: 2em; + padding: 4px; + max-width: 50em; overflow: auto; } @@ -87,7 +117,7 @@ a.button { caption { font-size: 1.5em; text-align: center; - color: #894C84; + color: var(--main-link-color); } table { @@ -105,6 +135,8 @@ table.services { } textarea { + background-color: var(--main-bg-color); + color: var(--main-text-color); word-break: break-all; } @@ -133,9 +165,34 @@ textarea { color: #56B734; } +button[type=submit] { + background-color: transparent; + color: var(--main-link-color); + text-decoration: none; + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input, select, select option { + background-color: var(--main-bg-color); + color: var(--main-link-color); + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input:focus, select:focus, select option:focus { + outline: none; +} + +input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + @media screen and (max-width: 1150px) { /* adaptive style */ .wrapper { - max-width: 58em; + max-width: 60em; } .menu { @@ -144,13 +201,14 @@ textarea { .content { margin-left: 2em; - max-width: 42em; + max-width: 46em; } } @media screen and (max-width: 980px) { body { - padding: 1.5em 0 0 0; + font: 100%/1.2em sans-serif; + padding: 1.2em 0 0 0; } .menu { @@ -178,9 +236,7 @@ textarea { } a, .slide label { - /* margin-right: 10px; */ display: block; - /* font-size: 18px; */ } .header { @@ -193,13 +249,12 @@ textarea { } a.button { - -webkit-appearance: button; - -moz-appearance: button; appearance: button; text-decoration: none; margin-top: 10px; padding: 6px; - border: 1px solid #894c84; + border: 2px solid var(--main-link-color); + border-radius: 5px; width: -webkit-fill-available; } @@ -207,8 +262,7 @@ textarea { width: 35%; text-align: center; padding: 5px; - border: 2px solid #ccc; - -webkit-border-radius: 5px; + border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 18px; } @@ -221,17 +275,16 @@ textarea { textarea { width: -webkit-fill-available; height: auto; - padding:5px; - border:2px solid #ccc; - -webkit-border-radius: 5px; + padding: 5px; + border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 12px; } button[type=submit] { padding: 5px 15px; - background: #ccc; - border: 0 none; + background: transparent; + border: 2px solid var(--main-link-color); cursor: pointer; -webkit-border-radius: 5px; border-radius: 5px; diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h index 876948e8..75cf2d6e 100644 --- a/daemon/HTTPServerResources.h +++ b/daemon/HTTPServerResources.h @@ -34,50 +34,59 @@ namespace http // bundled style sheet const std::string internalCSS = "\r\n"; // for external style sheet From fdde197c5800c723eba76eb891b160a8dfc695de Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Nov 2021 07:40:39 +0300 Subject: [PATCH 037/383] [webconsole] update stylesheet Signed-off-by: R4SAS --- contrib/webconsole/style.css | 12 ++++++------ daemon/HTTPServerResources.h | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index 3a6ab059..861e747a 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -7,7 +7,7 @@ * ****************************************************************** * - * This is styles heet for webconsole, with @media selectors for adaptive + * This is style sheet for webconsole, with @media selectors for adaptive * view on desktop and mobile devices, respecting preferred user's color * scheme used in system/browser. * @@ -22,7 +22,7 @@ @media (prefers-color-scheme: dark) { :root { - --main-bg-color: #121212; + --main-bg-color: #181818; --main-text-color: #156A3D; --main-link-color: #894C84; } @@ -63,7 +63,7 @@ a.button { .wrapper { margin: 0 auto; padding: 1em; - max-width: 64em; + max-width: 60em; } .menu { @@ -92,7 +92,7 @@ a.button { .content { float: left; font-size: 1em; - margin-left: 2em; + margin-left: 4em; padding: 4px; max-width: 50em; overflow: auto; @@ -192,7 +192,7 @@ input[type=number]::-webkit-inner-spin-button { @media screen and (max-width: 1150px) { /* adaptive style */ .wrapper { - max-width: 60em; + max-width: 56em; } .menu { @@ -201,7 +201,7 @@ input[type=number]::-webkit-inner-spin-button { .content { margin-left: 2em; - max-width: 46em; + max-width: 44em; } } diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h index 75cf2d6e..89c742d3 100644 --- a/daemon/HTTPServerResources.h +++ b/daemon/HTTPServerResources.h @@ -35,17 +35,17 @@ namespace http const std::string internalCSS = "