From 66f82cb43fba0daf5d4548287b1eeed82ff6e7e5 Mon Sep 17 00:00:00 2001 From: Tomas Globis Date: Tue, 3 Jan 2023 03:07:07 +0300 Subject: [PATCH 0001/1160] Use moving average to calculate tunnel creation success rate --- libi2pd/Tunnel.cpp | 9 ++++----- libi2pd/Tunnel.h | 26 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f3b7152d..5af4a9a4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -332,8 +332,7 @@ namespace tunnel Tunnels tunnels; Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), - m_NumSuccesiveTunnelCreations (0), m_NumFailedTunnelCreations (0) - { + m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) { } Tunnels::~Tunnels () @@ -630,7 +629,7 @@ namespace tunnel } // delete it = pendingTunnels.erase (it); - m_NumFailedTunnelCreations++; + FailedTunnelCreation(); } else ++it; @@ -638,7 +637,7 @@ namespace tunnel case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " failed, deleted"); it = pendingTunnels.erase (it); - m_NumFailedTunnelCreations++; + FailedTunnelCreation(); break; case eTunnelStateBuildReplyReceived: // intermediate state, will be either established of build failed @@ -647,7 +646,7 @@ namespace tunnel default: // success it = pendingTunnels.erase (it); - m_NumSuccesiveTunnelCreations++; + SuccesiveTunnelCreation(); } } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 6032d35f..c252e303 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -44,10 +44,13 @@ namespace tunnel const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds - + 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 + const double TCSR_SMOOTHING_CONSTANT = 0.0005; // smoothing constant in exponentially weighted moving average + const double TCSR_START_VALUE = 0.1; // start value of tunnel creation success rate + enum TunnelState { eTunnelStatePending, @@ -267,8 +270,19 @@ namespace tunnel i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; - // some stats - int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; + // Calculating of tunnel creation success rate + // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity + void SuccesiveTunnelCreation() { + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; + m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate; + + }; + void FailedTunnelCreation() { + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; + m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate; + }; + double m_TunnelCreationSuccessRate; + int m_TunnelCreationAttemptsNum; public: @@ -282,11 +296,7 @@ namespace tunnel size_t CountOutboundTunnels() const; int GetQueueSize () { return m_Queue.GetSize (); }; - int GetTunnelCreationSuccessRate () const // in percents - { - int totalNum = m_NumSuccesiveTunnelCreations + m_NumFailedTunnelCreations; - return totalNum ? m_NumSuccesiveTunnelCreations*100/totalNum : 0; - } + int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents }; extern Tunnels tunnels; From a1c16e129d8957ad80b5f203d339d21d3e350f90 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 4 Jan 2023 16:28:04 +0300 Subject: [PATCH 0002/1160] [rpm] fix date Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index e3d487e2..e1697130 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -158,7 +158,7 @@ getent passwd i2pd >/dev/null || \ %changelog -* Mon Tue 3 2023 orignal - 2.45.0 +* Tue Jan 3 2023 orignal - 2.45.0 - update to 2.45.0 * Sun Nov 20 2022 orignal - 2.44.0 From 55be5c74f0c37f7a064eb4cd542bb02ee7e5333a Mon Sep 17 00:00:00 2001 From: kleenex Date: Wed, 4 Jan 2023 22:41:54 +0900 Subject: [PATCH 0003/1160] Fix segfault when UPnP is enabled Added null check. Signed-off-by: kleenex --- daemon/UPnP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index b7182055..dbaf864a 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -163,7 +163,7 @@ namespace transport if (!a) return; for (const auto& address : *a) { - if (!address->host.is_v6 () && address->port) + if (address && !address->host.is_v6 () && address->port) TryPortMapping (address); } m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes @@ -215,7 +215,7 @@ namespace transport if (!a) return; for (const auto& address : *a) { - if (!address->host.is_v6 () && address->port) + if (address && !address->host.is_v6 () && address->port) CloseMapping (address); } } From 06fae976b3de009f01420d07c6b50cf50723f027 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 4 Jan 2023 17:10:06 +0300 Subject: [PATCH 0004/1160] [style] update editorconfig Signed-off-by: R4SAS --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.editorconfig b/.editorconfig index 97acf820..ed3973c5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,6 +13,11 @@ insert_final_newline = true indent_style = tab indent_size = 4 +[*.cmd] +indent_style = space +indent_size = 2 +end_of_line = crlf + [*.{h,cpp}] indent_style = tab indent_size = 4 From 0d3ede56cb278f10d1516057a68a2e0ad61dd751 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Jan 2023 11:59:47 -0500 Subject: [PATCH 0005/1160] reject duplicated trnsit tunnel --- libi2pd/I2NPProtocol.cpp | 8 +++++--- libi2pd/Tunnel.cpp | 8 ++++++-- libi2pd/Tunnel.h | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b8acbcbe..4d1ab6d4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -392,7 +392,8 @@ namespace i2p clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); - i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel)) + retCode = 30; } else retCode = 30; // always reject with bandwidth reason (30) @@ -590,7 +591,8 @@ namespace i2p layerKey, ivKey, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); - i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel)) + retCode = 30; } // encrypt reply diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f3b7152d..611b0ec0 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -433,12 +433,16 @@ namespace tunnel } } - void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) + bool Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) m_TransitTunnels.push_back (tunnel); else + { LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists"); + return false; + } + return true; } void Tunnels::Start () diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index af813c81..d4fc7d5b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -210,7 +210,7 @@ namespace tunnel std::shared_ptr GetExploratoryPool () const { return m_ExploratoryPool; }; std::shared_ptr GetTunnel (uint32_t tunnelID); int GetTransitTunnelsExpirationTimeout (); - void AddTransitTunnel (std::shared_ptr tunnel); + bool AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr pool, std::shared_ptr outboundTunnel); From 55704ece3aa477ef0b4c1e647dfe0ebd910d8acc Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Jan 2023 15:33:41 -0500 Subject: [PATCH 0006/1160] drop duplicated I2NP messages --- libi2pd/SSU2Session.cpp | 42 +++++++++++++++++++++++++++++++++++++---- libi2pd/SSU2Session.h | 11 ++++++++--- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index cf2eafde..38d52012 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -221,6 +221,7 @@ namespace transport m_IncompleteMessages.clear (); m_RelaySessions.clear (); m_PeerTests.clear (); + m_ReceivedI2NPMsgIDs.clear (); m_Server.RemoveSession (m_SourceConnID); transports.PeerDisconnected (shared_from_this ()); LogPrint (eLogDebug, "SSU2: Session terminated"); @@ -1450,7 +1451,7 @@ namespace transport nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header memcpy (nextMsg->GetNTCP2Header (), buf + offset, size); nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2 - m_Handler.PutNextMessage (std::move (nextMsg)); + HandleI2NPMsg (std::move (nextMsg)); m_IsDataReceived = true; break; } @@ -1738,7 +1739,7 @@ namespace transport { // we have all follow-on fragments already m->msg->FromNTCP2 (); - m_Handler.PutNextMessage (std::move (m->msg)); + HandleI2NPMsg (std::move (m->msg)); m_IncompleteMessages.erase (it); } } @@ -1760,14 +1761,14 @@ namespace transport if (isLast) { it->second->msg->FromNTCP2 (); - m_Handler.PutNextMessage (std::move (it->second->msg)); + HandleI2NPMsg (std::move (it->second->msg)); m_IncompleteMessages.erase (it); } else { if (ConcatOutOfSequenceFragments (it->second)) { - m_Handler.PutNextMessage (std::move (it->second->msg)); + HandleI2NPMsg (std::move (it->second->msg)); m_IncompleteMessages.erase (it); } else @@ -2268,6 +2269,25 @@ namespace transport } } + void SSU2Session::HandleI2NPMsg (std::shared_ptr&& msg) + { + if (!msg) return; + int32_t msgID = msg->GetMsgID (); + if (!m_ReceivedI2NPMsgIDs.count (msgID)) + { + if (!msg->IsExpired ()) + { + // m_LastActivityTimestamp is updated in ProcessData before + m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp); + m_Handler.PutNextMessage (std::move (msg)); + } + else + LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired"); + } + else + LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); + } + bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) { if (size < 2) return false; @@ -2790,6 +2810,20 @@ namespace transport else ++it; } + if (m_ReceivedI2NPMsgIDs.size () > SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS || ts > m_LastActivityTimestamp + SSU2_DECAY_INTERVAL) + // decay + m_ReceivedI2NPMsgIDs.clear (); + else + { + // delete old received msgIDs + for (auto it = m_ReceivedI2NPMsgIDs.begin (); it != m_ReceivedI2NPMsgIDs.end ();) + { + if (ts > it->second + SSU2_RECEIVED_I2NP_MSGIDS_CLEANUP_TIMEOUT) + it = m_ReceivedI2NPMsgIDs.erase (it); + else + ++it; + } + } if (!m_OutOfSequencePackets.empty ()) { if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index aab02127..b1cc234f 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -39,6 +39,9 @@ namespace transport const int SSU2_RESEND_INTERVAL = 300; // in milliseconds const int SSU2_MAX_NUM_RESENDS = 5; const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds + const int SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS = 5000; // how many msgID we store for duplicates check + const int SSU2_RECEIVED_I2NP_MSGIDS_CLEANUP_TIMEOUT = 10; // in seconds + const int SSU2_DECAY_INTERVAL = 20; // in seconds const size_t SSU2_MIN_WINDOW_SIZE = 16; // in packets const size_t SSU2_MAX_WINDOW_SIZE = 256; // in packets const size_t SSU2_MIN_RTO = 100; // in milliseconds @@ -47,7 +50,7 @@ namespace transport const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64; - + // flags const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01; @@ -308,7 +311,8 @@ namespace transport void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0); void HandleRelayResponse (const uint8_t * buf, size_t len); void HandlePeerTest (const uint8_t * buf, size_t len); - + void HandleI2NPMsg (std::shared_ptr&& msg); + size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep); size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr r); size_t CreateAckBlock (uint8_t * buf, size_t len); @@ -351,6 +355,7 @@ namespace transport SSU2TerminationReason m_TerminationReason; size_t m_MaxPayloadSize; std::unique_ptr m_PathChallenge; + std::unordered_map m_ReceivedI2NPMsgIDs; // msgID -> timestamp in seconds }; inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce) From acd6af709ee6371b3d0340d2c92cb86f6f4bcb97 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Jan 2023 18:16:36 -0500 Subject: [PATCH 0007/1160] don't use netdb memory pool for local RouterInfo --- libi2pd/RouterInfo.cpp | 26 +++++++++++++++++++++++--- libi2pd/RouterInfo.h | 6 +++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 4667be98..1aa0259b 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -206,13 +206,13 @@ namespace data s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); m_Timestamp = be64toh (m_Timestamp); // read addresses - auto addresses = netdb.NewRouterInfoAddresses (); + auto addresses = NewAddresses (); uint8_t numAddresses; s.read ((char *)&numAddresses, sizeof (numAddresses)); for (int i = 0; i < numAddresses; i++) { uint8_t supportedTransports = 0; - auto address = netdb.NewRouterInfoAddress (); + auto address = NewAddress (); uint8_t cost; // ignore s.read ((char *)&cost, sizeof (cost)); s.read ((char *)&address->date, sizeof (address->date)); @@ -974,6 +974,16 @@ namespace data return netdb.NewRouterInfoBuffer (); } + std::shared_ptr RouterInfo::NewAddress () const + { + return netdb.NewRouterInfoAddress (); + } + + boost::shared_ptr RouterInfo::NewAddresses () const + { + return netdb.NewRouterInfoAddresses (); + } + void RouterInfo::RefreshTimestamp () { m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); @@ -1255,6 +1265,16 @@ namespace data return std::make_shared (); } + std::shared_ptr LocalRouterInfo::NewAddress () const + { + return std::make_shared
(); + } + + boost::shared_ptr LocalRouterInfo::NewAddresses () const + { + return boost::make_shared (); + } + bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) { auto addresses = GetAddresses (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 5008b5b1..4e54d615 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -285,6 +285,8 @@ namespace data template std::shared_ptr GetAddress (Filter filter) const; virtual std::shared_ptr NewBuffer () const; + virtual std::shared_ptr
NewAddress () const; + virtual boost::shared_ptr NewAddresses () const; private: @@ -324,6 +326,8 @@ namespace data void UpdateCapsProperty (); void WriteString (const std::string& str, std::ostream& s) const; std::shared_ptr NewBuffer () const override; + std::shared_ptr
NewAddress () const override; + boost::shared_ptr NewAddresses () const override; private: From 4011502f5f9a9bf18597308bc45ef20a4c4e7d85 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Jan 2023 03:58:34 +0300 Subject: [PATCH 0008/1160] [docker] put config in correct place Signed-off-by: R4SAS --- contrib/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 129c5ff3..ead21f10 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -60,8 +60,8 @@ RUN apk update \ RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++ # 3. Copy preconfigured config file and entrypoint -COPY i2pd-docker.conf "$I2PD_HOME/i2pd.conf" -RUN chown i2pd:nobody "$I2PD_HOME/i2pd.conf" +COPY i2pd-docker.conf "$DATA_DIR/i2pd.conf" +RUN chown i2pd:nobody "$DATA_DIR/i2pd.conf" COPY entrypoint.sh /entrypoint.sh RUN chmod a+x /entrypoint.sh From a6f9a56e40a40f5a9d153e701a067c5251669ac4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Jan 2023 14:08:39 -0500 Subject: [PATCH 0009/1160] support C++20 --- Makefile.linux | 5 ++++- libi2pd/SSU2Session.cpp | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 28334082..a02419b7 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,9 +20,12 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic +else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10 - 19 + NEEDED_CXXFLAGS += -std=c++20 + LDLIBS = -latomic else # not supported $(error Compiler too old) endif diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 38d52012..cef67ea1 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2273,7 +2273,11 @@ namespace transport { if (!msg) return; int32_t msgID = msg->GetMsgID (); +#if __cplusplus >= 202002L // C++ 20 or higher + if (!m_ReceivedI2NPMsgIDs.contains (msgID)) +#else if (!m_ReceivedI2NPMsgIDs.count (msgID)) +#endif { if (!msg->IsExpired ()) { From e59ca8420eab18f1e536e951c50004e5bb55e86e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Jan 2023 18:20:26 -0500 Subject: [PATCH 0010/1160] temporary change back to C++17 --- Makefile.linux | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index a02419b7..9a3fdda3 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -24,7 +24,8 @@ else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10 - 19 - NEEDED_CXXFLAGS += -std=c++20 +# NEEDED_CXXFLAGS += -std=c++20 + NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else # not supported $(error Compiler too old) From c18e8f6c7879798951894ced468096b6733df1bb Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Jan 2023 10:54:49 -0500 Subject: [PATCH 0011/1160] drop too long LeaseSet without processing --- libi2pd/NetDb.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9eafd586..c46adff1 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -807,6 +807,11 @@ namespace data uint8_t storeType = buf[DATABASE_STORE_TYPE_OFFSET]; if (storeType) // LeaseSet or LeaseSet2 { + if (len > MAX_LS_BUFFER_SIZE + offset) + { + LogPrint (eLogError, "NetDb: Database store message is too long ", len); + return; + } if (!m->from) // unsolicited LS must be received directly { if (storeType == NETDB_STORE_TYPE_LEASESET) // 1 From 1cc68ea402c26d41d84d1227288a65be224fdf48 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Jan 2023 12:06:26 -0500 Subject: [PATCH 0012/1160] differentiate symmetric and full cone NAT --- daemon/HTTPServer.cpp | 3 +++ libi2pd/SSU2Session.cpp | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 281d3d53..dcd4f7f7 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -245,6 +245,9 @@ namespace http { case eRouterErrorSymmetricNAT: s << " - " << tr("Symmetric NAT"); break; + case eRouterErrorFullConeNAT: + s << " - " << tr("Full cone NAT"); + break; case eRouterErrorNoDescriptors: s << " - " << tr("No Descriptors"); break; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index cef67ea1..d10c694c 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1668,23 +1668,25 @@ namespace transport LogPrint (eLogInfo, "SSU2: Our port ", ep.port (), " received from ", m_RemoteEndpoint, " is different from ", m_Server.GetPort (isV4)); if (isV4) { - if (i2p::context.GetStatus () == eRouterStatusTesting || - m_State == eSSU2SessionStatePeerTest) + if (i2p::context.GetStatus () == eRouterStatusTesting) { i2p::context.SetStatus (eRouterStatusFirewalled); i2p::context.SetError (eRouterErrorSymmetricNAT); m_Server.RescheduleIntroducersUpdateTimer (); } + else if (m_State == eSSU2SessionStatePeerTest) + i2p::context.SetError (eRouterErrorFullConeNAT); } else { - if (i2p::context.GetStatusV6 () == eRouterStatusTesting || - m_State == eSSU2SessionStatePeerTest) + if (i2p::context.GetStatusV6 () == eRouterStatusTesting) { i2p::context.SetStatusV6 (eRouterStatusFirewalled); i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT); m_Server.RescheduleIntroducersUpdateTimerV6 (); } + else if (m_State == eSSU2SessionStatePeerTest) + i2p::context.SetErrorV6 (eRouterErrorFullConeNAT); } } else @@ -1697,6 +1699,8 @@ namespace transport i2p::context.SetStatus (eRouterStatusOK); i2p::context.SetError (eRouterErrorNone); } + else if (i2p::context.GetError () == eRouterErrorFullConeNAT) + i2p::context.SetError (eRouterErrorNone); } else { @@ -1706,6 +1710,8 @@ namespace transport i2p::context.SetStatusV6 (eRouterStatusOK); i2p::context.SetErrorV6 (eRouterErrorNone); } + else if (i2p::context.GetErrorV6 () == eRouterErrorFullConeNAT) + i2p::context.SetErrorV6 (eRouterErrorNone); } } } From 2921eaa055546d6e529537245f442dd78c481d5c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Jan 2023 12:11:51 -0500 Subject: [PATCH 0013/1160] differentiate symmetric and full cone NAT --- libi2pd/RouterContext.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index dd7f0272..d3638b15 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -48,7 +48,8 @@ namespace garlic eRouterErrorClockSkew = 1, eRouterErrorOffline = 2, eRouterErrorSymmetricNAT = 3, - eRouterErrorNoDescriptors = 4 + eRouterErrorFullConeNAT = 4, + eRouterErrorNoDescriptors = 5 }; class RouterContext: public i2p::garlic::GarlicDestination From a3c305032a5490a1815f3f60a0f21c4ddeed7c10 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 8 Jan 2023 08:25:23 -0500 Subject: [PATCH 0014/1160] don't set Firewalled upon SessionCreated if ports mismatch --- libi2pd/RouterContext.cpp | 10 +++++++--- libi2pd/SSU2Session.cpp | 8 -------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b1ebdec7..eb65d2ca 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -240,7 +240,6 @@ namespace i2p if (status != m_Status) { m_Status = status; - m_Error = eRouterErrorNone; switch (m_Status) { case eRouterStatusOK: @@ -249,6 +248,9 @@ namespace i2p case eRouterStatusFirewalled: SetUnreachable (true, false); // ipv4 break; + case eRouterStatusTesting: + m_Error = eRouterErrorNone; + break; default: ; } @@ -260,7 +262,6 @@ namespace i2p if (status != m_StatusV6) { m_StatusV6 = status; - m_ErrorV6 = eRouterErrorNone; switch (m_StatusV6) { case eRouterStatusOK: @@ -269,6 +270,9 @@ namespace i2p case eRouterStatusFirewalled: SetUnreachable (false, true); // ipv6 break; + case eRouterStatusTesting: + m_ErrorV6 = eRouterErrorNone; + break; default: ; } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index d10c694c..01675f80 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1669,22 +1669,14 @@ namespace transport if (isV4) { if (i2p::context.GetStatus () == eRouterStatusTesting) - { - i2p::context.SetStatus (eRouterStatusFirewalled); i2p::context.SetError (eRouterErrorSymmetricNAT); - m_Server.RescheduleIntroducersUpdateTimer (); - } else if (m_State == eSSU2SessionStatePeerTest) i2p::context.SetError (eRouterErrorFullConeNAT); } else { if (i2p::context.GetStatusV6 () == eRouterStatusTesting) - { - i2p::context.SetStatusV6 (eRouterStatusFirewalled); i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT); - m_Server.RescheduleIntroducersUpdateTimerV6 (); - } else if (m_State == eSSU2SessionStatePeerTest) i2p::context.SetErrorV6 (eRouterErrorFullConeNAT); } From f34abe60fac01aba30d24035e893d86018389a80 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Jan 2023 13:52:20 -0500 Subject: [PATCH 0015/1160] 2.45.1 --- ChangeLog | 11 +++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f9aba34..16cb6d6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.45.1] - 2023-01-11 +### Added +- Full Cone NAT status error +### Changed +- Drop duplicated I2NP messages in SSU2 +- Set rejection code 30 if tunnel with id already exists +- Network status is always OK if peer test msg 5 received +### Fixed +- UPnP crash if SSU2 or NTCP2 is disabled +- Crash on termination for some platforms + ## [2.45.0] - 2023-01-03 ### Added - Test for Symmetric NAT with peer test msgs 6 and 7 diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index e1697130..79d591ac 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.45.0 +Version: 2.45.1 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Jan 11 2023 orignal - 2.45.1 +- update to 2.45.1 + * Tue Jan 3 2023 orignal - 2.45.0 - update to 2.45.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5a56989f..07ecfbcc 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.45.0 +Version: 2.45.1 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Jan 11 2023 orignal - 2.45.1 +- update to 2.45.1 + * Tue Jan 3 2023 orignal - 2.45.0 - update to 2.45.0 diff --git a/debian/changelog b/debian/changelog index 10ca4082..77b174c5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.45.1-1) unstable; urgency=medium + + * updated to version 2.45.1/0.9.57 + +-- orignal Wed, 11 Jan 2023 19:00:00 +0000 + i2pd (2.45.0-1) unstable; urgency=high * updated to version 2.45.0/0.9.57 diff --git a/libi2pd/version.h b/libi2pd/version.h index 26f855be..65ca1fc4 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -17,7 +17,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 45 -#define I2PD_VERSION_MICRO 0 +#define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION GITVER From f79900653b2f687f6a004377c6ff634f19822487 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 12 Jan 2023 15:49:02 +0300 Subject: [PATCH 0016/1160] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6f2d23ec..d0481ed9 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,12 @@ Build instructions: **Supported systems:** -* GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml) - * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) - * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. +* GNU/Linux (Debian, Ubuntu, etc) - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml) +* CentOS, Fedora, Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) +* Alpine, ArchLinux, openSUSE, Gentoo, etc. * Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml) -* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml) -* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml) +* Mac OS - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml) +* Docker image - [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml) * Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd) * FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml) * Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml) From 7146a4dbaee7df1a165a18869593ce29089dde2b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 12 Jan 2023 15:41:57 -0500 Subject: [PATCH 0017/1160] check if session socket was closed before tunnels were built --- libi2pd_client/SAM.cpp | 23 ++++++++++++++--------- libi2pd_client/SAM.h | 4 ++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 8b991802..93df59fb 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -440,18 +440,23 @@ namespace client { if (ecode != boost::asio::error::operation_aborted) { - auto session = m_Owner.FindSession(m_ID); - if(session) + if (m_Socket.is_open ()) { - if (session->GetLocalDestination ()->IsReady ()) - SendSessionCreateReplyOk (); - else + auto session = m_Owner.FindSession(m_ID); + if(session) { - m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL)); - m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer, - shared_from_this (), std::placeholders::_1)); + if (session->GetLocalDestination ()->IsReady ()) + SendSessionCreateReplyOk (); + else + { + m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL)); + m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer, + shared_from_this (), std::placeholders::_1)); + } } } + else + Terminate ("SAM: session socket closed"); } } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 88990d7c..b6ac23a6 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -30,7 +30,7 @@ namespace client { const size_t SAM_SOCKET_BUFFER_SIZE = 8192; const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds - const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds + const int SAM_SESSION_READINESS_CHECK_INTERVAL = 3; // in seconds const char SAM_HANDSHAKE[] = "HELLO VERSION"; const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n"; const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n"; From d530269e4fbf6f3a92a0c1f1a1ba66d3cb0ba9e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Jan 2023 19:23:26 -0500 Subject: [PATCH 0018/1160] try to insert received msgid instead lookup --- libi2pd/SSU2Session.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 01675f80..f414baeb 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2271,23 +2271,16 @@ namespace transport { if (!msg) return; int32_t msgID = msg->GetMsgID (); -#if __cplusplus >= 202002L // C++ 20 or higher - if (!m_ReceivedI2NPMsgIDs.contains (msgID)) -#else - if (!m_ReceivedI2NPMsgIDs.count (msgID)) -#endif - { - if (!msg->IsExpired ()) - { - // m_LastActivityTimestamp is updated in ProcessData before - m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp); + if (!msg->IsExpired ()) + { + // m_LastActivityTimestamp is updated in ProcessData before + if (m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp).second) m_Handler.PutNextMessage (std::move (msg)); - } else - LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired"); - } + LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); + } else - LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); + LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired"); } bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) From 324ace103b9ea48554894d07fb1a30aae8f3a28d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Jan 2023 17:05:09 -0500 Subject: [PATCH 0019/1160] memoery pool for fragments --- libi2pd/SSU2.cpp | 33 ++++++++++++++++++++++++++------- libi2pd/SSU2.h | 14 ++++++++++---- libi2pd/SSU2Session.cpp | 2 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 351a8853..d2cb1a26 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -22,7 +22,7 @@ namespace transport RunnableServiceWithWork ("SSU2"), m_ReceiveService ("SSU2r"), m_SocketV4 (m_ReceiveService.GetService ()), m_SocketV6 (m_ReceiveService.GetService ()), m_AddressV4 (boost::asio::ip::address_v4()), m_AddressV6 (boost::asio::ip::address_v6()), - m_TerminationTimer (GetService ()), m_ResendTimer (GetService ()), + m_TerminationTimer (GetService ()), m_CleanupTimer (GetService ()), m_ResendTimer (GetService ()), m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()), m_IsPublished (true), m_IsSyncClockFromPeers (true), m_IsThroughProxy (false) { @@ -109,6 +109,7 @@ namespace transport m_ReceiveService.Start (); } ScheduleTermination (); + ScheduleCleanup (); ScheduleResend (false); } } @@ -118,6 +119,7 @@ namespace transport if (IsRunning ()) { m_TerminationTimer.cancel (); + m_CleanupTimer.cancel (); m_ResendTimer.cancel (); m_IntroducersUpdateTimer.cancel (); m_IntroducersUpdateTimerV6.cancel (); @@ -807,6 +809,22 @@ namespace transport it++; } + ScheduleTermination (); + } + } + + void SSU2Server::ScheduleCleanup () + { + m_CleanupTimer.expires_from_now (boost::posix_time::seconds(SSU2_CLEANUP_INTERVAL)); + m_CleanupTimer.async_wait (std::bind (&SSU2Server::HandleCleanupTimer, + this, std::placeholders::_1)); + } + + void SSU2Server::HandleCleanupTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + auto ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_Relays.begin (); it != m_Relays.begin ();) { if (it->second && it->second->GetState () == eSSU2SessionStateTerminated) @@ -830,13 +848,14 @@ namespace transport else it++; } - + m_PacketsPool.CleanUpMt (); m_SentPacketsPool.CleanUp (); - ScheduleTermination (); - } - } - + m_FragmentsPool.CleanUp (); + ScheduleCleanup (); + } + } + void SSU2Server::ScheduleResend (bool more) { m_ResendTimer.expires_from_now (boost::posix_time::milliseconds (more ? SSU2_RESEND_CHECK_MORE_TIMEOUT : diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 97372c17..68d507ca 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -18,7 +18,8 @@ namespace i2p { namespace transport { - const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // in seconds + const int SSU2_TERMINATION_CHECK_TIMEOUT = 25; // in seconds + const int SSU2_CLEANUP_INTERVAL = 72; // in seconds const int SSU2_RESEND_CHECK_TIMEOUT = 400; // in milliseconds const int SSU2_RESEND_CHECK_TIMEOUT_VARIANCE = 100; // in milliseconds const int SSU2_RESEND_CHECK_MORE_TIMEOUT = 10; // in milliseconds @@ -97,7 +98,8 @@ namespace transport void RescheduleIntroducersUpdateTimerV6 (); i2p::util::MemoryPool& GetSentPacketsPool () { return m_SentPacketsPool; }; - + i2p::util::MemoryPool& GetFragmentsPool () { return m_FragmentsPool; }; + private: boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint); @@ -111,6 +113,9 @@ namespace transport void ScheduleTermination (); void HandleTerminationTimer (const boost::system::error_code& ecode); + void ScheduleCleanup (); + void HandleCleanupTimer (const boost::system::error_code& ecode); + void ScheduleResend (bool more); void HandleResendTimer (const boost::system::error_code& ecode); @@ -147,7 +152,8 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to i2p::util::MemoryPoolMt m_PacketsPool; i2p::util::MemoryPool m_SentPacketsPool; - boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer, + i2p::util::MemoryPool m_FragmentsPool; + boost::asio::deadline_timer m_TerminationTimer, m_CleanupTimer, m_ResendTimer, m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6; std::shared_ptr m_LastSession; bool m_IsPublished; // if we maintain introducers diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index f414baeb..79e736fe 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1788,7 +1788,7 @@ namespace transport LogPrint (eLogWarning, "SSU2: Fragment number ", fragmentNum, " exceeds ", SSU2_MAX_NUM_FRAGMENTS); return; } - auto fragment = std::make_shared (); + auto fragment = m_Server.GetFragmentsPool ().AcquireShared (); memcpy (fragment->buf, buf + 5, len -5); fragment->len = len - 5; fragment->isLast = isLast; From 993dc72ce664612496e4e2c441b37d4bd704db30 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Jan 2023 22:50:54 -0500 Subject: [PATCH 0020/1160] use separate pointer to second fragment of incomplete message --- libi2pd/SSU2Session.cpp | 71 +++++++++++++++++++++++++++++------------ libi2pd/SSU2Session.h | 6 ++-- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 79e736fe..b3c539bc 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -32,7 +32,55 @@ namespace transport nextFragmentNum++; } + bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments () + { + bool isLast = false; + if (nextFragmentNum == 1) + { + if (secondFragment) + { + AttachNextFragment (secondFragment->buf, secondFragment->len); + isLast = secondFragment->isLast; + secondFragment = nullptr; + } + else + return false; + if (isLast) return true; + } + // might be more + if (outOfSequenceFragments) + { + for (auto it = outOfSequenceFragments->begin (); it != outOfSequenceFragments->end ();) + if (it->first == nextFragmentNum) + { + AttachNextFragment (it->second->buf, it->second->len); + isLast = it->second->isLast; + it = outOfSequenceFragments->erase (it); + } + else + break; + } + return isLast; + } + void SSU2IncompleteMessage::AddOutOfSequenceFragment (int fragmentNum, + std::shared_ptr fragment) + { + if (!fragmentNum || !fragment) return; // fragment 0 nun allowed + if (fragmentNum < nextFragmentNum) return; // already processed + if (fragmentNum == 1) + { + if (!secondFragment) secondFragment = fragment; + } + else + { + if (!outOfSequenceFragments) + outOfSequenceFragments.reset (new std::map >()); + outOfSequenceFragments->emplace (fragmentNum, fragment); + } + lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); + } + SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr in_RemoteRouter, std::shared_ptr addr): TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT), @@ -1733,7 +1781,7 @@ namespace transport m->msg = msg; m->nextFragmentNum = 1; m->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); - if (found && ConcatOutOfSequenceFragments (m)) + if (found && m->ConcatOutOfSequenceFragments ()) { // we have all follow-on fragments already m->msg->FromNTCP2 (); @@ -1764,7 +1812,7 @@ namespace transport } else { - if (ConcatOutOfSequenceFragments (it->second)) + if (it->second->ConcatOutOfSequenceFragments ()) { HandleI2NPMsg (std::move (it->second->msg)); m_IncompleteMessages.erase (it); @@ -1792,24 +1840,7 @@ namespace transport memcpy (fragment->buf, buf + 5, len -5); fragment->len = len - 5; fragment->isLast = isLast; - it->second->outOfSequenceFragments.emplace (fragmentNum, fragment); - it->second->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); - } - - bool SSU2Session::ConcatOutOfSequenceFragments (std::shared_ptr m) - { - if (!m) return false; - bool isLast = false; - for (auto it = m->outOfSequenceFragments.begin (); it != m->outOfSequenceFragments.end ();) - if (it->first == m->nextFragmentNum) - { - m->AttachNextFragment (it->second->buf, it->second->len); - isLast = it->second->isLast; - it = m->outOfSequenceFragments.erase (it); - } - else - break; - return isLast; + it->second->AddOutOfSequenceFragment (fragmentNum, fragment); } void SSU2Session::HandleRelayRequest (const uint8_t * buf, size_t len) diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index b1cc234f..97469ed4 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -177,9 +177,12 @@ namespace transport std::shared_ptr msg; int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds - std::map > outOfSequenceFragments; + std::shared_ptr secondFragment; // fragment #1 + std::unique_ptr > > outOfSequenceFragments; // fragments #2 and more void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize); + bool ConcatOutOfSequenceFragments (); // true if message complete + void AddOutOfSequenceFragment (int fragmentNum, std::shared_ptr fragment); }; struct SSU2SentPacket @@ -306,7 +309,6 @@ namespace transport bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate void HandleFirstFragment (const uint8_t * buf, size_t len); void HandleFollowOnFragment (const uint8_t * buf, size_t len); - bool ConcatOutOfSequenceFragments (std::shared_ptr m); // true if message complete void HandleRelayRequest (const uint8_t * buf, size_t len); void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0); void HandleRelayResponse (const uint8_t * buf, size_t len); From 10030a4e0d43038d26690504785cbba808582d15 Mon Sep 17 00:00:00 2001 From: acetone Date: Mon, 16 Jan 2023 13:31:13 +0300 Subject: [PATCH 0021/1160] Addresshelper updating: referer check --- libi2pd_client/HTTPProxy.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index b9d4d48c..28928836 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -333,6 +333,30 @@ namespace proxy { } else if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm) { + if (m_Confirm) + { + // Referer check to prevent forced overwriting by link with "&update=true" from harmful URL + const std::string referer_raw = m_ClientRequest.GetHeader("Referer"); + i2p::http::URL referer_url; + if (!referer_raw.empty ()) + { + referer_url.parse (referer_raw); + } + if (m_RequestURL.host != referer_url.host) + { + LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful"); + std::string full_url = m_RequestURL.to_string(); + std::stringstream ss; + ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; + ss << "" << tr("Be careful: source of this URL may be harmful") << "! "; + ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" ); + ss << " " << tr("Continue") << "."; + GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str()); + return true; /* request processed */ + } + } + i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, jump); LogPrint (eLogInfo, "HTTPProxy: Added address from addresshelper for ", m_RequestURL.host); std::string full_url = m_RequestURL.to_string(); From d8b6f5438c558b13d047f1b1e8d81e5a339c0017 Mon Sep 17 00:00:00 2001 From: acetone <63557806+freeacetone@users.noreply.github.com> Date: Mon, 16 Jan 2023 13:56:36 +0300 Subject: [PATCH 0022/1160] log typo --- libi2pd_client/HTTPProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 28928836..67d34e97 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -344,7 +344,7 @@ namespace proxy { } if (m_RequestURL.host != referer_url.host) { - LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful"); + LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful", ")"); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; From 9af5a907575cc85b390f170ff32d2a1658accaac Mon Sep 17 00:00:00 2001 From: acetone <63557806+freeacetone@users.noreply.github.com> Date: Mon, 16 Jan 2023 13:57:15 +0300 Subject: [PATCH 0023/1160] Copyright year updated --- libi2pd_client/HTTPProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 67d34e97..8c3a341e 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * From 013d5ff74f546f94fc3e21f457c128ba4c6ef0e1 Mon Sep 17 00:00:00 2001 From: acetone Date: Mon, 16 Jan 2023 16:16:16 +0300 Subject: [PATCH 0024/1160] Addresshelper request validation by Refer-header --- libi2pd_client/HTTPProxy.cpp | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 8c3a341e..a41320be 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -333,28 +333,39 @@ namespace proxy { } else if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm) { - if (m_Confirm) + // Referer check to prevent forced overwriting by link with "&update=true" from harmful URL + const std::string referer_raw = m_ClientRequest.GetHeader("Referer"); + i2p::http::URL referer_url; + if (!referer_raw.empty ()) { - // Referer check to prevent forced overwriting by link with "&update=true" from harmful URL - const std::string referer_raw = m_ClientRequest.GetHeader("Referer"); - i2p::http::URL referer_url; - if (!referer_raw.empty ()) - { - referer_url.parse (referer_raw); - } - if (m_RequestURL.host != referer_url.host) + referer_url.parse (referer_raw); + } + if (m_RequestURL.host != referer_url.host) + { + if (m_Confirm) { LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful", ")"); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; - ss << "" << tr("Be careful: source of this URL may be harmful") << "! "; + ss << "" << tr( /* Trying to overwrite an existing domain in the address book by direct link with "&update=true" is seems like an attack */ "Be careful: source of this URL may be harmful") << "! "; ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" ); ss << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str()); - return true; /* request processed */ } + else + { + LogPrint (eLogDebug, "HTTPProxy: Adding address from addresshelper for ", m_RequestURL.host, " (generate refer-base page)"); + std::string full_url = m_RequestURL.to_string(); + std::stringstream ss; + ss << tr("To add host") << " " << m_RequestURL.host << " " << tr("in router's addressbook") << ", "; + ss << tr("click here") << ":"; + ss << " " << tr("Continue") << "."; + GenericProxyInfo(tr("Addresshelper request"), ss.str()); + } + return true; /* request processed */ } i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, jump); @@ -363,7 +374,7 @@ namespace proxy { std::stringstream ss; ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; ss << tr("Click here to proceed:") << " " << tr("Continue") << "."; - GenericProxyInfo(tr("Addresshelper found"), ss.str()); + GenericProxyInfo(tr("Addresshelper adding"), ss.str()); return true; /* request processed */ } else @@ -374,7 +385,7 @@ namespace proxy { ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" ); ss << " " << tr("Continue") << "."; - GenericProxyInfo(tr("Addresshelper found"), ss.str()); + GenericProxyInfo(tr("Addresshelper update"), ss.str()); return true; /* request processed */ } } From 6ca6591c4365d62873eeac6328e5b1932862a614 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 17 Jan 2023 01:28:50 +0300 Subject: [PATCH 0025/1160] [make] set PREFIX from DESTDIR if it present Signed-off-by: R4SAS --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index d792360a..35ee08a9 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,10 @@ else LD_DEBUG = -s endif +ifneq (, $(DESTDIR)) + PREFIX = $(DESTDIR) +endif + ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) From bc888167a7c5483f2acc4d20d80fe9e1601c53f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Jan 2023 21:40:23 -0500 Subject: [PATCH 0026/1160] use linked list for out of sequence fragments --- libi2pd/SSU2Session.cpp | 64 ++++++++++++++++++++--------------------- libi2pd/SSU2Session.h | 7 +++-- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index b3c539bc..0f53bf7b 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -35,48 +35,45 @@ namespace transport bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments () { bool isLast = false; - if (nextFragmentNum == 1) - { - if (secondFragment) + while (outOfSequenceFragments) + { + if (outOfSequenceFragments->fragmentNum == nextFragmentNum) { - AttachNextFragment (secondFragment->buf, secondFragment->len); - isLast = secondFragment->isLast; - secondFragment = nullptr; + AttachNextFragment (outOfSequenceFragments->buf, outOfSequenceFragments->len); + isLast = outOfSequenceFragments->isLast; + if (isLast) + outOfSequenceFragments = nullptr; + else + outOfSequenceFragments = outOfSequenceFragments->next; } else - return false; - if (isLast) return true; - } - // might be more - if (outOfSequenceFragments) - { - for (auto it = outOfSequenceFragments->begin (); it != outOfSequenceFragments->end ();) - if (it->first == nextFragmentNum) - { - AttachNextFragment (it->second->buf, it->second->len); - isLast = it->second->isLast; - it = outOfSequenceFragments->erase (it); - } - else - break; + break; } return isLast; } - void SSU2IncompleteMessage::AddOutOfSequenceFragment (int fragmentNum, - std::shared_ptr fragment) + void SSU2IncompleteMessage::AddOutOfSequenceFragment (std::shared_ptr fragment) { - if (!fragmentNum || !fragment) return; // fragment 0 nun allowed - if (fragmentNum < nextFragmentNum) return; // already processed - if (fragmentNum == 1) - { - if (!secondFragment) secondFragment = fragment; - } + if (!fragment || !fragment->fragmentNum) return; // fragment 0 not allowed + if (fragment->fragmentNum < nextFragmentNum) return; // already processed + if (!outOfSequenceFragments) + outOfSequenceFragments = fragment; else { - if (!outOfSequenceFragments) - outOfSequenceFragments.reset (new std::map >()); - outOfSequenceFragments->emplace (fragmentNum, fragment); + auto frag = outOfSequenceFragments; + std::shared_ptr prev; + do + { + if (fragment->fragmentNum < frag->fragmentNum) break; // found + if (fragment->fragmentNum == frag->fragmentNum) return; // duplicate + prev = frag; frag = frag->next; + } + while (frag); + fragment->next = frag; + if (prev) + prev->next = fragment; + else + outOfSequenceFragments = fragment; } lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); } @@ -1839,8 +1836,9 @@ namespace transport auto fragment = m_Server.GetFragmentsPool ().AcquireShared (); memcpy (fragment->buf, buf + 5, len -5); fragment->len = len - 5; + fragment->fragmentNum = fragmentNum; fragment->isLast = isLast; - it->second->AddOutOfSequenceFragment (fragmentNum, fragment); + it->second->AddOutOfSequenceFragment (fragment); } void SSU2Session::HandleRelayRequest (const uint8_t * buf, size_t len) diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 97469ed4..08a4b7cf 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -171,18 +171,19 @@ namespace transport { uint8_t buf[SSU2_MAX_PACKET_SIZE]; size_t len; + int fragmentNum; bool isLast; + std::shared_ptr next; }; std::shared_ptr msg; int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds - std::shared_ptr secondFragment; // fragment #1 - std::unique_ptr > > outOfSequenceFragments; // fragments #2 and more + std::shared_ptr outOfSequenceFragments; // #1 and more void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize); bool ConcatOutOfSequenceFragments (); // true if message complete - void AddOutOfSequenceFragment (int fragmentNum, std::shared_ptr fragment); + void AddOutOfSequenceFragment (std::shared_ptr fragment); }; struct SSU2SentPacket From d105ab11af00297a164abab2ab29e8f80f642a13 Mon Sep 17 00:00:00 2001 From: acetone Date: Tue, 17 Jan 2023 08:45:18 +0300 Subject: [PATCH 0027/1160] Joining two strings to one and correct comments --- libi2pd_client/HTTPProxy.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index a41320be..cecda2bb 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -333,7 +333,6 @@ namespace proxy { } else if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm) { - // Referer check to prevent forced overwriting by link with "&update=true" from harmful URL const std::string referer_raw = m_ClientRequest.GetHeader("Referer"); i2p::http::URL referer_url; if (!referer_raw.empty ()) @@ -342,6 +341,7 @@ namespace proxy { } if (m_RequestURL.host != referer_url.host) { + // Attempt to forced overwriting by link with "&update=true" from harmful URL if (m_Confirm) { LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful", ")"); @@ -354,13 +354,13 @@ namespace proxy { ss << jump << "&update=true\">" << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str()); } + // Preventing unauthorized additions to the address book else { LogPrint (eLogDebug, "HTTPProxy: Adding address from addresshelper for ", m_RequestURL.host, " (generate refer-base page)"); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("To add host") << " " << m_RequestURL.host << " " << tr("in router's addressbook") << ", "; - ss << tr("click here") << ":"; + ss << tr("To add host" /*... in router's addressbook, click here */ ) << " " << m_RequestURL.host << " " << tr( /* To add host SOMESHORT.i2p ... */ "in router's addressbook, click here") << ":"; ss << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper request"), ss.str()); From b290ee1aa04f2f5f4b7b418b6a78df924b197c6a Mon Sep 17 00:00:00 2001 From: acetone Date: Tue, 17 Jan 2023 09:00:11 +0300 Subject: [PATCH 0028/1160] Cfg example: verbose comments for Web Console auth and addresshelper for public proxy --- contrib/i2pd.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index c65d2bee..c8baa046 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -122,6 +122,8 @@ port = 7070 ## Path to web console, default "/" # webroot = / ## Uncomment following lines to enable Web Console authentication +## You should not use Web Console via public networks without additional encryption. +## HTTP authentication is not encryption layer! # auth = true # user = i2pd # pass = changeme @@ -139,6 +141,8 @@ port = 4444 ## Optional keys file for proxy local destination # keys = http-proxy-keys.dat ## Enable address helper for adding .i2p domains with "jump URLs" (default: true) +## You should disable this feature if your i2pd HTTP Proxy is public, +## because anyone could spoof the short domain via addresshelper and forward other users to phishing links # addresshelper = true ## Address of a proxy server inside I2P, which is used to visit regular Internet # outproxy = http://false.i2p From e8be39af176628b5e0ef04c8bde5d8292ef6584e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 17 Jan 2023 21:32:36 -0500 Subject: [PATCH 0029/1160] memrory pool for SSU2IncompleteMessage --- libi2pd/SSU2.cpp | 1 + libi2pd/SSU2.h | 4 +++- libi2pd/SSU2Session.cpp | 15 ++++++++------- libi2pd/SSU2Session.h | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index d2cb1a26..5bb27a40 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -851,6 +851,7 @@ namespace transport m_PacketsPool.CleanUpMt (); m_SentPacketsPool.CleanUp (); + m_IncompleteMessagesPool.CleanUp (); m_FragmentsPool.CleanUp (); ScheduleCleanup (); } diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 68d507ca..8b755f60 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -98,8 +98,9 @@ namespace transport void RescheduleIntroducersUpdateTimerV6 (); i2p::util::MemoryPool& GetSentPacketsPool () { return m_SentPacketsPool; }; + i2p::util::MemoryPool& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; }; i2p::util::MemoryPool& GetFragmentsPool () { return m_FragmentsPool; }; - + private: boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint); @@ -152,6 +153,7 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to i2p::util::MemoryPoolMt m_PacketsPool; i2p::util::MemoryPool m_SentPacketsPool; + i2p::util::MemoryPool m_IncompleteMessagesPool; i2p::util::MemoryPool m_FragmentsPool; boost::asio::deadline_timer m_TerminationTimer, m_CleanupTimer, m_ResendTimer, m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 0f53bf7b..5e97b461 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1772,7 +1772,7 @@ namespace transport } else { - m = std::make_shared(); + m = m_Server.GetIncompleteMessagesPool ().AcquireShared (); m_IncompleteMessages.emplace (msgID, m); } m->msg = msg; @@ -1791,11 +1791,17 @@ namespace transport { if (len < 5) return; uint8_t fragmentNum = buf[0] >> 1; + if (!fragmentNum || fragmentNum >= SSU2_MAX_NUM_FRAGMENTS) + { + LogPrint (eLogWarning, "SSU2: Invalid follow-on fragment num ", fragmentNum); + return; + } bool isLast = buf[0] & 0x01; uint32_t msgID; memcpy (&msgID, buf + 1, 4); auto it = m_IncompleteMessages.find (msgID); if (it != m_IncompleteMessages.end ()) { + if (fragmentNum < it->second->nextFragmentNum) return; // duplicate if (it->second->nextFragmentNum == fragmentNum && fragmentNum < SSU2_MAX_NUM_FRAGMENTS && it->second->msg) { @@ -1823,16 +1829,11 @@ namespace transport else { // follow-on fragment before first fragment - auto msg = std::make_shared (); + auto msg = m_Server.GetIncompleteMessagesPool ().AcquireShared (); msg->nextFragmentNum = 0; it = m_IncompleteMessages.emplace (msgID, msg).first; } // insert out of sequence fragment - if (fragmentNum >= SSU2_MAX_NUM_FRAGMENTS) - { - LogPrint (eLogWarning, "SSU2: Fragment number ", fragmentNum, " exceeds ", SSU2_MAX_NUM_FRAGMENTS); - return; - } auto fragment = m_Server.GetFragmentsPool ().AcquireShared (); memcpy (fragment->buf, buf + 5, len -5); fragment->len = len - 5; diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 08a4b7cf..ef9ab573 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -345,7 +345,7 @@ namespace transport uint32_t m_SendPacketNum, m_ReceivePacketNum; std::set m_OutOfSequencePackets; // packet nums > receive packet num std::map > m_SentPackets; // packetNum -> packet - std::map > m_IncompleteMessages; // I2NP + std::unordered_map > m_IncompleteMessages; // msgID -> I2NP std::map, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice std::map, uint64_t > > m_PeerTests; // same as for relay sessions std::list > m_SendQueue; From e8ace998ba20f11c6eb204c1e254926e3927b21f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Jan 2023 07:21:36 +0300 Subject: [PATCH 0030/1160] [i18n] add support of string formatting Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 51 ++++++++++++++++++++--------------- i18n/Afrikaans.cpp | 8 +++--- i18n/Armenian.cpp | 18 ++++++------- i18n/Chinese.cpp | 18 ++++++------- i18n/Czech.cpp | 18 ++++++------- i18n/French.cpp | 18 ++++++------- i18n/German.cpp | 18 ++++++------- i18n/I18N.h | 62 ++++++++++++++++++++++++++++++++++++++++--- i18n/Italian.cpp | 18 ++++++------- i18n/Russian.cpp | 18 ++++++------- i18n/Spanish.cpp | 18 ++++++------- i18n/Turkmen.cpp | 18 ++++++------- i18n/Ukrainian.cpp | 18 ++++++------- i18n/Uzbek.cpp | 18 ++++++------- 14 files changed, 190 insertions(+), 129 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index dcd4f7f7..74e7df64 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -103,18 +103,18 @@ namespace http { int num; if ((num = seconds / 86400) > 0) { - s << num << " " << tr("day", "days", num) << ", "; + s << ntr("%d day", "%d days", num, num) << ", "; seconds -= num * 86400; } if ((num = seconds / 3600) > 0) { - s << num << " " << tr("hour", "hours", num) << ", "; + s << ntr("%d hour", "%d hours", num, num) << ", "; seconds -= num * 3600; } if ((num = seconds / 60) > 0) { - s << num << " " << tr("minute", "minutes", num) << ", "; + s << ntr("%d minute", "%d minutes", num, num) << ", "; seconds -= num * 60; } - s << seconds << " " << tr("second", "seconds", seconds); + s << ntr("%d second", "%d seconds", seconds, seconds); } static void ShowTraffic (std::stringstream& s, uint64_t bytes) @@ -122,11 +122,11 @@ namespace http { s << std::fixed << std::setprecision(2); auto numKBytes = (double) bytes / 1024; if (numKBytes < 1024) - s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB"); + s << tr(/* tr: Kibibyte */ "%.2f KiB", numKBytes); else if (numKBytes < 1024 * 1024) - s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB"); + s << tr(/* tr: Mebibyte */ "%.2f MiB", numKBytes / 1024); else - s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB"); + s << tr(/* tr: Gibibyte */ "%.2f GiB", numKBytes / 1024 / 1024); } static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) @@ -150,7 +150,7 @@ namespace http { else stateText = tr("unknown"); s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; - s << " " << (int) (bytes / 1024) << " " << tr(/* tr: Kibibit */ "KiB") << "\r\n"; + s << " " << tr(/* tr: Kibibit */ "%.2f KiB", (double) bytes / 1024) << "\r\n"; } static void SetLogLevel (const std::string& level) @@ -247,7 +247,7 @@ namespace http { break; case eRouterErrorFullConeNAT: s << " - " << tr("Full cone NAT"); - break; + break; case eRouterErrorNoDescriptors: s << " - " << tr("No Descriptors"); break; @@ -290,13 +290,13 @@ namespace http { s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << (double) i2p::transport::transports.GetInBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << (double) i2p::transport::transports.GetOutBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { @@ -338,7 +338,7 @@ namespace http { s << "" << address->host.to_string() << ":" << address->port << "\r\n"; else { - s << "" << tr("supported"); + s << "" << tr(/* tr: Shown when router doesn't publish itself and have "Firewalled" state */ "supported"); if (address->port) s << " :" << address->port; s << "\r\n"; @@ -466,7 +466,7 @@ namespace http { } s << "⇒ " << it->GetTunnelID () << ":me"; if (it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )"; + s << " ( " << tr(/* tr: Milliseconds */ "%dms", it->GetMeanLatency()) << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -486,22 +486,26 @@ namespace http { ); } if (it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); s << "\r\n"; } } s << "
\r\n"; - s << "" << tr("Tags") << "
\r\n" << tr("Incoming") << ": " << dest->GetNumIncomingTags () << "
\r\n"; + s << "" << tr("Tags") << "
\r\n" + << tr("Incoming") << ": " << dest->GetNumIncomingTags () << "
\r\n"; if (!dest->GetSessions ().empty ()) { std::stringstream tmp_s; uint32_t out_tags = 0; for (const auto& it: dest->GetSessions ()) { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; out_tags += it.second->GetNumOutgoingTags (); } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Amount") << "
\r\n
\r\n
\r\n"; + s << "
\r\n" + << "\r\n" + << "
\r\n" + << "\r\n\r\n" + << "\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Amount") << "
\r\n
\r\n
\r\n"; } else s << tr("Outgoing") << ": 0
\r\n"; s << "
\r\n"; @@ -516,8 +520,11 @@ namespace http { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "" << it.second->GetState () << "\r\n"; ecies_sessions++; } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Status") << "
\r\n
\r\n
\r\n"; + s << "
\r\n" + << "\r\n" + << "
\r\n\r\n" + << "\r\n" + << "\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Status") << "
\r\n
\r\n
\r\n"; } else s << tr("Tags sessions") << ": 0
\r\n"; s << "
\r\n"; @@ -671,7 +678,7 @@ namespace http { } s << "⇒ " << it->GetTunnelID () << ":me"; if (it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); s << "\r\n"; } @@ -691,7 +698,7 @@ namespace http { ); } if (it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << tr("%dms", it->GetMeanLatency()) << " )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ()); s << "\r\n"; } diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 5860facf..b582a06a 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -64,10 +64,10 @@ namespace afrikaans // language namespace static std::map> plurals { - {"days", {"dag", "dae"}}, - {"hours", {"uur", "ure"}}, - {"minutes", {"minuut", "minute"}}, - {"seconds", {"seconde", "sekondes"}}, + {"%d days", {"%d dag", "%d dae"}}, + {"%d hours", {"%d uur", "%d ure"}}, + {"%d minutes", {"%d minuut", "%d minute"}}, + {"%d seconds", {"%d seconde", "%d sekondes"}}, {"", {"", ""}}, }; diff --git a/i18n/Armenian.cpp b/i18n/Armenian.cpp index 586e7579..a18d35fc 100644 --- a/i18n/Armenian.cpp +++ b/i18n/Armenian.cpp @@ -31,9 +31,9 @@ namespace armenian // language namespace static std::map strings { - {"KiB", "ԿիԲ"}, - {"MiB", "ՄիԲ"}, - {"GiB", "ԳիԲ"}, + {"%.2f KiB", "%.2f ԿիԲ"}, + {"%.2f MiB", "%.2f ՄիԲ"}, + {"%.2f GiB", "%.2f ԳիԲ"}, {"building", "կառուցվում է"}, {"failed", "Անհաջող"}, {"expiring", "Լրանում է"}, @@ -68,7 +68,7 @@ namespace armenian // language namespace {"Family", "Խմբատեսակ"}, {"Tunnel creation success rate", "Հաջողությամբ կառուցված թունելներ"}, {"Received", "Ստացվել է"}, - {"KiB/s", "ԿիԲ/վ"}, + {"%.2f KiB/s", "%.2f ԿիԲ/վ"}, {"Sent", "Ուղարկվել է"}, {"Transit", "Տարանցում"}, {"Data path", "Տվյալների ուղին"}, @@ -94,7 +94,7 @@ namespace armenian // language namespace {"Type", "Տեսակը"}, {"EncType", "Գաղտնագրի տեսակը"}, {"Inbound tunnels", "Մուտքային թունելներ"}, - {"ms", "մլվ"}, + {"%dms", "%dմլվ"}, {"Outbound tunnels", "Ելքային թունելներ"}, {"Tags", "Թեգեր"}, {"Incoming", "Մուտքային"}, @@ -198,10 +198,10 @@ namespace armenian // language namespace static std::map> plurals { - {"days", {"օր", "օր"}}, - {"hours", {"ժամ", "ժամ"}}, - {"minutes", {"րոպե", "րոպե"}}, - {"seconds", {"վարկյան", "վարկյան"}}, + {"%d days", {"%d օր", "%d օր"}}, + {"%d hours", {"%d ժամ", "%d ժամ"}}, + {"%d minutes", {"%d րոպե", "%d րոպե"}}, + {"%d seconds", {"%d վարկյան", "%d վարկյան"}}, {"", {"", ""}}, }; diff --git a/i18n/Chinese.cpp b/i18n/Chinese.cpp index 2f6c14e2..8a554a11 100644 --- a/i18n/Chinese.cpp +++ b/i18n/Chinese.cpp @@ -32,9 +32,9 @@ namespace chinese // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "正在构建"}, {"failed", "连接失败"}, {"expiring", "即将过期"}, @@ -70,7 +70,7 @@ namespace chinese // language namespace {"Family", "家族"}, {"Tunnel creation success rate", "隧道创建成功率"}, {"Received", "已接收"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "已发送"}, {"Transit", "中转"}, {"Data path", "数据文件路径"}, @@ -96,7 +96,7 @@ namespace chinese // language namespace {"Type", "类型"}, {"EncType", "加密类型"}, {"Inbound tunnels", "入站隧道"}, - {"ms", "毫秒"}, + {"%dms", "%d毫秒"}, {"Outbound tunnels", "出站隧道"}, {"Tags", "标签"}, {"Incoming", "传入"}, @@ -200,10 +200,10 @@ namespace chinese // language namespace static std::map> plurals { - {"days", {"日"}}, - {"hours", {"时"}}, - {"minutes", {"分"}}, - {"seconds", {"秒"}}, + {"%d days", {"%d 日"}}, + {"%d hours", {"%d 时"}}, + {"%d minutes", {"%d 分"}}, + {"%d seconds", {"%d 秒"}}, {"", {""}}, }; diff --git a/i18n/Czech.cpp b/i18n/Czech.cpp index f6ac7188..93862053 100644 --- a/i18n/Czech.cpp +++ b/i18n/Czech.cpp @@ -31,9 +31,9 @@ namespace czech // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "vytváří se"}, {"failed", "selhalo"}, {"expiring", "končící"}, @@ -69,7 +69,7 @@ namespace czech // language namespace {"Family", "Rodina"}, {"Tunnel creation success rate", "Úspěšnost vytváření tunelů"}, {"Received", "Přijato"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Odesláno"}, {"Transit", "Tranzit"}, {"Data path", "Cesta k data souborům"}, @@ -95,7 +95,7 @@ namespace czech // language namespace {"Type", "Typ"}, {"EncType", "EncType"}, {"Inbound tunnels", "Příchozí tunely"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Odchozí tunely"}, {"Tags", "Štítky"}, {"Incoming", "Příchozí"}, @@ -199,10 +199,10 @@ namespace czech // language namespace static std::map> plurals { - {"days", {"den", "dny", "dní", "dní"}}, - {"hours", {"hodina", "hodiny", "hodin", "hodin"}}, - {"minutes", {"minuta", "minuty", "minut", "minut"}}, - {"seconds", {"vteřina", "vteřiny", "vteřin", "vteřin"}}, + {"%d days", {"%d den", "%d dny", "%d dní", "%d dní"}}, + {"%d hours", {"%d hodina", "%d hodiny", "%d hodin", "%d hodin"}}, + {"%d minutes", {"%d minuta", "%d minuty", "%d minut", "%d minut"}}, + {"%d seconds", {"%d vteřina", "%d vteřiny", "%d vteřin", "%d vteřin"}}, {"", {"", "", "", ""}}, }; diff --git a/i18n/French.cpp b/i18n/French.cpp index 1a49ddfc..0d32c5c2 100644 --- a/i18n/French.cpp +++ b/i18n/French.cpp @@ -31,9 +31,9 @@ namespace french // language namespace static std::map strings { - {"KiB", "Kio"}, - {"MiB", "Mio"}, - {"GiB", "Gio"}, + {"%.2f KiB", "%.2f Kio"}, + {"%.2f MiB", "%.2f Mio"}, + {"%.2f GiB", "%.2f Gio"}, {"building", "En construction"}, {"failed", "échoué"}, {"expiring", "expiré"}, @@ -69,7 +69,7 @@ namespace french // language namespace {"Family", "Famille"}, {"Tunnel creation success rate", "Taux de succès de création de tunnels"}, {"Received", "Reçu"}, - {"KiB/s", "kio/s"}, + {"%.2f KiB/s", "%.2f kio/s"}, {"Sent", "Envoyé"}, {"Transit", "Transité"}, {"Data path", "Emplacement des données"}, @@ -93,7 +93,7 @@ namespace french // language namespace {"Address", "Adresse"}, {"Type", "Type"}, {"Inbound tunnels", "Tunnels entrants"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Tunnels sortants"}, {"Tags", "Balises"}, {"Incoming", "Entrant"}, @@ -194,10 +194,10 @@ namespace french // language namespace static std::map> plurals { - {"days", {"jour", "jours"}}, - {"hours", {"heure", "heures"}}, - {"minutes", {"minute", "minutes"}}, - {"seconds", {"seconde", "secondes"}}, + {"%d days", {"%d jour", "%d jours"}}, + {"%d hours", {"%d heure", "%d heures"}}, + {"%d minutes", {"%d minute", "%d minutes"}}, + {"%d seconds", {"%d seconde", "%d secondes"}}, {"", {"", ""}}, }; diff --git a/i18n/German.cpp b/i18n/German.cpp index 489a93a7..ca669436 100644 --- a/i18n/German.cpp +++ b/i18n/German.cpp @@ -31,9 +31,9 @@ namespace german // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "In Bau"}, {"failed", "fehlgeschlagen"}, {"expiring", "läuft ab"}, @@ -69,7 +69,7 @@ namespace german // language namespace {"Family", "Familie"}, {"Tunnel creation success rate", "Erfolgsrate der Tunnelerstellung"}, {"Received", "Eingegangen"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Gesendet"}, {"Transit", "Transit"}, {"Data path", "Datenpfad"}, @@ -95,7 +95,7 @@ namespace german // language namespace {"Type", "Typ"}, {"EncType", "Verschlüsselungstyp"}, {"Inbound tunnels", "Eingehende Tunnel"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Ausgehende Tunnel"}, {"Tags", "Tags"}, {"Incoming", "Eingehend"}, @@ -199,10 +199,10 @@ namespace german // language namespace static std::map> plurals { - {"days", {"Tag", "Tage"}}, - {"hours", {"Stunde", "Stunden"}}, - {"minutes", {"Minute", "Minuten"}}, - {"seconds", {"Sekunde", "Sekunden"}}, + {"%d days", {"%d Tag", "%d Tage"}}, + {"%d hours", {"%d Stunde", "%d Stunden"}}, + {"%d minutes", {"%d Minute", "%d Minuten"}}, + {"%d seconds", {"%d Sekunde", "%d Sekunden"}}, {"", {"", ""}}, }; diff --git a/i18n/I18N.h b/i18n/I18N.h index 27e043b9..2489ddcf 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -67,17 +67,71 @@ namespace i18n const std::map> m_Plurals; std::function m_Formula; }; - + void SetLanguage(const std::string &lang); std::string translate (const std::string& arg); std::string translate (const std::string& arg, const std::string& arg2, const int& n); } // i18n } // i2p -template -std::string tr (TArgs&&... args) +/** + * @brief Get translation of string + * @param arg String with message + */ +template +std::string tr (TValue&& arg) { - return i2p::i18n::translate(std::forward(args)...); + return i2p::i18n::translate(std::forward(arg)); +} + +/** + * @brief Get translation of string and format it + * @param arg String with message + * @param args Array of arguments for string formatting +*/ +template +std::string tr (TValue&& arg, TArgs&&... args) +{ + std::string tr_str = i2p::i18n::translate(std::forward(arg)); + + size_t size = snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); + size = size + 1; + std::string str(size, 0); + snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + + return str; +} + +/** + * @brief Get translation of string with plural forms + * @param arg String with message in singular form + * @param arg2 String with message in plural form + * @param n Integer, used for selection of form + */ +template +std::string ntr (TValue&& arg, TValue2&& arg2, int& n) +{ + return i2p::i18n::translate(std::forward(arg), std::forward(arg2), std::forward(n)); +} + +/** + * @brief Get translation of string with plural forms and format it + * @param arg String with message in singular form + * @param arg2 String with message in plural form + * @param n Integer, used for selection of form + * @param args Array of arguments for string formatting + */ +template +std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args) +{ + std::string tr_str = i2p::i18n::translate(std::forward(arg), std::forward(arg2), std::forward(n)); + + size_t size = snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); + size = size + 1; + std::string str(size, 0); + snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + + return str; } #endif // __I18N_H__ diff --git a/i18n/Italian.cpp b/i18n/Italian.cpp index ef2e26d0..07e436d7 100644 --- a/i18n/Italian.cpp +++ b/i18n/Italian.cpp @@ -31,9 +31,9 @@ namespace italian // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "in costruzione"}, {"failed", "fallito"}, {"expiring", "in scadenza"}, @@ -69,7 +69,7 @@ namespace italian // language namespace {"Family", "Famiglia"}, {"Tunnel creation success rate", "Percentuale di tunnel creati con successo"}, {"Received", "Ricevuti"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Inviati"}, {"Transit", "Transitati"}, {"Data path", "Percorso dati"}, @@ -95,7 +95,7 @@ namespace italian // language namespace {"Type", "Tipologia"}, {"EncType", "Tipo di crittografia"}, {"Inbound tunnels", "Tunnel in entrata"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Tunnel in uscita"}, {"Tags", "Tag"}, {"Incoming", "In entrata"}, @@ -199,10 +199,10 @@ namespace italian // language namespace static std::map> plurals { - {"days", {"giorno", "giorni"}}, - {"hours", {"ora", "ore"}}, - {"minutes", {"minuto", "minuti"}}, - {"seconds", {"secondo", "secondi"}}, + {"%d days", {"%d giorno", "%d giorni"}}, + {"%d hours", {"%d ora", "%d ore"}}, + {"%d minutes", {"%d minuto", "%d minuti"}}, + {"%d seconds", {"%d secondo", "%d secondi"}}, {"", {"", ""}}, }; diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index d7616e9e..7d875f01 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -31,9 +31,9 @@ namespace russian // language namespace static std::map strings { - {"KiB", "КиБ"}, - {"MiB", "МиБ"}, - {"GiB", "ГиБ"}, + {"%.2f KiB", "%.2f КиБ"}, + {"%.2f MiB", "%.2f МиБ"}, + {"%.2f GiB", "%.2f ГиБ"}, {"building", "строится"}, {"failed", "неудачный"}, {"expiring", "истекает"}, @@ -68,7 +68,7 @@ namespace russian // language namespace {"Family", "Семейство"}, {"Tunnel creation success rate", "Успешно построенных туннелей"}, {"Received", "Получено"}, - {"KiB/s", "КиБ/с"}, + {"%.2f KiB/s", "%.2f КиБ/с"}, {"Sent", "Отправлено"}, {"Transit", "Транзит"}, {"Data path", "Путь к данным"}, @@ -94,7 +94,7 @@ namespace russian // language namespace {"Type", "Тип"}, {"EncType", "ТипШифр"}, {"Inbound tunnels", "Входящие туннели"}, - {"ms", "мс"}, + {"%dms", "%dмс"}, {"Outbound tunnels", "Исходящие туннели"}, {"Tags", "Теги"}, {"Incoming", "Входящие"}, @@ -198,10 +198,10 @@ namespace russian // language namespace static std::map> plurals { - {"days", {"день", "дня", "дней"}}, - {"hours", {"час", "часа", "часов"}}, - {"minutes", {"минуту", "минуты", "минут"}}, - {"seconds", {"секунду", "секунды", "секунд"}}, + {"%d days", {"%d день", "%d дня", "%d дней"}}, + {"%d hours", {"%d час", "%d часа", "%d часов"}}, + {"%d minutes", {"%d минуту", "%d минуты", "%d минут"}}, + {"%d seconds", {"%d секунду", "%d секунды", "%d секунд"}}, {"", {"", "", ""}}, }; diff --git a/i18n/Spanish.cpp b/i18n/Spanish.cpp index a2f53927..8b0e927a 100644 --- a/i18n/Spanish.cpp +++ b/i18n/Spanish.cpp @@ -31,9 +31,9 @@ namespace spanish // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "pendiente"}, {"failed", "fallido"}, {"expiring", "expiró"}, @@ -69,7 +69,7 @@ namespace spanish // language namespace {"Family", "Familia"}, {"Tunnel creation success rate", "Tasa de éxito de creación de túneles"}, {"Received", "Recibido"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Enviado"}, {"Transit", "Tránsito"}, {"Data path", "Ruta de datos"}, @@ -95,7 +95,7 @@ namespace spanish // language namespace {"Type", "Tipo"}, {"EncType", "TipoEncrip"}, {"Inbound tunnels", "Túneles entrantes"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Túneles salientes"}, {"Tags", "Etiquetas"}, {"Incoming", "Entrante"}, @@ -199,10 +199,10 @@ namespace spanish // language namespace static std::map> plurals { - {"days", {"día", "días"}}, - {"hours", {"hora", "horas"}}, - {"minutes", {"minuto", "minutos"}}, - {"seconds", {"segundo", "segundos"}}, + {"%d days", {"%d día", "%d días"}}, + {"%d hours", {"%d hora", "%d horas"}}, + {"%d minutes", {"%d minuto", "%d minutos"}}, + {"%d seconds", {"%d segundo", "%d segundos"}}, {"", {"", ""}}, }; diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 356ada85..7e7a24f0 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -31,9 +31,9 @@ namespace turkmen // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "bina"}, {"failed", "şowsuz"}, {"expiring", "möhleti gutarýar"}, @@ -68,7 +68,7 @@ namespace turkmen // language namespace {"Family", "Maşgala"}, {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, {"Received", "Alnan"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Ýerleşdirildi"}, {"Transit", "Tranzit"}, {"Data path", "Maglumat ýoly"}, @@ -94,7 +94,7 @@ namespace turkmen // language namespace {"Type", "Görnüş"}, {"EncType", "Şifrlemek görnüşi"}, {"Inbound tunnels", "Gelýän tuneller"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Çykýan tuneller"}, {"Tags", "Bellikler"}, {"Incoming", "Gelýän"}, @@ -198,10 +198,10 @@ namespace turkmen // language namespace static std::map> plurals { - {"days", {"gün", "gün"}}, - {"hours", {"sagat", "sagat"}}, - {"minutes", {"minut", "minut"}}, - {"seconds", {"sekunt", "sekunt"}}, + {"%d days", {"%d gün", "%d gün"}}, + {"%d hours", {"%d sagat", "%d sagat"}}, + {"%d minutes", {"%d minut", "%d minut"}}, + {"%d seconds", {"%d sekunt", "%d sekunt"}}, {"", {"", ""}}, }; diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index abbe8f81..991f46ab 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -31,9 +31,9 @@ namespace ukrainian // language namespace static std::map strings { - {"KiB", "КіБ"}, - {"MiB", "МіБ"}, - {"GiB", "ГіБ"}, + {"%.2f KiB", "%.2f КіБ"}, + {"%.2f MiB", "%.2f МіБ"}, + {"%.2f GiB", "%.2f ГіБ"}, {"building", "будується"}, {"failed", "невдалий"}, {"expiring", "завершується"}, @@ -68,7 +68,7 @@ namespace ukrainian // language namespace {"Family", "Сімейство"}, {"Tunnel creation success rate", "Успішно побудованих тунелів"}, {"Received", "Отримано"}, - {"KiB/s", "КіБ/с"}, + {"%.2f KiB/s", "%.2f КіБ/с"}, {"Sent", "Відправлено"}, {"Transit", "Транзит"}, {"Data path", "Шлях до даних"}, @@ -94,7 +94,7 @@ namespace ukrainian // language namespace {"Type", "Тип"}, {"EncType", "ТипШифр"}, {"Inbound tunnels", "Вхідні тунелі"}, - {"ms", "мс"}, + {"%dms", "%dмс"}, {"Outbound tunnels", "Вихідні тунелі"}, {"Tags", "Теги"}, {"Incoming", "Вхідні"}, @@ -198,10 +198,10 @@ namespace ukrainian // language namespace static std::map> plurals { - {"days", {"день", "дня", "днів"}}, - {"hours", {"годину", "години", "годин"}}, - {"minutes", {"хвилину", "хвилини", "хвилин"}}, - {"seconds", {"секунду", "секунди", "секунд"}}, + {"%d days", {"%d день", "%d дня", "%d днів"}}, + {"%d hours", {"%d годину", "%d години", "%d годин"}}, + {"%d minutes", {"%d хвилину", "%d хвилини", "%d хвилин"}}, + {"%d seconds", {"%d секунду", "%d секунди", "%d секунд"}}, {"", {"", "", ""}}, }; diff --git a/i18n/Uzbek.cpp b/i18n/Uzbek.cpp index e750918f..7355471b 100644 --- a/i18n/Uzbek.cpp +++ b/i18n/Uzbek.cpp @@ -31,9 +31,9 @@ namespace uzbek // language namespace static std::map strings { - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"building", "yaratilmoqda"}, {"failed", "muvaffaqiyatsiz"}, {"expiring", "muddati tugaydi"}, @@ -68,7 +68,7 @@ namespace uzbek // language namespace {"Family", "Oila"}, {"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"}, {"Received", "Qabul qilindi"}, - {"KiB/s", "KiB/s"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Yuborilgan"}, {"Transit", "Tranzit"}, {"Data path", "Ma'lumotlar joylanishi"}, @@ -94,7 +94,7 @@ namespace uzbek // language namespace {"Type", "Turi"}, {"EncType", "ShifrlashTuri"}, {"Inbound tunnels", "Kirish tunnellari"}, - {"ms", "ms"}, + {"%dms", "%dms"}, {"Outbound tunnels", "Chiquvchi tunnellar"}, {"Tags", "Teglar"}, {"Incoming", "Kiruvchi"}, @@ -198,10 +198,10 @@ namespace uzbek // language namespace static std::map> plurals { - {"days", {"kun", "kun"}}, - {"hours", {"soat", "soat"}}, - {"minutes", {"daqiqa", "daqiqa"}}, - {"seconds", {"soniya", "soniya"}}, + {"%d days", {"%d kun", "%d kun"}}, + {"%d hours", {"%d soat", "%d soat"}}, + {"%d minutes", {"%d daqiqa", "%d daqiqa"}}, + {"%d seconds", {"%d soniya", "%d soniya"}}, {"", {"", ""}}, }; From d68c7f8ea7d7f49d241d890111be44524097d56c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Jan 2023 08:19:45 +0300 Subject: [PATCH 0031/1160] [i18n] fix build on macos Signed-off-by: R4SAS --- i18n/I18N.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/I18N.h b/i18n/I18N.h index 2489ddcf..4217a384 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -94,10 +94,10 @@ std::string tr (TValue&& arg, TArgs&&... args) { std::string tr_str = i2p::i18n::translate(std::forward(arg)); - size_t size = snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); + size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); size = size + 1; std::string str(size, 0); - snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); return str; } @@ -126,10 +126,10 @@ std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args) { std::string tr_str = i2p::i18n::translate(std::forward(arg), std::forward(arg2), std::forward(n)); - size_t size = snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); + size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); size = size + 1; std::string str(size, 0); - snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); return str; } From 88dfe3ca4ea3273917badf4b5e28cd93b1348bc5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Jan 2023 18:56:21 +0300 Subject: [PATCH 0032/1160] [i18n] fix build on macos Signed-off-by: R4SAS --- i18n/I18N.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/I18N.h b/i18n/I18N.h index 4217a384..9b413222 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -97,7 +97,7 @@ std::string tr (TValue&& arg, TArgs&&... args) size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); size = size + 1; std::string str(size, 0); - std::snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(&str.front(), size, tr_str.c_str(), std::forward(args)...); return str; } @@ -129,7 +129,7 @@ std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args) size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); size = size + 1; std::string str(size, 0); - std::snprintf(str.data(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(&str.front(), size, tr_str.c_str(), std::forward(args)...); return str; } From a57ae4dc5693bc97d57fd16717d369bd376b723f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Jan 2023 05:53:29 +0300 Subject: [PATCH 0033/1160] [i18n] add sweedish translation Translation author: corona@mail.i2p Signed-off-by: R4SAS --- Win32/DaemonWin32.cpp | 6 +- i18n/I18N.h | 2 +- i18n/I18N_langs.h | 2 + i18n/Swedish.cpp | 217 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 i18n/Swedish.cpp diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 0badf802..affc301a 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -29,7 +29,7 @@ namespace util setlocale(LC_CTYPE, ""); SetConsoleCP(1251); SetConsoleOutputCP(1251); - setlocale(LC_ALL, "Russian"); + //setlocale(LC_ALL, "Russian"); setlocale(LC_TIME, "C"); i2p::log::SetThrowFunction ([](const std::string& s) @@ -61,7 +61,7 @@ namespace util setlocale(LC_CTYPE, ""); SetConsoleCP(1251); SetConsoleOutputCP(1251); - setlocale(LC_ALL, "Russian"); + //setlocale(LC_ALL, "Russian"); setlocale(LC_TIME, "C"); #ifdef WIN32_APP if (!i2p::win32::StartWin32App ()) return false; diff --git a/i18n/I18N.h b/i18n/I18N.h index 9b413222..395c18eb 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2022, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 9a236d7a..51e23b19 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -33,6 +33,7 @@ namespace i18n namespace italian { std::shared_ptr GetLocale (); } namespace russian { std::shared_ptr GetLocale (); } namespace spanish { std::shared_ptr GetLocale (); } + namespace swedish { std::shared_ptr GetLocale (); } namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } namespace uzbek { std::shared_ptr GetLocale (); } @@ -52,6 +53,7 @@ namespace i18n { "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} }, { "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} }, { "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} }, + { "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} }, { "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, { "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, { "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} }, diff --git a/i18n/Swedish.cpp b/i18n/Swedish.cpp new file mode 100644 index 00000000..180f74aa --- /dev/null +++ b/i18n/Swedish.cpp @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Swedish localization file + +namespace i2p +{ +namespace i18n +{ +namespace swedish // language namespace +{ + // language name in lowercase + static std::string language = "swedish"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, + {"building", "bygger"}, + {"failed", "misslyckad"}, + {"expiring", "utgår"}, + {"established", "upprättad"}, + {"unknown", "okänt"}, + {"exploratory", "utforskande"}, + {"Purple I2P Webconsole", "Purple I2P Webbkonsoll"}, + {"i2pd webbkonsoll", "i2pd-Webbkonsoll"}, + {"Main page", "Huvudsida"}, + {"Router commands", "Routerkommandon"}, + {"Local Destinations", "Lokala Platser"}, + {"LeaseSets", "Hyresuppsättningar"}, + {"Tunnels", "Tunnlar"}, + {"Transit Tunnels", "Förmedlande Tunnlar"}, + {"Transports", "Transporter"}, + {"I2P tunnels", "I2P-tunnlar"}, + {"SAM sessions", "SAM-perioder"}, + {"ERROR", "FEL"}, + {"OK", "OK"}, + {"Testing", "Prövar"}, + {"Firewalled", "Bakom Brandvägg"}, + {"Unknown", "Okänt"}, + {"Proxy", "Proxy"}, + {"Mesh", "Mesh"}, + {"Error", "Fel"}, + {"Clock skew", "Tidsförskjutning"}, + {"Offline", "Nedkopplad"}, + {"Symmetric NAT", "Symmetrisk NAT"}, + {"Uptime", "Upptid"}, + {"Network status", "Nätverkstillstånd"}, + {"Network status v6", "Nätverkstillstånd v6"}, + {"Stopping in", "Avstängd om"}, + {"Family", "Familj"}, + {"Tunnel creation success rate", "Andel framgångsrika tunnlar"}, + {"Received", "Mottaget"}, + {"%.2f KiB/s", "%.2f KiB/s"}, + {"Sent", "Skickat"}, + {"Transit", "Förmedlat"}, + {"Data path", "Sökväg"}, + {"Hidden content. Press on text to see.", "Dolt innehåll. Tryck för att visa."}, + {"Router Ident", "Routeridentitet"}, + {"Router Family", "Routerfamilj"}, + {"Router Caps", "Routerbegränsningar"}, + {"Version", "Version"}, + {"Our external address", "Vår externa adress"}, + {"supported", "stöds"}, + {"Routers", "Routrar"}, + {"Floodfills", "Översvämningsfyllare"}, + {"Client Tunnels", "Klienttunnlar"}, + {"Services", "Tjänster"}, + {"Enabled", "Påslaget"}, + {"Disabled", "Avslaget"}, + {"Encrypted B33 address", "Krypterad B33-Adress"}, + {"Address registration line", "Adressregistreringsrad"}, + {"Domain", "Domän"}, + {"Generate", "Skapa"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Uppmärksamma: den resulterande strängen kan enbart användas för att registrera 2LD-domäner (exempel.i2p). För att registrera underdomäner, vänligen använd i2pd-tools."}, + {"Address", "Adress"}, + {"Type", "Typ"}, + {"EncType", "EncTyp"}, + {"Inbound tunnels", "Ingående Tunnlar"}, + {"%dms", "%dms"}, + {"Outbound tunnels", "Utgående Tunnlar"}, + {"Tags", "Taggar"}, + {"Incoming", "Ingående"}, + {"Outgoing", "Utgående"}, + {"Destination", "Plats"}, + {"Amount", "Mängd"}, + {"Incoming Tags", "Ingående Taggar"}, + {"Tags sessions", "Tagg-perioder"}, + {"Status", "Tillstånd"}, + {"Local Destination", "Lokal Plats"}, + {"Streams", "Strömmar"}, + {"Close stream", "Stäng strömmen"}, + {"I2CP session not found", "I2CP-period hittades inte"}, + {"I2CP is not enabled", "I2CP är inte påslaget"}, + {"Invalid", "Ogiltig"}, + {"Store type", "Lagringstyp"}, + {"Expires", "Utgångsdatum"}, + {"Non Expired Leases", "Ickeutgångna Hyresuppsättningar"}, + {"Gateway", "Gateway"}, + {"TunnelID", "TunnelID"}, + {"EndDate", "EndDate"}, + {"not floodfill", "inte Översvämningsfyllare"}, + {"Queue size", "Köstorlek"}, + {"Run peer test", "Utför utsiktstest"}, + {"Decline transit tunnels", "Avvisa förmedlande tunnlar"}, + {"Accept transit tunnels", "Tillåt förmedlande tunnlar"}, + {"Cancel graceful shutdown", "Avbryt välvillig avstängning"}, + {"Start graceful shutdown", "Påbörja välvillig avstängning"}, + {"Force shutdown", "Tvingad avstängning"}, + {"Reload external CSS styles", "Ladda om externa CSS-stilar"}, + {"Note: any action done here are not persistent and not changes your config files.", "Uppmärksamma: inga ändringar här är beständiga eller påverkar dina inställningsfiler."}, + {"Logging level", "Protokollförningsnivå"}, + {"Transit tunnels limit", "Begränsa förmedlande tunnlar"}, + {"Change", "Ändra"}, + {"Change language", "Ändra språk"}, + {"no transit tunnels currently built", "inga förmedlande tunnlar har byggts"}, + {"SAM disabled", "SAM avslaget"}, + {"no sessions currently running", "inga perioder igång"}, + {"SAM session not found", "SAM-perioder hittades ej"}, + {"SAM Session", "SAM-period"}, + {"Server Tunnels", "Värdtunnlar"}, + {"Client Forwards", "Klientförpassningar"}, + {"Server Forwards", "Värdförpassningar"}, + {"Unknown page", "Okänd sida"}, + {"Invalid token", "Ogiltig polett"}, + {"SUCCESS", "FRAMGÅNG"}, + {"Stream closed", "Ström stängd"}, + {"Stream not found or already was closed", "Strömmen hittades inte eller var redan avslutad"}, + {"Destination not found", "Plats hittades ej"}, + {"StreamID can't be null", "Ström-ID kan inte vara null"}, + {"Return to destination page", "Återvänd till platssidan"}, + {"You will be redirected in 5 seconds", "Du omdirigeras inom fem sekunder"}, + {"Transit tunnels count must not exceed 65535", "Förmedlande tunnlar får inte överstiga 65535"}, + {"Back to commands list", "Tillbaka till kommandolistan"}, + {"Register at reg.i2p", "Registrera vid reg.i2p"}, + {"Description", "Beskrivning"}, + {"A bit information about service on domain", "Ett stycke information om domänens tjänst"}, + {"Submit", "Skicka"}, + {"Domain can't end with .b32.i2p", "Domänen får inte sluta med .b32.i2p"}, + {"Domain must end with .i2p", "Domänen måste sluta med .i2p"}, + {"Such destination is not found", "En sådan plats hittas ej"}, + {"Unknown command", "Okänt kommando"}, + {"Command accepted", "Kommando accepterades"}, + {"Proxy error", "Proxyfel"}, + {"Proxy info", "Proxyinfo"}, + {"Proxy error: Host not found", "Proxyfel: Värden hittades ej"}, + {"Remote host not found in router's addressbook", "Främmande värd hittades inte i routerns adressbok"}, + {"You may try to find this host on jump services below", "Du kan försöka att hitta värden genom hopptjänsterna nedan"}, + {"Invalid request", "Ogiltig förfrågan"}, + {"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"}, + {"addresshelper is not supported", "adresshjälparen stöds ej"}, + {"Host", "Värd"}, + {"added to router's addressbook from helper", "tillagd i routerns adressbok från adresshjälparen"}, + {"Click here to proceed:", "Tryck här för att fortsätta:"}, + {"Continue", "Fortsätt"}, + {"Addresshelper found", "Adresshjälpare hittad"}, + {"already in router's addressbook", "finns redan i routerns adressbok"}, + {"Click here to update record:", "Tryck här för att uppdatera:"}, + {"invalid request uri", "ogiltig förfrågnings-URI"}, + {"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"}, + {"Outproxy failure", "Utproxyfel"}, + {"bad outproxy settings", "ogiltig utproxyinställning"}, + {"not inside I2P network, but outproxy is not enabled", "adressen är inte inom I2P-näverket, men utproxy är inte påslaget"}, + {"unknown outproxy url", "okänt Utproxy-URL"}, + {"cannot resolve upstream proxy", "hittar inte uppströmsproxyt"}, + {"hostname too long", "värdnamnet är för långt"}, + {"cannot connect to upstream socks proxy", "kan inte ansluta till uppströmsproxyt"}, + {"Cannot negotiate with socks proxy", "Kan inte förhandla med socksproxyt"}, + {"CONNECT error", "CONNECT-fel"}, + {"Failed to Connect", "Anslutningen misslyckades"}, + {"socks proxy error", "Socksproxyfel"}, + {"failed to send request to upstream", "förfrågan uppströms kunde ej skickas"}, + {"No Reply From socks proxy", "Fick inget svar från socksproxyt"}, + {"cannot connect", "kan inte ansluta"}, + {"http out proxy not implemented", "HTTP-Utproxy ej implementerat"}, + {"cannot connect to upstream http proxy", "Kan inte ansluta till uppströms HTTP-proxy"}, + {"Host is down", "Värden är nere"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Kan inte ansluta till värden, den kan vara nere. Vänligen försök senare."}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d Dag", "%d Dagar"}}, + {"%d hours", {"%d Timme", "%d Timmar"}}, + {"%d minutes", {"%d Minut", "%d Minuter"}}, + {"%d seconds", {"%d Sekund", "%d Sekunder"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p + From 533c8a8a55665acd4e71b792d5c4db4c45296407 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Jan 2023 06:40:32 +0300 Subject: [PATCH 0034/1160] [i18n] set decimal point based on language Signed-off-by: R4SAS --- i18n/I18N.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/i18n/I18N.cpp b/i18n/I18N.cpp index fe04bcb6..cf4873eb 100644 --- a/i18n/I18N.cpp +++ b/i18n/I18N.cpp @@ -1,11 +1,12 @@ /* -* Copyright (c) 2021-2022, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * * See full license text in LICENSE file at top of project tree */ +#include #include "ClientContext.h" #include "I18N_langs.h" #include "I18N.h" @@ -18,9 +19,15 @@ namespace i18n { const auto it = i2p::i18n::languages.find(lang); if (it == i2p::i18n::languages.end()) // fallback + { i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale()); + setlocale(LC_NUMERIC, "english"); + } else + { i2p::client::context.SetLanguage (it->second.LocaleFunc()); + setlocale(LC_NUMERIC, lang.c_str()); // set decimal point based on language + } } std::string translate (const std::string& arg) From a0e71c41732cd4af06f3aae219653c301fd6282d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Jan 2023 07:46:54 +0300 Subject: [PATCH 0035/1160] [i18n] update strings and translation file Signed-off-by: R4SAS --- contrib/i18n/English.po | 542 +++++++++++++++++++---------------- daemon/HTTPServer.cpp | 28 +- daemon/HTTPServer.h | 2 + libi2pd_client/HTTPProxy.cpp | 59 ++-- 4 files changed, 330 insertions(+), 301 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index c9ded966..22010680 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -1,13 +1,13 @@ # i2pd -# Copyright (C) 2021-2022 PurpleI2P team +# Copyright (C) 2021-2023 PurpleI2P team # This file is distributed under the same license as the i2pd package. -# R4SAS , 2021-2022. +# R4SAS , 2021-2023. # msgid "" msgstr "" "Project-Id-Version: i2pd\n" "Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" -"POT-Creation-Date: 2022-07-26 21:22\n" +"POT-Creation-Date: 2023-01-19 04:18\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,712 +18,748 @@ msgstr "" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" -#: daemon/HTTPServer.cpp:108 -msgid "day" -msgid_plural "days" +#: daemon/HTTPServer.cpp:106 +#, c-format +msgid "%d day" +msgid_plural "%d days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:112 -msgid "hour" -msgid_plural "hours" +#: daemon/HTTPServer.cpp:110 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:116 -msgid "minute" -msgid_plural "minutes" +#: daemon/HTTPServer.cpp:114 +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:119 -msgid "second" -msgid_plural "seconds" +#: daemon/HTTPServer.cpp:117 +#, c-format +msgid "%d second" +msgid_plural "%d seconds" msgstr[0] "" msgstr[1] "" -#. tr: Kibibit -#: daemon/HTTPServer.cpp:127 daemon/HTTPServer.cpp:155 -msgid "KiB" +#. tr: Kibibyte +#: daemon/HTTPServer.cpp:125 daemon/HTTPServer.cpp:153 +#, c-format +msgid "%.2f KiB" msgstr "" -#. tr: Mebibit +#. tr: Mebibyte +#: daemon/HTTPServer.cpp:127 +#, c-format +msgid "%.2f MiB" +msgstr "" + +#. tr: Gibibyte #: daemon/HTTPServer.cpp:129 -msgid "MiB" +#, c-format +msgid "%.2f GiB" msgstr "" -#. tr: Gibibit -#: daemon/HTTPServer.cpp:131 -msgid "GiB" -msgstr "" - -#: daemon/HTTPServer.cpp:148 +#: daemon/HTTPServer.cpp:146 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:149 +#: daemon/HTTPServer.cpp:147 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:150 +#: daemon/HTTPServer.cpp:148 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:151 +#: daemon/HTTPServer.cpp:149 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:152 +#: daemon/HTTPServer.cpp:150 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:154 +#: daemon/HTTPServer.cpp:152 msgid "exploratory" msgstr "" #. tr: Webconsole page title -#: daemon/HTTPServer.cpp:185 +#: daemon/HTTPServer.cpp:183 msgid "Purple I2P Webconsole" msgstr "" -#: daemon/HTTPServer.cpp:190 +#: daemon/HTTPServer.cpp:188 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:193 +#: daemon/HTTPServer.cpp:191 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:700 +#: daemon/HTTPServer.cpp:192 daemon/HTTPServer.cpp:712 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:382 -#: daemon/HTTPServer.cpp:394 +#: daemon/HTTPServer.cpp:193 daemon/HTTPServer.cpp:387 +#: daemon/HTTPServer.cpp:399 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:352 -#: daemon/HTTPServer.cpp:438 daemon/HTTPServer.cpp:444 -#: daemon/HTTPServer.cpp:597 daemon/HTTPServer.cpp:640 -#: daemon/HTTPServer.cpp:644 +#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:357 +#: daemon/HTTPServer.cpp:443 daemon/HTTPServer.cpp:449 +#: daemon/HTTPServer.cpp:609 daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:656 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:650 +#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:662 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:359 -#: daemon/HTTPServer.cpp:770 daemon/HTTPServer.cpp:786 +#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:364 +#: daemon/HTTPServer.cpp:781 daemon/HTTPServer.cpp:797 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:839 +#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:855 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:204 +#: daemon/HTTPServer.cpp:202 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:908 -#: daemon/HTTPServer.cpp:918 +#: daemon/HTTPServer.cpp:204 daemon/HTTPServer.cpp:884 +#: daemon/HTTPServer.cpp:894 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1302 -#: daemon/HTTPServer.cpp:1305 daemon/HTTPServer.cpp:1308 -#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1367 -#: daemon/HTTPServer.cpp:1370 daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:220 daemon/HTTPServer.cpp:1278 +#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1284 +#: daemon/HTTPServer.cpp:1298 daemon/HTTPServer.cpp:1343 +#: daemon/HTTPServer.cpp:1346 daemon/HTTPServer.cpp:1349 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:229 +#: daemon/HTTPServer.cpp:227 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:230 +#: daemon/HTTPServer.cpp:228 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:231 +#: daemon/HTTPServer.cpp:229 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:253 -#: daemon/HTTPServer.cpp:325 +#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:233 +#: daemon/HTTPServer.cpp:329 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:369 -#: daemon/HTTPServer.cpp:370 daemon/HTTPServer.cpp:976 -#: daemon/HTTPServer.cpp:985 +#: daemon/HTTPServer.cpp:231 daemon/HTTPServer.cpp:374 +#: daemon/HTTPServer.cpp:375 daemon/HTTPServer.cpp:952 +#: daemon/HTTPServer.cpp:961 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:234 +#: daemon/HTTPServer.cpp:232 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:237 -msgid "Error" -msgstr "" - -#: daemon/HTTPServer.cpp:241 +#: daemon/HTTPServer.cpp:240 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:244 +#: daemon/HTTPServer.cpp:243 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:247 +#: daemon/HTTPServer.cpp:246 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:259 +#: daemon/HTTPServer.cpp:249 +msgid "Full cone NAT" +msgstr "" + +#: daemon/HTTPServer.cpp:252 +msgid "No Descriptors" +msgstr "" + +#: daemon/HTTPServer.cpp:261 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:262 +#: daemon/HTTPServer.cpp:264 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:267 +#: daemon/HTTPServer.cpp:269 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:273 daemon/HTTPServer.cpp:280 +#: daemon/HTTPServer.cpp:275 daemon/HTTPServer.cpp:282 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:287 +#: daemon/HTTPServer.cpp:289 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:288 +#: daemon/HTTPServer.cpp:290 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:289 +#: daemon/HTTPServer.cpp:291 msgid "Received" msgstr "" -#. tr: Kibibit/s -#: daemon/HTTPServer.cpp:291 daemon/HTTPServer.cpp:294 -#: daemon/HTTPServer.cpp:297 -msgid "KiB/s" +#. tr: Kibibyte/s +#: daemon/HTTPServer.cpp:293 daemon/HTTPServer.cpp:296 +#: daemon/HTTPServer.cpp:299 +#, c-format +msgid "%.2f KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:292 +#: daemon/HTTPServer.cpp:294 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:295 +#: daemon/HTTPServer.cpp:297 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:298 +#: daemon/HTTPServer.cpp:300 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:301 +#: daemon/HTTPServer.cpp:303 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:304 +#: daemon/HTTPServer.cpp:307 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:306 +#: daemon/HTTPServer.cpp:309 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:307 +#: daemon/HTTPServer.cpp:310 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:308 +#: daemon/HTTPServer.cpp:311 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:309 +#: daemon/HTTPServer.cpp:312 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:337 +#. tr: Shown when router doesn't publish itself and have "Firewalled" state +#: daemon/HTTPServer.cpp:341 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:350 +#: daemon/HTTPServer.cpp:355 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:351 +#: daemon/HTTPServer.cpp:356 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:358 daemon/HTTPServer.cpp:962 +#: daemon/HTTPServer.cpp:363 daemon/HTTPServer.cpp:938 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:368 +#: daemon/HTTPServer.cpp:373 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:369 daemon/HTTPServer.cpp:370 -#: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:372 -#: daemon/HTTPServer.cpp:373 daemon/HTTPServer.cpp:374 +#: daemon/HTTPServer.cpp:374 daemon/HTTPServer.cpp:375 +#: daemon/HTTPServer.cpp:376 daemon/HTTPServer.cpp:377 +#: daemon/HTTPServer.cpp:378 daemon/HTTPServer.cpp:379 msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:369 daemon/HTTPServer.cpp:370 -#: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:372 -#: daemon/HTTPServer.cpp:373 daemon/HTTPServer.cpp:374 +#: daemon/HTTPServer.cpp:374 daemon/HTTPServer.cpp:375 +#: daemon/HTTPServer.cpp:376 daemon/HTTPServer.cpp:377 +#: daemon/HTTPServer.cpp:378 daemon/HTTPServer.cpp:379 msgid "Disabled" msgstr "" -#: daemon/HTTPServer.cpp:417 +#: daemon/HTTPServer.cpp:422 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:426 +#: daemon/HTTPServer.cpp:431 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:431 +#: daemon/HTTPServer.cpp:436 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:432 +#: daemon/HTTPServer.cpp:437 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:433 +#: daemon/HTTPServer.cpp:438 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:439 +#: daemon/HTTPServer.cpp:444 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:439 +#: daemon/HTTPServer.cpp:444 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:439 +#: daemon/HTTPServer.cpp:444 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:449 daemon/HTTPServer.cpp:655 +#: daemon/HTTPServer.cpp:454 daemon/HTTPServer.cpp:667 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:464 daemon/HTTPServer.cpp:484 -#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:689 -msgid "ms" +#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:489 +#: daemon/HTTPServer.cpp:681 daemon/HTTPServer.cpp:701 +#, c-format +msgid "%dms" msgstr "" -#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:674 +#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:686 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:491 +#: daemon/HTTPServer.cpp:496 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:491 +#: daemon/HTTPServer.cpp:497 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:498 daemon/HTTPServer.cpp:501 +#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:510 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:499 daemon/HTTPServer.cpp:515 +#: daemon/HTTPServer.cpp:507 daemon/HTTPServer.cpp:526 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:499 +#: daemon/HTTPServer.cpp:507 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:506 +#: daemon/HTTPServer.cpp:515 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:514 daemon/HTTPServer.cpp:517 +#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:529 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:515 +#: daemon/HTTPServer.cpp:526 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:524 daemon/HTTPServer.cpp:582 +#: daemon/HTTPServer.cpp:536 daemon/HTTPServer.cpp:594 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:941 +#: daemon/HTTPServer.cpp:547 daemon/HTTPServer.cpp:917 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:558 +#: daemon/HTTPServer.cpp:570 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:587 +#: daemon/HTTPServer.cpp:599 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:590 +#: daemon/HTTPServer.cpp:602 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:616 +#: daemon/HTTPServer.cpp:628 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:619 +#: daemon/HTTPServer.cpp:631 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:620 +#: daemon/HTTPServer.cpp:632 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:625 +#: daemon/HTTPServer.cpp:637 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:640 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:629 +#: daemon/HTTPServer.cpp:641 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:630 +#: daemon/HTTPServer.cpp:642 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:640 -msgid "not floodfill" +#: daemon/HTTPServer.cpp:652 +msgid "floodfill mode is disabled" msgstr "" -#: daemon/HTTPServer.cpp:651 +#: daemon/HTTPServer.cpp:663 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:701 +#: daemon/HTTPServer.cpp:713 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:706 +#: daemon/HTTPServer.cpp:714 +msgid "Reload tunnels configuration" +msgstr "" + +#: daemon/HTTPServer.cpp:717 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:708 +#: daemon/HTTPServer.cpp:719 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:712 daemon/HTTPServer.cpp:717 +#: daemon/HTTPServer.cpp:723 daemon/HTTPServer.cpp:728 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:714 daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:730 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:722 +#: daemon/HTTPServer.cpp:733 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:723 +#: daemon/HTTPServer.cpp:734 msgid "Reload external CSS styles" msgstr "" -#: daemon/HTTPServer.cpp:726 +#: daemon/HTTPServer.cpp:737 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:728 +#: daemon/HTTPServer.cpp:739 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:736 +#: daemon/HTTPServer.cpp:747 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:741 daemon/HTTPServer.cpp:760 +#: daemon/HTTPServer.cpp:752 daemon/HTTPServer.cpp:771 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:748 +#: daemon/HTTPServer.cpp:759 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:786 +#: daemon/HTTPServer.cpp:797 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:902 daemon/HTTPServer.cpp:925 +#: daemon/HTTPServer.cpp:878 daemon/HTTPServer.cpp:901 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:918 +#: daemon/HTTPServer.cpp:894 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:931 +#: daemon/HTTPServer.cpp:907 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:936 +#: daemon/HTTPServer.cpp:912 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:993 +#: daemon/HTTPServer.cpp:969 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:1009 +#: daemon/HTTPServer.cpp:985 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1023 +#: daemon/HTTPServer.cpp:999 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1223 +#: daemon/HTTPServer.cpp:1199 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1242 +#: daemon/HTTPServer.cpp:1218 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1357 -#: daemon/HTTPServer.cpp:1397 +#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1333 +#: daemon/HTTPServer.cpp:1373 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1300 +#: daemon/HTTPServer.cpp:1276 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1302 +#: daemon/HTTPServer.cpp:1278 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1305 +#: daemon/HTTPServer.cpp:1281 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1308 +#: daemon/HTTPServer.cpp:1284 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1310 daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:1286 daemon/HTTPServer.cpp:1351 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1311 daemon/HTTPServer.cpp:1324 -#: daemon/HTTPServer.cpp:1399 -msgid "You will be redirected in 5 seconds" +#: daemon/HTTPServer.cpp:1287 daemon/HTTPServer.cpp:1300 +#: daemon/HTTPServer.cpp:1375 +#, c-format +msgid "You will be redirected in %d seconds" msgstr "" -#: daemon/HTTPServer.cpp:1322 -msgid "Transit tunnels count must not exceed 65535" +#: daemon/HTTPServer.cpp:1298 +#, c-format +msgid "Transit tunnels count must not exceed %d" msgstr "" -#: daemon/HTTPServer.cpp:1323 daemon/HTTPServer.cpp:1398 +#: daemon/HTTPServer.cpp:1299 daemon/HTTPServer.cpp:1374 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1359 +#: daemon/HTTPServer.cpp:1335 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1360 +#: daemon/HTTPServer.cpp:1336 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1360 +#: daemon/HTTPServer.cpp:1336 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1361 +#: daemon/HTTPServer.cpp:1337 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1367 +#: daemon/HTTPServer.cpp:1343 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1370 +#: daemon/HTTPServer.cpp:1346 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:1349 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1393 +#: daemon/HTTPServer.cpp:1369 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1397 +#: daemon/HTTPServer.cpp:1373 msgid "Command accepted" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:163 +#: libi2pd_client/HTTPProxy.cpp:166 msgid "Proxy error" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:171 +#: libi2pd_client/HTTPProxy.cpp:174 msgid "Proxy info" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:179 +#: libi2pd_client/HTTPProxy.cpp:182 msgid "Proxy error: Host not found" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:180 +#: libi2pd_client/HTTPProxy.cpp:183 msgid "Remote host not found in router's addressbook" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:181 +#: libi2pd_client/HTTPProxy.cpp:184 msgid "You may try to find this host on jump services below" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:282 libi2pd_client/HTTPProxy.cpp:297 -#: libi2pd_client/HTTPProxy.cpp:331 libi2pd_client/HTTPProxy.cpp:372 +#: libi2pd_client/HTTPProxy.cpp:309 libi2pd_client/HTTPProxy.cpp:324 +#: libi2pd_client/HTTPProxy.cpp:392 libi2pd_client/HTTPProxy.cpp:435 msgid "Invalid request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:282 +#: libi2pd_client/HTTPProxy.cpp:309 msgid "Proxy unable to parse your request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:297 -msgid "addresshelper is not supported" +#: libi2pd_client/HTTPProxy.cpp:324 +msgid "Addresshelper is not supported" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:349 +#, c-format +msgid "" +"Host %s is already in router's addressbook. Be " +"careful: source of this URL may be harmful! Click here to update record: " +"Continue." +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:351 +msgid "Addresshelper forced update rejected" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:358 +#, c-format +msgid "" +"To add host %s in router's addressbook, click here: Continue." +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:360 +msgid "Addresshelper request" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:369 +#, c-format +msgid "" +"Host %s added to router's addressbook from helper. Click here to proceed: Continue." +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:370 +msgid "Addresshelper adding" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:377 +#, c-format +msgid "" +"Host %s is already in router's addressbook. Click " +"here to update record: Continue." +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:379 +msgid "Addresshelper update" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:306 libi2pd_client/HTTPProxy.cpp:315 #: libi2pd_client/HTTPProxy.cpp:392 -msgid "Host" +msgid "Invalid request URI" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:306 -msgid "added to router's addressbook from helper" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:307 -msgid "Click here to proceed:" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:307 libi2pd_client/HTTPProxy.cpp:317 -msgid "Continue" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:308 libi2pd_client/HTTPProxy.cpp:318 -msgid "Addresshelper found" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:315 -msgid "already in router's addressbook" -msgstr "" - -#. tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. -#: libi2pd_client/HTTPProxy.cpp:316 -msgid "Click here to update record:" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:331 -msgid "invalid request uri" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:372 +#: libi2pd_client/HTTPProxy.cpp:435 msgid "Can't detect destination host from request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:389 libi2pd_client/HTTPProxy.cpp:393 +#: libi2pd_client/HTTPProxy.cpp:452 libi2pd_client/HTTPProxy.cpp:456 msgid "Outproxy failure" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:389 -msgid "bad outproxy settings" +#: libi2pd_client/HTTPProxy.cpp:452 +msgid "Bad outproxy settings" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:392 -msgid "not inside I2P network, but outproxy is not enabled" +#: libi2pd_client/HTTPProxy.cpp:455 +#, c-format +msgid "Host %s is not inside I2P network, but outproxy is not enabled" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:482 -msgid "unknown outproxy url" +#: libi2pd_client/HTTPProxy.cpp:544 +msgid "Unknown outproxy URL" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:490 -msgid "cannot resolve upstream proxy" +#: libi2pd_client/HTTPProxy.cpp:550 +msgid "Cannot resolve upstream proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:498 -msgid "hostname too long" +#: libi2pd_client/HTTPProxy.cpp:558 +msgid "Hostname is too long" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:525 -msgid "cannot connect to upstream socks proxy" +#: libi2pd_client/HTTPProxy.cpp:585 +msgid "Cannot connect to upstream SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:531 -msgid "Cannot negotiate with socks proxy" +#: libi2pd_client/HTTPProxy.cpp:591 +msgid "Cannot negotiate with SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:573 +#: libi2pd_client/HTTPProxy.cpp:633 msgid "CONNECT error" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:573 -msgid "Failed to Connect" +#: libi2pd_client/HTTPProxy.cpp:633 +msgid "Failed to connect" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:584 libi2pd_client/HTTPProxy.cpp:610 -msgid "socks proxy error" +#: libi2pd_client/HTTPProxy.cpp:644 libi2pd_client/HTTPProxy.cpp:670 +msgid "SOCKS proxy error" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:592 -msgid "failed to send request to upstream" +#: libi2pd_client/HTTPProxy.cpp:652 +msgid "Failed to send request to upstream" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:613 -msgid "No Reply From socks proxy" +#: libi2pd_client/HTTPProxy.cpp:673 +msgid "No reply from SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:620 -msgid "cannot connect" +#: libi2pd_client/HTTPProxy.cpp:680 +msgid "Cannot connect" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:620 -msgid "http out proxy not implemented" +#: libi2pd_client/HTTPProxy.cpp:680 +msgid "HTTP out proxy not implemented" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:621 -msgid "cannot connect to upstream http proxy" +#: libi2pd_client/HTTPProxy.cpp:681 +msgid "Cannot connect to upstream HTTP proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:654 +#: libi2pd_client/HTTPProxy.cpp:714 msgid "Host is down" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:654 +#: libi2pd_client/HTTPProxy.cpp:714 msgid "" "Can't create connection to requested host, it may be down. Please try again " "later." diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 74e7df64..e18ce053 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -150,7 +150,7 @@ namespace http { else stateText = tr("unknown"); s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; - s << " " << tr(/* tr: Kibibit */ "%.2f KiB", (double) bytes / 1024) << "\r\n"; + s << " " << tr(/* tr: Kibibyte */ "%.2f KiB", (double) bytes / 1024) << "\r\n"; } static void SetLogLevel (const std::string& level) @@ -290,13 +290,13 @@ namespace http { s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")
\r\n"; + s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")
\r\n"; + s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetOutBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << tr(/* tr: Kibibit/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")
\r\n"; + s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024) << ")
\r\n"; s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { @@ -649,7 +649,7 @@ namespace http { } else if (!i2p::context.IsFloodfill ()) { - s << "" << tr("LeaseSets") << ": " << tr("not floodfill") << ".
\r\n"; + s << "" << tr("LeaseSets") << ": " << tr(/* Message on LeaseSets page */ "floodfill mode is disabled") << ".
\r\n"; } else { @@ -794,7 +794,7 @@ namespace http { } else { - s << "" << tr("Transit Tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; + s << "" << tr("Transit Tunnels") << ": " << tr(/* Message on transit tunnels page */ "no transit tunnels currently built") << ".
\r\n"; } } @@ -891,7 +891,7 @@ namespace http { s << "
\r\n"; } else - s << "" << tr("SAM sessions") << ": " << tr("no sessions currently running") << ".
\r\n"; + s << "" << tr("SAM sessions") << ": " << tr(/* Message on SAM sessions page */ "no sessions currently running") << ".
\r\n"; } void ShowSAMSession (std::stringstream& s, const std::string& id) @@ -1210,7 +1210,7 @@ namespace http { url.parse_query(params); std::string webroot; i2p::config::GetOption("http.webroot", webroot); - std::string redirect = "5; url=" + webroot + "?page=commands"; + std::string redirect = COMMAND_REDIRECT_TIMEOUT + "; url=" + webroot + "?page=commands"; std::string token = params["token"]; if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) @@ -1284,20 +1284,20 @@ namespace http { s << "" << tr("ERROR") << ": " << tr("StreamID can't be null") << "
\r\n
\r\n"; s << "" << tr("Return to destination page") << "
\r\n"; - s << "

" << tr("You will be redirected in 5 seconds") << ""; - redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32; + s << "

" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << ""; + redirect = COMMAND_REDIRECT_TIMEOUT + "; url=" + webroot + "?page=local_destination&b32=" + b32; res.add_header("Refresh", redirect.c_str()); return; } else if (cmd == HTTP_COMMAND_LIMITTRANSIT) { uint32_t limit = std::stoul(params["limit"], nullptr); - if (limit > 0 && limit <= 65535) + if (limit > 0 && limit <= TRANSIT_TUNNELS_LIMIT) SetMaxNumTransitTunnels (limit); else { - s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed 65535") << "\r\n
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\r\n
\r\n
\r\n"; s << "" << tr("Back to commands list") << "\r\n
\r\n"; - s << "

" << tr("You will be redirected in 5 seconds") << ""; + s << "

" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << ""; res.add_header("Refresh", redirect.c_str()); return; } @@ -1372,7 +1372,7 @@ namespace http { s << "" << tr("SUCCESS") << ": " << tr("Command accepted") << "

\r\n"; s << "" << tr("Back to commands list") << "
\r\n"; - s << "

" << tr("You will be redirected in 5 seconds") << ""; + s << "

" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << ""; res.add_header("Refresh", redirect.c_str()); } diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 8646253f..603bc25e 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -24,6 +24,8 @@ namespace http { const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds + const int COMMAND_REDIRECT_TIMEOUT = 5; // in seconds + const int TRANSIT_TUNNELS_LIMIT = 65535; class HTTPConnection: public std::enable_shared_from_this { diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index cecda2bb..6b015f2b 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -321,7 +321,7 @@ namespace proxy { if (!m_Addresshelper) { LogPrint(eLogWarning, "HTTPProxy: Addresshelper request rejected"); - GenericProxyError(tr("Invalid request"), tr("addresshelper is not supported")); + GenericProxyError(tr("Invalid request"), tr("Addresshelper is not supported")); return true; } @@ -341,28 +341,22 @@ namespace proxy { } if (m_RequestURL.host != referer_url.host) { - // Attempt to forced overwriting by link with "&update=true" from harmful URL - if (m_Confirm) + if (m_Confirm) // Attempt to forced overwriting by link with "&update=true" from harmful URL { LogPrint (eLogWarning, "HTTPProxy: Address update from addresshelper rejected for ", m_RequestURL.host, " (referer is ", m_RequestURL.host.empty() ? "empty" : "harmful", ")"); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; - ss << "" << tr( /* Trying to overwrite an existing domain in the address book by direct link with "&update=true" is seems like an attack */ "Be careful: source of this URL may be harmful") << "! "; - ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" ); - ss << " " << tr("Continue") << "."; + ss << tr("Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", + m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str()); } - // Preventing unauthorized additions to the address book - else + else // Preventing unauthorized additions to the address book { LogPrint (eLogDebug, "HTTPProxy: Adding address from addresshelper for ", m_RequestURL.host, " (generate refer-base page)"); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("To add host" /*... in router's addressbook, click here */ ) << " " << m_RequestURL.host << " " << tr( /* To add host SOMESHORT.i2p ... */ "in router's addressbook, click here") << ":"; - ss << " " << tr("Continue") << "."; + ss << tr("To add host %s in router's addressbook, click here: Continue.", + m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); GenericProxyInfo(tr("Addresshelper request"), ss.str()); } return true; /* request processed */ @@ -372,8 +366,7 @@ namespace proxy { LogPrint (eLogInfo, "HTTPProxy: Added address from addresshelper for ", m_RequestURL.host); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; - ss << tr("Click here to proceed:") << " " << tr("Continue") << "."; + ss << tr("Host %s added to router's addressbook from helper. Click here to proceed: Continue.", m_RequestURL.host, full_url); GenericProxyInfo(tr("Addresshelper adding"), ss.str()); return true; /* request processed */ } @@ -381,10 +374,8 @@ namespace proxy { { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; - ss << tr(/* tr: The "record" means addressbook's record. That message appears when domain was already added to addressbook, but helper link is opened for it. */ "Click here to update record:" ); - ss << " " << tr("Continue") << "."; + ss << tr("Host %s is already in router's addressbook. Click here to update record: Continue.", + m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); GenericProxyInfo(tr("Addresshelper update"), ss.str()); return true; /* request processed */ } @@ -398,7 +389,7 @@ namespace proxy { auto pos = uri.find(":"); if(pos == std::string::npos || pos == uri.size() - 1) { - GenericProxyError(tr("Invalid request"), tr("invalid request uri")); + GenericProxyError(tr("Invalid request"), tr("Invalid request URI")); return true; } else @@ -458,10 +449,10 @@ namespace proxy { if(m_ProxyURL.parse(m_OutproxyUrl)) ForwardToUpstreamProxy(); else - GenericProxyError(tr("Outproxy failure"), tr("bad outproxy settings")); + GenericProxyError(tr("Outproxy failure"), tr("Bad outproxy settings")); } else { LogPrint (eLogWarning, "HTTPProxy: Outproxy failure for ", dest_host, ": no outproxy enabled"); - std::stringstream ss; ss << tr("Host") << " " << dest_host << " " << tr("not inside I2P network, but outproxy is not enabled"); + std::stringstream ss; ss << tr("Host %s is not inside I2P network, but outproxy is not enabled", dest_host); GenericProxyError(tr("Outproxy failure"), ss.str()); } return true; @@ -550,13 +541,13 @@ namespace proxy { else { /* unknown type, complain */ - GenericProxyError(tr("unknown outproxy url"), m_ProxyURL.to_string()); + GenericProxyError(tr("Unknown outproxy URL"), m_ProxyURL.to_string()); } } void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler) { - if(ec) GenericProxyError(tr("cannot resolve upstream proxy"), ec.message()); + if(ec) GenericProxyError(tr("Cannot resolve upstream proxy"), ec.message()); else handler(*it); } @@ -564,7 +555,7 @@ namespace proxy { { if(!ec) { if(m_RequestURL.host.size() > 255) { - GenericProxyError(tr("hostname too long"), m_RequestURL.host); + GenericProxyError(tr("Hostname is too long"), m_RequestURL.host); return; } uint16_t port = m_RequestURL.port; @@ -591,13 +582,13 @@ namespace proxy { reqsize += host.size(); m_socks_buf[++reqsize] = 0; boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2)); - } else GenericProxyError(tr("cannot connect to upstream socks proxy"), ec.message()); + } else GenericProxyError(tr("Cannot connect to upstream SOCKS proxy"), ec.message()); } void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred) { LogPrint(eLogDebug, "HTTPProxy: Upstream SOCKS handshake sent"); - if(ec) GenericProxyError(tr("Cannot negotiate with socks proxy"), ec.message()); + if(ec) GenericProxyError(tr("Cannot negotiate with SOCKS proxy"), ec.message()); else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2)); } @@ -639,7 +630,7 @@ namespace proxy { } else { - GenericProxyError(tr("CONNECT error"), tr("Failed to Connect")); + GenericProxyError(tr("CONNECT error"), tr("Failed to connect")); } } @@ -650,7 +641,7 @@ namespace proxy { m_send_buf = m_ClientResponse.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError(tr("socks proxy error"), ec.message()); + if(ec) GenericProxyError(tr("SOCKS proxy error"), ec.message()); else HandoverToUpstreamProxy(); }); } else { @@ -658,7 +649,7 @@ namespace proxy { LogPrint(eLogDebug, "HTTPProxy: Send ", m_send_buf.size(), " bytes"); boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError(tr("failed to send request to upstream"), ec.message()); + if(ec) GenericProxyError(tr("Failed to send request to upstream"), ec.message()); else HandoverToUpstreamProxy(); }); } @@ -676,18 +667,18 @@ namespace proxy { ss << "error code: "; ss << (int) m_socks_buf[1]; std::string msg = ss.str(); - GenericProxyError(tr("socks proxy error"), msg); + GenericProxyError(tr("SOCKS proxy error"), msg); } } - else GenericProxyError(tr("No Reply From socks proxy"), ec.message()); + else GenericProxyError(tr("No reply from SOCKS proxy"), ec.message()); } void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec) { if(!ec) { LogPrint(eLogDebug, "HTTPProxy: Connected to http upstream"); - GenericProxyError(tr("cannot connect"), tr("http out proxy not implemented")); - } else GenericProxyError(tr("cannot connect to upstream http proxy"), ec.message()); + GenericProxyError(tr("Cannot connect"), tr("HTTP out proxy not implemented")); + } else GenericProxyError(tr("Cannot connect to upstream HTTP proxy"), ec.message()); } /* will be called after some data received from client */ From 84d4e074ceeadb7d6dda39d87a70ced6ec75fe80 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Jan 2023 08:33:03 +0300 Subject: [PATCH 0036/1160] add loglevel checker, fix fields passing to translated string formatter Signed-off-by: R4SAS --- contrib/webconsole/style.css | 586 +++++++++++++++++------------------ daemon/HTTPServer.cpp | 15 +- daemon/HTTPServer.h | 2 +- daemon/HTTPServerResources.h | 4 +- libi2pd/Log.cpp | 2 +- libi2pd_client/HTTPProxy.cpp | 11 +- 6 files changed, 311 insertions(+), 309 deletions(-) diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index 5d63d1a7..89021539 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -1,293 +1,293 @@ -/* - * Copyright (c) 2021-2022, 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 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. - * - * Minified copy of that style sheet is bundled inside i2pd sources. -*/ - -:root { - --main-bg-color: #fafafa; - --main-text-color: #103456; - --main-link-color: #894c84; - --main-link-hover-color: #fafafa; -} - -@media (prefers-color-scheme: dark) { - :root { - --main-bg-color: #242424; - --main-text-color: #17ab5c; - --main-link-color: #bf64b7; - --main-link-hover-color: #000000; - } -} - -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: var(--main-link-hover-color); - 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; - padding: 4px; - 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: 2em; - padding: 4px; - max-width: 50em; - 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; - } - - .content { - max-width: 40em; - } -} - -@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 { - display: block; - } - - .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 +/* + * Copyright (c) 2021-2023, 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 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. + * + * Minified copy of that style sheet is bundled inside i2pd sources. +*/ + +:root { + --main-bg-color: #fafafa; + --main-text-color: #103456; + --main-link-color: #894c84; + --main-link-hover-color: #fafafa; +} + +@media (prefers-color-scheme: dark) { + :root { + --main-bg-color: #242424; + --main-text-color: #17ab5c; + --main-link-color: #bf64b7; + --main-link-hover-color: #000000; + } +} + +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, a.button.selected, .slide label:hover, button[type=submit]:hover { + color: var(--main-link-hover-color); + 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; + padding: 4px; + 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: 2em; + padding: 4px; + max-width: 50em; + 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; + } + + .content { + max-width: 40em; + } +} + +@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 { + display: block; + } + + .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; + } +} diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index e18ce053..2bf92df3 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -198,7 +198,7 @@ namespace http { if (i2p::context.AcceptsTunnels () || i2p::tunnel::tunnels.CountTransitTunnels()) s << " " << tr("Transit Tunnels") << "
\r\n"; s << - " " << tr ("Transports") << "
\r\n" + " " << tr("Transports") << "
\r\n" " " << tr("I2P tunnels") << "
\r\n"; if (i2p::client::context.GetSAMBridge ()) s << " " << tr("SAM sessions") << "
\r\n"; @@ -736,19 +736,20 @@ namespace http { s << "
\r\n" << tr("Note: any action done here are not persistent and not changes your config files.") << "\r\n
\r\n"; + auto loglevel = i2p::log::Logger().GetLogLevel(); s << "" << tr("Logging level") << "
\r\n"; - s << " none \r\n"; - s << " error \r\n"; - s << " warn \r\n"; - s << " info \r\n"; - s << " debug
\r\n
\r\n"; + s << " none \r\n"; + s << " error \r\n"; + s << " warn \r\n"; + s << " info \r\n"; + s << " debug
\r\n
\r\n"; uint16_t maxTunnels = GetMaxNumTransitTunnels (); s << "" << tr("Transit tunnels limit") << "
\r\n"; s << "

\r\n"; s << " \r\n"; s << " \r\n"; - s << " \r\n"; + s << " \r\n"; s << " \r\n"; s << "
\r\n
\r\n"; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 603bc25e..f41d925d 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h index 0acbe8d1..1e5b6f75 100644 --- a/daemon/HTTPServerResources.h +++ b/daemon/HTTPServerResources.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -38,7 +38,7 @@ namespace http "@media (prefers-color-scheme: dark) { :root { --main-bg-color: #242424; --main-text-color: #17ab5c; --main-link-color: #bf64b7; --main-link-hover-color: #000000; } }\r\n" "body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: var(--main-bg-color); color: var(--main-text-color); }\r\n" "a, .slide label { text-decoration: none; color: var(--main-link-color); }\r\n" - "a:hover, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n" + "a:hover, a.button.selected, .slide label:hover, button[type=submit]:hover { color: var(--main-link-hover-color); background: var(--main-link-color); }\r\n" "a.button { appearance: button; text-decoration: none; padding: 0 5px; border: 1px solid var(--main-link-color); }\r\n" ".header { font-size: 2.5em; text-align: center; margin: 1em 0; color: var(--main-link-color); }\r\n" ".wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 94e65691..65b00e10 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -126,7 +126,7 @@ namespace log { if (level == "none") { m_MinLevel = eLogNone; } else if (level == "error") { m_MinLevel = eLogError; } else if (level == "warn") { m_MinLevel = eLogWarning; } - else if (level == "info") { m_MinLevel = eLogInfo; } + else if (level == "info") { m_MinLevel = eLogInfo; } else if (level == "debug") { m_MinLevel = eLogDebug; } else { LogPrint(eLogError, "Log: Unknown loglevel: ", level); diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 6b015f2b..b8ecd199 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -347,7 +347,7 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", - m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); + m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str()); GenericProxyInfo(tr("Addresshelper forced update rejected"), ss.str()); } else // Preventing unauthorized additions to the address book @@ -356,7 +356,7 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("To add host %s in router's addressbook, click here: Continue.", - m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); + m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str()); GenericProxyInfo(tr("Addresshelper request"), ss.str()); } return true; /* request processed */ @@ -366,7 +366,8 @@ namespace proxy { LogPrint (eLogInfo, "HTTPProxy: Added address from addresshelper for ", m_RequestURL.host); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << tr("Host %s added to router's addressbook from helper. Click here to proceed: Continue.", m_RequestURL.host, full_url); + ss << tr("Host %s added to router's addressbook from helper. Click here to proceed: Continue.", + m_RequestURL.host.c_str(), full_url.c_str()); GenericProxyInfo(tr("Addresshelper adding"), ss.str()); return true; /* request processed */ } @@ -375,7 +376,7 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host %s is already in router's addressbook. Click here to update record: Continue.", - m_RequestURL.host, full_url, (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump); + m_RequestURL.host.c_str(), full_url.c_str(), (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper="), jump.c_str()); GenericProxyInfo(tr("Addresshelper update"), ss.str()); return true; /* request processed */ } @@ -452,7 +453,7 @@ namespace proxy { GenericProxyError(tr("Outproxy failure"), tr("Bad outproxy settings")); } else { LogPrint (eLogWarning, "HTTPProxy: Outproxy failure for ", dest_host, ": no outproxy enabled"); - std::stringstream ss; ss << tr("Host %s is not inside I2P network, but outproxy is not enabled", dest_host); + std::stringstream ss; ss << tr("Host %s is not inside I2P network, but outproxy is not enabled", dest_host.c_str()); GenericProxyError(tr("Outproxy failure"), ss.str()); } return true; From cd6d86c8c30a8c3250da2857a8a36722d185334e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Jan 2023 13:40:12 -0500 Subject: [PATCH 0037/1160] make sure that async CreateStream complete --- libi2pd/Destination.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 4a2cc4ae..7523b939 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1138,19 +1138,25 @@ namespace client template std::shared_ptr ClientDestination::CreateStreamSync (const Dest& dest, int port) { + volatile bool done = false; std::shared_ptr stream; std::condition_variable streamRequestComplete; std::mutex streamRequestCompleteMutex; - std::unique_lock l(streamRequestCompleteMutex); CreateStream ( - [&streamRequestComplete, &streamRequestCompleteMutex, &stream](std::shared_ptr s) + [&done, &streamRequestComplete, &streamRequestCompleteMutex, &stream](std::shared_ptr s) { stream = s; std::unique_lock l(streamRequestCompleteMutex); streamRequestComplete.notify_all (); + done = true; }, dest, port); - streamRequestComplete.wait (l); + while (!done) + { + std::unique_lock l(streamRequestCompleteMutex); + if (!done) + streamRequestComplete.wait (l); + } return stream; } From 47eb49c34e0da0a8db18cd70cd96e734f89e7c66 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 20 Jan 2023 18:52:56 +0200 Subject: [PATCH 0038/1160] use correct style for Server Forwards section --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 2bf92df3..7a5175ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1001,7 +1001,7 @@ namespace http { for (auto& it: serverForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; From d4426118c5f030f3b8a127922426c7a9b9f599dc Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Jan 2023 15:34:40 -0500 Subject: [PATCH 0039/1160] exclude router from tunnel build for 2.5 minutes if declined --- libi2pd/Profiling.cpp | 20 +++++++++++++++++++- libi2pd/Profiling.h | 7 +++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 55b95831..06b1ec17 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -12,6 +12,7 @@ #include "Base.h" #include "FS.h" #include "Log.h" +#include "Timestamp.h" #include "Profiling.h" namespace i2p @@ -22,6 +23,7 @@ namespace data RouterProfile::RouterProfile (): m_LastUpdateTime (boost::posix_time::second_clock::local_time()), + m_LastDeclineTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTimesTaken (0), m_NumTimesRejected (0) { @@ -131,9 +133,15 @@ namespace data { UpdateTime (); if (ret > 0) + { m_NumTunnelsDeclined++; + m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); + } else + { m_NumTunnelsAgreed++; + m_LastDeclineTime = 0; + } } void RouterProfile::TunnelNonReplied () @@ -153,8 +161,18 @@ namespace data return m_NumTunnelsNonReplied > 10*(total + 1); } + bool RouterProfile::IsDeclinedRecently () + { + if (!m_LastDeclineTime) return false; + auto ts = i2p::util::GetSecondsSinceEpoch (); + if (ts > m_LastDeclineTime + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL) + m_LastDeclineTime = 0; + return m_LastDeclineTime; + } + bool RouterProfile::IsBad () { + if (IsDeclinedRecently ()) return true; auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/; if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1)) { diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 49e362ca..1c523a22 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -31,6 +31,7 @@ namespace data const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days) const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours) + const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) class RouterProfile { @@ -55,10 +56,12 @@ namespace data bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; }; bool IsLowPartcipationRate () const; bool IsLowReplyRate () const; + bool IsDeclinedRecently (); private: - boost::posix_time::ptime m_LastUpdateTime; + boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono + uint64_t m_LastDeclineTime; // in seconds // participation uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsDeclined; From e1ec79daf239cf5f1945ef14ba875943b05b2b66 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 21 Jan 2023 00:50:53 +0300 Subject: [PATCH 0040/1160] [webconsole] format transit tunnels with table Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7a5175ce..6166c97c 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -779,19 +779,20 @@ namespace http { { if (i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "" << tr("Transit Tunnels") << ":
\r\n
\r\n"; + s << "" << tr("Transit Tunnels") << ":
\r\n"; + s << ""; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { - s << "
\r\n"; if (std::dynamic_pointer_cast(it)) - s << it->GetTunnelID () << " ⇒ "; + s << "
\r\n"; } - s << "\r\n"; + s << "
ID" << tr("Amount") << "
" << it->GetTunnelID () << ""; else if (std::dynamic_pointer_cast(it)) - s << " ⇒ " << it->GetTunnelID (); + s << "
" << it->GetTunnelID () << ""; else - s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "\r\n"; + s << "
" << it->GetTunnelID () << ""; + ShowTraffic(s, it->GetNumTransmittedBytes ()); + s << "
\r\n"; } else { From 8baf62eb2ccad24678e22edae5785ada434aa82d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 21 Jan 2023 01:55:43 +0300 Subject: [PATCH 0041/1160] [websonsole] fix int concatenation with char strings Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 6166c97c..02b689a6 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1212,7 +1212,7 @@ namespace http { url.parse_query(params); std::string webroot; i2p::config::GetOption("http.webroot", webroot); - std::string redirect = COMMAND_REDIRECT_TIMEOUT + "; url=" + webroot + "?page=commands"; + std::string redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=commands"; std::string token = params["token"]; if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) @@ -1287,7 +1287,7 @@ namespace http { s << "" << tr("Return to destination page") << "
\r\n"; s << "

" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << ""; - redirect = COMMAND_REDIRECT_TIMEOUT + "; url=" + webroot + "?page=local_destination&b32=" + b32; + redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32; res.add_header("Refresh", redirect.c_str()); return; } From ac287a896c289bebb9d0c69c711de53aeac449dc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 20 Jan 2023 23:03:00 +0000 Subject: [PATCH 0042/1160] [websonsole] use a function to format the amount of tunnel traffic Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 02b689a6..0b99c047 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -150,7 +150,8 @@ namespace http { else stateText = tr("unknown"); s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; - s << " " << tr(/* tr: Kibibyte */ "%.2f KiB", (double) bytes / 1024) << "\r\n"; + ShowTraffic(s, bytes); + s << "\r\n"; } static void SetLogLevel (const std::string& level) From 067fb45a252fa87ecba8ed2fe781f953fa14cc56 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 21 Jan 2023 19:40:43 -0500 Subject: [PATCH 0043/1160] exclude router from tunnel build for 2.5 minutes if doesn't reply too often --- libi2pd/Profiling.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 06b1ec17..f826bf43 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -148,6 +148,8 @@ namespace data { m_NumTunnelsNonReplied++; UpdateTime (); + if (m_NumTunnelsNonReplied > 2*m_NumTunnelsAgreed && m_NumTunnelsNonReplied > 3) + m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); } bool RouterProfile::IsLowPartcipationRate () const From 1f23584c24747dda91a67c17a38f23212489775a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Jan 2023 21:24:01 -0500 Subject: [PATCH 0044/1160] update all SSU2 addresses --- libi2pd/RouterContext.cpp | 76 ++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index eb65d2ca..4713bb8a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -397,41 +397,59 @@ namespace i2p { auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; - bool found = false, updated = false; - for (auto& it : *addresses) - { - if (it && it->IsSSU2 ()) - { - found = true; - if (enable) - { - it->s = m_SSU2Keys->staticPublicKey; - it->i = m_SSU2Keys->intro; - } - else - it.reset (); - updated = true; - } - } - if (enable && !found) + bool updated = false; + if (enable) { bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool published; i2p::config::GetOption("ntcp2.published", published); - if (published) + if (ipv4 && (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]) { - if (ipv4) m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV4); - if (ipv6) m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV6); - } - else + (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]->s = m_SSU2Keys->staticPublicKey; + (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]->i = m_SSU2Keys->intro; + ipv4 = false; + } + if (ipv6 && (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]) { - uint8_t addressCaps = 0; - if (ipv4) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4; - if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addressCaps); + (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]->s = m_SSU2Keys->staticPublicKey; + (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]->i = m_SSU2Keys->intro; + ipv6 = false; } - updated = true; - } + if (ipv4 && ipv6) + { + bool published; i2p::config::GetOption("ssu2.published", published); + if (!published) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, + i2p::data::RouterInfo::AddressCaps::eV4 | i2p::data::RouterInfo::AddressCaps::eV6); + ipv4 = false; ipv6 = false; + updated = true; + } + } + if (ipv4) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV4); + updated = true; + } + if (ipv6) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV6); + updated= true; + } + } + else + { + if ((*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]) + { + (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx] = nullptr; + updated = true; + } + if ((*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]) + { + (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx] = nullptr; + updated = true; + } + } + if (updated) UpdateRouterInfo (); } From 5479ddd03ce58b00a9bdd3f51667c0883f8f50df Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 24 Jan 2023 14:07:22 -0500 Subject: [PATCH 0045/1160] publish NTCP2 addreses by index --- libi2pd/RouterContext.cpp | 81 +++++++++++++++++++++------------------ libi2pd/RouterContext.h | 5 ++- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4713bb8a..6d529863 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -296,34 +296,50 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::PublishNTCP2Address (std::shared_ptr address, + int port, bool publish) const + { + if (!address) return; + if (!port && !address->port) port = SelectRandomPort (); + if (port) address->port = port; + address->published = publish; + memcpy (address->i, m_NTCP2Keys->iv, 16); + } + void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg) { if (!m_NTCP2Keys) return; auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; bool updated = false; - for (auto& address : *addresses) + if (v4) { - if (address && address->IsNTCP2 () && (address->port != port || address->published != publish)) + auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V4Idx]; + if (addr) { - bool isAddr = v4 && address->IsV4 (); - if (!isAddr && (v6 || ygg)) - { - if (i2p::util::net::IsYggdrasilAddress (address->host)) - isAddr = ygg; - else - isAddr = v6 && address->IsV6 (); - } - if (isAddr) - { - if (!port && !address->port) port = SelectRandomPort (); - if (port) address->port = port; - address->published = publish; - memcpy (address->i, m_NTCP2Keys->iv, 16); - updated = true; - } - } + PublishNTCP2Address (addr, port, publish); + updated = true; + } + } + if (v6) + { + auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; + if (addr) + { + PublishNTCP2Address (addr, port, publish); + updated = true; + } } + if (ygg) + { + auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; + if (addr) + { + PublishNTCP2Address (addr, port, publish); + updated = true; + } + } + if (updated) UpdateRouterInfo (); } @@ -916,29 +932,18 @@ namespace i2p void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { - bool isYgg = i2p::util::net::IsYggdrasilAddress (host); - bool updated = false; auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; - for (auto& addr: *addresses) + std::shared_ptr addr; + if (i2p::util::net::IsYggdrasilAddress (host)) // yggdrasil + addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; + else if (host.is_v6 ()) + addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; + if (addr && addr->IsPublishedNTCP2 () && addr->host != host) { - if (addr && addr->IsPublishedNTCP2 ()) - { - bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host); - if (addr->IsV6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1))) - { - if (addr->host != host) - { - addr->host = host; - updated = true; - } - break; - } - } - } - - if (updated) + addr->host = host; UpdateRouterInfo (); + } } void RouterContext::UpdateStats () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index d3638b15..a2fd268f 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -181,7 +181,8 @@ namespace garlic bool Load (); void SaveKeys (); uint16_t SelectRandomPort () const; - + void PublishNTCP2Address (std::shared_ptr address, int port, bool publish) const; + bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize); private: From 4fae7b8d651ab759df03bd15dcb84dad17cc08f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 24 Jan 2023 18:20:16 -0500 Subject: [PATCH 0046/1160] don't update local RouterInfo addresses in Load but in InitTransports only --- libi2pd/RouterContext.cpp | 64 +++++++++++++++------------------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6d529863..62f4f3de 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -315,7 +315,7 @@ namespace i2p if (v4) { auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V4Idx]; - if (addr) + if (addr && (addr->port != port || addr->published != publish)) { PublishNTCP2Address (addr, port, publish); updated = true; @@ -324,7 +324,7 @@ namespace i2p if (v6) { auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; - if (addr) + if (addr && (addr->port != port || addr->published != publish)) { PublishNTCP2Address (addr, port, publish); updated = true; @@ -333,7 +333,7 @@ namespace i2p if (ygg) { auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; - if (addr) + if (addr && (addr->port != port || addr->published != publish)) { PublishNTCP2Address (addr, port, publish); updated = true; @@ -1011,6 +1011,27 @@ namespace i2p } n2k.close (); } + // create new NTCP2 keys if required + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + if ((ntcp2 || ygg) && !m_NTCP2Keys) NewNTCP2Keys (); + // read SSU2 keys if available + std::ifstream s2k (i2p::fs::DataDirPath (SSU2_KEYS), std::ifstream::in | std::ifstream::binary); + if (s2k) + { + s2k.seekg (0, std::ios::end); + size_t len = s2k.tellg(); + s2k.seekg (0, std::ios::beg); + if (len == sizeof (SSU2PrivateKeys)) + { + m_SSU2Keys.reset (new SSU2PrivateKeys ()); + s2k.read ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); + } + s2k.close (); + } + // create new SSU2 keys if required + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + if (ssu2 && !m_SSU2Keys) NewSSU2Keys (); // read RouterInfo m_RouterInfo.SetRouterIdentity (oldIdentity ? oldIdentity : GetIdentity ()); i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); @@ -1030,42 +1051,6 @@ namespace i2p if (IsUnreachable ()) SetReachable (true, true); // we assume reachable until we discover firewall through peer tests - - // read NTCP2 - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); - if (ntcp2 || ygg) - { - if (!m_NTCP2Keys) NewNTCP2Keys (); - UpdateNTCP2Address (true); // enable NTCP2 - } - else - UpdateNTCP2Address (false); // disable NTCP2 - - // read SSU2 - bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - if (ssu2) - { - // read SSU2 keys if available - std::ifstream s2k (i2p::fs::DataDirPath (SSU2_KEYS), std::ifstream::in | std::ifstream::binary); - if (s2k) - { - s2k.seekg (0, std::ios::end); - size_t len = s2k.tellg(); - s2k.seekg (0, std::ios::beg); - if (len == sizeof (SSU2PrivateKeys)) - { - m_SSU2Keys.reset (new SSU2PrivateKeys ()); - s2k.read ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); - } - s2k.close (); - } - if (!m_SSU2Keys) NewSSU2Keys (); - UpdateSSU2Address (true); // enable SSU2 - } - else - UpdateSSU2Address (false); // disable SSU2 - return true; } @@ -1098,7 +1083,6 @@ namespace i2p return true; } - void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); From b31f52e332cdae586f02e39228c4e229d07bc4ea Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 25 Jan 2023 08:54:45 +0000 Subject: [PATCH 0047/1160] [http] keep query even if it was empty (closes #1844) Signed-off-by: R4SAS --- libi2pd/HTTP.cpp | 5 ++++- libi2pd/HTTP.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 8791eadb..b8d7e8c3 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -160,6 +160,7 @@ namespace http return true; } else if (url.at(pos_c) == '?') { /* found query part */ + hasquery = true; path = url.substr(pos_p, pos_c - pos_p); pos_p = pos_c + 1; pos_c = url.find('#', pos_p); @@ -218,8 +219,10 @@ namespace http } } out += path; + if (hasquery) // add query even if it was empty + out += "?"; if (query != "") - out += "?" + query; + out += query; if (frag != "") out += "#" + frag; return out; diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index 9445a01a..046eebb9 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -33,6 +33,7 @@ namespace http std::string host; unsigned short int port; std::string path; + bool hasquery; std::string query; std::string frag; From 273aa31b1e5253cb7795e6e7c8b38762d6c4dd4d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 25 Jan 2023 12:43:46 -0500 Subject: [PATCH 0048/1160] try another floodfill if it's incompatible with tunnels --- libi2pd/Destination.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 7523b939..17bce5c4 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -763,9 +763,17 @@ namespace client request->requestTime = ts; if (!SendLeaseSetRequest (dest, floodfill, request)) { - // request failed - m_LeaseSetRequests.erase (ret.first); - if (requestComplete) requestComplete (nullptr); + // try another + LogPrint (eLogWarning, "Destination: Couldn't send LeaseSet request to ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another"); + request->excluded.insert (floodfill->GetIdentHash ()); + floodfill = i2p::data::netdb.GetClosestFloodfill (dest, request->excluded); + if (!SendLeaseSetRequest (dest, floodfill, request)) + { + // request failed + LogPrint (eLogWarning, "Destination: LeaseSet request for ", dest.ToBase32 (), " was not sent"); + m_LeaseSetRequests.erase (ret.first); + if (requestComplete) requestComplete (nullptr); + } } } else // duplicate @@ -792,11 +800,11 @@ namespace client std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) - request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); - if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); + request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); // outbound from floodfill + if (!request->replyTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible inbound tunnels found"); if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) - request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); - if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); + request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); // inbound from floodfill + if (!request->outboundTunnel) LogPrint (eLogWarning, "Destination: Can't send LeaseSet request, no compatible outbound tunnels found"); if (request->replyTunnel && request->outboundTunnel) { From 4de6201b84dc8927fb46941495f3ee5872c7d642 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 25 Jan 2023 13:23:46 -0500 Subject: [PATCH 0049/1160] update RouuterInfo if NTCP2 or SSU2 keys were recreated --- libi2pd/RouterContext.cpp | 117 ++++++++++++-------------------------- libi2pd/RouterContext.h | 7 +-- 2 files changed, 39 insertions(+), 85 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 62f4f3de..4188fa47 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -344,35 +344,21 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::UpdateNTCP2Address (bool enable) + void RouterContext::UpdateNTCP2Keys () { + if (!m_NTCP2Keys) return; auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; - bool found = false, updated = false; for (auto& it: *addresses) { if (it && it->IsNTCP2 ()) { - found = true; - if (enable) - { - it->s = m_NTCP2Keys->staticPublicKey; - memcpy (it->i, m_NTCP2Keys->iv, 16); - } - else - it.reset (); - updated = true; + it->s = m_NTCP2Keys->staticPublicKey; + memcpy (it->i, m_NTCP2Keys->iv, 16); } } - if (enable && !found) - { - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); - updated = true; - } - if (updated) - UpdateRouterInfo (); - } - + } + void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) { if (!m_SSU2Keys) return; @@ -409,67 +395,21 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::UpdateSSU2Address (bool enable) + void RouterContext::UpdateSSU2Keys () { + if (!m_SSU2Keys) return; auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; - bool updated = false; - if (enable) + for (auto& it: *addresses) { - bool ipv4; i2p::config::GetOption("ipv4", ipv4); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - if (ipv4 && (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]) + if (it && it->IsSSU2 ()) { - (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]->s = m_SSU2Keys->staticPublicKey; - (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]->i = m_SSU2Keys->intro; - ipv4 = false; - } - if (ipv6 && (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]) - { - (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]->s = m_SSU2Keys->staticPublicKey; - (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]->i = m_SSU2Keys->intro; - ipv6 = false; + it->s = m_SSU2Keys->staticPublicKey; + it->i = m_SSU2Keys->intro; } - if (ipv4 && ipv6) - { - bool published; i2p::config::GetOption("ssu2.published", published); - if (!published) - { - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, - i2p::data::RouterInfo::AddressCaps::eV4 | i2p::data::RouterInfo::AddressCaps::eV6); - ipv4 = false; ipv6 = false; - updated = true; - } - } - if (ipv4) - { - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV4); - updated = true; - } - if (ipv6) - { - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::AddressCaps::eV6); - updated= true; - } - } - else - { - if ((*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]) - { - (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx] = nullptr; - updated = true; - } - if ((*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]) - { - (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx] = nullptr; - updated = true; - } - } + } + } - if (updated) - UpdateRouterInfo (); - } - void RouterContext::UpdateAddress (const boost::asio::ip::address& host) { auto addresses = m_RouterInfo.GetAddresses (); @@ -1011,10 +951,6 @@ namespace i2p } n2k.close (); } - // create new NTCP2 keys if required - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); - if ((ntcp2 || ygg) && !m_NTCP2Keys) NewNTCP2Keys (); // read SSU2 keys if available std::ifstream s2k (i2p::fs::DataDirPath (SSU2_KEYS), std::ifstream::in | std::ifstream::binary); if (s2k) @@ -1029,9 +965,6 @@ namespace i2p } s2k.close (); } - // create new SSU2 keys if required - bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - if (ssu2 && !m_SSU2Keys) NewSSU2Keys (); // read RouterInfo m_RouterInfo.SetRouterIdentity (oldIdentity ? oldIdentity : GetIdentity ()); i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); @@ -1051,6 +984,28 @@ namespace i2p if (IsUnreachable ()) SetReachable (true, true); // we assume reachable until we discover firewall through peer tests + + bool updated = false; + // create new NTCP2 keys if required + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + if ((ntcp2 || ygg) && !m_NTCP2Keys) + { + NewNTCP2Keys (); + UpdateNTCP2Keys (); + updated = true; + } + // create new SSU2 keys if required + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + if (ssu2 && !m_SSU2Keys) + { + NewSSU2Keys (); + UpdateSSU2Keys (); + updated = true; + } + if (updated) + UpdateRouterInfo (); + return true; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a2fd268f..22359ded 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -116,11 +116,9 @@ namespace garlic bool DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data); void UpdatePort (int port); // called from Daemon - void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon + void UpdateAddress (const boost::asio::ip::address& host); // called from SSU2 or Daemon void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); - void UpdateNTCP2Address (bool enable); void PublishSSU2Address (int port, bool publish, bool v4, bool v6); - void UpdateSSU2Address (bool enable); bool AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4); void RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4); void ClearSSU2Introducers (bool v4); @@ -177,7 +175,8 @@ namespace garlic void UpdateRouterInfo (); void NewNTCP2Keys (); void NewSSU2Keys (); - bool IsSSU2Only () const; // SSU2 and no SSU + void UpdateNTCP2Keys (); + void UpdateSSU2Keys (); bool Load (); void SaveKeys (); uint16_t SelectRandomPort () const; From 8ee461f60aa70a70ecc75c9c64dd1ecdbee4fa3e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 25 Jan 2023 18:11:26 -0500 Subject: [PATCH 0050/1160] enable all ipv4 adresses even if one is already enabled --- libi2pd/RouterContext.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4188fa47..54817b2e 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -749,10 +749,6 @@ namespace i2p void RouterContext::SetSupportsV4 (bool supportsV4) { - // check if updates - if (supportsV4 && SupportsV4 ()) return; - if (!supportsV4 && !SupportsV4 ()) return; - // update if (supportsV4) { bool foundNTCP2 = false, foundSSU2 = false; From e91d0bbec8310f77d5ca4f7b54dec5dfe8dfc3ad Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Jan 2023 11:21:08 -0500 Subject: [PATCH 0051/1160] delete address if corresponding transport is disabled --- libi2pd/RouterContext.cpp | 40 +++++++++++++++++++------------ libi2pd/RouterInfo.cpp | 50 ++++++++++++++++++++++++++++++++------- libi2pd/RouterInfo.h | 2 ++ 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 54817b2e..1c2e5be6 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -702,12 +702,12 @@ namespace i2p if (!port) port = SelectRandomPort (); } // NTCP2 - if (!foundNTCP2) + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) { - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); - if (ntcp2) + if (!foundNTCP2) { + bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) { std::string ntcp2Host; @@ -723,11 +723,13 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); } } + else + m_RouterInfo.RemoveNTCP2Address (false); // SSU2 - if (!foundSSU2) + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + if (ssu2) { - bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - if (ssu2) + if (!foundSSU2) { bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); if (ssu2Published) @@ -740,7 +742,10 @@ namespace i2p m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6); } } - m_RouterInfo.EnableV6 (); + else + m_RouterInfo.RemoveSSU2Address (false); + if (ntcp2 || ssu2) + m_RouterInfo.EnableV6 (); } else m_RouterInfo.DisableV6 (); @@ -781,10 +786,10 @@ namespace i2p if (!port) port = SelectRandomPort (); } // NTCP2 - if (!foundNTCP2) + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) { - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + if (!foundNTCP2) { bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) @@ -797,11 +802,13 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4); } } + else + m_RouterInfo.RemoveNTCP2Address (false); // SSU2 - if (!foundSSU2) + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + if (ssu2) { - bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - if (ssu2) + if (!foundSSU2) { bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); if (ssu2Published) @@ -814,7 +821,10 @@ namespace i2p m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV4); } } - m_RouterInfo.EnableV4 (); + else + m_RouterInfo.RemoveSSU2Address (false); + if (ntcp2 || ssu2) + m_RouterInfo.EnableV4 (); } else m_RouterInfo.DisableV4 (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 1aa0259b..9e4701d3 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -655,6 +655,23 @@ namespace data } } + void RouterInfo::RemoveNTCP2Address (bool v4) + { + if (v4) + { + if ((*m_Addresses)[eNTCP2V6Idx]) + (*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4; + (*m_Addresses)[eNTCP2V4Idx].reset (); + } + else + { + if ((*m_Addresses)[eNTCP2V4Idx]) + (*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6; + (*m_Addresses)[eNTCP2V6Idx].reset (); + } + UpdateSupportedTransports (); + } + void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps) { auto addr = std::make_shared

(); @@ -706,6 +723,23 @@ namespace data } } + void RouterInfo::RemoveSSU2Address (bool v4) + { + if (v4) + { + if ((*m_Addresses)[eSSU2V6Idx]) + (*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4; + (*m_Addresses)[eSSU2V4Idx].reset (); + } + else + { + if ((*m_Addresses)[eSSU2V4Idx]) + (*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6; + (*m_Addresses)[eSSU2V6Idx].reset (); + } + UpdateSupportedTransports (); + } + bool RouterInfo::IsNTCP2 (bool v4only) const { if (v4only) @@ -744,14 +778,14 @@ namespace data { if ((*m_Addresses)[eNTCP2V6Idx]) { - if ((*m_Addresses)[eNTCP2V6Idx]->IsV4 ()) - (*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV6; + if ((*m_Addresses)[eNTCP2V6Idx]->IsV4 () && (*m_Addresses)[eNTCP2V4Idx]) + (*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6; (*m_Addresses)[eNTCP2V6Idx].reset (); } if ((*m_Addresses)[eSSU2V6Idx]) { - if ((*m_Addresses)[eSSU2V6Idx]->IsV4 ()) - (*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV6; + if ((*m_Addresses)[eSSU2V6Idx]->IsV4 () && (*m_Addresses)[eSSU2V4Idx]) + (*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6; (*m_Addresses)[eSSU2V6Idx].reset (); } UpdateSupportedTransports (); @@ -764,14 +798,14 @@ namespace data { if ((*m_Addresses)[eNTCP2V4Idx]) { - if ((*m_Addresses)[eNTCP2V4Idx]->IsV6 ()) - (*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV4; + if ((*m_Addresses)[eNTCP2V4Idx]->IsV6 () && (*m_Addresses)[eNTCP2V6Idx]) + (*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4; (*m_Addresses)[eNTCP2V4Idx].reset (); } if ((*m_Addresses)[eSSU2V4Idx]) { - if ((*m_Addresses)[eSSU2V4Idx]->IsV6 ()) - (*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV4; + if ((*m_Addresses)[eSSU2V4Idx]->IsV6 () && (*m_Addresses)[eSSU2V6Idx]) + (*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4; (*m_Addresses)[eSSU2V4Idx].reset (); } UpdateSupportedTransports (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 4e54d615..10405a0a 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -200,9 +200,11 @@ namespace data void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0); + void RemoveNTCP2Address (bool v4); void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps = 0); // non published void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, const boost::asio::ip::address& host, int port); // published + void RemoveSSU2Address (bool v4); void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps void UpdateSupportedTransports (); bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; From ad5540c9f379d5ca6f3c31c81356c9395da020ad Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Jan 2023 11:32:59 -0500 Subject: [PATCH 0052/1160] delete address if corresponding transport is disabled --- libi2pd/RouterContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 1c2e5be6..86a0e915 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -803,7 +803,7 @@ namespace i2p } } else - m_RouterInfo.RemoveNTCP2Address (false); + m_RouterInfo.RemoveNTCP2Address (true); // SSU2 bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); if (ssu2) @@ -822,7 +822,7 @@ namespace i2p } } else - m_RouterInfo.RemoveSSU2Address (false); + m_RouterInfo.RemoveSSU2Address (true); if (ntcp2 || ssu2) m_RouterInfo.EnableV4 (); } From 126ca0209bb084942805c05aedf9f684c97b6e81 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 27 Jan 2023 20:11:05 +0000 Subject: [PATCH 0053/1160] [gha] update docker build workflow Signed-off-by: R4SAS --- .github/workflows/docker.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 899a7eec..262ab51c 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -57,6 +57,7 @@ jobs: tags: | purplei2p/i2pd:latest-${{ matrix.archname }} ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }} + provenance: false push: runs-on: ubuntu-latest @@ -92,15 +93,15 @@ jobs: - name: Create and push latest manifest image to Docker Hub uses: Noelware/docker-manifest-action@master with: - base-image: purplei2p/i2pd:latest - extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + images: purplei2p/i2pd:latest + inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push latest manifest image to GHCR uses: Noelware/docker-manifest-action@master with: - base-image: ghcr.io/purplei2p/i2pd:latest - extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + images: ghcr.io/purplei2p/i2pd:latest + inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true - name: Store release version to env @@ -111,30 +112,30 @@ jobs: if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - base-image: purplei2p/i2pd:latest-release - extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + images: purplei2p/i2pd:latest-release + inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push release manifest image to GHCR if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - base-image: ghcr.io/purplei2p/i2pd:latest-release - extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + images: ghcr.io/purplei2p/i2pd:latest-release + inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true - name: Create and push versioned manifest image to Docker Hub if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - base-image: purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - extra-images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + images: purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push versioned manifest image to GHCR if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - base-image: ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - extra-images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + images: ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true From f9331897b881338f108ae4479bbbe14491480066 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 27 Jan 2023 21:11:26 +0000 Subject: [PATCH 0054/1160] [gha] fix docker manifest merging Signed-off-by: R4SAS --- .github/workflows/docker.yml | 38 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 262ab51c..1f3142e4 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -91,51 +91,37 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Create and push latest manifest image to Docker Hub + if: ${{ !startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - images: purplei2p/i2pd:latest - inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + inputs: purplei2p/i2pd:latest + images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push latest manifest image to GHCR + if: ${{ !startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - images: ghcr.io/purplei2p/i2pd:latest - inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + inputs: ghcr.io/purplei2p/i2pd:latest + images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true - name: Store release version to env if: ${{ startsWith(github.ref, 'refs/tags/') }} run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV - - name: Create and push release manifest image to Docker Hub + - name: Create and push release manifest to Docker Hub if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - images: purplei2p/i2pd:latest-release - inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - - name: Create and push release manifest image to GHCR + - name: Create and push release manifest to GHCR if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: Noelware/docker-manifest-action@master with: - images: ghcr.io/purplei2p/i2pd:latest-release - inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 - push: true - - - name: Create and push versioned manifest image to Docker Hub - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - images: purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - inputs: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 - push: true - - - name: Create and push versioned manifest image to GHCR - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - images: ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - inputs: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true From 8a106eb09e421eb99e6cbb6c93df6e48a51bf2e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 28 Jan 2023 17:18:54 -0500 Subject: [PATCH 0055/1160] fixed test-http-req --- libi2pd/HTTP.cpp | 10 +++++++++- libi2pd/HTTP.h | 4 +++- tests/test-http-req.cpp | 30 +++++++++++++++--------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index b8d7e8c3..8b61c7e5 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -350,6 +350,14 @@ namespace http return ""; } + size_t HTTPReq::GetNumHeaders (const std::string& name) const + { + size_t num = 0; + for (auto& it : headers) + if (it.first == name) num++; + return num; + } + bool HTTPRes::is_chunked() const { auto it = headers.find("Transfer-Encoding"); diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index 046eebb9..9b8788ec 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -102,6 +102,8 @@ namespace http void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); }; std::string GetHeader (const std::string& name) const; + size_t GetNumHeaders (const std::string& name) const; + size_t GetNumHeaders () const { return headers.size (); }; }; struct HTTPRes : HTTPMsg { diff --git a/tests/test-http-req.cpp b/tests/test-http-req.cpp index 6deb66b0..db973a2e 100644 --- a/tests/test-http-req.cpp +++ b/tests/test-http-req.cpp @@ -22,13 +22,13 @@ int main() { assert(req->version == "HTTP/1.0"); assert(req->method == "GET"); assert(req->uri == "/"); - assert(req->headers.size() == 3); - assert(req->headers.count("Host") == 1); - assert(req->headers.count("Accept") == 1); - assert(req->headers.count("User-Agent") == 1); - assert(req->headers.find("Host")->second == "inr.i2p"); - assert(req->headers.find("Accept")->second == "*/*"); - assert(req->headers.find("User-Agent")->second == "curl/7.26.0"); + assert(req->GetNumHeaders () == 3); + assert(req->GetNumHeaders("Host") == 1); + assert(req->GetNumHeaders("Accept") == 1); + assert(req->GetNumHeaders("User-Agent") == 1); + assert(req->GetHeader("Host") == "inr.i2p"); + assert(req->GetHeader("Accept") == "*/*"); + assert(req->GetHeader("User-Agent") == "curl/7.26.0"); delete req; /* test: parsing request without body */ @@ -41,7 +41,7 @@ int main() { assert(req->version == "HTTP/1.0"); assert(req->method == "GET"); assert(req->uri == "/"); - assert(req->headers.size() == 0); + assert(req->GetNumHeaders () == 0); delete req; /* test: parsing request without body */ @@ -74,13 +74,13 @@ int main() { assert((ret = req->parse(buf, len)) == len); /* no host header */ assert(req->method == "GET"); assert(req->uri == "http://inr.i2p"); - assert(req->headers.size() == 3); - assert(req->headers.count("Host") == 1); - assert(req->headers.count("Accept") == 1); - assert(req->headers.count("Accept-Encoding") == 1); - assert(req->headers["Host"] == "stats.i2p"); - assert(req->headers["Accept"] == "*/*"); - assert(req->headers["Accept-Encoding"] == ""); + assert(req->GetNumHeaders () == 3); + assert(req->GetNumHeaders("Host") == 1); + assert(req->GetNumHeaders("Accept") == 1); + assert(req->GetNumHeaders("Accept-Encoding") == 1); + assert(req->GetHeader("Host") == "stats.i2p"); + assert(req->GetHeader("Accept") == "*/*"); + assert(req->GetHeader("Accept-Encoding") == ""); delete req; return 0; From 70fec2bc99612d7d7085ae69a4a42dfb46ab91b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 28 Jan 2023 22:33:44 -0500 Subject: [PATCH 0056/1160] don't publish localhost addresses in RouterInfo --- libi2pd/Config.cpp | 4 +- libi2pd/RouterContext.cpp | 208 +++++++++++++++++++++++++------------- libi2pd/RouterInfo.cpp | 38 +++++-- libi2pd/RouterInfo.h | 5 +- 4 files changed, 170 insertions(+), 85 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 556b226b..07ab2f20 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -45,7 +45,7 @@ namespace config { ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") - ("host", value()->default_value("0.0.0.0"), "External IP") + ("host", value()->default_value(""), "External IP") ("ifname", value()->default_value(""), "Network interface to bind to") ("ifname4", value()->default_value(""), "Network interface to bind to for ipv4") ("ifname6", value()->default_value(""), "Network interface to bind to for ipv6") diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 86a0e915..d37bd440 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -88,92 +88,115 @@ namespace i2p uint8_t caps = 0, addressCaps = 0; if (ipv4) { - std::string host = "127.0.0.1"; - if (!i2p::config::IsDefault("host")) - i2p::config::GetOption("host", host); - else if (!nat) - { + std::string host; + if (!nat) // we have no NAT so set external address from local address - std::string address4; i2p::config::GetOption("address4", address4); - if (!address4.empty ()) host = address4; - } + i2p::config::GetOption("address4", host); + if (host.empty ()) i2p::config::GetOption("host", host); if (ntcp2) { - if (ntcp2Published) - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port); - else // add non-published NTCP2 address + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; + if (ntcp2Published && ntcp2Port) + { + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } + } + if (!added) { + // add non-published NTCP2 address addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV4); } } if (ssu2) { - if (ssu2Published) - { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), ssu2Port); - } - else + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; + if (ssu2Published && ssu2Port) + { + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) { addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV4); } } } if (ipv6) { - std::string host; - if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only - i2p::config::GetOption("host", host); - else - { - std::string address6; i2p::config::GetOption("address6", address6); - if (!address6.empty ()) host = address6; - } + std::string host; i2p::config::GetOption("address6", host); + if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented if (ntcp2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; bool added = false; - if (ntcp2Published) + if (ntcp2Published && ntcp2Port) { std::string ntcp2Host; if (!i2p::config::IsDefault ("ntcp2.addressv6")) i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else ntcp2Host = host; - if (!ntcp2Host.empty () && port) + if (!ntcp2Host.empty ()) { - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port); - added = true; + auto addr = boost::asio::ip::address::from_string (ntcp2Host); + if (addr.is_v6 ()) + { + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } } } if (!added) { if (!ipv4) // no other ntcp2 addresses yet - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV6); addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } if (ssu2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; bool added = false; - if (ssu2Published) + if (ssu2Published && ssu2Port) { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - if (!host.empty () && ssu2Port) - { - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), ssu2Port); - added = true; - } + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v6 ()) + { + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } } if (!added) { if (!ipv4) // no other ssu2 addresses yet - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV6); addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } @@ -286,7 +309,7 @@ namespace i2p bool updated = false; for (auto& address : *addresses) { - if (address && address->port != port && address->transportStyle == i2p::data::RouterInfo::eTransportSSU2) + if (address && address->port != port) { address->port = port; updated = true; @@ -707,6 +730,9 @@ namespace i2p { if (!foundNTCP2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) { @@ -714,13 +740,19 @@ namespace i2p if (!i2p::config::IsDefault ("ntcp2.addressv6")) i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else - ntcp2Host = "::1"; - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + i2p::config::GetOption("host", ntcp2Host); + if (!ntcp2Host.empty () && ntcp2Port) + { + auto addr = boost::asio::ip::address::from_string (ntcp2Host); + if (addr.is_v6 ()) + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } } - else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); + if (!added) + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV6); } } else @@ -731,15 +763,25 @@ namespace i2p { if (!foundSSU2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); - if (ssu2Published) + if (ssu2Published && ssu2Port) { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port); - } - else - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6); + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v6 ()) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV6); } } else @@ -757,7 +799,6 @@ namespace i2p if (supportsV4) { bool foundNTCP2 = false, foundSSU2 = false; - std::string host = "127.0.0.1"; uint16_t port = 0; auto addresses = m_RouterInfo.GetAddresses (); if (addresses) @@ -791,15 +832,25 @@ namespace i2p { if (!foundNTCP2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); - if (ntcp2Published) - { - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port); - } - else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4); + if (ntcp2Published && ntcp2Port) + { + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV4); } } else @@ -810,15 +861,26 @@ namespace i2p { if (!foundSSU2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); - if (ssu2Published) - { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port); - } - else - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV4); + std::string host; i2p::config::GetOption("host", host); + if (ssu2Published && ssu2Port) + { + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV4); } } else diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9e4701d3..ff86fb51 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -620,22 +620,44 @@ namespace data return l+1; } - void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, - const boost::asio::ip::address& host, int port, uint8_t caps) + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,int port, uint8_t caps) { auto addr = std::make_shared
(); - addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP2; addr->caps = caps; addr->date = 0; - if (port) addr->published = true; + addr->published = false; memcpy (addr->s, staticKey, 32); memcpy (addr->i, iv, 16); if (addr->IsV4 ()) { m_SupportedTransports |= eNTCP2V4; - if (addr->published) m_ReachableTransports |= eNTCP2V4; + (*m_Addresses)[eNTCP2V4Idx] = addr; + } + if (addr->IsV6 ()) + { + m_SupportedTransports |= eNTCP2V6; + (*m_Addresses)[eNTCP2V6Idx] = addr; + } + } + + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, + const boost::asio::ip::address& host, int port) + { + auto addr = std::make_shared
(); + addr->host = host; + addr->port = port; + addr->transportStyle = eTransportNTCP2; + addr->caps = 0; + addr->date = 0; + addr->published = true; + memcpy (addr->s, staticKey, 32); + memcpy (addr->i, iv, 16); + if (addr->IsV4 ()) + { + m_SupportedTransports |= eNTCP2V4; + m_ReachableTransports |= eNTCP2V4; (*m_Addresses)[eNTCP2V4Idx] = addr; } if (addr->IsV6 ()) @@ -649,7 +671,7 @@ namespace data else { m_SupportedTransports |= eNTCP2V6; - if (addr->published) m_ReachableTransports |= eNTCP2V6; + m_ReachableTransports |= eNTCP2V6; (*m_Addresses)[eNTCP2V6Idx] = addr; } } @@ -672,11 +694,11 @@ namespace data UpdateSupportedTransports (); } - void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps) + void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, int port, uint8_t caps) { auto addr = std::make_shared
(); addr->transportStyle = eTransportSSU2; - addr->port = 0; + addr->port = port; addr->caps = caps; addr->date = 0; addr->ssu.reset (new SSUExt ()); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 10405a0a..7d004a33 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -198,10 +198,11 @@ namespace data std::shared_ptr GetSSU2V6Address () const; std::shared_ptr GetSSU2Address (bool v4) const; + void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,int port, uint8_t caps); // non published void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, - const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0); + const boost::asio::ip::address& host, int port); // published void RemoveNTCP2Address (bool v4); - void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps = 0); // non published + void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, int port, uint8_t caps); // non published void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, const boost::asio::ip::address& host, int port); // published void RemoveSSU2Address (bool v4); From 86dbfdb53686906e46ddcbce6d013d37872ffd5a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 Jan 2023 09:19:12 -0500 Subject: [PATCH 0057/1160] mutex for encrypted LeaseSet update --- libi2pd/Destination.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 17bce5c4..d202af96 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -467,12 +467,15 @@ namespace client { auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ()); - if (ls2->IsValid ()) + if (ls2->IsValid () && !ls2->IsExpired ()) { + leaseSet = ls2; + std::lock_guard lock(m_RemoteLeaseSetsMutex); m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup - leaseSet = ls2; } + else + LogPrint (eLogError, "Destination: New remote encrypted LeaseSet2 failed"); } else LogPrint (eLogInfo, "Destination: Couldn't find request for encrypted LeaseSet2"); From 3cee8bfcb28a66ea832464ff31d722602c646416 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 30 Jan 2023 01:17:49 +0000 Subject: [PATCH 0058/1160] Update tests and corresponding makefiles (#1862) --- Makefile | 4 +-- Makefile.linux | 4 +-- build/.gitignore | 3 ++ libi2pd/HTTP.cpp | 4 +-- tests/.gitignore | 12 +++++++ tests/CMakeLists.txt | 48 ++++++++------------------ tests/Makefile | 52 ++++++++++++++++++----------- tests/test-aeadchacha20poly1305.cpp | 12 +++---- tests/test-blinding.cpp | 14 ++++---- tests/test-elligator.cpp | 12 +++---- tests/test-x25519.cpp | 7 ++-- 11 files changed, 89 insertions(+), 83 deletions(-) create mode 100644 tests/.gitignore diff --git a/Makefile b/Makefile index 35ee08a9..520a56ba 100644 --- a/Makefile +++ b/Makefile @@ -118,9 +118,9 @@ obj/%.o: %.cpp | mk_obj_dir $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif $(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG) diff --git a/Makefile.linux b/Makefile.linux index 9a3fdda3..d01f2b73 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,10 +20,10 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9 +else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10 - 19 +else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10+ # NEEDED_CXXFLAGS += -std=c++20 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic diff --git a/build/.gitignore b/build/.gitignore index 872332c5..7689cc88 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,5 +1,7 @@ # Various generated files /CMakeFiles/ +/Testing/ +/tests/ /i2pd /libi2pd.a /libi2pdclient.a @@ -8,6 +10,7 @@ /CMakeCache.txt /CPackConfig.cmake /CPackSourceConfig.cmake +/CTestTestfile.cmake /install_manifest.txt /arch.c # windows build script diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 8b61c7e5..7cc87df8 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -356,8 +356,8 @@ namespace http for (auto& it : headers) if (it.first == name) num++; return num; - } - + } + bool HTTPRes::is_chunked() const { auto it = headers.find("Transfer-Encoding"); diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..90457c23 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,12 @@ +/test-http-merge_chunked +/test-http-req +/test-http-res +/test-http-url +/test-http-url_decode +/test-gost +/test-gost-sig +/test-base-64 +/test-x25519 +/test-aeadchacha20poly1305 +/test-blinding +/test-elligator diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c6eec047..21daadd9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,9 +4,9 @@ include_directories(${CHECK_INCLUDE_DIRS}) # Compiler flags: if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -Wl,-undefined,dynamic_lookup") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -Wl,-undefined,dynamic_lookup") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -D_GLIBCXX_USE_NANOSLEEP=1 -Wl,--unresolved-symbols=ignore-in-object-files") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -Wl,--unresolved-symbols=ignore-in-object-files") endif() set(TEST_PATH ${CMAKE_CURRENT_BINARY_DIR}) @@ -18,80 +18,50 @@ include_directories( ) set(test-http-merge_chunked_SRCS - ../libi2pd/HTTP.cpp test-http-merge_chunked.cpp ) set(test-http-req_SRCS - ../libi2pd/HTTP.cpp test-http-req.cpp ) set(test-http-res_SRCS - ../libi2pd/HTTP.cpp test-http-res.cpp ) set(test-http-url_decode_SRCS - ../libi2pd/HTTP.cpp test-http-url_decode.cpp ) set(test-http-url_SRCS - ../libi2pd/HTTP.cpp test-http-url.cpp ) set(test-base-64_SRCS - ../libi2pd/Base.cpp test-base-64.cpp ) set(test-gost_SRCS - ../libi2pd/Gost.cpp - ../libi2pd/I2PEndian.cpp test-gost.cpp ) set(test-gost-sig_SRCS - ../libi2pd/Gost.cpp - ../libi2pd/I2PEndian.cpp - ../libi2pd/Crypto.cpp - ../libi2pd/Log.cpp test-gost-sig.cpp ) set(test-x25519_SRCS - ../libi2pd/Ed25519.cpp - ../libi2pd/I2PEndian.cpp - ../libi2pd/Log.cpp - ../libi2pd/Crypto.cpp test-x25519.cpp ) set(test-aeadchacha20poly1305_SRCS - ../libi2pd/Crypto.cpp - ../libi2pd/ChaCha20.cpp - ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp ) set(test-blinding_SRCS - ../libi2pd/Crypto.cpp - ../libi2pd/Blinding.cpp - ../libi2pd/Ed25519.cpp - ../libi2pd/I2PEndian.cpp - ../libi2pd/Log.cpp - ../libi2pd/util.cpp - ../libi2pd/Identity.cpp - ../libi2pd/Signature.cpp - ../libi2pd/Timestamp.cpp test-blinding.cpp ) SET(test-elligator_SRCS - ../libi2pd/Elligator.cpp - ../libi2pd/Crypto.cpp test-elligator.cpp ) @@ -109,15 +79,23 @@ add_executable(test-blinding ${test-blinding_SRCS}) add_executable(test-elligator ${test-elligator_SRCS}) set(LIBS + libi2pd ${Boost_LIBRARIES} - ${CHECK_LDFLAGS} - ${CMAKE_REQUIRED_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto + ZLIB::ZLIB Threads::Threads + ${CHECK_LDFLAGS} + ${CMAKE_REQUIRED_LIBRARIES} ) -target_link_libraries(test-gost OpenSSL::Crypto Threads::Threads) +target_link_libraries(test-http-merge_chunked ${LIBS}) +target_link_libraries(test-http-req ${LIBS}) +target_link_libraries(test-http-res ${LIBS}) +target_link_libraries(test-http-url_decode ${LIBS}) +target_link_libraries(test-http-url ${LIBS}) +target_link_libraries(test-base-64 ${LIBS}) +target_link_libraries(test-gost ${LIBS}) target_link_libraries(test-gost-sig ${LIBS}) target_link_libraries(test-x25519 ${LIBS}) target_link_libraries(test-aeadchacha20poly1305 ${LIBS}) diff --git a/tests/Makefile b/tests/Makefile index f8f6cf77..db71a06e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,36 +1,50 @@ -CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files +CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -DOPENSSL_SUPPRESS_DEPRECATED -pthread -Wl,--unresolved-symbols=ignore-in-object-files INCFLAGS += -I../libi2pd -TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator +LIBI2PD = ../libi2pd.a + +TESTS = \ + test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \ + test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator + +LDLIBS = \ + -lcrypto \ + -lssl \ + -lboost_filesystem \ + -lboost_program_options \ + -lpthread all: $(TESTS) run -test-http-%: ../libi2pd/HTTP.cpp test-http-%.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ +$(LIBI2PD): + @echo "Building libi2pd.a ..." && cd .. && $(MAKE) libi2pd.a -test-base-%: ../libi2pd/Base.cpp test-base-%.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ +test-http-%: test-http-%.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-gost: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp test-gost.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto +test-base-%: test-base-%.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-gost-sig: ../libi2pd/Gost.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Crypto.cpp ../libi2pd/Log.cpp test-gost-sig.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system +test-gost: test-gost.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/Crypto.cpp test-x25519.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system +test-gost-sig: test-gost-sig.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system +test-x25519: test-x25519.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system +test-aeadchacha20poly1305: test-aeadchacha20poly1305.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) -test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system +test-blinding: test-blinding.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + +test-elligator: test-elligator.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) run: $(TESTS) - @for TEST in $(TESTS); do ./$$TEST ; done + @for TEST in $(TESTS); do echo Running $$TEST; ./$$TEST ; done clean: rm -f $(TESTS) diff --git a/tests/test-aeadchacha20poly1305.cpp b/tests/test-aeadchacha20poly1305.cpp index de9f1db2..64a0f358 100644 --- a/tests/test-aeadchacha20poly1305.cpp +++ b/tests/test-aeadchacha20poly1305.cpp @@ -7,28 +7,28 @@ char text[] = "Ladies and Gentlemen of the class of '99: If I could offer you " "only one tip for the future, sunscreen would be it."; // 114 bytes -uint8_t key[32] = +uint8_t key[32] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f }; -uint8_t ad[12] = +uint8_t ad[12] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }; -uint8_t nonce[12] = +uint8_t nonce[12] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 }; -uint8_t tag[16] = +uint8_t tag[16] = { 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 }; -uint8_t encrypted[114] = +uint8_t encrypted[114] = { 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, @@ -53,7 +53,7 @@ int main () assert (memcmp (buf1, text, 114) == 0); // test encryption of multiple buffers memcpy (buf, text, 114); - std::vector > bufs{ std::make_pair (buf, 20), std::make_pair (buf + 20, 10), std::make_pair (buf + 30, 70), std::make_pair (buf + 100, 14) }; + std::vector > bufs{ std::make_pair (buf, 20), std::make_pair (buf + 20, 10), std::make_pair (buf + 30, 70), std::make_pair (buf + 100, 14) }; i2p::crypto::AEADChaCha20Poly1305Encrypt (bufs, key, nonce, buf + 114); i2p::crypto::AEADChaCha20Poly1305 (buf, 114, nullptr, 0, key, nonce, buf1, 114, false); assert (memcmp (buf1, text, 114) == 0); diff --git a/tests/test-blinding.cpp b/tests/test-blinding.cpp index d7c41809..10b72e4f 100644 --- a/tests/test-blinding.cpp +++ b/tests/test-blinding.cpp @@ -13,12 +13,12 @@ void BlindTest (SigningKeyType sigType) { auto keys = PrivateKeys::CreateRandomKeys (sigType); BlindedPublicKey blindedKey (keys.GetPublic ()); - auto timestamp = GetSecondsSinceEpoch (); + auto timestamp = GetSecondsSinceEpoch (); char date[9]; GetDateString (timestamp, date); - uint8_t blindedPriv[32], blindedPub[32]; + uint8_t blindedPriv[32], blindedPub[32]; auto publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); - uint8_t blindedPub1[32]; + uint8_t blindedPub1[32]; blindedKey.GetBlindedKey (date, blindedPub1); // check if public key produced from private blinded key matches blided public key assert (!memcmp (blindedPub, blindedPub1, publicKeyLen)); @@ -26,16 +26,16 @@ void BlindTest (SigningKeyType sigType) std::unique_ptr blindedSigner (PrivateKeys::CreateSigner (blindedKey.GetBlindedSigType (), blindedPriv)); uint8_t buf[100], signature[64]; memset (buf, 1, 100); - blindedSigner->Sign (buf, 100, signature); + blindedSigner->Sign (buf, 100, signature); std::unique_ptr blindedVerifier (IdentityEx::CreateVerifier (blindedKey.GetBlindedSigType ())); blindedVerifier->SetPublicKey (blindedPub); - assert (blindedVerifier->Verify (buf, 100, signature)); + assert (blindedVerifier->Verify (buf, 100, signature)); } int main () { - // EdDSA test + // EdDSA test BlindTest (SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); - // RedDSA test + // RedDSA test BlindTest (SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); } diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp index 48c9e31a..359c71c5 100644 --- a/tests/test-elligator.cpp +++ b/tests/test-elligator.cpp @@ -4,19 +4,19 @@ #include "Elligator.h" -const uint8_t key[32] = +const uint8_t key[32] = { 0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, 0x78, 0x06, 0x3c, 0xcf, 0xd0, 0x34, 0x8a, 0xf4, 0x21, 0x50, 0xca, 0x16, 0xd2, 0x64, 0x6f, 0x2c, 0x58, 0x56, 0xe8, 0x33, 0x83, 0x77, 0xd8, 0x80 }; -const uint8_t encoded_key[32] = +const uint8_t encoded_key[32] = { 0x28, 0x20, 0xb6, 0xb2, 0x41, 0xe0, 0xf6, 0x8a, 0x6c, 0x4a, 0x7f, 0xee, 0x3d, 0x97, 0x82, 0x28, 0xef, 0x3a, 0xe4, 0x55, 0x33, 0xcd, 0x41, 0x0a, 0xa9, 0x1a, 0x41, 0x53, 0x31, 0xd8, 0x61, 0x2d }; -const uint8_t encoded_key_high_y[32] = +const uint8_t encoded_key_high_y[32] = { 0x3c, 0xfb, 0x87, 0xc4, 0x6c, 0x0b, 0x45, 0x75, 0xca, 0x81, 0x75, 0xe0, 0xed, 0x1c, 0x0a, 0xe9, 0xda, 0xe7, 0x9d, 0xb7, 0x8d, 0xf8, 0x69, 0x97, 0xc4, 0x84, 0x7b, 0x9f, 0x20, 0xb2, 0x77, 0x18 @@ -28,7 +28,7 @@ const uint8_t encoded1[32] = 0x14, 0x50, 0x95, 0x89, 0x28, 0x84, 0x57, 0x99, 0x5a, 0x2b, 0x4c, 0xa3, 0x49, 0x0a, 0xa2, 0x07 }; -const uint8_t key1[32] = +const uint8_t key1[32] = { 0x1e, 0x8a, 0xff, 0xfe, 0xd6, 0xbf, 0x53, 0xfe, 0x27, 0x1a, 0xd5, 0x72, 0x47, 0x32, 0x62, 0xde, 0xd8, 0xfa, 0xec, 0x68, 0xe5, 0xe6, 0x7e, 0xf4, 0x5e, 0xbb, 0x82, 0xee, 0xba, 0x52, 0x60, 0x4f @@ -40,7 +40,7 @@ const uint8_t encoded2[32] = 0xd9, 0x03, 0x65, 0xf2, 0x4a, 0x38, 0xaa, 0x7a, 0xef, 0x1b, 0x97, 0xe2, 0x39, 0x54, 0x10, 0x1b }; -const uint8_t key2[32] = +const uint8_t key2[32] = { 0x79, 0x4f, 0x05, 0xba, 0x3e, 0x3a, 0x72, 0x95, 0x80, 0x22, 0x46, 0x8c, 0x88, 0x98, 0x1e, 0x0b, 0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63 @@ -52,7 +52,7 @@ const uint8_t encoded3[32] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f }; -const uint8_t key3[32] = +const uint8_t key3[32] = { 0x9c, 0xdb, 0x52, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 diff --git a/tests/test-x25519.cpp b/tests/test-x25519.cpp index 2ab8ad6a..a1f3f424 100644 --- a/tests/test-x25519.cpp +++ b/tests/test-x25519.cpp @@ -4,21 +4,21 @@ #include "Ed25519.h" -const uint8_t k[32] = +const uint8_t k[32] = { 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4 }; -const uint8_t u[32] = +const uint8_t u[32] = { 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c }; -uint8_t p[32] = +uint8_t p[32] = { 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea, 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, @@ -36,4 +36,3 @@ int main () assert(memcmp (buf, p, 32) == 0); #endif } - From 2a6883e305d5258bf049258696d88584aaf214d5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 30 Jan 2023 20:57:08 +0300 Subject: [PATCH 0059/1160] [debian] add missing space in changelog (closes #1863) --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 77b174c5..d4464668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,7 +2,7 @@ i2pd (2.45.1-1) unstable; urgency=medium * updated to version 2.45.1/0.9.57 --- orignal Wed, 11 Jan 2023 19:00:00 +0000 + -- orignal Wed, 11 Jan 2023 19:00:00 +0000 i2pd (2.45.0-1) unstable; urgency=high From fafdb0c59009ffa9525486965fd4ef7acc44f6e8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Jan 2023 15:06:40 -0500 Subject: [PATCH 0060/1160] drop too long or too short LeaseSet --- libi2pd/Destination.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d202af96..9be0c06e 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -399,6 +399,11 @@ namespace client void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) { + if (len < DATABASE_STORE_HEADER_SIZE) + { + LogPrint (eLogError, "Destination: Database store msg is too short ", len); + return; + } uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); size_t offset = DATABASE_STORE_HEADER_SIZE; if (replyToken) @@ -406,6 +411,11 @@ namespace client LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore"); offset += 36; } + if (offset > len || len > i2p::data::MAX_LS_BUFFER_SIZE + offset) + { + LogPrint (eLogError, "Destination: Database store message is too long ", len); + return; + } i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET); std::shared_ptr leaseSet; switch (buf[DATABASE_STORE_TYPE_OFFSET]) From 2ed281472f20cd01043351e8debb44bab30fcf0b Mon Sep 17 00:00:00 2001 From: Vort Date: Wed, 1 Feb 2023 00:25:41 +0200 Subject: [PATCH 0061/1160] enclose IPv6 address in square brackets --- daemon/HTTPServer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 0b99c047..d9daeb5e 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -329,14 +329,15 @@ namespace http { default: s << tr("Unknown"); } - if (address->IsV6 ()) + bool v6 = address->IsV6 (); + if (v6) { if (address->IsV4 ()) s << "v4"; s << "v6"; } s << "\r\n"; if (address->published) - s << "" << address->host.to_string() << ":" << address->port << "\r\n"; + s << "" << (v6 ? "[" : "") << address->host.to_string() << (v6 ? "]:" : ":") << address->port << "\r\n"; else { s << "" << tr(/* tr: Shown when router doesn't publish itself and have "Firewalled" state */ "supported"); From 22b1066b0a880083d447ca9101aa600018a58c37 Mon Sep 17 00:00:00 2001 From: weko Date: Wed, 1 Feb 2023 14:06:28 +0300 Subject: [PATCH 0062/1160] Add parameter for show TCSR with old algorithm and it's realization --- daemon/HTTPServer.cpp | 5 +++++ libi2pd/Config.cpp | 1 + libi2pd/Tunnel.cpp | 6 +++++- libi2pd/Tunnel.h | 9 ++++++++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d9daeb5e..5095bcd7 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -289,6 +289,11 @@ namespace http { if (family.length () > 0) s << ""<< tr("Family") << ": " << family << "
\r\n"; s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; + bool isOldTCSR; + i2p::config::GetOption("http.old_tcsr", isOldTCSR); + if (isOldTCSR) { + s << "" << tr("Tunnel creation success rate (old algorithm)") << ": " << i2p::tunnel::tunnels.OldGetTunnelCreationSuccessRate() << "%
\r\n"; + } s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); s << " (" << tr(/* tr: Kibibyte/s */ "%.2f KiB/s", (double) i2p::transport::transports.GetInBandwidth15s () / 1024) << ")
\r\n"; diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 07ab2f20..9181e28e 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -95,6 +95,7 @@ namespace config { ("http.hostname", value()->default_value("localhost"), "Expected hostname for WebUI") ("http.webroot", value()->default_value("/"), "WebUI root path (default: / )") ("http.lang", value()->default_value("english"), "WebUI language (default: english )") + ("http.old_tcsr", value()->default_value(false), "Show TCSR with old algorithm (default: false)") ; options_description httpproxy("HTTP Proxy options"); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 4d205544..d19649d6 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -332,7 +332,8 @@ namespace tunnel Tunnels tunnels; Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), - m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) { + m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0), + m_OldNumSuccesiveTunnelCreations (0), m_OldNumFailedTunnelCreations (0) { } Tunnels::~Tunnels () @@ -634,6 +635,7 @@ namespace tunnel // delete it = pendingTunnels.erase (it); FailedTunnelCreation(); + m_OldNumFailedTunnelCreations++; } else ++it; @@ -642,6 +644,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " failed, deleted"); it = pendingTunnels.erase (it); FailedTunnelCreation(); + m_OldNumFailedTunnelCreations++; break; case eTunnelStateBuildReplyReceived: // intermediate state, will be either established of build failed @@ -651,6 +654,7 @@ namespace tunnel // success it = pendingTunnels.erase (it); SuccesiveTunnelCreation(); + m_OldNumSuccesiveTunnelCreations++; } } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 7fa1eb54..a997502a 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -269,7 +269,9 @@ namespace tunnel i2p::util::Queue > m_Queue; i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; - + // some old stats + int m_OldNumSuccesiveTunnelCreations, m_OldNumFailedTunnelCreations; + // Calculating of tunnel creation success rate // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity void SuccesiveTunnelCreation() { @@ -297,6 +299,11 @@ namespace tunnel int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents + int OldGetTunnelCreationSuccessRate () const // in percents + { + int totalNum = m_OldNumSuccesiveTunnelCreations + m_OldNumFailedTunnelCreations; + return totalNum ? m_OldNumSuccesiveTunnelCreations*100/totalNum : 0; + } }; extern Tunnels tunnels; From 7df2ed611470f105669a5daf668fc5ce08f9a116 Mon Sep 17 00:00:00 2001 From: weko Date: Wed, 1 Feb 2023 19:14:56 +0300 Subject: [PATCH 0063/1160] rename and refactor --- daemon/HTTPServer.cpp | 8 ++++---- libi2pd/Config.cpp | 2 +- libi2pd/Tunnel.cpp | 5 +---- libi2pd/Tunnel.h | 16 ++++++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 5095bcd7..8706f786 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -289,10 +289,10 @@ namespace http { if (family.length () > 0) s << ""<< tr("Family") << ": " << family << "
\r\n"; s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; - bool isOldTCSR; - i2p::config::GetOption("http.old_tcsr", isOldTCSR); - if (isOldTCSR) { - s << "" << tr("Tunnel creation success rate (old algorithm)") << ": " << i2p::tunnel::tunnels.OldGetTunnelCreationSuccessRate() << "%
\r\n"; + bool isTotalTCSR; + i2p::config::GetOption("http.showTotalTCSR", isTotalTCSR); + if (isTotalTCSR) { + s << "" << tr("Total tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTotalTunnelCreationSuccessRate() << "%
\r\n"; } s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 9181e28e..971b1273 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -95,7 +95,7 @@ namespace config { ("http.hostname", value()->default_value("localhost"), "Expected hostname for WebUI") ("http.webroot", value()->default_value("/"), "WebUI root path (default: / )") ("http.lang", value()->default_value("english"), "WebUI language (default: english )") - ("http.old_tcsr", value()->default_value(false), "Show TCSR with old algorithm (default: false)") + ("http.showTotalTCSR", value()->default_value(false), "Show additional value with total TCSR since router's start (default: false)") ; options_description httpproxy("HTTP Proxy options"); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index d19649d6..a0e36978 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -333,7 +333,7 @@ namespace tunnel Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0), - m_OldNumSuccesiveTunnelCreations (0), m_OldNumFailedTunnelCreations (0) { + m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0) { // for normal avarage } Tunnels::~Tunnels () @@ -635,7 +635,6 @@ namespace tunnel // delete it = pendingTunnels.erase (it); FailedTunnelCreation(); - m_OldNumFailedTunnelCreations++; } else ++it; @@ -644,7 +643,6 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " failed, deleted"); it = pendingTunnels.erase (it); FailedTunnelCreation(); - m_OldNumFailedTunnelCreations++; break; case eTunnelStateBuildReplyReceived: // intermediate state, will be either established of build failed @@ -654,7 +652,6 @@ namespace tunnel // success it = pendingTunnels.erase (it); SuccesiveTunnelCreation(); - m_OldNumSuccesiveTunnelCreations++; } } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a997502a..03693206 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -269,17 +269,21 @@ namespace tunnel i2p::util::Queue > m_Queue; i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; - // some old stats - int m_OldNumSuccesiveTunnelCreations, m_OldNumFailedTunnelCreations; + // count of tunnels for total TCSR algorithm + int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; // Calculating of tunnel creation success rate - // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity void SuccesiveTunnelCreation() { + // total TCSR + m_TotalNumSuccesiveTunnelCreations++; + // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate; }; void FailedTunnelCreation() { + m_TotalNumFailedTunnelCreations++; + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate; }; @@ -299,10 +303,10 @@ namespace tunnel int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents - int OldGetTunnelCreationSuccessRate () const // in percents + int GetTotalTunnelCreationSuccessRate () const // in percents { - int totalNum = m_OldNumSuccesiveTunnelCreations + m_OldNumFailedTunnelCreations; - return totalNum ? m_OldNumSuccesiveTunnelCreations*100/totalNum : 0; + int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations; + return totalNum ? m_TotalNumSuccesiveTunnelCreations*100/totalNum : 0; } }; From bf8eecf407cd2a5bebf66b1c5641870929362687 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Feb 2023 16:04:09 -0500 Subject: [PATCH 0064/1160] more attempts to find good peer --- libi2pd/Transports.cpp | 98 ++++++++++++++++++++++++++++++++++++++---- libi2pd/Transports.h | 3 ++ 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 4f4dd929..05776dc4 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -815,20 +815,100 @@ namespace transport } } - std::shared_ptr Transports::GetRandomPeer () const + template + std::shared_ptr Transports::GetRandomPeer (Filter filter) const { - if (m_Peers.empty ()) return nullptr; + if (m_Peers.empty()) return nullptr; + bool found = false; i2p::data::IdentHash ident; { + uint16_t inds[3]; + RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::unique_lock l(m_PeersMutex); + inds[0] %= m_Peers.size (); auto it = m_Peers.begin (); - std::advance (it, rand () % m_Peers.size ()); - if (it == m_Peers.end () || it->second.router || it->second.sessions.empty () || - it->second.sessions.front ()->GetSendQueueSize () > PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE) - return nullptr; // not connected or overloaded - ident = it->first; - } - return i2p::data::netdb.FindRouter (ident); + std::advance (it, inds[0]); + // try random peer + if (it != m_Peers.end () && filter (it->second)) + { + ident = it->first; + found = true; + } + else + { + // try some peers around + auto it1 = m_Peers.begin (); + if (inds[0]) + { + // before + inds[1] %= inds[0]; + std::advance (it1, (inds[1] + inds[0])/2); + } + else + it1 = it; + auto it2 = it; + if (inds[0] < m_Peers.size () - 1) + { + // after + inds[2] %= (m_Peers.size () - 1 - inds[0]); inds[2] /= 2; + std::advance (it2, inds[2]); + } + // it1 - from, it2 - to + it = it1; + while (it != it2 && it != m_Peers.end ()) + { + if (filter (it->second)) + { + ident = it->first; + found = true; + break; + } + it++; + } + if (!found) + { + // still not found, try from the beginning + it = m_Peers.begin (); + while (it != it1 && it != m_Peers.end ()) + { + if (filter (it->second)) + { + ident = it->first; + found = true; + break; + } + it++; + } + if (!found) + { + // still not found, try to the beginning + it = it2; + while (it != m_Peers.end ()) + { + if (filter (it->second)) + { + ident = it->first; + found = true; + break; + } + it++; + } + } + } + } + } + return found ? i2p::data::netdb.FindRouter (ident) : nullptr; + } + + std::shared_ptr Transports::GetRandomPeer () const + { + return GetRandomPeer ( + [](const Peer& peer)->bool + { + // connected and not overloaded + return !peer.router && !peer.sessions.empty () && + peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE; + }); } void Transports::RestrictRoutesToFamilies(const std::set& families) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index bbe98bf3..76b6a089 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -163,6 +163,9 @@ namespace transport void DetectExternalIP (); + template + std::shared_ptr GetRandomPeer (Filter filter) const; + private: volatile bool m_IsOnline; From 4960587f466d54e378f00fa2bb899adbc5d1f3c5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Feb 2023 18:37:31 -0500 Subject: [PATCH 0065/1160] cleanup out-of-sequnce list more aggressivly --- libi2pd/SSU2Session.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 5e97b461..4a934ab2 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2851,7 +2851,8 @@ namespace transport } if (!m_OutOfSequencePackets.empty ()) { - if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || + int ranges = 0; + while (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + 255*8) { uint32_t packet = *m_OutOfSequencePackets.begin (); @@ -2861,9 +2862,14 @@ namespace transport packet--; m_ReceivePacketNum = packet - 1; UpdateReceivePacketNum (packet); + ranges++; + if (ranges > SSU2_MAX_NUM_ACK_RANGES) break; } else + { LogPrint (eLogError, "SSU2: Out of sequence packet ", packet, " is less than last received ", m_ReceivePacketNum); + break; + } } if (m_OutOfSequencePackets.size () > 255*4) { From e9f0ed64733677cd9dd98fdbe91cc842325df7d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Feb 2023 19:05:04 -0500 Subject: [PATCH 0066/1160] cleanup out-of-sequnce list more aggressivly --- libi2pd/SSU2Session.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 4a934ab2..bf6ac61e 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2852,8 +2852,9 @@ namespace transport if (!m_OutOfSequencePackets.empty ()) { int ranges = 0; - while (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || - *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + 255*8) + while (ranges < SSU2_MAX_NUM_ACK_RANGES && !m_OutOfSequencePackets.empty () && + (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || + *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + 255*8)) { uint32_t packet = *m_OutOfSequencePackets.begin (); if (packet > m_ReceivePacketNum + 1) @@ -2863,7 +2864,6 @@ namespace transport m_ReceivePacketNum = packet - 1; UpdateReceivePacketNum (packet); ranges++; - if (ranges > SSU2_MAX_NUM_ACK_RANGES) break; } else { From f7101cc260cfead45a5046638d25fbfbf771cfc7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Feb 2023 21:28:05 -0500 Subject: [PATCH 0067/1160] fixed warning --- libi2pd/Tunnel.cpp | 5 +++-- libi2pd/Tunnel.h | 36 +++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a0e36978..065befbe 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -332,8 +332,9 @@ namespace tunnel Tunnels tunnels; Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), - m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0), - m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0) { // for normal avarage + m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal avarage + m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) + { } Tunnels::~Tunnels () diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 03693206..36dee936 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -253,6 +253,24 @@ namespace tunnel std::shared_ptr CreateZeroHopsInboundTunnel (std::shared_ptr pool); std::shared_ptr CreateZeroHopsOutboundTunnel (std::shared_ptr pool); + // Calculating of tunnel creation success rate + void SuccesiveTunnelCreation() + { + // total TCSR + m_TotalNumSuccesiveTunnelCreations++; + // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; + m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate; + + } + void FailedTunnelCreation() + { + m_TotalNumFailedTunnelCreations++; + + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; + m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate; + } + private: bool m_IsRunning; @@ -270,23 +288,7 @@ namespace tunnel i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // count of tunnels for total TCSR algorithm - int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; - - // Calculating of tunnel creation success rate - void SuccesiveTunnelCreation() { - // total TCSR - m_TotalNumSuccesiveTunnelCreations++; - // A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity - double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; - m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate; - - }; - void FailedTunnelCreation() { - m_TotalNumFailedTunnelCreations++; - - double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; - m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate; - }; + int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; int m_TunnelCreationAttemptsNum; From 02e7f6b0c369eb3d67ac9bef800267addacfd8cd Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Feb 2023 13:52:48 -0500 Subject: [PATCH 0068/1160] cleanup out of sequence packet nums in one call --- libi2pd/SSU2Session.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index bf6ac61e..c9bd45ef 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2757,15 +2757,25 @@ namespace transport if (packetNum <= m_ReceivePacketNum) return false; // duplicate if (packetNum == m_ReceivePacketNum + 1) { - for (auto it = m_OutOfSequencePackets.begin (); it != m_OutOfSequencePackets.end ();) + if (!m_OutOfSequencePackets.empty ()) { + auto it = m_OutOfSequencePackets.begin (); if (*it == packetNum + 1) { - packetNum++; - it = m_OutOfSequencePackets.erase (it); - } - else - break; + // first out of sequence packet is in sequence now + packetNum++; it++; + while (it != m_OutOfSequencePackets.end ()) + { + if (*it == packetNum + 1) + { + packetNum++; + it++; + } + else // next out of sequence + break; + } + m_OutOfSequencePackets.erase (m_OutOfSequencePackets.begin (), it); + } } m_ReceivePacketNum = packetNum; } @@ -2852,7 +2862,7 @@ namespace transport if (!m_OutOfSequencePackets.empty ()) { int ranges = 0; - while (ranges < SSU2_MAX_NUM_ACK_RANGES && !m_OutOfSequencePackets.empty () && + while (ranges < 8 && !m_OutOfSequencePackets.empty () && (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + 255*8)) { From 9bc3b11b96e66558b62bb8671cba28e9c0184563 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 3 Feb 2023 00:05:58 +0200 Subject: [PATCH 0069/1160] Sort transports by IP:port pairs --- daemon/HTTPServer.cpp | 51 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8706f786..2f846257 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -810,37 +810,46 @@ namespace http { template static void ShowTransportSessions (std::stringstream& s, const Sessions& sessions, const std::string name) { - std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0; - for (const auto& it: sessions ) + auto comp = [](typename Sessions::mapped_type a, typename Sessions::mapped_type b) + { return a->GetRemoteEndpoint() < b->GetRemoteEndpoint(); }; + std::set sortedSessions(comp); + for (const auto& it : sessions) { - auto endpoint = it.second->GetRemoteEndpoint (); - if (it.second && it.second->IsEstablished () && endpoint.address ().is_v4 ()) + auto ret = sortedSessions.insert(it.second); + if (!ret.second) + LogPrint(eLogError, "HTTPServer: Duplicate remote endpoint detected: ", (*ret.first)->GetRemoteEndpoint()); + } + std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0; + for (const auto& it: sortedSessions) + { + auto endpoint = it->GetRemoteEndpoint (); + if (it && it->IsEstablished () && endpoint.address ().is_v4 ()) { tmp_s << "
\r\n"; - if (it.second->IsOutgoing ()) tmp_s << " ⇒ "; - tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " + if (it->IsOutgoing ()) tmp_s << " ⇒ "; + tmp_s << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": " << endpoint.address ().to_string () << ":" << endpoint.port (); - if (!it.second->IsOutgoing ()) tmp_s << " ⇒ "; - tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - if (it.second->GetRelayTag ()) - tmp_s << " [itag:" << it.second->GetRelayTag () << "]"; - if (it.second->GetSendQueueSize () > 0) - tmp_s << " [queue:" << it.second->GetSendQueueSize () << "]"; + if (!it->IsOutgoing ()) tmp_s << " ⇒ "; + tmp_s << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]"; + if (it->GetRelayTag ()) + tmp_s << " [itag:" << it->GetRelayTag () << "]"; + if (it->GetSendQueueSize () > 0) + tmp_s << " [queue:" << it->GetSendQueueSize () << "]"; tmp_s << "
\r\n" << std::endl; cnt++; } - if (it.second && it.second->IsEstablished () && endpoint.address ().is_v6 ()) + if (it && it->IsEstablished () && endpoint.address ().is_v6 ()) { tmp_s6 << "
\r\n"; - if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; - tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " + if (it->IsOutgoing ()) tmp_s6 << " ⇒ "; + tmp_s6 << i2p::data::GetIdentHashAbbreviation (it->GetRemoteIdentity ()->GetIdentHash ()) << ": " << "[" << endpoint.address ().to_string () << "]:" << endpoint.port (); - if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; - tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - if (it.second->GetRelayTag ()) - tmp_s6 << " [itag:" << it.second->GetRelayTag () << "]"; - if (it.second->GetSendQueueSize () > 0) - tmp_s6 << " [queue:" << it.second->GetSendQueueSize () << "]"; + if (!it->IsOutgoing ()) tmp_s6 << " ⇒ "; + tmp_s6 << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]"; + if (it->GetRelayTag ()) + tmp_s6 << " [itag:" << it->GetRelayTag () << "]"; + if (it->GetSendQueueSize () > 0) + tmp_s6 << " [queue:" << it->GetSendQueueSize () << "]"; tmp_s6 << "
\r\n" << std::endl; cnt6++; } From 21542e81504155279cc459ce422a8489d7609cb0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Feb 2023 15:59:56 -0500 Subject: [PATCH 0070/1160] select first hop from high bandwidth peer for client tunnels --- libi2pd/Transports.cpp | 11 ++++++----- libi2pd/Transports.h | 15 +++++++++++++-- libi2pd/TunnelPool.cpp | 8 ++++---- libi2pd/TunnelPool.h | 10 ++++------ libi2pd_client/MatchedDestination.cpp | 4 ++-- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 05776dc4..7a2fb431 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -476,7 +476,7 @@ namespace transport bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer) { if (!peer.router) // reconnect - peer.router = netdb.FindRouter (ident); // try to get new one from netdb + peer.SetRouter (netdb.FindRouter (ident)); // try to get new one from netdb if (peer.router) // we have RI already { if (peer.priority.empty ()) @@ -598,7 +598,7 @@ namespace transport if (r) { LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect"); - it->second.router = r; + it->second.SetRouter (r); ConnectToPeer (ident, it->second); } else @@ -900,14 +900,15 @@ namespace transport return found ? i2p::data::netdb.FindRouter (ident) : nullptr; } - std::shared_ptr Transports::GetRandomPeer () const + std::shared_ptr Transports::GetRandomPeer (bool isHighBandwidth) const { return GetRandomPeer ( - [](const Peer& peer)->bool + [isHighBandwidth](const Peer& peer)->bool { // connected and not overloaded return !peer.router && !peer.sessions.empty () && - peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE; + peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE && + (!isHighBandwidth || peer.isHighBandwidth); }); } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 76b6a089..ebb6261e 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -72,11 +72,15 @@ namespace transport uint64_t creationTime, nextRouterInfoUpdateTime; std::vector > delayedMessages; std::vector priority; + bool isHighBandwidth; Peer (std::shared_ptr r, uint64_t ts): numAttempts (0), router (r), creationTime (ts), - nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL) + nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL), + isHighBandwidth (false) { + if (router) + isHighBandwidth = router->IsHighBandwidth (); } void Done () @@ -84,6 +88,13 @@ namespace transport for (auto& it: sessions) it->Done (); } + + void SetRouter (std::shared_ptr r) + { + router = r; + if (router) + isHighBandwidth = router->IsHighBandwidth (); + } }; const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds @@ -131,7 +142,7 @@ namespace transport bool IsBandwidthExceeded () const; bool IsTransitBandwidthExceeded () const; size_t GetNumPeers () const { return m_Peers.size (); }; - std::shared_ptr GetRandomPeer () const; + std::shared_ptr GetRandomPeer (bool isHighBandwidth) const; /** get a trusted first hop for restricted routes */ std::shared_ptr GetRestrictedPeer() const; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index ee115b7e..a9592efd 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -480,7 +480,7 @@ namespace tunnel return hop; } - bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop) + bool TunnelPool::StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop) { int start = 0; std::shared_ptr prevHop = i2p::context.GetSharedRouterInfo (); @@ -496,7 +496,7 @@ namespace tunnel else if (i2p::transport::transports.GetNumPeers () > 100 || (inbound && i2p::transport::transports.GetNumPeers () > 25)) { - auto r = i2p::transport::transports.GetRandomPeer (); + auto r = i2p::transport::transports.GetRandomPeer (IsExploratory ()); if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { @@ -512,7 +512,7 @@ namespace tunnel if (!hop && !i) // if no suitable peer found for first hop, try already connected { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); - hop = i2p::transport::transports.GetRandomPeer (); + hop = i2p::transport::transports.GetRandomPeer (false); if (hop && !hop->IsECIES ()) hop = nullptr; } if (!hop) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index aed29eaf..6936d3ad 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -54,12 +54,9 @@ namespace tunnel virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0; }; - - typedef std::function(std::shared_ptr, bool)> SelectHopFunc; - bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); - class TunnelPool: public std::enable_shared_from_this // per local destination { + typedef std::function(std::shared_ptr, bool)> SelectHopFunc; public: TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, @@ -116,7 +113,8 @@ namespace tunnel // for overriding tunnel peer selection std::shared_ptr SelectNextHop (std::shared_ptr prevHop, bool reverse) const; - + bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); + private: void TestTunnels (); diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index ce800ecc..1e2e8275 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -72,7 +72,7 @@ namespace client bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound) { auto pool = GetTunnelPool(); - if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound, + if(!pool || !pool->StandardSelectPeers(path, hops, inbound, std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2))) return false; // more here for outbound tunnels From 5a6b50ae51d3906acf514fa5449a811acfe714a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Feb 2023 17:32:43 -0500 Subject: [PATCH 0071/1160] fixed typo --- libi2pd/TunnelPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a9592efd..bafc1c2d 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -496,7 +496,7 @@ namespace tunnel else if (i2p::transport::transports.GetNumPeers () > 100 || (inbound && i2p::transport::transports.GetNumPeers () > 25)) { - auto r = i2p::transport::transports.GetRandomPeer (IsExploratory ()); + auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ()); if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { From 54fb234424aa9a7875d51698d66e9e5e6ce3375b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Feb 2023 19:17:46 -0500 Subject: [PATCH 0072/1160] limit number of acked packets to 510 --- libi2pd/SSU2Session.cpp | 52 ++++++++++++++++++++++++----------------- libi2pd/SSU2Session.h | 2 ++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index c9bd45ef..2f814b4c 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2455,21 +2455,24 @@ namespace transport if (ackThrough) { if (m_OutOfSequencePackets.empty ()) - acnt = std::min ((int)ackThrough, 255); // no gaps + acnt = std::min ((int)ackThrough, SSU2_MAX_NUM_ACNT); // no gaps else { auto it = m_OutOfSequencePackets.rbegin (); it++; // prev packet num while (it != m_OutOfSequencePackets.rend () && *it == ackThrough - acnt - 1) { acnt++; - it++; + if (acnt >= SSU2_MAX_NUM_ACK_PACKETS) + break; + else + it++; } // ranges uint32_t lastNum = ackThrough - acnt; - if (acnt > 255) + if (acnt > SSU2_MAX_NUM_ACNT) { - auto d = std::div (acnt - 255, 255); - acnt = 255; + auto d = std::div (acnt - SSU2_MAX_NUM_ACNT, SSU2_MAX_NUM_ACNT); + acnt = SSU2_MAX_NUM_ACNT; if (d.quot > maxNumRanges) { d.quot = maxNumRanges; @@ -2478,7 +2481,7 @@ namespace transport // Acks only ranges for acnt for (int i = 0; i < d.quot; i++) { - buf[8 + numRanges*2] = 0; buf[8 + numRanges*2 + 1] = 255; // NACKs 0, Acks 255 + buf[8 + numRanges*2] = 0; buf[8 + numRanges*2 + 1] = SSU2_MAX_NUM_ACNT; // NACKs 0, Acks 255 numRanges++; } if (d.rem > 0) @@ -2487,21 +2490,25 @@ namespace transport numRanges++; } } - while (it != m_OutOfSequencePackets.rend () && numRanges < maxNumRanges) + int numPackets = acnt + numRanges*SSU2_MAX_NUM_ACNT; + while (it != m_OutOfSequencePackets.rend () && + numRanges < maxNumRanges && numPackets < SSU2_MAX_NUM_ACK_PACKETS) { - if (lastNum - (*it) > 255) + if (lastNum - (*it) > SSU2_MAX_NUM_ACNT) { // NACKs only ranges - if (lastNum > (*it) + 255*(maxNumRanges - numRanges)) break; // too many NACKs - while (lastNum - (*it) > 255) + if (lastNum > (*it) + SSU2_MAX_NUM_ACNT*(maxNumRanges - numRanges)) break; // too many NACKs + while (lastNum - (*it) > SSU2_MAX_NUM_ACNT) { - buf[8 + numRanges*2] = 255; buf[8 + numRanges*2 + 1] = 0; // NACKs 255, Acks 0 - lastNum -= 255; + buf[8 + numRanges*2] = SSU2_MAX_NUM_ACNT; buf[8 + numRanges*2 + 1] = 0; // NACKs 255, Acks 0 + lastNum -= SSU2_MAX_NUM_ACNT; numRanges++; + numPackets += SSU2_MAX_NUM_ACNT; } } // NACKs and Acks ranges buf[8 + numRanges*2] = lastNum - (*it) - 1; // NACKs + numPackets += buf[8 + numRanges*2]; lastNum = *it; it++; int numAcks = 1; while (it != m_OutOfSequencePackets.rend () && lastNum > 0 && *it == lastNum - 1) @@ -2509,28 +2516,31 @@ namespace transport numAcks++; lastNum--; it++; } - while (numAcks > 255) + while (numAcks > SSU2_MAX_NUM_ACNT) { // Acks only ranges - buf[8 + numRanges*2 + 1] = 255; // Acks 255 - numAcks -= 255; + buf[8 + numRanges*2 + 1] = SSU2_MAX_NUM_ACNT; // Acks 255 + numAcks -= SSU2_MAX_NUM_ACNT; numRanges++; + numPackets += SSU2_MAX_NUM_ACNT; buf[8 + numRanges*2] = 0; // NACKs 0 - if (numRanges >= maxNumRanges) break; + if (numRanges >= maxNumRanges || numPackets >= SSU2_MAX_NUM_ACK_PACKETS) break; } - if (numAcks > 255) numAcks = 255; + if (numAcks > SSU2_MAX_NUM_ACNT) numAcks = SSU2_MAX_NUM_ACNT; buf[8 + numRanges*2 + 1] = (uint8_t)numAcks; // Acks + numPackets += numAcks; numRanges++; } - if (numRanges < maxNumRanges && it == m_OutOfSequencePackets.rend ()) + if (it == m_OutOfSequencePackets.rend () && + numRanges < maxNumRanges && numPackets < SSU2_MAX_NUM_ACK_PACKETS) { // add range between out-of-sequence and received int nacks = *m_OutOfSequencePackets.begin () - m_ReceivePacketNum - 1; if (nacks > 0) { - if (nacks > 255) nacks = 255; + if (nacks > SSU2_MAX_NUM_ACNT) nacks = SSU2_MAX_NUM_ACNT; buf[8 + numRanges*2] = nacks; - buf[8 + numRanges*2 + 1] = std::min ((int)m_ReceivePacketNum + 1, 255); + buf[8 + numRanges*2 + 1] = std::min ((int)m_ReceivePacketNum + 1, SSU2_MAX_NUM_ACNT); numRanges++; } } @@ -2864,7 +2874,7 @@ namespace transport int ranges = 0; while (ranges < 8 && !m_OutOfSequencePackets.empty () && (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || - *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + 255*8)) + *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + SSU2_MAX_NUM_ACK_PACKETS)) { uint32_t packet = *m_OutOfSequencePackets.begin (); if (packet > m_ReceivePacketNum + 1) diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index ef9ab573..03395d0f 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -48,6 +48,8 @@ namespace transport const size_t SSU2_MAX_RTO = 2500; // in milliseconds const float SSU2_kAPPA = 1.8; const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages + const int SSU2_MAX_NUM_ACNT = 255; // acnt, acks or nacks + const int SSU2_MAX_NUM_ACK_PACKETS = 510; // 2*255 ack + nack const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64; From 212a1156a1607c41f1e8d75bfd0e9172e6f831da Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Feb 2023 11:00:00 -0500 Subject: [PATCH 0073/1160] filter our addresses with invalid hosts --- libi2pd/RouterInfo.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ff86fb51..49cfd72d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -252,7 +252,15 @@ namespace data { boost::system::error_code ecode; address->host = boost::asio::ip::address::from_string (value, ecode); - if (!ecode && !address->host.is_unspecified ()) isHost = true; + if (!ecode && !address->host.is_unspecified ()) + { + if (!i2p::util::net::IsInReservedRange (address->host) || + i2p::util::net::IsYggdrasilAddress (address->host)) + isHost = true; + else + // we consider such address as invalid + address->transportStyle = eTransportUnknown; + } } else if (!strcmp (key, "port")) { @@ -390,7 +398,7 @@ namespace data { if (address->IsV4 ()) supportedTransports |= eSSU2V4; if (address->IsV6 ()) supportedTransports |= eSSU2V6; - if (address->port) + if (isHost && address->port) { if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4; if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6; From f1415c22346452a69a0a935ce49a3c135cc0139f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Feb 2023 15:42:46 -0500 Subject: [PATCH 0074/1160] compare published address and actual endpoint --- libi2pd/SSU2Session.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 2f814b4c..8ef1058c 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1047,6 +1047,12 @@ namespace transport LogPrint (eLogError, "SSU2: No SSU2 address with static key found in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; } + if (m_Address->published && m_RemoteEndpoint.address () != m_Address->host) + { + LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host, + " and actual enpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); + return false; + } // update RouterInfo in netdb ri = i2p::data::netdb.AddRouterInfo (ri->GetBuffer (), ri->GetBufferLen ()); // ri points to one from netdb now if (!ri) From 21123e2afaa28d6ca7cac24427061518c907d431 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Feb 2023 18:26:09 -0500 Subject: [PATCH 0075/1160] compare published address and actual endpoint --- libi2pd/NTCP2.cpp | 13 ++++++++++--- libi2pd/RouterInfo.cpp | 19 +++++-------------- libi2pd/RouterInfo.h | 4 ++-- libi2pd/SSU2Session.cpp | 8 ++++---- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e5199bdc..dadd2075 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -693,13 +693,20 @@ namespace transport SendTerminationAndTerminate (eNTCP2Message3Error); return; } - auto addr = ri.GetNTCP2AddressWithStaticKey (m_Establisher->m_RemoteStaticKey); - if (!addr) + auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri.GetNTCP2V4Address () : + (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri.GetYggdrasilAddress () : ri.GetNTCP2V6Address ()); + if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) { - LogPrint (eLogError, "NTCP2: No NTCP2 address with static key found in SessionConfirmed"); + LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed"); Terminate (); return; } + if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host) + { + LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); + Terminate (); + return; + } i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 49cfd72d..28959fe9 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -910,25 +910,16 @@ namespace data return nullptr; } - std::shared_ptr RouterInfo::GetNTCP2AddressWithStaticKey (const uint8_t * key) const + std::shared_ptr RouterInfo::GetNTCP2V4Address () const { - if (!key) return nullptr; - return GetAddress ( - [key](std::shared_ptr address)->bool - { - return address->IsNTCP2 () && !memcmp (address->s, key, 32); - }); + return (*GetAddresses ())[eNTCP2V4Idx]; } - std::shared_ptr RouterInfo::GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const + std::shared_ptr RouterInfo::GetNTCP2V6Address () const { - if (!key) return nullptr; - auto addr = (*GetAddresses ())[isV6 ? eSSU2V6Idx : eSSU2V4Idx]; - if (addr && !memcmp (addr->s, key, 32)) - return addr; - return nullptr; + return (*GetAddresses ())[eNTCP2V6Idx]; } - + std::shared_ptr RouterInfo::GetPublishedNTCP2V4Address () const { auto addr = (*GetAddresses ())[eNTCP2V4Idx]; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 7d004a33..ea0abf41 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -189,8 +189,8 @@ namespace data virtual void SetProperty (const std::string& key, const std::string& value) {}; virtual void ClearProperties () {}; boost::shared_ptr GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr - std::shared_ptr GetNTCP2AddressWithStaticKey (const uint8_t * key) const; - std::shared_ptr GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const; + std::shared_ptr GetNTCP2V4Address () const; + std::shared_ptr GetNTCP2V6Address () const; std::shared_ptr GetPublishedNTCP2V4Address () const; std::shared_ptr GetPublishedNTCP2V6Address () const; std::shared_ptr GetYggdrasilAddress () const; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 8ef1058c..4c359454 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1041,16 +1041,16 @@ namespace transport LogPrint (eLogError, "SSU2: SessionConfirmed malformed RouterInfo block"); return false; } - m_Address = ri->GetSSU2AddressWithStaticKey (S, m_RemoteEndpoint.address ().is_v6 ()); - if (!m_Address) + m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address (); + if (!m_Address || memcmp (S, m_Address->s, 32)) { - LogPrint (eLogError, "SSU2: No SSU2 address with static key found in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); + LogPrint (eLogError, "SSU2: Wrong static key in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; } if (m_Address->published && m_RemoteEndpoint.address () != m_Address->host) { LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host, - " and actual enpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); + " and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; } // update RouterInfo in netdb From 3c02cade5849371e26b63416304647a3732fba16 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Feb 2023 19:19:20 -0500 Subject: [PATCH 0076/1160] compare only first 8 bytes for temporary addreses --- libi2pd/NTCP2.cpp | 4 +++- libi2pd/SSU2Session.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index dadd2075..bc532a52 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -701,7 +701,9 @@ namespace transport Terminate (); return; } - if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host) + if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && + (!m_RemoteEndpoint.address ().is_v6 () || + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8))) // temporary address { LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); Terminate (); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 4c359454..121e93be 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1047,7 +1047,9 @@ namespace transport LogPrint (eLogError, "SSU2: Wrong static key in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; } - if (m_Address->published && m_RemoteEndpoint.address () != m_Address->host) + if (m_Address->published && m_RemoteEndpoint.address () != m_Address->host && + (!m_RemoteEndpoint.address ().is_v6 () || + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), m_Address->host.to_v6 ().to_bytes ().data (), 8))) // temporary address { LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host, " and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); From 80a55c5b75dd2a7d4891e331394bc92432474e19 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Feb 2023 13:19:41 -0500 Subject: [PATCH 0077/1160] store unrechable in profile --- libi2pd/NetDb.cpp | 14 ++++++++++++-- libi2pd/Profiling.cpp | 23 ++++++++++++++++++++--- libi2pd/Profiling.h | 11 ++++++++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index c46adff1..02e1c058 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -427,7 +427,15 @@ namespace data { auto it = m_RouterInfos.find (ident); if (it != m_RouterInfos.end ()) - return it->second->SetUnreachable (unreachable); + { + it->second->SetUnreachable (unreachable); + if (unreachable) + { + auto profile = it->second->GetProfile (); + if (profile) + profile->Unreachable (); + } + } } void NetDb::Reseed () @@ -626,6 +634,8 @@ namespace data updatedCount++; continue; } + if (it.second->GetProfile ()->IsUnreachable ()) + it.second->SetUnreachable (true); // make router reachable back if too few routers or floodfills if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS || isLowRate || (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) @@ -1334,7 +1344,7 @@ namespace data std::unique_lock l(m_FloodfillsMutex); for (const auto& it: m_Floodfills) { - if (!it->IsUnreachable ()) + if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) { XORMetric m = destKey ^ it->GetIdentHash (); if (m < minMetric && !excluded.count (it->GetIdentHash ())) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index f826bf43..6f805193 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -23,7 +23,7 @@ namespace data RouterProfile::RouterProfile (): m_LastUpdateTime (boost::posix_time::second_clock::local_time()), - m_LastDeclineTime (0), + m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTimesTaken (0), m_NumTimesRejected (0) { @@ -52,6 +52,8 @@ namespace data // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); + if (m_LastUnreachableTime) + pt.put (PEER_PROFILE_LAST_UNREACHABLE_TIME, m_LastUnreachableTime); pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation); pt.put_child (PEER_PROFILE_SECTION_USAGE, usage); @@ -96,6 +98,7 @@ namespace data m_LastUpdateTime = boost::posix_time::time_from_string (t); if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT) { + m_LastUnreachableTime = pt.get (PEER_PROFILE_LAST_UNREACHABLE_TIME, 0); try { // read participations @@ -152,6 +155,11 @@ namespace data m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); } + void RouterProfile::Unreachable () + { + m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch (); + } + bool RouterProfile::IsLowPartcipationRate () const { return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate @@ -169,12 +177,12 @@ namespace data auto ts = i2p::util::GetSecondsSinceEpoch (); if (ts > m_LastDeclineTime + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL) m_LastDeclineTime = 0; - return m_LastDeclineTime; + return (bool)m_LastDeclineTime; } bool RouterProfile::IsBad () { - if (IsDeclinedRecently ()) return true; + if (IsDeclinedRecently () || IsUnreachable ()) return true; auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/; if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1)) { @@ -188,6 +196,15 @@ namespace data return isBad; } + bool RouterProfile::IsUnreachable () + { + if (!m_LastUnreachableTime) return false; + auto ts = i2p::util::GetSecondsSinceEpoch (); + if (ts > m_LastUnreachableTime + PEER_PROFILE_UNREACHABLE_INTERVAL) + m_LastUnreachableTime = 0; + return (bool)m_LastUnreachableTime; + } + std::shared_ptr GetRouterProfile (const IdentHash& identHash) { auto profile = std::make_shared (); diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 1c523a22..58b5e2ea 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -22,6 +22,7 @@ namespace data const char PEER_PROFILE_SECTION_USAGE[] = "usage"; // params const char PEER_PROFILE_LAST_UPDATE_TIME[] = "lastupdatetime"; + const char PEER_PROFILE_LAST_UNREACHABLE_TIME[] = "lastunreachabletime"; const char PEER_PROFILE_PARTICIPATION_AGREED[] = "agreed"; const char PEER_PROFILE_PARTICIPATION_DECLINED[] = "declined"; const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied"; @@ -32,7 +33,8 @@ namespace data const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) - + const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) + class RouterProfile { public: @@ -44,10 +46,13 @@ namespace data void Load (const IdentHash& identHash); bool IsBad (); - + bool IsUnreachable (); + void TunnelBuildResponse (uint8_t ret); void TunnelNonReplied (); + void Unreachable (); + private: boost::posix_time::ptime GetTime () const; @@ -61,7 +66,7 @@ namespace data private: boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono - uint64_t m_LastDeclineTime; // in seconds + uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds // participation uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsDeclined; From d30d1e8a7de213dbe93ae686e7aa7a523e526103 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Feb 2023 14:18:15 -0500 Subject: [PATCH 0078/1160] don't set unrechable for routers without published addresses --- libi2pd/Transports.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7a2fb431..bfd1b190 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -539,7 +539,8 @@ namespace transport } LogPrint (eLogInfo, "Transports: No compatible addresses available"); - i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed + if (peer.router->IsReachableFrom (i2p::context.GetRouterInfo ())) + i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed but router claimed them peer.Done (); std::unique_lock l(m_PeersMutex); m_Peers.erase (ident); From 4930157e93093f8b38e260c2124ccb9e8df5e45f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Feb 2023 16:18:16 -0500 Subject: [PATCH 0079/1160] don't innsert back unreachable router --- libi2pd/NetDb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 02e1c058..2bf3ab08 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -295,7 +295,7 @@ namespace data else { r = std::make_shared (buf, len); - if (!r->IsUnreachable () && r->HasValidAddresses () && + if (!r->IsUnreachable () && r->HasValidAddresses () && !r->GetProfile ()->IsUnreachable () && i2p::util::GetMillisecondsSinceEpoch () + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL > r->GetTimestamp ()) { bool inserted = false; From d1c98c58b9860346d1a953c6782adfc20499eeda Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Feb 2023 19:31:31 -0500 Subject: [PATCH 0080/1160] update status before deleting session --- libi2pd/SSU2Session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 121e93be..ac570b84 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2296,9 +2296,9 @@ namespace transport m_Server.RemoveSession (~htobe64 (((uint64_t)nonce << 32) | nonce)); break; case 7: // Alice from Charlie 2 - m_Server.RemoveSession (htobe64 (((uint64_t)nonce << 32) | nonce)); if (m_Address->IsV6 ()) i2p::context.SetStatusV6 (eRouterStatusOK); // set status OK for ipv6 even if from SSU2 + m_Server.RemoveSession (htobe64 (((uint64_t)nonce << 32) | nonce)); break; default: LogPrint (eLogWarning, "SSU2: PeerTest unexpected msg num ", buf[0]); From f29ef2c057d3b81853e015b87be78af35f8e00b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Feb 2023 15:28:33 -0500 Subject: [PATCH 0081/1160] don't compare first byte for yggdrasil addresses --- libi2pd/NTCP2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index bc532a52..ccc0086b 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -702,7 +702,8 @@ namespace transport return; } if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && - (!m_RemoteEndpoint.address ().is_v6 () || + (!m_RemoteEndpoint.address ().is_v6 () || i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8))) // temporary address { LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); From 2baaa8bb8f0f0499f56420319ecda3c99c32906d Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Feb 2023 18:01:24 -0500 Subject: [PATCH 0082/1160] fixed typo --- libi2pd/NTCP2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ccc0086b..47b8081f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -702,9 +702,9 @@ namespace transport return; } if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && - (!m_RemoteEndpoint.address ().is_v6 () || i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? + (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8))) // temporary address + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address { LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); Terminate (); From aac9a8d18f8d14c5b16b24502429918cb6896c74 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Feb 2023 18:32:18 -0500 Subject: [PATCH 0083/1160] check if clock was adjusted backwards --- libi2pd/NetDb.cpp | 15 +++-- libi2pd/Tunnel.cpp | 144 ++++++++++++++++++++++----------------------- libi2pd/Tunnel.h | 12 ++-- 3 files changed, 86 insertions(+), 85 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 2bf3ab08..0ffdb3ef 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -153,13 +153,13 @@ namespace data if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastManageRequest >= 15) // manage requests every 15 seconds + if (ts - lastManageRequest >= 15 || ts + 15 < lastManageRequest) // manage requests every 15 seconds { m_Requests.ManageRequests (); lastManageRequest = ts; } - if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute + if (ts - lastSave >= 60 || ts + 60 < lastSave) // save routers, manage leasesets and validate subscriptions every minute { if (lastSave) { @@ -169,13 +169,15 @@ namespace data lastSave = ts; } - if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT) + if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT || + ts + i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT < lastDestinationCleanup) { i2p::context.CleanupDestination (); lastDestinationCleanup = ts; } - if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance)) + if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) || + ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup) { DeleteObsoleteProfiles (); lastProfilesCleanup = ts; @@ -192,7 +194,8 @@ namespace data if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true; } else if (i2p::context.GetLastUpdateTime () > lastPublish || - ts - lastPublish >= NETDB_PUBLISH_INTERVAL) + ts - lastPublish >= NETDB_PUBLISH_INTERVAL || + ts + NETDB_PUBLISH_INTERVAL < lastPublish) { // new publish m_PublishExcluded.clear (); @@ -208,7 +211,7 @@ namespace data } } - if (ts - lastExploratory >= 30) // exploratory every 30 seconds + if (ts - lastExploratory >= 30 || ts + 30 < lastExploratory) // exploratory every 30 seconds { auto numRouters = m_RouterInfos.size (); if (!numRouters) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 065befbe..12fa7771 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -537,17 +537,20 @@ namespace tunnel if (i2p::transport::transports.IsOnline()) { uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastTs >= TUNNEL_MANAGE_INTERVAL) // manage tunnels every 15 seconds + if (ts - lastTs >= TUNNEL_MANAGE_INTERVAL || // manage tunnels every 15 seconds + ts + TUNNEL_MANAGE_INTERVAL < lastTs) { - ManageTunnels (); + ManageTunnels (ts); lastTs = ts; } - if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL) // manage pools every 5 seconds + if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 secondsts + ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs) { ManageTunnelPools (ts); lastPoolsTs = ts; } - if (ts - lastMemoryPoolTs >= TUNNEL_MEMORY_POOL_MANAGE_INTERVAL) // manage memory pool every 2 minutes + if (ts - lastMemoryPoolTs >= TUNNEL_MEMORY_POOL_MANAGE_INTERVAL || + ts + TUNNEL_MEMORY_POOL_MANAGE_INTERVAL < lastMemoryPoolTs) // manage memory pool every 2 minutes { m_I2NPTunnelEndpointMessagesMemoryPool.CleanUpMt (); m_I2NPTunnelMessagesMemoryPool.CleanUpMt (); @@ -589,32 +592,32 @@ namespace tunnel tunnel->SendTunnelDataMsg (msg); } - void Tunnels::ManageTunnels () + void Tunnels::ManageTunnels (uint64_t ts) { - ManagePendingTunnels (); - ManageInboundTunnels (); - ManageOutboundTunnels (); - ManageTransitTunnels (); + ManagePendingTunnels (ts); + ManageInboundTunnels (ts); + ManageOutboundTunnels (ts); + ManageTransitTunnels (ts); } - void Tunnels::ManagePendingTunnels () + void Tunnels::ManagePendingTunnels (uint64_t ts) { - ManagePendingTunnels (m_PendingInboundTunnels); - ManagePendingTunnels (m_PendingOutboundTunnels); + ManagePendingTunnels (m_PendingInboundTunnels, ts); + ManagePendingTunnels (m_PendingOutboundTunnels, ts); } template - void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels) + void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts) { // check pending tunnel. delete failed or timeout - uint64_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) { auto tunnel = it->second; switch (tunnel->GetState ()) { case eTunnelStatePending: - if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT) + if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT || + ts + TUNNEL_CREATION_TIMEOUT < tunnel->GetCreationTime ()) { LogPrint (eLogDebug, "Tunnel: Pending build request ", it->first, " timeout, deleted"); // update stats @@ -657,41 +660,38 @@ namespace tunnel } } - void Tunnels::ManageOutboundTunnels () + void Tunnels::ManageOutboundTunnels (uint64_t ts) { - uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) { - for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) + auto tunnel = *it; + if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - auto tunnel = *it; - if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); + auto pool = tunnel->GetTunnelPool (); + if (pool) + pool->TunnelExpired (tunnel); + // we don't have outbound tunnels in m_Tunnels + it = m_OutboundTunnels.erase (it); + } + else + { + if (tunnel->IsEstablished ()) { - LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); - auto pool = tunnel->GetTunnelPool (); - if (pool) - pool->TunnelExpired (tunnel); - // we don't have outbound tunnels in m_Tunnels - it = m_OutboundTunnels.erase (it); - } - else - { - if (tunnel->IsEstablished ()) + if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + auto pool = tunnel->GetTunnelPool (); + // let it die if the tunnel pool has been reconfigured and this is old + if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) { - auto pool = tunnel->GetTunnelPool (); - // let it die if the tunnel pool has been reconfigured and this is old - if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) - { - tunnel->SetRecreated (true); - pool->RecreateOutboundTunnel (tunnel); - } + tunnel->SetRecreated (true); + pool->RecreateOutboundTunnel (tunnel); } - if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) - tunnel->SetState (eTunnelStateExpiring); } - ++it; + if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + tunnel->SetState (eTunnelStateExpiring); } + ++it; } } @@ -711,44 +711,42 @@ namespace tunnel } } - void Tunnels::ManageInboundTunnels () + void Tunnels::ManageInboundTunnels (uint64_t ts) { - uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) { - for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) + auto tunnel = *it; + if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT || + ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ()) { - auto tunnel = *it; - if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); + auto pool = tunnel->GetTunnelPool (); + if (pool) + pool->TunnelExpired (tunnel); + m_Tunnels.erase (tunnel->GetTunnelID ()); + it = m_InboundTunnels.erase (it); + } + else + { + if (tunnel->IsEstablished ()) { - LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); - auto pool = tunnel->GetTunnelPool (); - if (pool) - pool->TunnelExpired (tunnel); - m_Tunnels.erase (tunnel->GetTunnelID ()); - it = m_InboundTunnels.erase (it); - } - else - { - if (tunnel->IsEstablished ()) + if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + auto pool = tunnel->GetTunnelPool (); + // let it die if the tunnel pool was reconfigured and has different number of hops + if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) { - auto pool = tunnel->GetTunnelPool (); - // let it die if the tunnel pool was reconfigured and has different number of hops - if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) - { - tunnel->SetRecreated (true); - pool->RecreateInboundTunnel (tunnel); - } + tunnel->SetRecreated (true); + pool->RecreateInboundTunnel (tunnel); } - - if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) - tunnel->SetState (eTunnelStateExpiring); - else // we don't need to cleanup expiring tunnels - tunnel->Cleanup (); } - it++; + + if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + tunnel->SetState (eTunnelStateExpiring); + else // we don't need to cleanup expiring tunnels + tunnel->Cleanup (); } + it++; } } @@ -787,13 +785,13 @@ namespace tunnel } } - void Tunnels::ManageTransitTunnels () + void Tunnels::ManageTransitTunnels (uint64_t ts) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { auto tunnel = *it; - if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT || + ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ()) { LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired"); m_Tunnels.erase (tunnel->GetTunnelID ()); diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 36dee936..a603ff92 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -241,13 +241,13 @@ namespace tunnel void HandleTunnelGatewayMsg (std::shared_ptr tunnel, std::shared_ptr msg); void Run (); - void ManageTunnels (); - void ManageOutboundTunnels (); - void ManageInboundTunnels (); - void ManageTransitTunnels (); - void ManagePendingTunnels (); + void ManageTunnels (uint64_t ts); + void ManageOutboundTunnels (uint64_t ts); + void ManageInboundTunnels (uint64_t ts); + void ManageTransitTunnels (uint64_t ts); + void ManagePendingTunnels (uint64_t ts); template - void ManagePendingTunnels (PendingTunnels& pendingTunnels); + void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts); void ManageTunnelPools (uint64_t ts); std::shared_ptr CreateZeroHopsInboundTunnel (std::shared_ptr pool); From 993900aa7738eb2f69b743dcb18d5c0221fb93df Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Feb 2023 18:49:35 -0500 Subject: [PATCH 0084/1160] terminate sessions if clock was adjusted backwards too much --- libi2pd/Profiling.cpp | 6 ++++-- libi2pd/TransportSession.h | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 6f805193..6909e209 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -175,7 +175,8 @@ namespace data { if (!m_LastDeclineTime) return false; auto ts = i2p::util::GetSecondsSinceEpoch (); - if (ts > m_LastDeclineTime + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL) + if (ts > m_LastDeclineTime + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL || + ts + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL < m_LastDeclineTime) m_LastDeclineTime = 0; return (bool)m_LastDeclineTime; } @@ -200,7 +201,8 @@ namespace data { if (!m_LastUnreachableTime) return false; auto ts = i2p::util::GetSecondsSinceEpoch (); - if (ts > m_LastUnreachableTime + PEER_PROFILE_UNREACHABLE_INTERVAL) + if (ts > m_LastUnreachableTime + PEER_PROFILE_UNREACHABLE_INTERVAL || + ts + PEER_PROFILE_UNREACHABLE_INTERVAL < m_LastUnreachableTime) m_LastUnreachableTime = 0; return (bool)m_LastUnreachableTime; } diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 56f6b9bc..03ade393 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -107,7 +107,10 @@ namespace transport int GetTerminationTimeout () const { return m_TerminationTimeout; }; void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; }; bool IsTerminationTimeoutExpired (uint64_t ts) const - { return ts >= m_LastActivityTimestamp + GetTerminationTimeout (); }; + { + return ts >= m_LastActivityTimestamp + GetTerminationTimeout () || + ts + GetTerminationTimeout () < m_LastActivityTimestamp; + }; uint32_t GetCreationTime () const { return m_CreationTime; }; void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers From 0829b186b7179210cc784318d76b6ad02b7fe423 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 10 Feb 2023 01:57:43 +0200 Subject: [PATCH 0085/1160] Fix debug log output --- libi2pd/NetDb.cpp | 2 +- libi2pd/SSU2Session.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 0ffdb3ef..4a6fed70 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -834,7 +834,7 @@ namespace data } else // all others are considered as LeaseSet2 { - LogPrint (eLogDebug, "NetDb: Store request: LeaseSet2 of type ", storeType, " for ", ident.ToBase32()); + LogPrint (eLogDebug, "NetDb: Store request: LeaseSet2 of type ", int(storeType), " for ", ident.ToBase32()); updated = AddLeaseSet2 (ident, buf + offset, len - offset, storeType); } } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index ac570b84..76dce891 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2308,7 +2308,7 @@ namespace transport void SSU2Session::HandleI2NPMsg (std::shared_ptr&& msg) { if (!msg) return; - int32_t msgID = msg->GetMsgID (); + uint32_t msgID = msg->GetMsgID (); if (!msg->IsExpired ()) { // m_LastActivityTimestamp is updated in ProcessData before From cb44a35fde728c6d4afb8128297b810131b49d26 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 10 Feb 2023 16:58:42 +0200 Subject: [PATCH 0086/1160] Fix description for nettime.enabled option --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 971b1273..1bb3717c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -285,7 +285,7 @@ namespace config { options_description nettime("Time sync options"); nettime.add_options() - ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") + ("nettime.enabled", value()->default_value(false), "Enable NTP time sync (default: disabled)") ("nettime.ntpservers", value()->default_value( "0.pool.ntp.org," "1.pool.ntp.org," From ac94341203b90e1553a9860fcd8b360311f638bd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Feb 2023 11:48:11 -0500 Subject: [PATCH 0087/1160] disconnect established session if clock skew detected --- libi2pd/NTCP2.cpp | 14 +++++++++++++- libi2pd/SSU2Session.cpp | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 47b8081f..b659ba78 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -884,8 +884,20 @@ namespace transport switch (blk) { case eNTCP2BlkDateTime: + { LogPrint (eLogDebug, "NTCP2: Datetime"); - break; + if (m_IsEstablished) + { + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + uint64_t tsA = bufbe32toh (frame + offset); + if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW) + { + LogPrint (eLogWarning, "NTCP2: Established session time difference ", (int)(ts - tsA), " exceeds clock skew"); + SendTerminationAndTerminate (eNTCP2ClockSkew); + } + } + break; + } case eNTCP2BlkOptions: LogPrint (eLogDebug, "NTCP2: Options"); break; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 76dce891..a36536a8 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1617,6 +1617,7 @@ namespace transport { case eSSU2SessionStateSessionRequestReceived: case eSSU2SessionStateTokenRequestReceived: + case eSSU2SessionStateEstablished: if (std::abs (offset) > SSU2_CLOCK_SKEW) m_TerminationReason = eSSU2TerminationReasonClockSkew; break; From 1c4cc02c234bd8ca1bf0c7c87aee318e9fc49f43 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Feb 2023 18:21:12 -0500 Subject: [PATCH 0088/1160] drop garlic message in garlic clove --- libi2pd/RouterContext.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index d37bd440..b6c7a5d9 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1100,6 +1100,12 @@ namespace i2p bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { + if (typeID == eI2NPGarlic) + { + // TODO: implement + LogPrint (eLogWarning, "Router: garlic message in garlic clove. Dropped"); + return false; + } auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); From 97b7ea0da5184caeaeef3a706c88af6d0f20d115 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Feb 2023 22:04:42 -0500 Subject: [PATCH 0089/1160] create separate new ipv4 and ipv6 published addresses --- libi2pd/RouterContext.cpp | 80 +++++++++++++++------------------------ 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b6c7a5d9..91bfadbc 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -85,7 +85,7 @@ namespace i2p bool ssu2Published = false; if (ssu2) i2p::config::GetOption("ssu2.published", ssu2Published); - uint8_t caps = 0, addressCaps = 0; + uint8_t caps = 0; if (ipv4) { std::string host; @@ -98,47 +98,41 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - bool added = false; if (ntcp2Published && ntcp2Port) { + boost::asio::ip::address addr; if (!host.empty ()) - { - auto addr = boost::asio::ip::address::from_string (host); - if (addr.is_v4 ()) - { - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); - added = true; - } - } + addr = boost::asio::ip::address::from_string (host); + if (!addr.is_v4()) + addr = boost::asio::ip::address_v4 (); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); } - if (!added) + else { // add non-published NTCP2 address - addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV4); + uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; + if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, addressCaps); } } if (ssu2) { uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); if (!ssu2Port) ssu2Port = port; - bool added = false; if (ssu2Published && ssu2Port) { + boost::asio::ip::address addr; if (!host.empty ()) - { - auto addr = boost::asio::ip::address::from_string (host); - if (addr.is_v4 ()) - { - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); - added = true; - } - } + addr = boost::asio::ip::address::from_string (host); + if (!addr.is_v4()) + addr = boost::asio::ip::address_v4 (); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); } - if (!added) + else { - addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV4); + uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; + if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, addressCaps); } } } @@ -151,7 +145,6 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - bool added = false; if (ntcp2Published && ntcp2Port) { std::string ntcp2Host; @@ -159,45 +152,36 @@ namespace i2p i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else ntcp2Host = host; + boost::asio::ip::address addr; if (!ntcp2Host.empty ()) - { - auto addr = boost::asio::ip::address::from_string (ntcp2Host); - if (addr.is_v6 ()) - { - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); - added = true; - } - } + addr = boost::asio::ip::address::from_string (ntcp2Host); + if (!addr.is_v6()) + addr = boost::asio::ip::address_v6 (); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); } - if (!added) + else { if (!ipv4) // no other ntcp2 addresses yet routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV6); - addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } if (ssu2) { uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); if (!ssu2Port) ssu2Port = port; - bool added = false; if (ssu2Published && ssu2Port) { + boost::asio::ip::address addr; if (!host.empty ()) - { - auto addr = boost::asio::ip::address::from_string (host); - if (addr.is_v6 ()) - { - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); - added = true; - } - } + addr = boost::asio::ip::address::from_string (host); + if (!addr.is_v6()) + addr = boost::asio::ip::address_v6 (); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); } - if (!added) + else { if (!ipv4) // no other ssu2 addresses yet routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV6); - addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } } @@ -208,8 +192,6 @@ namespace i2p routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); } - if (addressCaps) - routerInfo.SetUnreachableAddressesTransportCaps (addressCaps); routerInfo.UpdateCaps (caps); // caps + L routerInfo.SetProperty ("netId", std::to_string (m_NetID)); routerInfo.SetProperty ("router.version", I2P_VERSION); From 3c65012a63a0015db8ab871204e814fb88284fdd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Feb 2023 06:29:37 +0000 Subject: [PATCH 0090/1160] [ssu2] close socket if it was opened on OpenSocket Signed-off-by: R4SAS --- libi2pd/SSU2.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 5bb27a40..3773f03d 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -212,6 +212,8 @@ namespace transport boost::asio::ip::udp::socket& socket = localEndpoint.address ().is_v6 () ? m_SocketV6 : m_SocketV4; try { + if (socket.is_open ()) + socket.close (); socket.open (localEndpoint.protocol ()); if (localEndpoint.address ().is_v6 ()) socket.set_option (boost::asio::ip::v6_only (true)); @@ -819,7 +821,7 @@ namespace transport m_CleanupTimer.async_wait (std::bind (&SSU2Server::HandleCleanupTimer, this, std::placeholders::_1)); } - + void SSU2Server::HandleCleanupTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) @@ -848,15 +850,15 @@ namespace transport else it++; } - + m_PacketsPool.CleanUpMt (); m_SentPacketsPool.CleanUp (); m_IncompleteMessagesPool.CleanUp (); m_FragmentsPool.CleanUp (); ScheduleCleanup (); - } - } - + } + } + void SSU2Server::ScheduleResend (bool more) { m_ResendTimer.expires_from_now (boost::posix_time::milliseconds (more ? SSU2_RESEND_CHECK_MORE_TIMEOUT : From 86fc12e3959e105032e73b28bdf6c8f62407c3d7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Feb 2023 09:41:51 +0300 Subject: [PATCH 0091/1160] [style] clean code Signed-off-by: R4SAS --- libi2pd/Config.cpp | 2 +- libi2pd/Destination.cpp | 8 ++-- libi2pd/NTCP2.cpp | 14 +++--- libi2pd/NetDb.cpp | 10 ++-- libi2pd/Profiling.cpp | 20 ++++---- libi2pd/Profiling.h | 8 ++-- libi2pd/RouterContext.cpp | 98 +++++++++++++++++++------------------- libi2pd/RouterContext.h | 2 +- libi2pd/RouterInfo.cpp | 54 ++++++++++----------- libi2pd/SSU2.h | 4 +- libi2pd/SSU2Session.cpp | 58 +++++++++++----------- libi2pd/SSU2Session.h | 4 +- libi2pd/TransportSession.h | 4 +- libi2pd/Transports.cpp | 32 ++++++------- libi2pd/Transports.h | 4 +- libi2pd/Tunnel.cpp | 14 +++--- libi2pd/Tunnel.h | 10 ++-- libi2pd/TunnelPool.h | 4 +- 18 files changed, 175 insertions(+), 175 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 1bb3717c..8df08118 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -45,7 +45,7 @@ namespace config { ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") - ("host", value()->default_value(""), "External IP") + ("host", value()->default_value(""), "External IP") ("ifname", value()->default_value(""), "Network interface to bind to") ("ifname4", value()->default_value(""), "Network interface to bind to for ipv4") ("ifname6", value()->default_value(""), "Network interface to bind to for ipv6") diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 9be0c06e..5d6b71b9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -415,7 +415,7 @@ namespace client { LogPrint (eLogError, "Destination: Database store message is too long ", len); return; - } + } i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET); std::shared_ptr leaseSet; switch (buf[DATABASE_STORE_TYPE_OFFSET]) @@ -786,7 +786,7 @@ namespace client LogPrint (eLogWarning, "Destination: LeaseSet request for ", dest.ToBase32 (), " was not sent"); m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); - } + } } } else // duplicate @@ -1173,11 +1173,11 @@ namespace client }, dest, port); while (!done) - { + { std::unique_lock l(streamRequestCompleteMutex); if (!done) streamRequestComplete.wait (l); - } + } return stream; } diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index b659ba78..68ed7353 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -693,8 +693,8 @@ namespace transport SendTerminationAndTerminate (eNTCP2Message3Error); return; } - auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri.GetNTCP2V4Address () : - (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri.GetYggdrasilAddress () : ri.GetNTCP2V6Address ()); + auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri.GetNTCP2V4Address () : + (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri.GetYggdrasilAddress () : ri.GetNTCP2V6Address ()); if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) { LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed"); @@ -703,13 +703,13 @@ namespace transport } if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address { LogPrint (eLogError, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); Terminate (); return; - } + } i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options @@ -884,7 +884,7 @@ namespace transport switch (blk) { case eNTCP2BlkDateTime: - { + { LogPrint (eLogDebug, "NTCP2: Datetime"); if (m_IsEstablished) { @@ -894,8 +894,8 @@ namespace transport { LogPrint (eLogWarning, "NTCP2: Established session time difference ", (int)(ts - tsA), " exceeds clock skew"); SendTerminationAndTerminate (eNTCP2ClockSkew); - } - } + } + } break; } case eNTCP2BlkOptions: diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4a6fed70..d28b0bb3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -430,15 +430,15 @@ namespace data { auto it = m_RouterInfos.find (ident); if (it != m_RouterInfos.end ()) - { + { it->second->SetUnreachable (unreachable); if (unreachable) - { + { auto profile = it->second->GetProfile (); if (profile) profile->Unreachable (); - } - } + } + } } void NetDb::Reseed () @@ -824,7 +824,7 @@ namespace data { LogPrint (eLogError, "NetDb: Database store message is too long ", len); return; - } + } if (!m->from) // unsolicited LS must be received directly { if (storeType == NETDB_STORE_TYPE_LEASESET) // 1 diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 6909e209..a127ce81 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -136,15 +136,15 @@ namespace data { UpdateTime (); if (ret > 0) - { + { m_NumTunnelsDeclined++; m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); - } + } else - { + { m_NumTunnelsAgreed++; m_LastDeclineTime = 0; - } + } } void RouterProfile::TunnelNonReplied () @@ -158,8 +158,8 @@ namespace data void RouterProfile::Unreachable () { m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch (); - } - + } + bool RouterProfile::IsLowPartcipationRate () const { return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate @@ -179,8 +179,8 @@ namespace data ts + PEER_PROFILE_DECLINED_RECENTLY_INTERVAL < m_LastDeclineTime) m_LastDeclineTime = 0; return (bool)m_LastDeclineTime; - } - + } + bool RouterProfile::IsBad () { if (IsDeclinedRecently () || IsUnreachable ()) return true; @@ -205,8 +205,8 @@ namespace data ts + PEER_PROFILE_UNREACHABLE_INTERVAL < m_LastUnreachableTime) m_LastUnreachableTime = 0; return (bool)m_LastUnreachableTime; - } - + } + std::shared_ptr GetRouterProfile (const IdentHash& identHash) { auto profile = std::make_shared (); diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 58b5e2ea..bccf19de 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -33,8 +33,8 @@ namespace data const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) - const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) - + const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) + class RouterProfile { public: @@ -47,12 +47,12 @@ namespace data bool IsBad (); bool IsUnreachable (); - + void TunnelBuildResponse (uint8_t ret); void TunnelNonReplied (); void Unreachable (); - + private: boost::posix_time::ptime GetTime () const; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 91bfadbc..a91b9217 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -88,7 +88,7 @@ namespace i2p uint8_t caps = 0; if (ipv4) { - std::string host; + std::string host; if (!nat) // we have no NAT so set external address from local address i2p::config::GetOption("address4", host); @@ -99,15 +99,15 @@ namespace i2p uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; if (ntcp2Published && ntcp2Port) - { + { boost::asio::ip::address addr; if (!host.empty ()) addr = boost::asio::ip::address::from_string (host); if (!addr.is_v4()) addr = boost::asio::ip::address_v4 (); - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); - } - else + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + } + else { // add non-published NTCP2 address uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; @@ -120,14 +120,14 @@ namespace i2p uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); if (!ssu2Port) ssu2Port = port; if (ssu2Published && ssu2Port) - { + { boost::asio::ip::address addr; if (!host.empty ()) addr = boost::asio::ip::address::from_string (host); if (!addr.is_v4()) addr = boost::asio::ip::address_v4 (); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); - } + } else { uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; @@ -138,7 +138,7 @@ namespace i2p } if (ipv6) { - std::string host; i2p::config::GetOption("address6", host); + std::string host; i2p::config::GetOption("address6", host); if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented if (ntcp2) @@ -255,7 +255,7 @@ namespace i2p break; case eRouterStatusTesting: m_Error = eRouterErrorNone; - break; + break; default: ; } @@ -277,7 +277,7 @@ namespace i2p break; case eRouterStatusTesting: m_ErrorV6 = eRouterErrorNone; - break; + break; default: ; } @@ -309,8 +309,8 @@ namespace i2p if (port) address->port = port; address->published = publish; memcpy (address->i, m_NTCP2Keys->iv, 16); - } - + } + void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg) { if (!m_NTCP2Keys) return; @@ -324,8 +324,8 @@ namespace i2p { PublishNTCP2Address (addr, port, publish); updated = true; - } - } + } + } if (v6) { auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; @@ -333,7 +333,7 @@ namespace i2p { PublishNTCP2Address (addr, port, publish); updated = true; - } + } } if (ygg) { @@ -342,9 +342,9 @@ namespace i2p { PublishNTCP2Address (addr, port, publish); updated = true; - } + } } - + if (updated) UpdateRouterInfo (); } @@ -362,8 +362,8 @@ namespace i2p memcpy (it->i, m_NTCP2Keys->iv, 16); } } - } - + } + void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) { if (!m_SSU2Keys) return; @@ -413,8 +413,8 @@ namespace i2p it->i = m_SSU2Keys->intro; } } - } - + } + void RouterContext::UpdateAddress (const boost::asio::ip::address& host) { auto addresses = m_RouterInfo.GetAddresses (); @@ -727,11 +727,11 @@ namespace i2p { auto addr = boost::asio::ip::address::from_string (ntcp2Host); if (addr.is_v6 ()) - { + { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); added = true; - } - } + } + } } if (!added) m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV6); @@ -753,15 +753,15 @@ namespace i2p { std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) - { + { auto addr = boost::asio::ip::address::from_string (host); if (addr.is_v6 ()) - { + { m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); added = true; } - } - } + } + } if (!added) m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV6); } @@ -819,18 +819,18 @@ namespace i2p bool added = false; bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published && ntcp2Port) - { + { std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) - { + { auto addr = boost::asio::ip::address::from_string (host); if (addr.is_v4 ()) - { + { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); added = true; - } - } - } + } + } + } if (!added) m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV4); } @@ -849,18 +849,18 @@ namespace i2p bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); std::string host; i2p::config::GetOption("host", host); if (ssu2Published && ssu2Port) - { + { std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) - { + { auto addr = boost::asio::ip::address::from_string (host); if (addr.is_v4 ()) - { + { m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); added = true; } - } - } + } + } if (!added) m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV4); } @@ -933,7 +933,7 @@ namespace i2p { addr->host = host; UpdateRouterInfo (); - } + } } void RouterContext::UpdateStats () @@ -1034,28 +1034,28 @@ namespace i2p if (IsUnreachable ()) SetReachable (true, true); // we assume reachable until we discover firewall through peer tests - + bool updated = false; // create new NTCP2 keys if required bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); - if ((ntcp2 || ygg) && !m_NTCP2Keys) - { + if ((ntcp2 || ygg) && !m_NTCP2Keys) + { NewNTCP2Keys (); UpdateNTCP2Keys (); updated = true; - } + } // create new SSU2 keys if required bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - if (ssu2 && !m_SSU2Keys) - { + if (ssu2 && !m_SSU2Keys) + { NewSSU2Keys (); UpdateSSU2Keys (); updated = true; - } + } if (updated) UpdateRouterInfo (); - + return true; } @@ -1087,7 +1087,7 @@ namespace i2p // TODO: implement LogPrint (eLogWarning, "Router: garlic message in garlic clove. Dropped"); return false; - } + } auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 22359ded..9fbbb178 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -181,7 +181,7 @@ namespace garlic void SaveKeys (); uint16_t SelectRandomPort () const; void PublishNTCP2Address (std::shared_ptr address, int port, bool publish) const; - + bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize); private: diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 28959fe9..32b01217 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -252,15 +252,15 @@ namespace data { boost::system::error_code ecode; address->host = boost::asio::ip::address::from_string (value, ecode); - if (!ecode && !address->host.is_unspecified ()) + if (!ecode && !address->host.is_unspecified ()) { - if (!i2p::util::net::IsInReservedRange (address->host) || + if (!i2p::util::net::IsInReservedRange (address->host) || i2p::util::net::IsYggdrasilAddress (address->host)) isHost = true; else - // we consider such address as invalid - address->transportStyle = eTransportUnknown; - } + // we consider such address as invalid + address->transportStyle = eTransportUnknown; + } } else if (!strcmp (key, "port")) { @@ -648,8 +648,8 @@ namespace data m_SupportedTransports |= eNTCP2V6; (*m_Addresses)[eNTCP2V6Idx] = addr; } - } - + } + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port) { @@ -688,20 +688,20 @@ namespace data void RouterInfo::RemoveNTCP2Address (bool v4) { if (v4) - { + { if ((*m_Addresses)[eNTCP2V6Idx]) (*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4; (*m_Addresses)[eNTCP2V4Idx].reset (); - } + } else - { + { if ((*m_Addresses)[eNTCP2V4Idx]) (*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6; (*m_Addresses)[eNTCP2V6Idx].reset (); - } + } UpdateSupportedTransports (); - } - + } + void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, int port, uint8_t caps) { auto addr = std::make_shared
(); @@ -756,20 +756,20 @@ namespace data void RouterInfo::RemoveSSU2Address (bool v4) { if (v4) - { + { if ((*m_Addresses)[eSSU2V6Idx]) (*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4; (*m_Addresses)[eSSU2V4Idx].reset (); - } + } else - { + { if ((*m_Addresses)[eSSU2V4Idx]) (*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6; (*m_Addresses)[eSSU2V6Idx].reset (); - } + } UpdateSupportedTransports (); - } - + } + bool RouterInfo::IsNTCP2 (bool v4only) const { if (v4only) @@ -919,7 +919,7 @@ namespace data { return (*GetAddresses ())[eNTCP2V6Idx]; } - + std::shared_ptr RouterInfo::GetPublishedNTCP2V4Address () const { auto addr = (*GetAddresses ())[eNTCP2V4Idx]; @@ -1032,13 +1032,13 @@ namespace data std::shared_ptr RouterInfo::NewAddress () const { return netdb.NewRouterInfoAddress (); - } - + } + boost::shared_ptr RouterInfo::NewAddresses () const { return netdb.NewRouterInfoAddresses (); - } - + } + void RouterInfo::RefreshTimestamp () { m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); @@ -1324,12 +1324,12 @@ namespace data { return std::make_shared
(); } - + boost::shared_ptr LocalRouterInfo::NewAddresses () const { return boost::make_shared (); - } - + } + bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) { auto addresses = GetAddresses (); diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 8b755f60..2e652786 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -100,7 +100,7 @@ namespace transport i2p::util::MemoryPool& GetSentPacketsPool () { return m_SentPacketsPool; }; i2p::util::MemoryPool& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; }; i2p::util::MemoryPool& GetFragmentsPool () { return m_FragmentsPool; }; - + private: boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint); @@ -116,7 +116,7 @@ namespace transport void ScheduleCleanup (); void HandleCleanupTimer (const boost::system::error_code& ecode); - + void ScheduleResend (bool more); void HandleResendTimer (const boost::system::error_code& ecode); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index a36536a8..b713f02d 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -36,34 +36,34 @@ namespace transport { bool isLast = false; while (outOfSequenceFragments) - { + { if (outOfSequenceFragments->fragmentNum == nextFragmentNum) { AttachNextFragment (outOfSequenceFragments->buf, outOfSequenceFragments->len); isLast = outOfSequenceFragments->isLast; if (isLast) outOfSequenceFragments = nullptr; - else + else outOfSequenceFragments = outOfSequenceFragments->next; - } + } else break; - } + } return isLast; - } + } void SSU2IncompleteMessage::AddOutOfSequenceFragment (std::shared_ptr fragment) - { + { if (!fragment || !fragment->fragmentNum) return; // fragment 0 not allowed if (fragment->fragmentNum < nextFragmentNum) return; // already processed - if (!outOfSequenceFragments) + if (!outOfSequenceFragments) outOfSequenceFragments = fragment; else { auto frag = outOfSequenceFragments; std::shared_ptr prev; do - { + { if (fragment->fragmentNum < frag->fragmentNum) break; // found if (fragment->fragmentNum == frag->fragmentNum) return; // duplicate prev = frag; frag = frag->next; @@ -71,13 +71,13 @@ namespace transport while (frag); fragment->next = frag; if (prev) - prev->next = fragment; + prev->next = fragment; else outOfSequenceFragments = fragment; - } + } lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); } - + SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr in_RemoteRouter, std::shared_ptr addr): TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT), @@ -1041,20 +1041,20 @@ namespace transport LogPrint (eLogError, "SSU2: SessionConfirmed malformed RouterInfo block"); return false; } - m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address (); + m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address (); if (!m_Address || memcmp (S, m_Address->s, 32)) { LogPrint (eLogError, "SSU2: Wrong static key in SessionConfirmed from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; } if (m_Address->published && m_RemoteEndpoint.address () != m_Address->host && - (!m_RemoteEndpoint.address ().is_v6 () || + (!m_RemoteEndpoint.address ().is_v6 () || memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), m_Address->host.to_v6 ().to_bytes ().data (), 8))) // temporary address { - LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host, + LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host, " and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); return false; - } + } // update RouterInfo in netdb ri = i2p::data::netdb.AddRouterInfo (ri->GetBuffer (), ri->GetBufferLen ()); // ri points to one from netdb now if (!ri) @@ -1617,7 +1617,7 @@ namespace transport { case eSSU2SessionStateSessionRequestReceived: case eSSU2SessionStateTokenRequestReceived: - case eSSU2SessionStateEstablished: + case eSSU2SessionStateEstablished: if (std::abs (offset) > SSU2_CLOCK_SKEW) m_TerminationReason = eSSU2TerminationReasonClockSkew; break; @@ -1804,7 +1804,7 @@ namespace transport { LogPrint (eLogWarning, "SSU2: Invalid follow-on fragment num ", fragmentNum); return; - } + } bool isLast = buf[0] & 0x01; uint32_t msgID; memcpy (&msgID, buf + 1, 4); auto it = m_IncompleteMessages.find (msgID); @@ -2307,21 +2307,21 @@ namespace transport } void SSU2Session::HandleI2NPMsg (std::shared_ptr&& msg) - { + { if (!msg) return; uint32_t msgID = msg->GetMsgID (); if (!msg->IsExpired ()) { // m_LastActivityTimestamp is updated in ProcessData before if (m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp).second) - m_Handler.PutNextMessage (std::move (msg)); + m_Handler.PutNextMessage (std::move (msg)); else LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); } else LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired"); - } - + } + bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) { if (size < 2) return false; @@ -2473,7 +2473,7 @@ namespace transport acnt++; if (acnt >= SSU2_MAX_NUM_ACK_PACKETS) break; - else + else it++; } // ranges @@ -2499,8 +2499,8 @@ namespace transport numRanges++; } } - int numPackets = acnt + numRanges*SSU2_MAX_NUM_ACNT; - while (it != m_OutOfSequencePackets.rend () && + int numPackets = acnt + numRanges*SSU2_MAX_NUM_ACNT; + while (it != m_OutOfSequencePackets.rend () && numRanges < maxNumRanges && numPackets < SSU2_MAX_NUM_ACK_PACKETS) { if (lastNum - (*it) > SSU2_MAX_NUM_ACNT) @@ -2786,7 +2786,7 @@ namespace transport while (it != m_OutOfSequencePackets.end ()) { if (*it == packetNum + 1) - { + { packetNum++; it++; } @@ -2794,7 +2794,7 @@ namespace transport break; } m_OutOfSequencePackets.erase (m_OutOfSequencePackets.begin (), it); - } + } } m_ReceivePacketNum = packetNum; } @@ -2881,7 +2881,7 @@ namespace transport if (!m_OutOfSequencePackets.empty ()) { int ranges = 0; - while (ranges < 8 && !m_OutOfSequencePackets.empty () && + while (ranges < 8 && !m_OutOfSequencePackets.empty () && (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || *m_OutOfSequencePackets.rbegin () > m_ReceivePacketNum + SSU2_MAX_NUM_ACK_PACKETS)) { @@ -2895,10 +2895,10 @@ namespace transport ranges++; } else - { + { LogPrint (eLogError, "SSU2: Out of sequence packet ", packet, " is less than last received ", m_ReceivePacketNum); break; - } + } } if (m_OutOfSequencePackets.size () > 255*4) { diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 03395d0f..151aae4d 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -52,7 +52,7 @@ namespace transport const int SSU2_MAX_NUM_ACK_PACKETS = 510; // 2*255 ack + nack const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64; - + // flags const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01; @@ -317,7 +317,7 @@ namespace transport void HandleRelayResponse (const uint8_t * buf, size_t len); void HandlePeerTest (const uint8_t * buf, size_t len); void HandleI2NPMsg (std::shared_ptr&& msg); - + size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep); size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr r); size_t CreateAckBlock (uint8_t * buf, size_t len); diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 03ade393..83b6cacd 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -107,9 +107,9 @@ namespace transport int GetTerminationTimeout () const { return m_TerminationTimeout; }; void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; }; bool IsTerminationTimeoutExpired (uint64_t ts) const - { + { return ts >= m_LastActivityTimestamp + GetTerminationTimeout () || - ts + GetTerminationTimeout () < m_LastActivityTimestamp; + ts + GetTerminationTimeout () < m_LastActivityTimestamp; }; uint32_t GetCreationTime () const { return m_CreationTime; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index bfd1b190..aa326a92 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -831,12 +831,12 @@ namespace transport std::advance (it, inds[0]); // try random peer if (it != m_Peers.end () && filter (it->second)) - { + { ident = it->first; found = true; - } + } else - { + { // try some peers around auto it1 = m_Peers.begin (); if (inds[0]) @@ -859,48 +859,48 @@ namespace transport while (it != it2 && it != m_Peers.end ()) { if (filter (it->second)) - { + { ident = it->first; found = true; break; - } + } it++; } if (!found) - { + { // still not found, try from the beginning it = m_Peers.begin (); while (it != it1 && it != m_Peers.end ()) { if (filter (it->second)) - { + { ident = it->first; found = true; break; - } + } it++; } if (!found) - { + { // still not found, try to the beginning it = it2; while (it != m_Peers.end ()) { if (filter (it->second)) - { + { ident = it->first; found = true; break; - } + } it++; } - } - } - } - } + } + } + } + } return found ? i2p::data::netdb.FindRouter (ident) : nullptr; } - + std::shared_ptr Transports::GetRandomPeer (bool isHighBandwidth) const { return GetRandomPeer ( diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index ebb6261e..dc97a952 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -94,7 +94,7 @@ namespace transport router = r; if (router) isHighBandwidth = router->IsHighBandwidth (); - } + } }; const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds @@ -176,7 +176,7 @@ namespace transport template std::shared_ptr GetRandomPeer (Filter filter) const; - + private: volatile bool m_IsOnline; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 12fa7771..372c3ff9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -334,7 +334,7 @@ namespace tunnel Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal avarage m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) - { + { } Tunnels::~Tunnels () @@ -439,11 +439,11 @@ namespace tunnel if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) m_TransitTunnels.push_back (tunnel); else - { + { LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists"); - return false; - } - return true; + return false; + } + return true; } void Tunnels::Start () @@ -538,13 +538,13 @@ namespace tunnel { uint64_t ts = i2p::util::GetSecondsSinceEpoch (); if (ts - lastTs >= TUNNEL_MANAGE_INTERVAL || // manage tunnels every 15 seconds - ts + TUNNEL_MANAGE_INTERVAL < lastTs) + ts + TUNNEL_MANAGE_INTERVAL < lastTs) { ManageTunnels (ts); lastTs = ts; } if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 secondsts - ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs) + ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs) { ManageTunnelPools (ts); lastPoolsTs = ts; diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a603ff92..b690d1eb 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -254,7 +254,7 @@ namespace tunnel std::shared_ptr CreateZeroHopsOutboundTunnel (std::shared_ptr pool); // Calculating of tunnel creation success rate - void SuccesiveTunnelCreation() + void SuccesiveTunnelCreation() { // total TCSR m_TotalNumSuccesiveTunnelCreations++; @@ -263,14 +263,14 @@ namespace tunnel m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate; } - void FailedTunnelCreation() + void FailedTunnelCreation() { m_TotalNumFailedTunnelCreations++; - + double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum; m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate; } - + private: bool m_IsRunning; @@ -288,7 +288,7 @@ namespace tunnel i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // count of tunnels for total TCSR algorithm - int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; + int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; int m_TunnelCreationAttemptsNum; diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 6936d3ad..7d952559 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -56,7 +56,7 @@ namespace tunnel class TunnelPool: public std::enable_shared_from_this // per local destination { - typedef std::function(std::shared_ptr, bool)> SelectHopFunc; + typedef std::function(std::shared_ptr, bool)> SelectHopFunc; public: TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, @@ -114,7 +114,7 @@ namespace tunnel // for overriding tunnel peer selection std::shared_ptr SelectNextHop (std::shared_ptr prevHop, bool reverse) const; bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); - + private: void TestTunnels (); From 48a3c767e58435ee448ced2bf9664f4c6a09822d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Feb 2023 16:22:02 -0500 Subject: [PATCH 0092/1160] in-meory storage for router profiles --- libi2pd/NetDb.cpp | 16 +++++----- libi2pd/Profiling.cpp | 68 ++++++++++++++++++++++++++++++++++--------- libi2pd/Profiling.h | 14 ++++++--- libi2pd/RouterInfo.h | 2 +- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index d28b0bb3..0d68cee3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -85,8 +85,7 @@ namespace data if (m_IsRunning) { if (m_PersistProfiles) - for (auto& it: m_RouterInfos) - it.second->SaveProfile (); + SaveProfiles (); DeleteObsoleteProfiles (); m_RouterInfos.clear (); m_Floodfills.clear (); @@ -179,6 +178,7 @@ namespace data if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) || ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup) { + if (m_PersistProfiles) PersistProfiles (); DeleteObsoleteProfiles (); lastProfilesCleanup = ts; profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE); @@ -684,12 +684,12 @@ namespace data for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();) { if (it->second->IsUnreachable ()) - { - if (m_PersistProfiles) it->second->SaveProfile (); it = m_RouterInfos.erase (it); - continue; - } - ++it; + else + { + it->second->DropProfile (); + it++; + } } } // clean up expired floodfills or not floodfills anymore @@ -699,7 +699,7 @@ namespace data if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ()) it = m_Floodfills.erase (it); else - ++it; + it++; } } } diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index a127ce81..2dafe8ca 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include "Base.h" @@ -19,24 +20,26 @@ namespace i2p { namespace data { - i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); + static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); + static std::unordered_map > g_Profiles; + static boost::posix_time::ptime GetTime () + { + return boost::posix_time::second_clock::local_time(); + } + RouterProfile::RouterProfile (): - m_LastUpdateTime (boost::posix_time::second_clock::local_time()), + m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTimesTaken (0), m_NumTimesRejected (0) { } - boost::posix_time::ptime RouterProfile::GetTime () const - { - return boost::posix_time::second_clock::local_time(); - } - void RouterProfile::UpdateTime () { m_LastUpdateTime = GetTime (); + m_IsUpdated = true; } void RouterProfile::Save (const IdentHash& identHash) @@ -59,7 +62,7 @@ namespace data // save to file std::string ident = identHash.ToBase64 (); - std::string path = m_ProfilesStorage.Path(ident); + std::string path = g_ProfilesStorage.Path(ident); try { boost::property_tree::write_ini (path, pt); @@ -72,7 +75,7 @@ namespace data void RouterProfile::Load (const IdentHash& identHash) { std::string ident = identHash.ToBase64 (); - std::string path = m_ProfilesStorage.Path(ident); + std::string path = g_ProfilesStorage.Path(ident); boost::property_tree::ptree pt; if (!i2p::fs::Exists(path)) @@ -158,6 +161,7 @@ namespace data void RouterProfile::Unreachable () { m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch (); + UpdateTime (); } bool RouterProfile::IsLowPartcipationRate () const @@ -209,30 +213,68 @@ namespace data std::shared_ptr GetRouterProfile (const IdentHash& identHash) { + auto it = g_Profiles.find (identHash); + if (it != g_Profiles.end ()) + return it->second; auto profile = std::make_shared (); profile->Load (identHash); // if possible + g_Profiles.emplace (identHash, profile); return profile; } void InitProfilesStorage () { - m_ProfilesStorage.SetPlace(i2p::fs::GetDataDir()); - m_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64); + g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir()); + g_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64); } + void PersistProfiles () + { + auto ts = GetTime (); + for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) + { + if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) + { + if (it->second->IsUpdated ()) + it->second->Save (it->first); + it = g_Profiles.erase (it); + } + else + it++; + } + } + + void SaveProfiles () + { + auto ts = GetTime (); + for (auto it: g_Profiles) + if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + it.second->Save (it.first); + g_Profiles.clear (); + } + void DeleteObsoleteProfiles () { + auto ts = GetTime (); + for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) + { + if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + it = g_Profiles.erase (it); + else + it++; + } + struct stat st; std::time_t now = std::time(nullptr); std::vector files; - m_ProfilesStorage.Traverse(files); + g_ProfilesStorage.Traverse(files); for (const auto& path: files) { if (stat(path.c_str(), &st) != 0) { LogPrint(eLogWarning, "Profiling: Can't stat(): ", path); continue; } - if (((now - st.st_mtime) / 3600) >= PEER_PROFILE_EXPIRATION_TIMEOUT) { + if (now - st.st_mtime >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) { LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path); i2p::fs::Remove(path); } diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index bccf19de..752d6190 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -29,10 +29,11 @@ namespace data const char PEER_PROFILE_USAGE_TAKEN[] = "taken"; const char PEER_PROFILE_USAGE_REJECTED[] = "rejected"; - const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days) - const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day) - const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours) + const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days) + const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours) + const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) + const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes) const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) class RouterProfile @@ -53,9 +54,11 @@ namespace data void Unreachable (); + boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; + bool IsUpdated () const { return m_IsUpdated; }; + private: - boost::posix_time::ptime GetTime () const; void UpdateTime (); bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; }; @@ -66,6 +69,7 @@ namespace data private: boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono + bool m_IsUpdated; uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds // participation uint32_t m_NumTunnelsAgreed; @@ -79,6 +83,8 @@ namespace data std::shared_ptr GetRouterProfile (const IdentHash& identHash); void InitProfilesStorage (); void DeleteObsoleteProfiles (); + void SaveProfiles (); + void PersistProfiles (); } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ea0abf41..f31b3cc2 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -251,7 +251,7 @@ namespace data bool SaveToFile (const std::string& fullPath); std::shared_ptr GetProfile () const; - void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); }; + void DropProfile () { m_Profile = nullptr; }; void Update (const uint8_t * buf, size_t len); void DeleteBuffer () { m_Buffer = nullptr; }; From d79bdc9f66fc687b08b2ca073f2330b4bdda25e8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Feb 2023 20:11:34 -0500 Subject: [PATCH 0093/1160] send datetime block after approximately every 250 packets --- libi2pd/SSU2Session.cpp | 17 +++++++++++++---- libi2pd/SSU2Session.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index b713f02d..e45a33a2 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -83,9 +83,9 @@ namespace transport TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT), m_Server (server), m_Address (addr), m_RemoteTransports (0), m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown), - m_SendPacketNum (0), m_ReceivePacketNum (0), m_IsDataReceived (false), - m_WindowSize (SSU2_MIN_WINDOW_SIZE), m_RTT (SSU2_RESEND_INTERVAL), - m_RTO (SSU2_RESEND_INTERVAL*SSU2_kAPPA), m_RelayTag (0), + m_SendPacketNum (0), m_ReceivePacketNum (0), m_LastDatetimeSentPacketNum (0), + m_IsDataReceived (false), m_WindowSize (SSU2_MIN_WINDOW_SIZE), + m_RTT (SSU2_RESEND_INTERVAL), m_RTO (SSU2_RESEND_INTERVAL*SSU2_kAPPA), m_RelayTag (0), m_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose), m_MaxPayloadSize (SSU2_MIN_PACKET_SIZE - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - 32) // min size { @@ -2806,7 +2806,16 @@ namespace transport void SSU2Session::SendQuickAck () { uint8_t payload[SSU2_MAX_PACKET_SIZE]; - size_t payloadSize = CreateAckBlock (payload, m_MaxPayloadSize); + size_t payloadSize = 0; + if (m_SendPacketNum > m_LastDatetimeSentPacketNum + SSU2_SEND_DATETIME_NUM_PACKETS) + { + payload[0] = eSSU2BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); + payloadSize += 7; + m_LastDatetimeSentPacketNum = m_SendPacketNum; + } + payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); SendData (payload, payloadSize); } diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 151aae4d..363cb982 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -52,6 +52,7 @@ namespace transport const int SSU2_MAX_NUM_ACK_PACKETS = 510; // 2*255 ack + nack const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64; + const int SSU2_SEND_DATETIME_NUM_PACKETS = 250; // flags const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01; @@ -344,7 +345,7 @@ namespace transport uint64_t m_DestConnID, m_SourceConnID; SSU2SessionState m_State; uint8_t m_KeyDataSend[64], m_KeyDataReceive[64]; - uint32_t m_SendPacketNum, m_ReceivePacketNum; + uint32_t m_SendPacketNum, m_ReceivePacketNum, m_LastDatetimeSentPacketNum; std::set m_OutOfSequencePackets; // packet nums > receive packet num std::map > m_SentPackets; // packetNum -> packet std::unordered_map > m_IncompleteMessages; // msgID -> I2NP From 88f19f551d9c11330b5e0b96f52bcfdab6ccf195 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Feb 2023 09:21:59 -0500 Subject: [PATCH 0094/1160] don't save RouterInfo buffer if invalid --- libi2pd/RouterInfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 32b01217..1bf1d42d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -99,13 +99,13 @@ namespace data m_Caps = 0; // don't clean up m_Addresses, it will be replaced in ReadFromStream ClearProperties (); - // copy buffer - UpdateBuffer (buf, len); // skip identity size_t identityLen = m_RouterIdentity->GetFullLen (); // read new RI - std::stringstream str (std::string ((char *)m_Buffer->data () + identityLen, m_BufferLen - identityLen)); + std::stringstream str (std::string ((char *)buf + identityLen, len - identityLen)); ReadFromStream (str); + if (!m_IsUnreachable) + UpdateBuffer (buf, len); // save buffer // don't delete buffer until saved to the file } else From 7bde4de1f557d9c86ab9f4abc9b49046d71a7d10 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Feb 2023 15:28:06 -0500 Subject: [PATCH 0095/1160] don't try to save unreachable routers --- libi2pd/RouterInfo.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 1bf1d42d..65b6a0f0 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -595,14 +595,16 @@ namespace data bool RouterInfo::SaveToFile (const std::string& fullPath) { + if (m_IsUnreachable) return false; // don't save bad router if (!m_Buffer) { - LogPrint (eLogError, "RouterInfo: Can't save, m_Buffer == NULL"); + LogPrint (eLogWarning, "RouterInfo: Can't save, m_Buffer == NULL"); return false; } std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); - if (!f.is_open ()) { - LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); + if (!f.is_open ()) + { + LogPrint (eLogError, "RouterInfo: Can't save to ", fullPath); return false; } f.write ((char *)m_Buffer->data (), m_BufferLen); From d15581d95e0662a511d25903ee29e04af0b0701a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Feb 2023 18:02:16 -0500 Subject: [PATCH 0096/1160] delete invalid router after update --- libi2pd/NetDb.cpp | 17 ++++++++++++++++- libi2pd/RouterInfo.cpp | 16 ++++++++-------- libi2pd/RouterInfo.h | 2 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 0d68cee3..374d2d6d 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -276,7 +276,22 @@ namespace data bool wasFloodfill = r->IsFloodfill (); { std::unique_lock l(m_RouterInfosMutex); - r->Update (buf, len); + if (!r->Update (buf, len)) + { + updated = false; + return r; + } + if (r->IsUnreachable ()) + { + // delete router as invalid after update + m_RouterInfos.erase (ident); + if (wasFloodfill) + { + std::unique_lock l(m_FloodfillsMutex); + m_Floodfills.remove (r); + } + return nullptr; + } } LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64()); if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 65b6a0f0..3cf79f11 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -79,13 +79,12 @@ namespace data { } - void RouterInfo::Update (const uint8_t * buf, size_t len) + bool RouterInfo::Update (const uint8_t * buf, size_t len) { if (len > MAX_RI_BUFFER_SIZE) { - LogPrint (eLogError, "RouterInfo: Buffer is too long ", len); - m_IsUnreachable = true; - return; + LogPrint (eLogWarning, "RouterInfo: Updated buffer is too long ", len, ". Not changed"); + return false; } // verify signature since we have identity already int l = len - m_RouterIdentity->GetSignatureLen (); @@ -109,10 +108,11 @@ namespace data // don't delete buffer until saved to the file } else - { - LogPrint (eLogError, "RouterInfo: Signature verification failed"); - m_IsUnreachable = true; - } + { + LogPrint (eLogWarning, "RouterInfo: Updated signature verification failed. Not changed"); + return false; + } + return true; } void RouterInfo::SetRouterIdentity (std::shared_ptr identity) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f31b3cc2..dcdabf39 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -253,7 +253,7 @@ namespace data std::shared_ptr GetProfile () const; void DropProfile () { m_Profile = nullptr; }; - void Update (const uint8_t * buf, size_t len); + bool Update (const uint8_t * buf, size_t len); void DeleteBuffer () { m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; From c2faa5c6145dd5b5064564c52cdc4338618ef8f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Feb 2023 19:10:22 -0500 Subject: [PATCH 0097/1160] don't try to save RouterInfo if no buffer --- libi2pd/NetDb.cpp | 12 +++++++++--- libi2pd/RouterInfo.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 374d2d6d..153553a3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -279,6 +279,7 @@ namespace data if (!r->Update (buf, len)) { updated = false; + m_Requests.RequestComplete (ident, r); return r; } if (r->IsUnreachable ()) @@ -290,6 +291,7 @@ namespace data std::unique_lock l(m_FloodfillsMutex); m_Floodfills.remove (r); } + m_Requests.RequestComplete (ident, nullptr); return nullptr; } } @@ -645,10 +647,14 @@ namespace data std::string ident = it.second->GetIdentHashBase64(); if (it.second->IsUpdated ()) { - it.second->SaveToFile (m_Storage.Path(ident)); + if (it.second->GetBuffer ()) + { + // we have something to save + it.second->SaveToFile (m_Storage.Path(ident)); + it.second->SetUnreachable (false); + it.second->DeleteBuffer (); + } it.second->SetUpdated (false); - it.second->SetUnreachable (false); - it.second->DeleteBuffer (); updatedCount++; continue; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index dcdabf39..1024cda8 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -242,7 +242,7 @@ namespace data void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; bool IsUnreachable () const { return m_IsUnreachable; }; - const uint8_t * GetBuffer () const { return m_Buffer->data (); }; + const uint8_t * GetBuffer () const { return m_Buffer ? m_Buffer->data () : nullptr; }; const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary size_t GetBufferLen () const { return m_BufferLen; }; From 7b632bd03d2e28be4dbd31098697a55db7df38b0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Feb 2023 13:25:02 -0500 Subject: [PATCH 0098/1160] set minimal floodfill version to 0.9.51 --- libi2pd/NetDb.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 90ebe824..599a2bff 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -48,8 +48,8 @@ namespace data const int NETDB_PUBLISH_INTERVAL = 60 * 40; const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; - const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 - const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 + const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 + const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 /** function for visiting a leaseset stored in a floodfill */ From 4d0ad474919253ce7e055802fd89692b7d30deb2 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Feb 2023 13:45:06 -0500 Subject: [PATCH 0099/1160] GetBit for IdentHash --- libi2pd/Tag.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index d898395f..d0b0c056 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -80,6 +80,13 @@ namespace data { return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); } + uint8_t GetBit (int i) const + { + int pos = i >> 3; // /8 + if (pos >= sz) return 0; + return m_Buf[pos] & (1 << (7 - (i & 0x07))); + } + private: union // 8 bytes aligned From 4f3a416e37126ed35eb18baec3e8d3e7fa9e6e95 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Feb 2023 15:44:20 -0500 Subject: [PATCH 0100/1160] send DateTime together with RouterInfo --- libi2pd/NTCP2.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 68ed7353..6ccd0f80 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1142,12 +1142,17 @@ namespace transport { if (!IsEstablished ()) return; auto riLen = i2p::context.GetRouterInfo ().GetBufferLen (); - size_t payloadLen = riLen + 4; // 3 bytes block header + 1 byte RI flag + size_t payloadLen = riLen + 4 + 1 + 7; // 3 bytes block header + 1 byte RI flag + 7 bytes DateTime m_NextSendBuffer = new uint8_t[payloadLen + 16 + 2 + 64]; // up to 64 bytes padding - m_NextSendBuffer[2] = eNTCP2BlkRouterInfo; - htobe16buf (m_NextSendBuffer + 3, riLen + 1); // size - m_NextSendBuffer[5] = 0; // flag - memcpy (m_NextSendBuffer + 6, i2p::context.GetRouterInfo ().GetBuffer (), riLen); + // DateTime block + m_NextSendBuffer[2] = eNTCP2BlkDateTime; + htobe16buf (m_NextSendBuffer + 3, 4); + htobe32buf (m_NextSendBuffer + 5, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); + // RouterInfo block + m_NextSendBuffer[9] = eNTCP2BlkRouterInfo; + htobe16buf (m_NextSendBuffer + 10, riLen + 1); // size + m_NextSendBuffer[12] = 0; // flag + memcpy (m_NextSendBuffer + 13, i2p::context.GetRouterInfo ().GetBuffer (), riLen); // padding block auto paddingSize = CreatePaddingBlock (payloadLen, m_NextSendBuffer + 2 + payloadLen, 64); payloadLen += paddingSize; From 532a29b0c41f8730330a1a8aa3ff342a0c5a9fc9 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Feb 2023 19:18:02 -0500 Subject: [PATCH 0101/1160] don't reply with unreachable router --- libi2pd/NetDb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 153553a3..694eb7c4 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1040,7 +1040,7 @@ namespace data lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP) { auto router = FindRouter (ident); - if (router) + if (router && !router->IsUnreachable ()) { LogPrint (eLogDebug, "NetDb: Requested RouterInfo ", key, " found"); PopulateRouterInfoBuffer (router); From 1ad38c0b95edea5c578bfe9d4b7b8bd9559ce41e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Feb 2023 19:37:11 -0500 Subject: [PATCH 0102/1160] fixed typo --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 6ccd0f80..813ea6d5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1142,7 +1142,7 @@ namespace transport { if (!IsEstablished ()) return; auto riLen = i2p::context.GetRouterInfo ().GetBufferLen (); - size_t payloadLen = riLen + 4 + 1 + 7; // 3 bytes block header + 1 byte RI flag + 7 bytes DateTime + size_t payloadLen = riLen + 3 + 1 + 7; // 3 bytes block header + 1 byte RI flag + 7 bytes DateTime m_NextSendBuffer = new uint8_t[payloadLen + 16 + 2 + 64]; // up to 64 bytes padding // DateTime block m_NextSendBuffer[2] = eNTCP2BlkDateTime; From abb81c353de037fb418a04b4281cf2c82c9c0ccb Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Feb 2023 09:33:10 -0500 Subject: [PATCH 0103/1160] fixed race condition --- libi2pd/Profiling.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 2dafe8ca..4f032326 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include "Base.h" @@ -22,6 +23,7 @@ namespace data { static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); static std::unordered_map > g_Profiles; + static std::mutex g_ProfilesMutex; static boost::posix_time::ptime GetTime () { @@ -213,11 +215,15 @@ namespace data std::shared_ptr GetRouterProfile (const IdentHash& identHash) { - auto it = g_Profiles.find (identHash); - if (it != g_Profiles.end ()) - return it->second; + { + std::unique_lock l(g_ProfilesMutex); + auto it = g_Profiles.find (identHash); + if (it != g_Profiles.end ()) + return it->second; + } auto profile = std::make_shared (); profile->Load (identHash); // if possible + std::unique_lock l(g_ProfilesMutex); g_Profiles.emplace (identHash, profile); return profile; } @@ -231,6 +237,7 @@ namespace data void PersistProfiles () { auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) { if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) @@ -247,6 +254,7 @@ namespace data void SaveProfiles () { auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); for (auto it: g_Profiles) if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it.second->Save (it.first); @@ -255,14 +263,17 @@ namespace data void DeleteObsoleteProfiles () { - auto ts = GetTime (); - for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) - { - if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) - it = g_Profiles.erase (it); - else - it++; - } + { + auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); + for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) + { + if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + it = g_Profiles.erase (it); + else + it++; + } + } struct stat st; std::time_t now = std::time(nullptr); From 03111ad0dff2d8873e9fc5094aa42db1d3c60f86 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Feb 2023 09:50:32 -0500 Subject: [PATCH 0104/1160] don't save profiles under mutex --- libi2pd/Profiling.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 4f032326..311d1c86 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -237,28 +238,37 @@ namespace data void PersistProfiles () { auto ts = GetTime (); - std::unique_lock l(g_ProfilesMutex); - for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) - { - if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) - { - if (it->second->IsUpdated ()) - it->second->Save (it->first); - it = g_Profiles.erase (it); - } - else - it++; - } + std::list > > tmp; + { + std::unique_lock l(g_ProfilesMutex); + for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) + { + if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) + { + if (it->second->IsUpdated ()) + tmp.push_back (std::make_pair (it->first, it->second)); + it = g_Profiles.erase (it); + } + else + it++; + } + } + for (auto& it: tmp) + if (it.second) it.second->Save (it.first); } void SaveProfiles () { + std::unordered_map > tmp; + { + std::unique_lock l(g_ProfilesMutex); + tmp = g_Profiles; + g_Profiles.clear (); + } auto ts = GetTime (); - std::unique_lock l(g_ProfilesMutex); - for (auto it: g_Profiles) + for (auto& it: tmp) if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it.second->Save (it.first); - g_Profiles.clear (); } void DeleteObsoleteProfiles () From 9e0c5d67c7c4e6b92e0fa9971f3d0afa07f549f7 Mon Sep 17 00:00:00 2001 From: weko Date: Tue, 14 Feb 2023 14:58:11 +0300 Subject: [PATCH 0105/1160] Don't use reversed port for choise random port. (by whothefuckami) --- libi2pd/RouterContext.cpp | 8 +++++++- libi2pd/util.cpp | 16 ++++++++++++++++ libi2pd/util.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a91b9217..a0a0ab06 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -202,7 +202,13 @@ namespace i2p uint16_t RouterContext::SelectRandomPort () const { - uint16_t port = rand () % (30777 - 9111) + 9111; // I2P network ports range + uint16_t port; + do + { + port = rand () % (30777 - 9111) + 9111; // I2P network ports range + } + while(i2p::util::net::IsPortInReservedRange(port)); + if (port == 9150) port = 9151; // Tor browser return port; } diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f0e9a7c6..48a8fab3 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include "util.h" @@ -487,6 +488,21 @@ namespace net return IsYggdrasilAddress (addr.to_v6 ().to_bytes ().data ()); } + bool IsPortInReservedRange (const uint16_t port) noexcept + { + static const std::unordered_set reservedPorts{ + 9119,9306,9312,9389,9418,9535,9536,9695, + 9800,9899,10000,10050,10051,10110,10212, + 10933,11001,11112,11235,11371,12222,12223, + 13075,13400,13720,13721,13724,13782,13783, + 13785,13786,15345,17224,17225,17500,18104, + 19788,19812,19813,19814,19999,20000,24465, + 24554,26000,27000,27001,27002,27003,27004, + 27005,27006,27007,27008,27009,28000}; + + return (reservedPorts.find(port) != reservedPorts.end()); + } + boost::asio::ip::address_v6 GetYggdrasilAddress () { #if defined(_WIN32) diff --git a/libi2pd/util.h b/libi2pd/util.h index 248c2bad..7ba24694 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -224,6 +224,7 @@ namespace util bool IsLocalAddress (const boost::asio::ip::address& addr); bool IsInReservedRange (const boost::asio::ip::address& host); bool IsYggdrasilAddress (const boost::asio::ip::address& addr); + bool IsPortInReservedRange (const uint16_t port) noexcept; } } } From 76d39cc7c9fe5d26ebd37d2746c622ec7c1b6b98 Mon Sep 17 00:00:00 2001 From: weko Date: Tue, 14 Feb 2023 20:03:04 +0300 Subject: [PATCH 0106/1160] changed to tabs, move tor port to function --- libi2pd/RouterContext.cpp | 9 ++++----- libi2pd/util.cpp | 27 ++++++++++++++------------- libi2pd/util.h | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a0a0ab06..72b723ea 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -204,12 +204,11 @@ namespace i2p { uint16_t port; do - { - port = rand () % (30777 - 9111) + 9111; // I2P network ports range - } - while(i2p::util::net::IsPortInReservedRange(port)); + { + port = rand () % (30777 - 9111) + 9111; // I2P network ports range + } + while(i2p::util::net::IsPortInReservedRange(port)); - if (port == 9150) port = 9151; // Tor browser return port; } diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 48a8fab3..369f999e 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -488,20 +488,21 @@ namespace net return IsYggdrasilAddress (addr.to_v6 ().to_bytes ().data ()); } - bool IsPortInReservedRange (const uint16_t port) noexcept - { - static const std::unordered_set reservedPorts{ - 9119,9306,9312,9389,9418,9535,9536,9695, - 9800,9899,10000,10050,10051,10110,10212, - 10933,11001,11112,11235,11371,12222,12223, - 13075,13400,13720,13721,13724,13782,13783, - 13785,13786,15345,17224,17225,17500,18104, - 19788,19812,19813,19814,19999,20000,24465, - 24554,26000,27000,27001,27002,27003,27004, - 27005,27006,27007,27008,27009,28000}; + bool IsPortInReservedRange (const uint16_t port) noexcept + { + // https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers (Feb. 3, 2023) + Tor browser (9150) + static const std::unordered_set reservedPorts{ + 9119,9150,9306,9312,9389,9418,9535,9536,9695, + 9800,9899,10000,10050,10051,10110,10212, + 10933,11001,11112,11235,11371,12222,12223, + 13075,13400,13720,13721,13724,13782,13783, + 13785,13786,15345,17224,17225,17500,18104, + 19788,19812,19813,19814,19999,20000,24465, + 24554,26000,27000,27001,27002,27003,27004, + 27005,27006,27007,27008,27009,28000}; - return (reservedPorts.find(port) != reservedPorts.end()); - } + return (reservedPorts.find(port) != reservedPorts.end()); + } boost::asio::ip::address_v6 GetYggdrasilAddress () { diff --git a/libi2pd/util.h b/libi2pd/util.h index 7ba24694..e2037212 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -224,7 +224,7 @@ namespace util bool IsLocalAddress (const boost::asio::ip::address& addr); bool IsInReservedRange (const boost::asio::ip::address& host); bool IsYggdrasilAddress (const boost::asio::ip::address& addr); - bool IsPortInReservedRange (const uint16_t port) noexcept; + bool IsPortInReservedRange (const uint16_t port) noexcept; } } } From 77142e59eee1058e09d65618bb2132a342721cb8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 14 Feb 2023 18:51:14 +0000 Subject: [PATCH 0107/1160] [http] fix query detection, addresshelper processing, update tests Signed-off-by: R4SAS --- libi2pd/HTTP.h | 2 +- libi2pd_client/HTTPProxy.cpp | 28 ++++++++++++++++++++++++++-- tests/Makefile | 34 +++++++++++++++++++++++----------- tests/test-http-url.cpp | 9 +++++++++ 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index 9b8788ec..f9d5d009 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -37,7 +37,7 @@ namespace http std::string query; std::string frag; - URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), query(""), frag("") {}; + URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag("") {}; /** * @brief Tries to parse url from string diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index b8ecd199..3e5ab595 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -238,9 +238,33 @@ namespace proxy { std::string value = params["i2paddresshelper"]; len += value.length(); b64 = i2p::http::UrlDecode(value); + // if we need update exists, request formed with update param - if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; } - if (pos != 0 && url.query[pos-1] == '&') { pos--; len++; } // if helper is not only one query option + if (params["update"] == "true") + { + len += std::strlen("&update=true"); + confirm = true; + } + + // if helper is not only one query option and it placed after user's query + if (pos != 0 && url.query[pos-1] == '&') + { + pos--; + len++; + } + // if helper is not only one query option and it placed before user's query + else if (pos == 0 && url.query.length () > len && url.query[len] == '&') + { + // we don't touch the '?' but remove the trailing '&' + len++; + } + else + { + // there is no more query options, resetting hasquery flag + url.hasquery = false; + } + + // reset hasquery flag and remove addresshelper from URL url.query.replace(pos, len, ""); return true; } diff --git a/tests/Makefile b/tests/Makefile index db71a06e..9c5711e2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,3 +1,5 @@ +SYS := $(shell $(CXX) -dumpmachine) + CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -DOPENSSL_SUPPRESS_DEPRECATED -pthread -Wl,--unresolved-symbols=ignore-in-object-files INCFLAGS += -I../libi2pd @@ -7,41 +9,51 @@ TESTS = \ test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \ test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator +ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS))) + CXXFLAGS += -DWIN32_LEAN_AND_MEAN + LDFLAGS += -mwindows -static + BOOST_SUFFIX = -mt + NEEDED_LDLIBS = -lwsock32 -lws2_32 -lgdi32 -liphlpapi -lole32 +endif + LDLIBS = \ - -lcrypto \ + -lboost_filesystem$(BOOST_SUFFIX) \ + -lboost_program_options$(BOOST_SUFFIX) \ -lssl \ - -lboost_filesystem \ - -lboost_program_options \ + -lcrypto \ + -lz \ + $(NEEDED_LDLIBS) \ -lpthread + all: $(TESTS) run $(LIBI2PD): @echo "Building libi2pd.a ..." && cd .. && $(MAKE) libi2pd.a test-http-%: test-http-%.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-base-%: test-base-%.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-gost: test-gost.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-gost-sig: test-gost-sig.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-x25519: test-x25519.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-aeadchacha20poly1305: test-aeadchacha20poly1305.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-blinding: test-blinding.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) test-elligator: test-elligator.cpp $(LIBI2PD) - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(LDLIBS) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) run: $(TESTS) @for TEST in $(TESTS); do echo Running $$TEST; ./$$TEST ; done diff --git a/tests/test-http-url.cpp b/tests/test-http-url.cpp index 1759a3a8..a5021c43 100644 --- a/tests/test-http-url.cpp +++ b/tests/test-http-url.cpp @@ -15,6 +15,7 @@ int main() { assert(url->host == "127.0.0.1"); assert(url->port == 7070); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == "12345"); assert(url->to_string() == "https://127.0.0.1:7070/asdasd?12345"); delete url; @@ -27,6 +28,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 8080); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == "123456"); delete url; @@ -38,6 +40,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 0); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == "name=value"); delete url; @@ -49,6 +52,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 0); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == "name=value1&name=value2"); delete url; @@ -60,6 +64,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 0); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == "name1=value1&name2&name3=value2"); assert(url->parse_query(params)); assert(params.size() == 3); @@ -79,6 +84,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 800); assert(url->path == "/asdasd"); + assert(url->hasquery == true); assert(url->query == ""); delete url; @@ -90,6 +96,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 17); assert(url->path == ""); + assert(url->hasquery == false); assert(url->query == ""); delete url; @@ -101,6 +108,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 0); assert(url->path == ""); + assert(url->hasquery == false); assert(url->query == ""); delete url; @@ -112,6 +120,7 @@ int main() { assert(url->host == "site.com"); assert(url->port == 84); assert(url->path == "/asdasd/@17"); + assert(url->hasquery == false); assert(url->query == ""); assert(url->frag == "frag"); delete url; From 02a36a9fa81e5734938749136f783b7075f90868 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Feb 2023 15:44:35 -0500 Subject: [PATCH 0108/1160] don't populate buffer of unreachable router --- libi2pd/NetDb.cpp | 10 +++++----- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterInfo.cpp | 2 ++ libi2pd/SSU2Session.cpp | 11 +++++------ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 694eb7c4..34ad5efc 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1043,8 +1043,7 @@ namespace data if (router && !router->IsUnreachable ()) { LogPrint (eLogDebug, "NetDb: Requested RouterInfo ", key, " found"); - PopulateRouterInfoBuffer (router); - if (router->GetBuffer ()) + if (PopulateRouterInfoBuffer (router)) replyMsg = CreateDatabaseStoreMsg (router); } } @@ -1481,10 +1480,11 @@ namespace data m_LeasesPool.CleanUpMt (); } - void NetDb::PopulateRouterInfoBuffer (std::shared_ptr r) + bool NetDb::PopulateRouterInfoBuffer (std::shared_ptr r) { - if (!r || r->GetBuffer ()) return; - r->LoadBuffer (m_Storage.Path (r->GetIdentHashBase64 ())); + if (!r) return false; + if (r->GetBuffer ()) return true; + return r->LoadBuffer (m_Storage.Path (r->GetIdentHashBase64 ())); } } } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 599a2bff..f0315582 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -124,7 +124,7 @@ namespace data void ClearRouterInfos () { m_RouterInfos.clear (); }; std::shared_ptr NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); }; - void PopulateRouterInfoBuffer (std::shared_ptr r); + bool PopulateRouterInfoBuffer (std::shared_ptr r); std::shared_ptr NewRouterInfoAddress () { return m_RouterInfoAddressesPool.AcquireSharedMt (); }; boost::shared_ptr NewRouterInfoAddresses () { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3cf79f11..afa8cbe0 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -589,6 +589,8 @@ namespace data { if (LoadFile (fullPath)) LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file"); + else + return nullptr; } return m_Buffer->data (); } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index e45a33a2..f2b002cd 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1872,10 +1872,9 @@ namespace transport // send relay intro to Charlie auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI - if (r) - i2p::data::netdb.PopulateRouterInfoBuffer (r); - else - LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found"); + if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; + if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found"); + uint8_t payload[SSU2_MAX_PACKET_SIZE]; size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0; if (!payloadSize && r) @@ -2069,7 +2068,7 @@ namespace transport auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); // Alice's RouterInfo auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); - if (r) i2p::data::netdb.PopulateRouterInfoBuffer (r); + if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0; if (!packet->payloadSize && r) session->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); @@ -2173,7 +2172,7 @@ namespace transport uint8_t payload[SSU2_MAX_PACKET_SIZE]; // Charlie's RouterInfo auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); - if (r) i2p::data::netdb.PopulateRouterInfoBuffer (r); + if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0; if (!payloadSize && r) it->second.first->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); From fa286a6fb3dd3c0d1621abf9282b835da9c00a48 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Feb 2023 19:49:29 -0500 Subject: [PATCH 0109/1160] faster GetBit --- libi2pd/Tag.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index d0b0c056..72f181a2 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -83,8 +83,8 @@ namespace data { uint8_t GetBit (int i) const { int pos = i >> 3; // /8 - if (pos >= sz) return 0; - return m_Buf[pos] & (1 << (7 - (i & 0x07))); + if (pos >= (int)sz) return 0; + return m_Buf[pos] & (0x80 >> (i & 0x07)); } private: From c6c71916823246cccfb379bece2f0912402824e7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 15 Feb 2023 17:55:16 +0000 Subject: [PATCH 0110/1160] [debian] exclude parallel flag, remove conffiles Signed-off-by: R4SAS --- debian/conffiles | 2 -- debian/rules | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 debian/conffiles diff --git a/debian/conffiles b/debian/conffiles deleted file mode 100644 index 6894732c..00000000 --- a/debian/conffiles +++ /dev/null @@ -1,2 +0,0 @@ -/etc/i2pd/i2pd.conf -/etc/i2pd/tunnels.conf diff --git a/debian/rules b/debian/rules index 11791d9b..fc769066 100755 --- a/debian/rules +++ b/debian/rules @@ -8,6 +8,6 @@ export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = %: - dh $@ --parallel + dh $@ override_dh_auto_install: From 359781c69881688d4a4c58e3ab60f620ebefeeba Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 15 Feb 2023 17:56:44 +0000 Subject: [PATCH 0111/1160] [webconsole] streams table little fix Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 2f846257..f78057b3 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -554,7 +554,7 @@ namespace http { << tr("Streams") << "\r\n\r\n" << "StreamID" - << "" // Stream closing button column + << " " // Stream closing button column << "Destination" << "Sent" << "Received" From 385e592045898191eb26fd786d23676a92851d4b Mon Sep 17 00:00:00 2001 From: barracuda156 Date: Wed, 15 Feb 2023 11:55:13 +0800 Subject: [PATCH 0112/1160] TargetArch.cmake: fix info re OSX arch support, update copyright year --- build/cmake_modules/TargetArch.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build/cmake_modules/TargetArch.cmake b/build/cmake_modules/TargetArch.cmake index ac7275b1..d59925c8 100644 --- a/build/cmake_modules/TargetArch.cmake +++ b/build/cmake_modules/TargetArch.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The PurpleI2P Project +# Copyright (c) 2017-2023, 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 @@ -83,13 +83,13 @@ function(target_architecture output_var) # First let's normalize the order of the values # Note that it's not possible to compile PowerPC applications if you are using - # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we - # disable it by default + # the OS X SDK version 10.7 or later - you'll need 10.4/10.5/10.6 for that, so we + # disable it by default. Also, ppc64 is not supported in 10.6. # See this page for more information: # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. - # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. + # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise; 10.6 also supports ppc. foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) if("${osx_arch}" STREQUAL "ppc" AND ppc_support) @@ -133,11 +133,11 @@ function(target_architecture output_var) enable_language(C) # Detect the architecture in a rather creative way... - # This compiles a small C program which is a series of ifdefs that selects a - # particular #error preprocessor directive whose message string contains the - # target architecture. The program will always fail to compile (both because - # file is not a valid C program, and obviously because of the presence of the - # #error preprocessor directives... but by exploiting the preprocessor in this + # This compiles a small C program which is a series of ifdefs that selects + # a particular #error preprocessor directive whose message string contains + # the target architecture. The program will always fail to compile (both because + # file is not a valid C program, and obviously because of the presence of + # the #error preprocessor directives... but by exploiting the preprocessor in this # way, we can detect the correct target architecture even when cross-compiling, # since the program itself never needs to be run (only the compiler/preprocessor) try_run( From 00c75a7afa2124cb634f7d93e2c27c0ef2ec7f94 Mon Sep 17 00:00:00 2001 From: barracuda156 Date: Wed, 15 Feb 2023 12:04:30 +0800 Subject: [PATCH 0113/1160] CMakeLists.txt: update comment re Boost and atomics on PPC --- build/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d9c50e9c..f6f52001 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -178,6 +178,7 @@ endif() # Use std::atomic instead of GCC builtins on macOS PowerPC: # For more information refer to: https://github.com/PurpleI2P/i2pd/issues/1726#issuecomment-1306335111 +# This has been fixed in Boost 1.81, nevertheless we retain the setting for the sake of compatibility. if(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc") add_definitions(-DBOOST_SP_USE_STD_ATOMIC) endif() From 182a721674748adf23cb258d278cced6f0fb6d35 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 15 Feb 2023 14:47:02 -0500 Subject: [PATCH 0114/1160] 2.46.0 --- ChangeLog | 30 ++++++++++++++++++++++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16cb6d6b..ff3f9697 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,36 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.46.0] - 2023-02-15 +### Added +- Limit number of acked SSU2 packets to 511 +- Localization to Swedish +- Periodically send Datetime block in NTCP2 and SSU2 +- Don't select random port from reserved +- In memory table for peer profiles +- Store if router was unreachable in it's peer profile +- Show IPv6 addresses in square brackets in webconsole +### Changed +- Algorithm for tunnel creation success rate calculation +- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint' +- Exclude actually unreachable router from netdb for 2 hours +- Select first hop from high bandwidth peers for client tunnels +- Drop too long or too short LeaseSet +- Delete router from netdb if became inavlid after update +- Terminate existing session if clock skew detected +- Close previous UDP socket if open before reopening +- Minimal version for floodfill is 0.9.51 +- Sort transports by endpoints in webconsole +### Fixed +- Deadlock druing processing I2NP block with Garlic in ECIES encrypted message to router +- Race condition with encrypted LeaseSets +- HTTP query detection +- Connection attempts to IPs from invalid ranges +- Publish "0.0.0.0" in RouterInfo +- Crash upon receiving PeerTest 7 +- Tunnels for closed SAM session socket +- Missing NTCP2 address in RouterInfo if enabled back + ## [2.45.1] - 2023-01-11 ### Added - Full Cone NAT status error diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 79d591ac..e902d1fd 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.45.1 +Version: 2.46.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Feb 15 2023 orignal - 2.46.0 +- update to 2.46.0 + * Wed Jan 11 2023 orignal - 2.45.1 - update to 2.45.1 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 07ecfbcc..5ddd8727 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.45.1 +Version: 2.46.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Feb 15 2023 orignal - 2.46.0 +- update to 2.46.0 + * Wed Jan 11 2023 orignal - 2.45.1 - update to 2.45.1 diff --git a/debian/changelog b/debian/changelog index d4464668..5408d4d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.46.0-1) unstable; urgency=medium + + * updated to version 2.46.0/0.9.57 + + -- orignal Wed, 15 Feb 2023 19:00:00 +0000 + i2pd (2.45.1-1) unstable; urgency=medium * updated to version 2.45.1/0.9.57 diff --git a/libi2pd/version.h b/libi2pd/version.h index 65ca1fc4..e1206d21 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -16,8 +16,8 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 45 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MINOR 46 +#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION GITVER From e53fe2d988e9158d228dbb97a08486ef134c5484 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 15 Feb 2023 20:39:18 +0000 Subject: [PATCH 0115/1160] 2.46.0 Signed-off-by: R4SAS --- ChangeLog | 19 ++++++++++--------- debian/changelog | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff3f9697..4606a69b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,26 +3,27 @@ ## [2.46.0] - 2023-02-15 ### Added -- Limit number of acked SSU2 packets to 511 +- Limit number of acked SSU2 packets to 511 - Localization to Swedish - Periodically send Datetime block in NTCP2 and SSU2 - Don't select random port from reserved - In memory table for peer profiles - Store if router was unreachable in it's peer profile - Show IPv6 addresses in square brackets in webconsole +- Check referer when processing Addresshelper ### Changed - Algorithm for tunnel creation success rate calculation -- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint' +- Drop incoming NTCP2 and SSU2 connection if published IP doesn't match actual endpoint - Exclude actually unreachable router from netdb for 2 hours -- Select first hop from high bandwidth peers for client tunnels +- Select first hop from high bandwidth peers for client tunnels - Drop too long or too short LeaseSet -- Delete router from netdb if became inavlid after update +- Delete router from netdb if became invalid after update - Terminate existing session if clock skew detected -- Close previous UDP socket if open before reopening +- Close previous UDP socket if open before reopening - Minimal version for floodfill is 0.9.51 -- Sort transports by endpoints in webconsole -### Fixed -- Deadlock druing processing I2NP block with Garlic in ECIES encrypted message to router +- Sort transports by endpoints in webconsole +### Fixed +- Deadlock during processing I2NP block with Garlic in ECIES encrypted message to router - Race condition with encrypted LeaseSets - HTTP query detection - Connection attempts to IPs from invalid ranges @@ -39,7 +40,7 @@ - Set rejection code 30 if tunnel with id already exists - Network status is always OK if peer test msg 5 received ### Fixed -- UPnP crash if SSU2 or NTCP2 is disabled +- UPnP crash if SSU2 or NTCP2 is disabled - Crash on termination for some platforms ## [2.45.0] - 2023-01-03 diff --git a/debian/changelog b/debian/changelog index 5408d4d0..91d8f1dc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -i2pd (2.46.0-1) unstable; urgency=medium +i2pd (2.46.0-1) unstable; urgency=high * updated to version 2.46.0/0.9.57 From a1fb97cfad9ca63ba4cf5a3cf135da24bf1d5ac8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 16 Feb 2023 00:42:31 +0300 Subject: [PATCH 0116/1160] [i18n] update and add Polish, Portuguese, Turkish Signed-off-by: R4SAS --- contrib/i18n/README.md | 58 +++++------ i18n/Armenian.cpp | 53 ++++------ i18n/Chinese.cpp | 78 ++++++++------- i18n/Czech.cpp | 44 +++------ i18n/French.cpp | 64 ++++++------ i18n/German.cpp | 44 +++------ i18n/I18N_langs.h | 36 ++++--- i18n/Italian.cpp | 49 ++++----- i18n/Polish.cpp | 59 +++++++++++ i18n/Portuguese.cpp | 219 +++++++++++++++++++++++++++++++++++++++++ i18n/Russian.cpp | 60 +++++------ i18n/Spanish.cpp | 44 +++------ i18n/Swedish.cpp | 55 +++++------ i18n/Turkish.cpp | 114 +++++++++++++++++++++ i18n/Turkmen.cpp | 45 ++++----- i18n/Ukrainian.cpp | 60 +++++------ i18n/Uzbek.cpp | 60 +++++------ 17 files changed, 744 insertions(+), 398 deletions(-) create mode 100644 i18n/Polish.cpp create mode 100644 i18n/Portuguese.cpp create mode 100644 i18n/Turkish.cpp diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md index 57021f60..56d76c5a 100644 --- a/contrib/i18n/README.md +++ b/contrib/i18n/README.md @@ -1,29 +1,29 @@ -`xgettext` command for extracting translation ---- - -``` -xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp -``` - -Regex for transforming gettext translations to our format: ---- - -``` -in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? -out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n -``` - -``` -in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n -out: {"$1", "$2"},\n -``` - -``` -in: ^#[:.](.*)$\n -out: -``` - -``` -in: \n\n -out: \n -``` +`xgettext` command for extracting translation +--- + +``` +xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp +``` + +Regex for transforming gettext translations to our format: +--- + +``` +in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? +out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n +``` + +``` +in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n +out: {"$1", "$2"},\n +``` + +``` +in: ^#[:.,](.*)$\n +out: +``` + +``` +in: \n\n +out: \n +``` diff --git a/i18n/Armenian.cpp b/i18n/Armenian.cpp index a18d35fc..b99e5032 100644 --- a/i18n/Armenian.cpp +++ b/i18n/Armenian.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -40,6 +40,7 @@ namespace armenian // language namespace {"established", "կարգավոյված է"}, {"unknown", "անհայտ"}, {"exploratory", "հետազոտոկան"}, + {"Purple I2P Webconsole", "Վեբ-կոնսոլ Purple I2P"}, {"i2pd webconsole", "Վեբ-կոնսոլ i2pd"}, {"Main page", "Գլխավոր էջ"}, {"Router commands", "Երթուղիչի հրահանգներ"}, @@ -57,10 +58,10 @@ namespace armenian // language namespace {"Unknown", "Անհայտ"}, {"Proxy", "Պրոկսի"}, {"Mesh", "MESH-ցանց"}, - {"Error", "Սխալ"}, {"Clock skew", "Ոչ ճշգրիտ ժամանակ"}, {"Offline", "Օֆլայն"}, {"Symmetric NAT", "Սիմետրիկ NAT"}, + {"Full cone NAT", "Full cone NAT"}, {"Uptime", "Առկայություն"}, {"Network status", "Ցանցի կարգավիճակ"}, {"Network status v6", "Ցանցի կարգավիճակ v6"}, @@ -89,7 +90,7 @@ namespace armenian // language namespace {"Address registration line", "Հասցեի գրանցման տող"}, {"Domain", "Տիրույթ"}, {"Generate", "Գեներացնել"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", " Նշում. արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", " Նշում. արդյունքի տողը կարող է օգտագործվել միայն 2LD տիրույթներ գրանցելու համար (example.i2p): Ենթատիրույթներ գրանցելու համար խնդրում ենք օգտագործել i2pd-tools գործիքակազմը:"}, {"Address", "Հասցե"}, {"Type", "Տեսակը"}, {"EncType", "Գաղտնագրի տեսակը"}, @@ -112,11 +113,10 @@ namespace armenian // language namespace {"Invalid", "Անվավեր"}, {"Store type", "Պահեստավորման տեսակը"}, {"Expires", "Սպառվում է"}, - {"Non Expired Leases", "Չսպառված Lease-եր"}, + {"Non Expired Leases", "Չսպառված Lease-եր"}, {"Gateway", "Դարպաս"}, {"TunnelID", "Թունելի ID"}, {"EndDate", "Ավարտ"}, - {"not floodfill", "ոչ floodfill-ներ"}, {"Queue size", "Հերթի չափսը"}, {"Run peer test", "Գործարկել փորձարկումը"}, {"Decline transit tunnels", "Մերժել տարանցիկ թունելներ"}, @@ -146,10 +146,7 @@ namespace armenian // language namespace {"Destination not found", "Հասցեի վայրը չի գտնվել"}, {"StreamID can't be null", "StreamID-ն չի կարող լինել դատարկ"}, {"Return to destination page", "Վերադառնալ նախորդ էջի հասցե"}, - {"You will be redirected in 5 seconds", "Դուք կտեղափոխվեք 5 վայրկյանից"}, - {"Transit tunnels count must not exceed 65535", "Տարանցիկ թունելների քանակը չպետք է գերազանցի 65535-ը"}, {"Back to commands list", "Վերադառնալ հրահանգների ցուցակ"}, - {"Register at reg.i2p", "Գրանցել reg.i2p-ում"}, {"Description", "Նկարագրություն"}, {"A bit information about service on domain", "Մի փոքր տեղեկատվություն տիրոիյթում գտնվող ծառայության մասին"}, {"Submit", "Ուղարկվել"}, @@ -165,34 +162,26 @@ namespace armenian // language namespace {"You may try to find this host on jump services below", "Ստորև Դուք կարող եք գտնել այս հոսթը jump ծառայությունների միջոցով"}, {"Invalid request", "Սխալ հարցում"}, {"Proxy unable to parse your request", "Պրոկսին չի կարող հասկանալ Ձեր հարցումը"}, - {"addresshelper is not supported", "addresshelper-ը համատեղելի չէ"}, - {"Host", "Հոսթ"}, - {"added to router's addressbook from helper", "Ավելացված է երթուղիչի հասցեագրքում helper-ի միջոցով"}, - {"Click here to proceed:", "Շարունակելու համար սեղմեք այստեղ"}, - {"Continue", "Շարունակել"}, - {"Addresshelper found", "addresshelper-ը գնտված է"}, - {"already in router's addressbook", "արդեն առկա է երթուղիչի հասցեագրքում"}, - {"Click here to update record:", "Սեղմեկ այստեղ որպեսզի թարվացնեք գրառումը"}, - {"invalid request uri", "Սխալ ձևավորված URI հարցում"}, + {"Invalid request URI", "Սխալ ձևավորված URI հարցում"}, {"Can't detect destination host from request", "Չհաջողվեց հայնտաբերեկ վայրի հասցեն նշված հարցմամբ"}, {"Outproxy failure", "Սխալ արտաքին պրոքսի"}, - {"bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"}, - {"not inside I2P network, but outproxy is not enabled", "Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"}, - {"unknown outproxy url", "արտաքին պրոքսիի անհայտ URL"}, - {"cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"}, - {"hostname too long", "Հոսթի անունը չափազանց երկար է"}, - {"cannot connect to upstream socks proxy", "չհաջողվեց միանալ վերադաս socks պրոկսիին"}, - {"Cannot negotiate with socks proxy", "Չհաջողվեց պայմանավորվել վերադաս socks պրոկսիի հետ"}, + {"Bad outproxy settings", "Սխալ արտաքին պրոկսի կարգավորումներ"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Հոսթ %s Հարցումը I2P ցանցից դուրս է, բայց արտաքին պրոքսին միացված չէ"}, + {"Unknown outproxy URL", "Արտաքին պրոքսիի անհայտ URL"}, + {"Cannot resolve upstream proxy", "Չհաջողվեց որոշել վերադաս պրոկսին"}, + {"Hostname is too long", "Հոսթի անունը չափազանց երկար է"}, + {"Cannot connect to upstream SOCKS proxy", "Չհաջողվեց միանալ վերադաս SOCKS պրոկսի սերվերին"}, + {"Cannot negotiate with SOCKS proxy", "Չհաջողվեց պայմանավորվել վերադաս SOCKS պրոկսիի հետ"}, {"CONNECT error", "Սխալ CONNECT հարցում"}, - {"Failed to Connect", "Միանալ չhաջողվեց"}, - {"socks proxy error", "Սխալ SOCKS պրոկսի"}, - {"failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"}, - {"No Reply From socks proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"}, - {"cannot connect", "Հնարավոր չե միանալ"}, - {"http out proxy not implemented", "Արտաքին http պրոկսին դեռ իրականացված չէ"}, - {"cannot connect to upstream http proxy", "Չհաջողվեց միանալ վերադաս http պրոկսի սերվերին"}, + {"Failed to connect", "Միանալ չhաջողվեց"}, + {"SOCKS proxy error", "Սխալ SOCKS պրոկսի"}, + {"Failed to send request to upstream", "Չհաջողվեց հարցումն ուղարկել վերադաս պրոկսիին"}, + {"No reply from SOCKS proxy", "Բացակայում է պատասխանը SOCKS պրոկսի սերվերի կողմից"}, + {"Cannot connect", "Հնարավոր չե միանալ"}, + {"HTTP out proxy not implemented", "Արտաքին HTTP պրոկսին դեռ իրականացված չէ"}, + {"Cannot connect to upstream HTTP proxy", "Չհաջողվեց միանալ վերադաս HTTP պրոկսի սերվերին"}, {"Host is down", "Հոսթն անհասանելի է"}, - {"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Հոսթի հետ կապը հաստատել չհաջողվեց, հնարավոր է այն անջատված է, փորձեք միանալ քիչ ուշ:"}, {"", ""}, }; diff --git a/i18n/Chinese.cpp b/i18n/Chinese.cpp index 8a554a11..cd38fa0f 100644 --- a/i18n/Chinese.cpp +++ b/i18n/Chinese.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -13,7 +13,6 @@ #include "I18N.h" // Simplified Chinese localization file -// This is an example translation file without strings in it. namespace i2p { @@ -46,7 +45,7 @@ namespace chinese // language namespace {"Main page", "主页"}, {"Router commands", "路由命令"}, {"Local Destinations", "本地目标"}, - {"LeaseSets", "租契集"}, + {"LeaseSets", "租约集"}, {"Tunnels", "隧道"}, {"Transit Tunnels", "中转隧道"}, {"Transports", "传输"}, @@ -58,11 +57,12 @@ namespace chinese // language namespace {"Firewalled", "受到防火墙限制"}, {"Unknown", "未知"}, {"Proxy", "代理"}, - {"Mesh", "Mesh组网"}, - {"Error", "错误"}, + {"Mesh", "自组网"}, {"Clock skew", "时钟偏移"}, {"Offline", "离线"}, {"Symmetric NAT", "对称 NAT"}, + {"Full cone NAT", "全锥型NAT"}, + {"No Descriptors", "无描述符"}, {"Uptime", "运行时间"}, {"Network status", "IPv4 网络状态"}, {"Network status v6", "IPv6 网络状态"}, @@ -91,12 +91,12 @@ namespace chinese // language namespace {"Address registration line", "地址域名注册"}, {"Domain", "域名"}, {"Generate", "生成"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "注意: 结果字符串只能用于注册次级域名(例如:example.i2p)。若需注册子域名,请使用 i2pd-tools。"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "注意: 结果字符串只能用于注册二级域名(例如:example.i2p)。若需注册三级域名,请使用 i2pd-tools。"}, {"Address", "地址"}, {"Type", "类型"}, {"EncType", "加密类型"}, {"Inbound tunnels", "入站隧道"}, - {"%dms", "%d毫秒"}, + {"%dms", "%dms"}, {"Outbound tunnels", "出站隧道"}, {"Tags", "标签"}, {"Incoming", "传入"}, @@ -118,9 +118,10 @@ namespace chinese // language namespace {"Gateway", "网关"}, {"TunnelID", "隧道 ID"}, {"EndDate", "结束日期"}, - {"not floodfill", "非洪泛"}, + {"floodfill mode is disabled", "洪泛已禁用"}, {"Queue size", "队列大小"}, {"Run peer test", "运行节点测试"}, + {"Reload tunnels configuration", "重新载入隧道配置"}, {"Decline transit tunnels", "拒绝中转隧道"}, {"Accept transit tunnels", "允许中转隧道"}, {"Cancel graceful shutdown", "取消平滑关闭"}, @@ -128,7 +129,7 @@ namespace chinese // language namespace {"Force shutdown", "强制停止"}, {"Reload external CSS styles", "重载外部 CSS 样式"}, {"Note: any action done here are not persistent and not changes your config files.", "注意: 此处完成的任何操作都不是永久的,不会更改您的配置文件。"}, - {"Logging level", "日志记录级别"}, + {"Logging level", "日志级别"}, {"Transit tunnels limit", "中转隧道限制"}, {"Change", "修改"}, {"Change language", "更改语言"}, @@ -148,8 +149,8 @@ namespace chinese // language namespace {"Destination not found", "找不到目标"}, {"StreamID can't be null", "StreamID 不能为空"}, {"Return to destination page", "返回目标页面"}, - {"You will be redirected in 5 seconds", "您将在5秒内被重定向"}, - {"Transit tunnels count must not exceed 65535", "中转隧道数量不能超过 65535"}, + {"You will be redirected in %d seconds", "您将在%d秒内被重定向"}, + {"Transit tunnels count must not exceed %d", "中转隧道数量限制为 %d"}, {"Back to commands list", "返回命令列表"}, {"Register at reg.i2p", "在 reg.i2p 注册域名"}, {"Description", "描述"}, @@ -164,35 +165,36 @@ namespace chinese // language namespace {"Proxy info", "代理信息"}, {"Proxy error: Host not found", "代理错误:未找到主机"}, {"Remote host not found in router's addressbook", "在路由地址簿中未找到远程主机"}, - {"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到该主机"}, + {"You may try to find this host on jump services below", "您可以尝试在下方的跳转服务中找到此主机"}, {"Invalid request", "无效请求"}, {"Proxy unable to parse your request", "代理无法解析您的请求"}, - {"addresshelper is not supported", "不支持地址助手"}, - {"Host", "主机"}, - {"added to router's addressbook from helper", "将此地址从地址助手添加到路由地址簿"}, - {"Click here to proceed:", "点击此处继续:"}, - {"Continue", "继续"}, - {"Addresshelper found", "已找到地址助手"}, - {"already in router's addressbook", "已在路由地址簿中"}, - {"Click here to update record:", "点击此处更新地址簿记录"}, - {"invalid request uri", "无效的 URL 请求"}, + {"Addresshelper is not supported", "不支持地址助手"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "主机 %s 已在路由地址簿中请注意:此地址的来源可能是有害的!点击此处更新记录:继续"}, + {"Addresshelper forced update rejected", "地址助手强制更新被拒绝"}, + {"To add host %s in router's addressbook, click here: Continue.", "若要在路由器地址簿中添加主机 %s 请点击这里: 继续"}, + {"Addresshelper request", "请求地址助手"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "主机 %s 已通过地址助手添加到路由地址簿中。点击此处继续:继续"}, + {"Addresshelper adding", "正在添加地址助手"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "主机 %s 已在路由地址簿中。点击此处更新记录:继续"}, + {"Addresshelper update", "更新地址助手"}, + {"Invalid request URI", "无效的 URI 请求"}, {"Can't detect destination host from request", "无法从请求中检测到目标主机"}, {"Outproxy failure", "出口代理故障"}, - {"bad outproxy settings", "错误的出口代理设置"}, - {"not inside I2P network, but outproxy is not enabled", "该地址不在 I2P 网络内,但未启用出口代理"}, - {"unknown outproxy url", "未知的出口代理地址"}, - {"cannot resolve upstream proxy", "无法解析上游代理"}, - {"hostname too long", "主机名过长"}, - {"cannot connect to upstream socks proxy", "无法连接到上游 socks 代理"}, - {"Cannot negotiate with socks proxy", "无法与 socks 代理协商"}, + {"Bad outproxy settings", "错误的出口代理设置"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "主机 %s 不在 I2P 网络内,但出口代理未启用"}, + {"Unknown outproxy URL", "未知的出口代理地址"}, + {"Cannot resolve upstream proxy", "无法解析上游代理"}, + {"Hostname is too long", "主机名过长"}, + {"Cannot connect to upstream SOCKS proxy", "无法连接到上游 SOCKS 代理"}, + {"Cannot negotiate with SOCKS proxy", "无法与 SOCKS 代理协商"}, {"CONNECT error", "连接错误"}, - {"Failed to Connect", "连接失败"}, - {"socks proxy error", "socks 代理错误"}, - {"failed to send request to upstream", "向上游发送请求失败"}, - {"No Reply From socks proxy", "没有来自 socks 代理的回复"}, - {"cannot connect", "无法连接"}, - {"http out proxy not implemented", "http 出口代理未实现"}, - {"cannot connect to upstream http proxy", "无法连接到上游 http 代理"}, + {"Failed to connect", "连接失败"}, + {"SOCKS proxy error", "SOCKS 代理错误"}, + {"Failed to send request to upstream", "向上游发送请求失败"}, + {"No reply from SOCKS proxy", "没有来自 SOCKS 代理的回复"}, + {"Cannot connect", "无法连接"}, + {"HTTP out proxy not implemented", "HTTP 出口代理未实现"}, + {"Cannot connect to upstream HTTP proxy", "无法连接到上游 HTTP 代理"}, {"Host is down", "主机已关闭"}, {"Can't create connection to requested host, it may be down. Please try again later.", "无法创建到目标主机的连接。主机可能已下线,请稍后再试。"}, {"", ""}, @@ -200,9 +202,9 @@ namespace chinese // language namespace static std::map> plurals { - {"%d days", {"%d 日"}}, - {"%d hours", {"%d 时"}}, - {"%d minutes", {"%d 分"}}, + {"%d days", {"%d 天"}}, + {"%d hours", {"%d 小时"}}, + {"%d minutes", {"%d 分钟"}}, {"%d seconds", {"%d 秒"}}, {"", {""}}, }; diff --git a/i18n/Czech.cpp b/i18n/Czech.cpp index 93862053..09a56d50 100644 --- a/i18n/Czech.cpp +++ b/i18n/Czech.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -58,7 +58,6 @@ namespace czech // language namespace {"Unknown", "Neznámý"}, {"Proxy", "Proxy"}, {"Mesh", "Síť"}, - {"Error", "Chyba"}, {"Clock skew", "Časová nesrovnalost"}, {"Offline", "Offline"}, {"Symmetric NAT", "Symetrický NAT"}, @@ -117,7 +116,6 @@ namespace czech // language namespace {"Gateway", "Brána"}, {"TunnelID", "ID tunelu"}, {"EndDate", "Datum ukončení"}, - {"not floodfill", "není floodfill"}, {"Queue size", "Velikost fronty"}, {"Run peer test", "Spustit peer test"}, {"Decline transit tunnels", "Odmítnout tranzitní tunely"}, @@ -147,8 +145,6 @@ namespace czech // language namespace {"Destination not found", "Destinace nenalezena"}, {"StreamID can't be null", "StreamID nemůže být null"}, {"Return to destination page", "Zpět na stránku destinací"}, - {"You will be redirected in 5 seconds", "Budete přesměrováni za 5 vteřin"}, - {"Transit tunnels count must not exceed 65535", "Počet tranzitních tunelů nesmí přesáhnout 65535"}, {"Back to commands list", "Zpět na list příkazů"}, {"Register at reg.i2p", "Zaregistrovat na reg.i2p"}, {"Description", "Popis"}, @@ -166,32 +162,24 @@ namespace czech // language namespace {"You may try to find this host on jump services below", "Můžete se pokusit najít tohoto hostitele na startovacích službách níže"}, {"Invalid request", "Neplatný požadavek"}, {"Proxy unable to parse your request", "Proxy server nemohl zpracovat váš požadavek"}, - {"addresshelper is not supported", "Adresshelper není podporován"}, - {"Host", "Hostitel"}, - {"added to router's addressbook from helper", "přidáno do adresáře routeru od pomocníka"}, - {"Click here to proceed:", "Pro pokračování, klikněte zde:"}, - {"Continue", "Pokračovat"}, - {"Addresshelper found", "Adresář nalezen"}, - {"already in router's addressbook", "je již v adresáři routeru"}, - {"Click here to update record:", "Pro aktualizaci záznamu, klikněte zde:"}, - {"invalid request uri", "neplatný URI požadavek"}, + {"Invalid request URI", "Neplatný URI požadavek"}, {"Can't detect destination host from request", "Nelze zjistit cílového hostitele z požadavku"}, {"Outproxy failure", "Outproxy selhání"}, - {"bad outproxy settings", "špatné outproxy nastavení"}, - {"not inside I2P network, but outproxy is not enabled", "není uvnitř I2P sítě a outproxy není nastavena"}, - {"unknown outproxy url", "neznámá outproxy URL"}, - {"cannot resolve upstream proxy", "nelze rozluštit upstream proxy server"}, - {"hostname too long", "Název hostitele je příliš dlouhý"}, - {"cannot connect to upstream socks proxy", "nelze se připojit k upstream socks proxy serveru"}, - {"Cannot negotiate with socks proxy", "Nelze vyjednávat se socks proxy serverem"}, + {"Bad outproxy settings", "Špatné outproxy nastavení"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Hostitel %s není uvnitř I2P sítě a outproxy není nastavena"}, + {"Unknown outproxy URL", "Neznámá outproxy URL"}, + {"Cannot resolve upstream proxy", "Nelze rozluštit upstream proxy server"}, + {"Hostname is too long", "Název hostitele je příliš dlouhý"}, + {"Cannot connect to upstream SOCKS proxy", "Nelze se připojit k upstream SOCKS proxy serveru"}, + {"Cannot negotiate with SOCKS proxy", "Nelze vyjednávat se SOCKS proxy serverem"}, {"CONNECT error", "Chyba PŘIPOJENÍ"}, - {"Failed to Connect", "Připojení se nezdařilo"}, - {"socks proxy error", "chyba socks proxy serveru"}, - {"failed to send request to upstream", "odeslání žádosti upstream serveru se nezdařilo"}, - {"No Reply From socks proxy", "Žádná odpověď od socks proxy serveru"}, - {"cannot connect", "nelze se připojit"}, - {"http out proxy not implemented", "http out proxy není implementován"}, - {"cannot connect to upstream http proxy", "nelze se připojit k upstream socks proxy serveru"}, + {"Failed to connect", "Připojení se nezdařilo"}, + {"SOCKS proxy error", "Chyba SOCKS proxy serveru"}, + {"Failed to send request to upstream", "Odeslání žádosti upstream serveru se nezdařilo"}, + {"No reply from SOCKS proxy", "Žádná odpověď od SOCKS proxy serveru"}, + {"Cannot connect", "Nelze se připojit"}, + {"HTTP out proxy not implemented", "HTTP out proxy není implementován"}, + {"Cannot connect to upstream HTTP proxy", "Nelze se připojit k upstream HTTP proxy serveru"}, {"Host is down", "Hostitel je nedostupný"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Připojení k požadovanému hostiteli nelze vytvořit, může být nedostupný. Zkuste to, prosím, znovu později."}, {"", ""}, diff --git a/i18n/French.cpp b/i18n/French.cpp index 0d32c5c2..0ce044e1 100644 --- a/i18n/French.cpp +++ b/i18n/French.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -58,10 +58,11 @@ namespace french // language namespace {"Unknown", "Inconnu"}, {"Proxy", "Proxy"}, {"Mesh", "Maillé"}, - {"Error", "Erreur"}, {"Clock skew", "Horloge décalée"}, {"Offline", "Hors ligne"}, {"Symmetric NAT", "NAT symétrique"}, + {"Full cone NAT", "NAT à cône complet"}, + {"No Descriptors", "Aucuns Descripteurs"}, {"Uptime", "Temps de fonctionnement"}, {"Network status", "État du réseau"}, {"Network status v6", "État du réseau v6"}, @@ -69,7 +70,7 @@ namespace french // language namespace {"Family", "Famille"}, {"Tunnel creation success rate", "Taux de succès de création de tunnels"}, {"Received", "Reçu"}, - {"%.2f KiB/s", "%.2f kio/s"}, + {"%.2f KiB/s", "%.2f Kio/s"}, {"Sent", "Envoyé"}, {"Transit", "Transité"}, {"Data path", "Emplacement des données"}, @@ -81,6 +82,7 @@ namespace french // language namespace {"Our external address", "Notre adresse externe"}, {"supported", "supporté"}, {"Routers", "Routeurs"}, + {"Floodfills", "Remplisseurs"}, {"Client Tunnels", "Tunnels clients"}, {"Services", "Services"}, {"Enabled", "Activé"}, @@ -92,6 +94,7 @@ namespace french // language namespace {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Note: La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."}, {"Address", "Adresse"}, {"Type", "Type"}, + {"EncType", "EncType"}, {"Inbound tunnels", "Tunnels entrants"}, {"%dms", "%dms"}, {"Outbound tunnels", "Tunnels sortants"}, @@ -115,8 +118,10 @@ namespace french // language namespace {"Gateway", "Passerelle"}, {"TunnelID", "ID du tunnel"}, {"EndDate", "Date de fin"}, + {"floodfill mode is disabled", "le mode de remplissage est désactivé"}, {"Queue size", "Longueur de la file"}, {"Run peer test", "Lancer test des pairs"}, + {"Reload tunnels configuration", "Recharger la configuration des tunnels"}, {"Decline transit tunnels", "Refuser les tunnels transitoires"}, {"Accept transit tunnels", "Accepter les tunnels transitoires"}, {"Cancel graceful shutdown", "Annuler l'arrêt gracieux"}, @@ -134,6 +139,8 @@ namespace french // language namespace {"SAM session not found", "session SAM introuvable"}, {"SAM Session", "Session SAM"}, {"Server Tunnels", "Tunnels serveurs"}, + {"Client Forwards", "Transmission du client"}, + {"Server Forwards", "Transmission du serveur"}, {"Unknown page", "Page inconnue"}, {"Invalid token", "Jeton invalide"}, {"SUCCESS", "SUCCÈS"}, @@ -142,8 +149,8 @@ namespace french // language namespace {"Destination not found", "Destination introuvable"}, {"StreamID can't be null", "StreamID ne peut pas être vide"}, {"Return to destination page", "Retourner à la page de destination"}, - {"You will be redirected in 5 seconds", "Vous allez être redirigé dans cinq secondes"}, - {"Transit tunnels count must not exceed 65535", "Le nombre de tunnels transitoires ne doit pas dépasser 65535"}, + {"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"}, + {"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"}, {"Back to commands list", "Retour à la liste des commandes"}, {"Register at reg.i2p", "Inscription à reg.i2p"}, {"Description", "Description"}, @@ -161,32 +168,33 @@ namespace french // language namespace {"You may try to find this host on jump services below", "Vous pouvez essayer de trouver cet hôte sur des services de redirection ci-dessous"}, {"Invalid request", "Requête invalide"}, {"Proxy unable to parse your request", "Proxy incapable de comprendre votre requête"}, - {"addresshelper is not supported", "Assistant d'adresse non supporté"}, - {"Host", "Hôte"}, - {"added to router's addressbook from helper", "Ajouté au carnet d'adresse du routeur par l'assistant"}, - {"Click here to proceed:", "Cliquez ici pour continuer:"}, - {"Continue", "Continuer"}, - {"Addresshelper found", "Assistant d'adresse trouvé"}, - {"already in router's addressbook", "déjà dans le carnet d'adresses du routeur"}, - {"Click here to update record:", "Cliquez ici pour mettre à jour le carnet d'adresse:"}, - {"invalid request uri", "uri de la requête invalide"}, + {"Addresshelper is not supported", "Assistant d'adresse non supporté"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Attention : la source de cette URL peut être nuisible ! Cliquez ici pour mettre à jour l'enregistrement : Continuer."}, + {"Addresshelper forced update rejected", "Mise à jour forcée des assistants d'adresses rejetée"}, + {"To add host %s in router's addressbook, click here: Continue.", "Pour ajouter l'hôte %s au carnet d'adresses du routeur, cliquez ici : Continuer."}, + {"Addresshelper request", "Demande à l'assistant d'adresse"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "L'hôte %s a été ajouté au carnet d'adresses du routeur depuis l'assistant. Cliquez ici pour continuer : Continuer."}, + {"Addresshelper adding", "Ajout de l'assistant d'adresse"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Cliquez ici pour mettre à jour le dossier : Continuer."}, + {"Addresshelper update", "Mise à jour de l'assistant d'adresse"}, + {"Invalid request URI", "URI de la requête invalide"}, {"Can't detect destination host from request", "Impossible de détecter l'hôte de destination à partir de la requête"}, {"Outproxy failure", "Échec de proxy de sortie"}, - {"bad outproxy settings", "Mauvaise configuration du proxy de sortie"}, - {"not inside I2P network, but outproxy is not enabled", "pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"}, - {"unknown outproxy url", "URL du proxy de sortie inconnu"}, - {"cannot resolve upstream proxy", "impossible de résoudre l'adresse du proxy en amont"}, - {"hostname too long", "nom d'hôte trop long"}, - {"cannot connect to upstream socks proxy", "impossible de se connecter au proxy socks en amont"}, - {"Cannot negotiate with socks proxy", "Impossible de négocier avec le proxy socks"}, + {"Bad outproxy settings", "Mauvaise configuration du proxy de sortie"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Hôte %s pas dans le réseau I2P, mais le proxy de sortie n'est pas activé"}, + {"Unknown outproxy URL", "URL du proxy de sortie inconnu"}, + {"Cannot resolve upstream proxy", "Impossible de résoudre l'adresse du proxy en amont"}, + {"Hostname is too long", "Nom d'hôte trop long"}, + {"Cannot connect to upstream SOCKS proxy", "Impossible de se connecter au proxy SOCKS en amont"}, + {"Cannot negotiate with SOCKS proxy", "Impossible de négocier avec le proxy SOCKS"}, {"CONNECT error", "Erreur de connexion"}, - {"Failed to Connect", "Échec de connexion"}, - {"socks proxy error", "Erreur de proxy socks"}, - {"failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"}, - {"No Reply From socks proxy", "Pas de réponse du proxy socks"}, - {"cannot connect", "impossible de connecter"}, - {"http out proxy not implemented", "Proxy de sortie HTTP non implémenté"}, - {"cannot connect to upstream http proxy", "impossible de se connecter au proxy HTTP en amont"}, + {"Failed to connect", "Échec de connexion"}, + {"SOCKS proxy error", "Erreur de proxy SOCKS"}, + {"Failed to send request to upstream", "Erreur lors de l'envoie de la requête en amont"}, + {"No reply from SOCKS proxy", "Pas de réponse du proxy SOCKS"}, + {"Cannot connect", "Impossible de connecter"}, + {"HTTP out proxy not implemented", "Proxy de sortie HTTP non implémenté"}, + {"Cannot connect to upstream HTTP proxy", "Impossible de se connecter au proxy HTTP en amont"}, {"Host is down", "Hôte hors service"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Impossible d'établir une connexion avec l'hôte, il est peut-être hors service. Veuillez réessayer plus tard."}, {"", ""}, diff --git a/i18n/German.cpp b/i18n/German.cpp index ca669436..0db3d6be 100644 --- a/i18n/German.cpp +++ b/i18n/German.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -58,7 +58,6 @@ namespace german // language namespace {"Unknown", "Unbekannt"}, {"Proxy", "Proxy"}, {"Mesh", "Mesh"}, - {"Error", "Fehler"}, {"Clock skew", "Zeitabweichung"}, {"Offline", "Offline"}, {"Symmetric NAT", "Symmetrisches NAT"}, @@ -117,7 +116,6 @@ namespace german // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "Enddatum"}, - {"not floodfill", "kein Floodfill"}, {"Queue size", "Größe der Warteschlange"}, {"Run peer test", "Peer-Test durchführen"}, {"Decline transit tunnels", "Transittunnel ablehnen"}, @@ -147,8 +145,6 @@ namespace german // language namespace {"Destination not found", "Ziel nicht gefunden"}, {"StreamID can't be null", "StreamID kann nicht null sein"}, {"Return to destination page", "Zurück zur Ziel-Seite"}, - {"You will be redirected in 5 seconds", "Du wirst in 5 Sekunden weitergeleitet"}, - {"Transit tunnels count must not exceed 65535", "Es darf maximal 65535 Transittunnel geben"}, {"Back to commands list", "Zurück zur Befehlsliste"}, {"Register at reg.i2p", "Auf reg.i2p registrieren"}, {"Description", "Beschreibung"}, @@ -166,32 +162,24 @@ namespace german // language namespace {"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einem der nachfolgenden Jump-Services finden"}, {"Invalid request", "Ungültige Anfrage"}, {"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht verarbeiten"}, - {"addresshelper is not supported", "Addresshelfer wird nicht unterstützt"}, - {"Host", "Host"}, - {"added to router's addressbook from helper", "vom Helfer zum Router-Adressbuch hinzugefügt"}, - {"Click here to proceed:", "Klicke hier um fortzufahren:"}, - {"Continue", "Fortsetzen"}, - {"Addresshelper found", "Adresshelfer gefunden"}, - {"already in router's addressbook", "bereits im Adressbuch des Routers"}, - {"Click here to update record:", "Klicke hier, um den Eintrag zu aktualisieren:"}, - {"invalid request uri", "ungültige Anfrage-URI"}, + {"Invalid request URI", "Ungültige Anfrage-URI"}, {"Can't detect destination host from request", "Kann den Ziel-Host von der Anfrage nicht erkennen"}, {"Outproxy failure", "Outproxy-Fehler"}, - {"bad outproxy settings", "ungültige Outproxy-Einstellungen"}, - {"not inside I2P network, but outproxy is not enabled", "außerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"}, - {"unknown outproxy url", "unbekannte Outproxy-URL"}, - {"cannot resolve upstream proxy", "kann den Upstream-Proxy nicht auflösen"}, - {"hostname too long", "Hostname zu lang"}, - {"cannot connect to upstream socks proxy", "Kann keine Verbindung zum Upstream-Socks-Proxy herstellen"}, - {"Cannot negotiate with socks proxy", "Kann nicht mit Socks-Proxy verhandeln"}, + {"Bad outproxy settings", "Ungültige Outproxy-Einstellungen"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s außerhalb des I2P-Netzwerks, aber Outproxy ist nicht aktiviert"}, + {"Unknown outproxy URL", "Unbekannte Outproxy-URL"}, + {"Cannot resolve upstream proxy", "Kann den Upstream-Proxy nicht auflösen"}, + {"Hostname is too long", "Hostname zu lang"}, + {"Cannot connect to upstream SOCKS proxy", "Kann keine Verbindung zum Upstream-SOCKS-Proxy herstellen"}, + {"Cannot negotiate with SOCKS proxy", "Kann nicht mit SOCKS-Proxy verhandeln"}, {"CONNECT error", "CONNECT-Fehler"}, - {"Failed to Connect", "Verbindung konnte nicht hergestellt werden"}, - {"socks proxy error", "Socks-Proxy-Fehler"}, - {"failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"}, - {"No Reply From socks proxy", "Keine Antwort vom Socks-Proxy"}, - {"cannot connect", "kann nicht verbinden"}, - {"http out proxy not implemented", "HTTP-Outproxy nicht implementiert"}, - {"cannot connect to upstream http proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"}, + {"Failed to connect", "Verbindung konnte nicht hergestellt werden"}, + {"SOCKS proxy error", "SOCKS-Proxy-Fehler"}, + {"Failed to send request to upstream", "Anfrage an den Upstream zu senden ist gescheitert"}, + {"No reply from SOCKS proxy", "Keine Antwort vom SOCKS-Proxy"}, + {"Cannot connect", "Kann nicht verbinden"}, + {"HTTP out proxy not implemented", "HTTP-Outproxy nicht implementiert"}, + {"Cannot connect to upstream HTTP proxy", "Kann nicht zu Upstream-HTTP-Proxy verbinden"}, {"Host is down", "Host ist offline"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Konnte keine Verbindung zum angefragten Host aufbauen, vielleicht ist er offline. Versuche es später noch mal."}, {"", ""}, diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 51e23b19..6426e2ce 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2022, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -23,20 +23,23 @@ namespace i18n }; // Add localization here with language name as namespace - namespace afrikaans { std::shared_ptr GetLocale (); } - namespace armenian { std::shared_ptr GetLocale (); } - namespace chinese { std::shared_ptr GetLocale (); } - namespace czech { std::shared_ptr GetLocale (); } - namespace english { std::shared_ptr GetLocale (); } - namespace french { std::shared_ptr GetLocale (); } - namespace german { std::shared_ptr GetLocale (); } - namespace italian { std::shared_ptr GetLocale (); } - namespace russian { std::shared_ptr GetLocale (); } - namespace spanish { std::shared_ptr GetLocale (); } - namespace swedish { std::shared_ptr GetLocale (); } - namespace turkmen { std::shared_ptr GetLocale (); } - namespace ukrainian { std::shared_ptr GetLocale (); } - namespace uzbek { std::shared_ptr GetLocale (); } + namespace afrikaans { std::shared_ptr GetLocale (); } + namespace armenian { std::shared_ptr GetLocale (); } + namespace chinese { std::shared_ptr GetLocale (); } + namespace czech { std::shared_ptr GetLocale (); } + namespace english { std::shared_ptr GetLocale (); } + namespace french { std::shared_ptr GetLocale (); } + namespace german { std::shared_ptr GetLocale (); } + namespace italian { std::shared_ptr GetLocale (); } + namespace polish { std::shared_ptr GetLocale (); } + namespace portuguese { std::shared_ptr GetLocale (); } + namespace russian { std::shared_ptr GetLocale (); } + namespace spanish { std::shared_ptr GetLocale (); } + namespace swedish { std::shared_ptr GetLocale (); } + namespace turkish { std::shared_ptr GetLocale (); } + namespace turkmen { std::shared_ptr GetLocale (); } + namespace ukrainian { std::shared_ptr GetLocale (); } + namespace uzbek { std::shared_ptr GetLocale (); } /** * That map contains international language name lower-case, name in it's language and it's code @@ -51,9 +54,12 @@ namespace i18n { "french", {"Français", "fr", i2p::i18n::french::GetLocale} }, { "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} }, { "italian", {"Italiano", "it", i2p::i18n::italian::GetLocale} }, + { "polish", {"Polski", "pl", i2p::i18n::polish::GetLocale} }, + { "portuguese", {"Português", "pt", i2p::i18n::portuguese::GetLocale} }, { "russian", {"Русский язык", "ru", i2p::i18n::russian::GetLocale} }, { "spanish", {"Español", "es", i2p::i18n::spanish::GetLocale} }, { "swedish", {"Svenska", "sv", i2p::i18n::swedish::GetLocale} }, + { "turkish", {"Türk dili", "tr", i2p::i18n::turkish::GetLocale} }, { "turkmen", {"Türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, { "ukrainian", {"Украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, { "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} }, diff --git a/i18n/Italian.cpp b/i18n/Italian.cpp index 07e436d7..c51e15a5 100644 --- a/i18n/Italian.cpp +++ b/i18n/Italian.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -58,7 +58,6 @@ namespace italian // language namespace {"Unknown", "Sconosciuto"}, {"Proxy", "Proxy"}, {"Mesh", "Mesh"}, - {"Error", "Errore"}, {"Clock skew", "Orologio disallineato"}, {"Offline", "Disconnesso"}, {"Symmetric NAT", "NAT simmetrico"}, @@ -117,9 +116,9 @@ namespace italian // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "Data di fine"}, - {"not floodfill", "no floodfill"}, {"Queue size", "Dimensione della coda"}, {"Run peer test", "Esegui il test dei peer"}, + {"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"}, {"Decline transit tunnels", "Rifiuta tunnel di transito"}, {"Accept transit tunnels", "Accetta tunnel di transito"}, {"Cancel graceful shutdown", "Annulla l'interruzione controllata"}, @@ -147,8 +146,8 @@ namespace italian // language namespace {"Destination not found", "Destinazione non trovata"}, {"StreamID can't be null", "Lo StreamID non può essere null"}, {"Return to destination page", "Ritorna alla pagina di destinazione"}, - {"You will be redirected in 5 seconds", "Verrai reindirizzato in 5 secondi"}, - {"Transit tunnels count must not exceed 65535", "Il numero di tunnel di transito non può superare i 65535"}, + {"You will be redirected in %d seconds", "Sarai reindirizzato tra %d secondi"}, + {"Transit tunnels count must not exceed %d", "Il conteggio dei tunnel di transito non deve superare %d"}, {"Back to commands list", "Ritorna alla lista dei comandi"}, {"Register at reg.i2p", "Registra a reg.i2p"}, {"Description", "Descrizione"}, @@ -166,32 +165,26 @@ namespace italian // language namespace {"You may try to find this host on jump services below", "Si può provare a trovare questo host sui servizi di salto qui sotto"}, {"Invalid request", "Richiesta non valida"}, {"Proxy unable to parse your request", "Il proxy non è in grado di elaborare la tua richiesta"}, - {"addresshelper is not supported", "addresshelper non è supportato"}, - {"Host", "Host"}, - {"added to router's addressbook from helper", "aggiunto alla rubrica tramite l'helper"}, - {"Click here to proceed:", "Clicca qui per procedere:"}, - {"Continue", "Continua"}, - {"Addresshelper found", "Addresshelper trovato"}, - {"already in router's addressbook", "già presente nella rubrica del router"}, - {"Click here to update record:", "Clicca qui per aggiornare l'elemento:"}, - {"invalid request uri", "uri della richiesta non valido"}, + {"To add host %s in router's addressbook, click here: Continue.", "Per aggiungere host %s nella rubrica del router, clicca qui: Continua."}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "L'host %s è già nella rubrica del router. Clicca qui per aggiornare il record: Continua."}, + {"Invalid request URI", "URI della richiesta non valido"}, {"Can't detect destination host from request", "Impossibile determinare l'host di destinazione dalla richiesta"}, {"Outproxy failure", "Fallimento del proxy di uscita"}, - {"bad outproxy settings", "impostazioni errate del proxy di uscita"}, - {"not inside I2P network, but outproxy is not enabled", "non all'interno della rete I2P, ma il proxy di uscita non è abilitato"}, - {"unknown outproxy url", "url del proxy di uscita sconosciuto"}, - {"cannot resolve upstream proxy", "impossibile identificare il flusso a monte del proxy"}, - {"hostname too long", "il nome dell'host è troppo lungo"}, - {"cannot connect to upstream socks proxy", "impossibile connettersi al flusso a monte del proxy socks"}, - {"Cannot negotiate with socks proxy", "Impossibile negoziare con il proxy socks"}, + {"Bad outproxy settings", "Impostazioni errate del proxy di uscita"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Host %s non all'interno della rete I2P, ma il proxy di uscita non è abilitato"}, + {"Unknown outproxy URL", "URL del proxy di uscita sconosciuto"}, + {"Cannot resolve upstream proxy", "Impossibile identificare il flusso a monte del proxy"}, + {"Hostname is too long", "Il nome dell'host è troppo lungo"}, + {"Cannot connect to upstream SOCKS proxy", "Impossibile connettersi al flusso a monte del proxy SOCKS"}, + {"Cannot negotiate with SOCKS proxy", "Impossibile negoziare con il proxy SOCKS"}, {"CONNECT error", "Errore di connessione"}, - {"Failed to Connect", "Connessione fallita"}, - {"socks proxy error", "errore del proxy socks"}, - {"failed to send request to upstream", "invio della richiesta a monte non riuscito"}, - {"No Reply From socks proxy", "Nessuna risposta dal proxy socks"}, - {"cannot connect", "impossibile connettersi"}, - {"http out proxy not implemented", "proxy http di uscita non implementato"}, - {"cannot connect to upstream http proxy", "impossibile connettersi al proxy http a monte"}, + {"Failed to connect", "Connessione fallita"}, + {"SOCKS proxy error", "Errore del proxy SOCKS"}, + {"Failed to send request to upstream", "Invio della richiesta a monte non riuscito"}, + {"No reply from SOCKS proxy", "Nessuna risposta dal proxy SOCKS"}, + {"Cannot connect", "Impossibile connettersi"}, + {"HTTP out proxy not implemented", "Proxy HTTP di uscita non implementato"}, + {"Cannot connect to upstream HTTP proxy", "Impossibile connettersi al flusso a monte del proxy HTTP"}, {"Host is down", "L'host è offline"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Impossibile creare la connessione all'host richiesto, probabilmente è offline. Riprova più tardi."}, {"", ""}, diff --git a/i18n/Polish.cpp b/i18n/Polish.cpp new file mode 100644 index 00000000..26661231 --- /dev/null +++ b/i18n/Polish.cpp @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Polish localization file + +namespace i2p +{ +namespace i18n +{ +namespace polish // language namespace +{ + // language name in lowercase + static std::string language = "polish"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); + } + + static std::map strings + { + {"building", "Kompilowanie"}, + {"failed", "nieudane"}, + {"expiring", "wygasający"}, + {"established", "ustanowiony"}, + {"Main page", "Strona główna"}, + {"Router commands", "Komendy routera"}, + {"Tunnels", "Tunele"}, + {"OK", "Ok"}, + {"Uptime", "Czas pracy"}, + {"Sent", "Wysłane"}, + {"", ""}, + }; + + static std::map> plurals + { + {"", {"", "", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Portuguese.cpp b/i18n/Portuguese.cpp new file mode 100644 index 00000000..528be389 --- /dev/null +++ b/i18n/Portuguese.cpp @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Portuguese localization file + +namespace i2p +{ +namespace i18n +{ +namespace portuguese // language namespace +{ + // language name in lowercase + static std::string language = "portuguese"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, + {"building", "construindo"}, + {"failed", "falhou"}, + {"expiring", "expirando"}, + {"established", "estabelecido"}, + {"unknown", "desconhecido"}, + {"exploratory", "exploratório"}, + {"Purple I2P Webconsole", "Webconsole Purple I2P"}, + {"i2pd webconsole", "webconsole i2pd"}, + {"Main page", "Página Principal"}, + {"Router commands", "Comandos do Roteador"}, + {"Local Destinations", "Destinos Locais"}, + {"LeaseSets", "LeaseSets"}, + {"Tunnels", "Túneis"}, + {"Transit Tunnels", "Túneis de Trânsito"}, + {"Transports", "Transportes"}, + {"I2P tunnels", "Túneis I2P"}, + {"SAM sessions", "Sessões do SAM"}, + {"ERROR", "ERRO"}, + {"OK", "OK"}, + {"Testing", "Testando"}, + {"Firewalled", "Sob Firewall"}, + {"Unknown", "Desconhecido"}, + {"Proxy", "Proxy"}, + {"Mesh", "Malha"}, + {"Clock skew", "Defasagem do Relógio"}, + {"Offline", "Desligado"}, + {"Symmetric NAT", "NAT Simétrico"}, + {"Full cone NAT", "Full cone NAT"}, + {"No Descriptors", "Sem Descritores"}, + {"Uptime", "Tempo Ativo"}, + {"Network status", "Estado da rede"}, + {"Network status v6", "Estado da rede v6"}, + {"Stopping in", "Parando em"}, + {"Family", "Família"}, + {"Tunnel creation success rate", "Taxa de sucesso na criação de túneis"}, + {"Received", "Recebido"}, + {"%.2f KiB/s", "%.2f KiB/s"}, + {"Sent", "Enviado"}, + {"Transit", "Trânsito"}, + {"Data path", "Caminho dos dados"}, + {"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."}, + {"Router Ident", "Identidade do Roteador"}, + {"Router Family", "Família do Roteador"}, + {"Router Caps", "Limites do Roteador"}, + {"Version", "Versão"}, + {"Our external address", "Nosso endereço externo"}, + {"supported", "suportado"}, + {"Routers", "Roteadores"}, + {"Floodfills", "Modo Inundação"}, + {"Client Tunnels", "Túneis de Clientes"}, + {"Services", "Serviços"}, + {"Enabled", "Ativado"}, + {"Disabled", "Desativado"}, + {"Encrypted B33 address", "Endereço B33 criptografado"}, + {"Address registration line", "Linha de cadastro de endereço"}, + {"Domain", "Domínio"}, + {"Generate", "Gerar"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", " Nota: A string resultante só pode ser usada para registrar domínios 2LD (exemplo.i2p). Para registrar subdomínios por favor utilize o i2pd-tools."}, + {"Address", "Endereço"}, + {"Type", "Tipo"}, + {"EncType", "Tipo de Criptografia"}, + {"Inbound tunnels", "Túneis de Entrada"}, + {"%dms", "%dms"}, + {"Outbound tunnels", "Túneis de Saída"}, + {"Tags", "Etiquetas"}, + {"Incoming", "Entradas"}, + {"Outgoing", "Saídas"}, + {"Destination", "Destinos"}, + {"Amount", "Quantidade"}, + {"Incoming Tags", "Etiquetas de Entrada"}, + {"Tags sessions", "Sessões de etiquetas"}, + {"Status", "Estado"}, + {"Local Destination", "Destinos Locais"}, + {"Streams", "Fluxos"}, + {"Close stream", "Fechar fluxo"}, + {"I2CP session not found", "Sessão do I2CP não encontrada"}, + {"I2CP is not enabled", "I2CP não está ativado"}, + {"Invalid", "Inválido"}, + {"Store type", "Tipo de armazenamento"}, + {"Expires", "Expira em"}, + {"Non Expired Leases", "Sessões não expiradas"}, + {"Gateway", "Gateway"}, + {"TunnelID", "TunnelID"}, + {"EndDate", "Data final"}, + {"floodfill mode is disabled", "Mode de inundação está desativado"}, + {"Queue size", "Tamanho da fila"}, + {"Run peer test", "Executar teste de peers"}, + {"Reload tunnels configuration", "Recarregar a configuração dos túneis"}, + {"Decline transit tunnels", "Negar túnel de trânsito"}, + {"Accept transit tunnels", "Aceitar túnel de trânsito"}, + {"Cancel graceful shutdown", "Cancelar desligamento gracioso"}, + {"Start graceful shutdown", "Iniciar desligamento gracioso"}, + {"Force shutdown", "Forçar desligamento"}, + {"Reload external CSS styles", "Recarregar estilos CSS externos"}, + {"Note: any action done here are not persistent and not changes your config files.", " Nota: Qualquer ação feita aqui não será permanente e não altera os seus arquivos de configuração."}, + {"Logging level", "Nível de registro"}, + {"Transit tunnels limit", "Limite nos túneis de trânsito"}, + {"Change", "Mudar"}, + {"Change language", "Trocar idioma"}, + {"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"}, + {"SAM disabled", "SAM desativado"}, + {"no sessions currently running", "Nenhuma sessão funcionando no momento"}, + {"SAM session not found", "Nenhuma sessão do SAM encontrada"}, + {"SAM Session", "Sessão do SAM"}, + {"Server Tunnels", "Túneis de Servidor"}, + {"Client Forwards", "Túneis de Cliente"}, + {"Server Forwards", "Encaminhamentos de Servidor"}, + {"Unknown page", "Página desconhecida"}, + {"Invalid token", "Token Inválido"}, + {"SUCCESS", "SUCESSO"}, + {"Stream closed", "Fluxo fechado"}, + {"Stream not found or already was closed", "Fluxo não encontrado ou já encerrado"}, + {"Destination not found", "Destino não encontrado"}, + {"StreamID can't be null", "StreamID não pode ser nulo"}, + {"Return to destination page", "Retornar para à página de destino"}, + {"You will be redirected in %d seconds", "Você será redirecionado em %d segundos"}, + {"Transit tunnels count must not exceed %d", "A contagem de túneis de trânsito não deve exceder %d"}, + {"Back to commands list", "Voltar para a lista de comandos"}, + {"Register at reg.i2p", "Registrar na reg.i2p"}, + {"Description", "Descrição"}, + {"A bit information about service on domain", "Algumas informações sobre o serviço no domínio"}, + {"Submit", "Enviar"}, + {"Domain can't end with .b32.i2p", "O domínio não pode terminar com .b32.i2p"}, + {"Domain must end with .i2p", "O domínio não pode terminar com .i2p"}, + {"Such destination is not found", "Tal destino não foi encontrado"}, + {"Unknown command", "Comando desconhecido"}, + {"Command accepted", "Comando aceito"}, + {"Proxy error", "Erro no proxy"}, + {"Proxy info", "Informações do proxy"}, + {"Proxy error: Host not found", "Erro no proxy: Host não encontrado"}, + {"Remote host not found in router's addressbook", "O host remoto não foi encontrado no livro de endereços do roteador"}, + {"You may try to find this host on jump services below", "Você pode tentar encontrar este host nos jump services abaixo"}, + {"Invalid request", "Requisição inválida"}, + {"Proxy unable to parse your request", "O proxy foi incapaz de processar a sua requisição"}, + {"Addresshelper is not supported", "O Auxiliar de Endereços não é suportado"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "O host %s já está no catálogo de endereços do roteador. Cuidado: a fonte desta URL pode ser perigosa! Clique aqui para atualizar o registro: Continuar."}, + {"Addresshelper forced update rejected", "A atualização forçada do Auxiliar de Endereços foi rejeitada"}, + {"To add host %s in router's addressbook, click here: Continue.", "Para adicionar o host %s ao catálogo de endereços do roteador, clique aqui: Continuar ."}, + {"Addresshelper request", "Requisição do Auxiliar de Endereços"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "O host %s foi adicionado ao catálogo de endereços do roteador por um auxiliar. Clique aqui para proceder: Continuar ."}, + {"Addresshelper adding", "Auxiliar de Endereço adicionando"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "O host %s já está no catálogo de endereços do roteador . Clique aqui para atualizar o registro: Continuar."}, + {"Addresshelper update", "Atualização do Auxiliar de Endereços"}, + {"Invalid request URI", "A URI de requisição é inválida"}, + {"Can't detect destination host from request", "Incapaz de detectar o host de destino da requisição"}, + {"Outproxy failure", "Falha no outproxy"}, + {"Bad outproxy settings", "Configurações ruins de outproxy"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "O host %s não está dentro da rede I2P, mas o outproxy não está ativado"}, + {"Unknown outproxy URL", "URL de outproxy desconhecida"}, + {"Cannot resolve upstream proxy", "Não é possível resolver o proxy de entrada"}, + {"Hostname is too long", "O hostname é muito longo"}, + {"Cannot connect to upstream SOCKS proxy", "Não é possível se conectar ao proxy SOCKS de entrada"}, + {"Cannot negotiate with SOCKS proxy", "Não é possível negociar com o proxy SOCKS"}, + {"CONNECT error", "Erro de CONEXÃO"}, + {"Failed to connect", "Falha ao conectar"}, + {"SOCKS proxy error", "Erro no proxy SOCKS"}, + {"Failed to send request to upstream", "Falha ao enviar requisição para o fluxo de entrada"}, + {"No reply from SOCKS proxy", "Sem resposta do proxy SOCKS"}, + {"Cannot connect", "Impossível conectar"}, + {"HTTP out proxy not implemented", "proxy de saída HTTP não implementado"}, + {"Cannot connect to upstream HTTP proxy", "Não é possível conectar ao proxy HTTP de entrada"}, + {"Host is down", "Host está desligado"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Não é possível se conectar ao host requisitado, talvez ele esteja for do ar. Por favor, tente novamente mais tarde."}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d Dia", "%d Dias"}}, + {"%d hours", {"%d hora", "%d horas"}}, + {"%d minutes", {"%d minuto", "%d minutos"}}, + {"%d seconds", {"%d Segundo", "%d segundos"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 7d875f01..dbfb13f2 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -40,6 +40,7 @@ namespace russian // language namespace {"established", "работает"}, {"unknown", "неизвестно"}, {"exploratory", "исследовательский"}, + {"Purple I2P Webconsole", "Веб-консоль Purple I2P"}, {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Главная"}, {"Router commands", "Команды роутера"}, @@ -57,10 +58,11 @@ namespace russian // language namespace {"Unknown", "Неизвестно"}, {"Proxy", "Прокси"}, {"Mesh", "MESH-сеть"}, - {"Error", "Ошибка"}, {"Clock skew", "Не точное время"}, {"Offline", "Оффлайн"}, {"Symmetric NAT", "Симметричный NAT"}, + {"Full cone NAT", "Full cone NAT"}, + {"No Descriptors", "Нет дескрипторов"}, {"Uptime", "В сети"}, {"Network status", "Сетевой статус"}, {"Network status v6", "Сетевой статус v6"}, @@ -116,9 +118,10 @@ namespace russian // language namespace {"Gateway", "Шлюз"}, {"TunnelID", "ID туннеля"}, {"EndDate", "Заканчивается"}, - {"not floodfill", "не флудфил"}, + {"floodfill mode is disabled", "режим флудфила отключен"}, {"Queue size", "Размер очереди"}, {"Run peer test", "Запустить тестирование"}, + {"Reload tunnels configuration", "Перезагрузить конфигурацию туннелей"}, {"Decline transit tunnels", "Отклонять транзитные туннели"}, {"Accept transit tunnels", "Принимать транзитные туннели"}, {"Cancel graceful shutdown", "Отменить плавную остановку"}, @@ -146,8 +149,8 @@ namespace russian // language namespace {"Destination not found", "Точка назначения не найдена"}, {"StreamID can't be null", "StreamID не может быть пустым"}, {"Return to destination page", "Вернуться на страницу точки назначения"}, - {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, - {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, + {"You will be redirected in %d seconds", "Вы будете переадресованы через %d секунд"}, + {"Transit tunnels count must not exceed %d", "Число транзитных туннелей не должно превышать %d"}, {"Back to commands list", "Вернуться к списку команд"}, {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, {"Description", "Описание"}, @@ -165,32 +168,33 @@ namespace russian // language namespace {"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"}, {"Invalid request", "Некорректный запрос"}, {"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"}, - {"addresshelper is not supported", "addresshelper не поддерживается"}, - {"Host", "Узел"}, - {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"}, - {"Continue", "Продолжить"}, - {"Addresshelper found", "Найден addresshelper"}, - {"already in router's addressbook", "уже в адресной книге роутера"}, - {"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"}, - {"invalid request uri", "некорректный URI запроса"}, + {"Addresshelper is not supported", "Addresshelper не поддерживается"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Узел %s уже в адресной книге роутера. Будьте осторожны: источник данной ссылки может быть вредоносным! Нажмите здесь, чтобы обновить запись: Продолжить."}, + {"Addresshelper forced update rejected", "Принудительное обновление через Addresshelper отклонено"}, + {"To add host %s in router's addressbook, click here: Continue.", "Чтобы добавить узел %s в адресную книгу роутера, нажмите здесь: Продолжить."}, + {"Addresshelper request", "Запрос добавления Addresshelper"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Узел %s добавлен в адресную книгу роутера через хелпер. Нажмите здесь, чтобы продолжить: Продолжить."}, + {"Addresshelper adding", "Добавление Addresshelper"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Узел %s уже в адресной книге роутера. Нажмите здесь, чтобы обновить запись: Продолжить."}, + {"Addresshelper update", "Обновление записи через Addresshelper"}, + {"Invalid request URI", "Некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, - {"bad outproxy settings", "некорректные настройки внешнего прокси"}, - {"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"}, - {"unknown outproxy url", "неизвестный URL внешнего прокси"}, - {"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"}, - {"hostname too long", "имя хоста слишком длинное"}, - {"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"}, - {"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"}, + {"Bad outproxy settings", "Некорректные настройки внешнего прокси"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Узел %s не в I2P сети, но внешний прокси не включен"}, + {"Unknown outproxy URL", "Неизвестный URL внешнего прокси"}, + {"Cannot resolve upstream proxy", "Не удается определить вышестоящий прокси"}, + {"Hostname is too long", "Имя хоста слишком длинное"}, + {"Cannot connect to upstream SOCKS proxy", "Не удалось подключиться к вышестоящему SOCKS прокси серверу"}, + {"Cannot negotiate with SOCKS proxy", "Не удается договориться с вышестоящим SOCKS прокси"}, {"CONNECT error", "Ошибка CONNECT запроса"}, - {"Failed to Connect", "Не удалось подключиться"}, - {"socks proxy error", "ошибка SOCKS прокси"}, - {"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"}, - {"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"}, - {"cannot connect", "не удалось подключиться"}, - {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, - {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, + {"Failed to connect", "Не удалось соединиться"}, + {"SOCKS proxy error", "Ошибка SOCKS прокси"}, + {"Failed to send request to upstream", "Не удалось отправить запрос вышестоящему прокси серверу"}, + {"No reply from SOCKS proxy", "Нет ответа от SOCKS прокси сервера"}, + {"Cannot connect", "Не удалось подключиться"}, + {"HTTP out proxy not implemented", "Поддержка внешнего HTTP прокси сервера не реализована"}, + {"Cannot connect to upstream HTTP proxy", "Не удалось подключиться к вышестоящему HTTP прокси серверу"}, {"Host is down", "Узел недоступен"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."}, {"", ""}, diff --git a/i18n/Spanish.cpp b/i18n/Spanish.cpp index 8b0e927a..a5ecc30a 100644 --- a/i18n/Spanish.cpp +++ b/i18n/Spanish.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022, The PurpleI2P Project +* Copyright (c) 2022-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -58,7 +58,6 @@ namespace spanish // language namespace {"Unknown", "Desconocido"}, {"Proxy", "Proxy"}, {"Mesh", "Malla"}, - {"Error", "Error"}, {"Clock skew", "Reloj desfasado"}, {"Offline", "Desconectado"}, {"Symmetric NAT", "NAT simétrico"}, @@ -117,7 +116,6 @@ namespace spanish // language namespace {"Gateway", "Puerta de enlace"}, {"TunnelID", "TunnelID"}, {"EndDate", "FechaVenc"}, - {"not floodfill", "no inundado"}, {"Queue size", "Tamaño de cola"}, {"Run peer test", "Ejecutar prueba de par"}, {"Decline transit tunnels", "Rechazar túneles de tránsito"}, @@ -147,8 +145,6 @@ namespace spanish // language namespace {"Destination not found", "Destino no encontrado"}, {"StreamID can't be null", "StreamID no puede ser nulo"}, {"Return to destination page", "Volver a la página de destino"}, - {"You will be redirected in 5 seconds", "Serás redirigido en 5 segundos"}, - {"Transit tunnels count must not exceed 65535", "La cantidad de túneles de tránsito no puede exceder 65535"}, {"Back to commands list", "Volver a lista de comandos"}, {"Register at reg.i2p", "Registrar en reg.i2p"}, {"Description", "Descripción"}, @@ -166,32 +162,24 @@ namespace spanish // language namespace {"You may try to find this host on jump services below", "Puede intentar encontrar este dominio en los siguientes servicios de salto"}, {"Invalid request", "Solicitud inválida"}, {"Proxy unable to parse your request", "Proxy no puede procesar su solicitud"}, - {"addresshelper is not supported", "ayudante de dirección no soportado"}, - {"Host", "Dominio"}, - {"added to router's addressbook from helper", "añadido a la libreta de direcciones desde el ayudante"}, - {"Click here to proceed:", "Haga clic aquí para continuar:"}, - {"Continue", "Continuar"}, - {"Addresshelper found", "Se encontró ayudante de dirección"}, - {"already in router's addressbook", "ya se encontró en libreta de direcciones"}, - {"Click here to update record:", "Haga clic aquí para actualizar el registro:"}, - {"invalid request uri", "uri de solicitud inválida"}, + {"Invalid request URI", "URI de solicitud inválida"}, {"Can't detect destination host from request", "No se puede detectar el host de destino de la solicitud"}, {"Outproxy failure", "Fallo en el proxy saliente"}, - {"bad outproxy settings", "configuración de outproxy incorrecta"}, - {"not inside I2P network, but outproxy is not enabled", "no está dentro de la red I2P, pero el proxy de salida no está activado"}, - {"unknown outproxy url", "url de proxy outproxy desconocido"}, - {"cannot resolve upstream proxy", "no se puede resolver el proxy de upstream"}, - {"hostname too long", "nombre de dominio muy largo"}, - {"cannot connect to upstream socks proxy", "no se puede conectar al proxy socks principal"}, - {"Cannot negotiate with socks proxy", "No se puede negociar con el proxy socks"}, + {"Bad outproxy settings", "Configuración de outproxy incorrecta"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Dominio %s no está dentro de la red I2P, pero el proxy de salida no está activado"}, + {"Unknown outproxy URL", "URL de proxy outproxy desconocido"}, + {"Cannot resolve upstream proxy", "No se puede resolver el proxy de upstream"}, + {"Hostname is too long", "Nombre de dominio muy largo"}, + {"Cannot connect to upstream SOCKS proxy", "No se puede conectar al proxy SOCKS principal"}, + {"Cannot negotiate with SOCKS proxy", "No se puede negociar con el proxy SOCKS"}, {"CONNECT error", "Error de CONNECT"}, - {"Failed to Connect", "Error al Conectar"}, - {"socks proxy error", "error de proxy socks"}, - {"failed to send request to upstream", "no se pudo enviar petición al principal"}, - {"No Reply From socks proxy", "Sin respuesta del proxy socks"}, - {"cannot connect", "no se puede conectar"}, - {"http out proxy not implemented", "proxy externo http no implementado"}, - {"cannot connect to upstream http proxy", "no se puede conectar al proxy http principal"}, + {"Failed to connect", "Error al conectar"}, + {"SOCKS proxy error", "Error de proxy SOCKS"}, + {"Failed to send request to upstream", "No se pudo enviar petición al principal"}, + {"No reply from SOCKS proxy", "Sin respuesta del proxy SOCKS"}, + {"Cannot connect", "No se puede conectar"}, + {"HTTP out proxy not implemented", "Proxy externo HTTP no implementado"}, + {"Cannot connect to upstream HTTP proxy", "No se puede conectar al proxy HTTP principal"}, {"Host is down", "Servidor caído"}, {"Can't create connection to requested host, it may be down. Please try again later.", "No se puede crear la conexión al servidor solicitado, puede estar caído. Intente de nuevo más tarde."}, {"", ""}, diff --git a/i18n/Swedish.cpp b/i18n/Swedish.cpp index 180f74aa..e7f84e69 100644 --- a/i18n/Swedish.cpp +++ b/i18n/Swedish.cpp @@ -41,7 +41,7 @@ namespace swedish // language namespace {"unknown", "okänt"}, {"exploratory", "utforskande"}, {"Purple I2P Webconsole", "Purple I2P Webbkonsoll"}, - {"i2pd webbkonsoll", "i2pd-Webbkonsoll"}, + {"i2pd webconsole", "i2pd-Webbkonsoll"}, {"Main page", "Huvudsida"}, {"Router commands", "Routerkommandon"}, {"Local Destinations", "Lokala Platser"}, @@ -58,7 +58,6 @@ namespace swedish // language namespace {"Unknown", "Okänt"}, {"Proxy", "Proxy"}, {"Mesh", "Mesh"}, - {"Error", "Fel"}, {"Clock skew", "Tidsförskjutning"}, {"Offline", "Nedkopplad"}, {"Symmetric NAT", "Symmetrisk NAT"}, @@ -117,7 +116,6 @@ namespace swedish // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "EndDate"}, - {"not floodfill", "inte Översvämningsfyllare"}, {"Queue size", "Köstorlek"}, {"Run peer test", "Utför utsiktstest"}, {"Decline transit tunnels", "Avvisa förmedlande tunnlar"}, @@ -147,8 +145,8 @@ namespace swedish // language namespace {"Destination not found", "Plats hittades ej"}, {"StreamID can't be null", "Ström-ID kan inte vara null"}, {"Return to destination page", "Återvänd till platssidan"}, - {"You will be redirected in 5 seconds", "Du omdirigeras inom fem sekunder"}, - {"Transit tunnels count must not exceed 65535", "Förmedlande tunnlar får inte överstiga 65535"}, + {"You will be redirected in %d seconds", "Du omdirigeras inom %d sekunder"}, + {"Transit tunnels count must not exceed %d", "Förmedlande tunnlar får inte överstiga %d"}, {"Back to commands list", "Tillbaka till kommandolistan"}, {"Register at reg.i2p", "Registrera vid reg.i2p"}, {"Description", "Beskrivning"}, @@ -166,32 +164,25 @@ namespace swedish // language namespace {"You may try to find this host on jump services below", "Du kan försöka att hitta värden genom hopptjänsterna nedan"}, {"Invalid request", "Ogiltig förfrågan"}, {"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"}, - {"addresshelper is not supported", "adresshjälparen stöds ej"}, - {"Host", "Värd"}, - {"added to router's addressbook from helper", "tillagd i routerns adressbok från adresshjälparen"}, - {"Click here to proceed:", "Tryck här för att fortsätta:"}, - {"Continue", "Fortsätt"}, - {"Addresshelper found", "Adresshjälpare hittad"}, - {"already in router's addressbook", "finns redan i routerns adressbok"}, - {"Click here to update record:", "Tryck här för att uppdatera:"}, - {"invalid request uri", "ogiltig förfrågnings-URI"}, + {"Addresshelper is not supported", "Adresshjälparen stöds ej"}, + {"Invalid request URI", "Ogiltig förfrågnings-URI"}, {"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"}, {"Outproxy failure", "Utproxyfel"}, - {"bad outproxy settings", "ogiltig utproxyinställning"}, - {"not inside I2P network, but outproxy is not enabled", "adressen är inte inom I2P-näverket, men utproxy är inte påslaget"}, - {"unknown outproxy url", "okänt Utproxy-URL"}, - {"cannot resolve upstream proxy", "hittar inte uppströmsproxyt"}, - {"hostname too long", "värdnamnet är för långt"}, - {"cannot connect to upstream socks proxy", "kan inte ansluta till uppströmsproxyt"}, - {"Cannot negotiate with socks proxy", "Kan inte förhandla med socksproxyt"}, + {"Bad outproxy settings", "Ogiltig utproxyinställning"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Värd %s är inte inom I2P-näverket, men utproxy är inte påslaget"}, + {"Unknown outproxy URL", "okänt Utproxy-URL"}, + {"Cannot resolve upstream proxy", "Hittar inte uppströmsproxyt"}, + {"Hostname is too long", "Värdnamnet är för långt"}, + {"Cannot connect to upstream SOCKS proxy", "Kan inte ansluta till uppström SOCKS-proxy"}, + {"Cannot negotiate with SOCKS proxy", "Kan inte förhandla med SOCKSproxyt"}, {"CONNECT error", "CONNECT-fel"}, - {"Failed to Connect", "Anslutningen misslyckades"}, - {"socks proxy error", "Socksproxyfel"}, - {"failed to send request to upstream", "förfrågan uppströms kunde ej skickas"}, - {"No Reply From socks proxy", "Fick inget svar från socksproxyt"}, - {"cannot connect", "kan inte ansluta"}, - {"http out proxy not implemented", "HTTP-Utproxy ej implementerat"}, - {"cannot connect to upstream http proxy", "Kan inte ansluta till uppströms HTTP-proxy"}, + {"Failed to connect", "Anslutningen misslyckades"}, + {"SOCKS proxy error", "SOCKSproxyfel"}, + {"Failed to send request to upstream", "Förfrågan uppströms kunde ej skickas"}, + {"No reply from SOCKS proxy", "Fick inget svar från SOCKSproxyt"}, + {"Cannot connect", "Kan inte ansluta"}, + {"HTTP out proxy not implemented", "HTTP-Utproxy ej implementerat"}, + {"Cannot connect to upstream HTTP proxy", "Kan inte ansluta till uppströms HTTP-proxy"}, {"Host is down", "Värden är nere"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Kan inte ansluta till värden, den kan vara nere. Vänligen försök senare."}, {"", ""}, @@ -199,10 +190,10 @@ namespace swedish // language namespace static std::map> plurals { - {"%d days", {"%d Dag", "%d Dagar"}}, - {"%d hours", {"%d Timme", "%d Timmar"}}, - {"%d minutes", {"%d Minut", "%d Minuter"}}, - {"%d seconds", {"%d Sekund", "%d Sekunder"}}, + {"%d days", {"%d dag", "%d dagar"}}, + {"%d hours", {"%d timme", "%d timmar"}}, + {"%d minutes", {"%d minut", "%d minuter"}}, + {"%d seconds", {"%d sekund", "%d sekunder"}}, {"", {"", ""}}, }; diff --git a/i18n/Turkish.cpp b/i18n/Turkish.cpp new file mode 100644 index 00000000..d4398ebe --- /dev/null +++ b/i18n/Turkish.cpp @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Turkish localization file + +namespace i2p +{ +namespace i18n +{ +namespace turkish // language namespace +{ + // language name in lowercase + static std::string language = "turkish"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, + {"building", "kuruluyor"}, + {"failed", "başarısız"}, + {"expiring", "süresi geçiyor"}, + {"established", "kurulmuş"}, + {"unknown", "bilinmeyen"}, + {"Purple I2P Webconsole", "Mor I2P Webkonsolu"}, + {"i2pd webconsole", "i2pd webkonsolu"}, + {"Main page", "Ana sayfa"}, + {"Router commands", "Router komutları"}, + {"Local Destinations", "Yerel Hedefler"}, + {"Tunnels", "Tüneller"}, + {"Transit Tunnels", "Transit Tünelleri"}, + {"Transports", "Taşıma"}, + {"I2P tunnels", "I2P tünelleri"}, + {"SAM sessions", "SAM oturumları"}, + {"ERROR", "HATA"}, + {"OK", "TAMAM"}, + {"Testing", "Test ediliyor"}, + {"Firewalled", "Güvenlik Duvarı Kısıtlaması"}, + {"Unknown", "Bilinmeyen"}, + {"Proxy", "Proxy"}, + {"Clock skew", "Saat sorunu"}, + {"Offline", "Çevrimdışı"}, + {"Symmetric NAT", "Simetrik NAT"}, + {"Full cone NAT", "Full cone NAT"}, + {"No Descriptors", "Tanımlayıcı Yok"}, + {"Uptime", "Bağlantı süresi"}, + {"Network status", "Ağ durumu"}, + {"Network status v6", "Ağ durumu v6"}, + {"Family", "Aile"}, + {"Tunnel creation success rate", "Tünel oluşturma başarı oranı"}, + {"Received", "Alındı"}, + {"%.2f KiB/s", "%.2f KiB/s"}, + {"Sent", "Gönderildi"}, + {"Transit", "Transit"}, + {"Data path", "Veri yolu"}, + {"Hidden content. Press on text to see.", "Gizlenmiş içerik. Görmek için yazıya tıklayınız."}, + {"Router Family", "Router Familyası"}, + {"Decline transit tunnels", "Transit tünellerini reddet"}, + {"Accept transit tunnels", "Transit tünellerini kabul et"}, + {"Cancel graceful shutdown", "Düzgün durdurmayı iptal Et"}, + {"Start graceful shutdown", "Düzgün durdurmayı başlat"}, + {"Force shutdown", "Durdurmaya zorla"}, + {"Reload external CSS styles", "Harici CSS stilini yeniden yükle"}, + {"Note: any action done here are not persistent and not changes your config files.", "Not: burada yapılan ayarların hiçbiri kalıcı değildir ve ayar dosyalarınızı değiştirmez."}, + {"Logging level", "Kayıt tutma seviyesi"}, + {"Transit tunnels limit", "Transit tünel limiti"}, + {"Change", "Değiştir"}, + {"Change language", "Dil değiştir"}, + {"no transit tunnels currently built", "kurulmuş bir transit tüneli bulunmamakta"}, + {"SAM disabled", "SAM devre dışı"}, + {"no sessions currently running", "hiçbir oturum şu anda çalışmıyor"}, + {"SAM session not found", "SAM oturumu bulunamadı"}, + {"SAM Session", "SAM oturumu"}, + {"Server Tunnels", "Sunucu Tünelleri"}, + {"Unknown page", "Bilinmeyen sayfa"}, + {"Invalid token", "Geçersiz token"}, + {"SUCCESS", "BAŞARILI"}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d gün", "%d gün"}}, + {"%d hours", {"%d saat", "%d saat"}}, + {"%d minutes", {"%d dakika", "%d dakika"}}, + {"%d seconds", {"%d saniye", "%d saniye"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 7e7a24f0..35ee0f89 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2022, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -40,6 +40,7 @@ namespace turkmen // language namespace {"established", "işleýär"}, {"unknown", "näbelli"}, {"exploratory", "gözleg"}, + {"Purple I2P Webconsole", "Web konsoly Purple I2P"}, {"i2pd webconsole", "Web konsoly i2pd"}, {"Main page", "Esasy sahypa"}, {"Router commands", "Marşrutizator buýruklary"}, @@ -57,7 +58,6 @@ namespace turkmen // language namespace {"Unknown", "Näbelli"}, {"Proxy", "Proksi"}, {"Mesh", "MESH-tor"}, - {"Error", "Ýalňyşlyk"}, {"Clock skew", "Takyk wagt däl"}, {"Offline", "Awtonom"}, {"Symmetric NAT", "Simmetriklik NAT"}, @@ -116,7 +116,6 @@ namespace turkmen // language namespace {"Gateway", "Derweze"}, {"TunnelID", "Tuneliň ID"}, {"EndDate", "Gutarýar"}, - {"not floodfill", "fludfil däl"}, {"Queue size", "Nobatyň ululygy"}, {"Run peer test", "Synag başlaň"}, {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, @@ -146,8 +145,6 @@ namespace turkmen // language namespace {"Destination not found", "Niýetlenen ýeri tapylmady"}, {"StreamID can't be null", "StreamID boş bolup bilmez"}, {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, - {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, - {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, {"Back to commands list", "Topar sanawyna dolan"}, {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, {"Description", "Beýany"}, @@ -165,32 +162,24 @@ namespace turkmen // language namespace {"You may try to find this host on jump services below", "Aşakdaky böküş hyzmatlarynda bu öý eýesini tapmaga synanyşyp bilersiňiz"}, {"Invalid request", "Nädogry haýyş"}, {"Proxy unable to parse your request", "Proksi haýyşyňyzy derňäp bilmeýär"}, - {"addresshelper is not supported", "Salgylandyryjy goldanok"}, - {"Host", "Adres"}, - {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, - {"Click here to proceed:", "Dowam etmek bu ýerde basyň:"}, - {"Continue", "Dowam et"}, - {"Addresshelper found", "Forgelper tapyldy"}, - {"already in router's addressbook", "marşruteriň adres kitaby"}, - {"Click here to update record:", "Recordazgyny täzelemek üçin bu ýerde basyň:"}, - {"invalid request uri", "nädogry haýyş URI"}, + {"Invalid request URI", "Nädogry haýyş URI"}, {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, - {"bad outproxy settings", "daşarky daşarky proksi sazlamalary nädogry"}, - {"not inside I2P network, but outproxy is not enabled", "I2P torunda däl, ýöne daşarky proksi goşulmaýar"}, - {"unknown outproxy url", "näbelli daşarky proksi URL"}, - {"cannot resolve upstream proxy", "has ýokary proksi kesgitläp bilmeýär"}, - {"hostname too long", "hoster eýesi ady gaty uzyn"}, - {"cannot connect to upstream socks proxy", "ýokary jorap SOCKS proksi bilen birigip bolmaýar"}, - {"Cannot negotiate with socks proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"}, + {"Bad outproxy settings", "Daşarky Daşarky proksi sazlamalary nädogry"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Adres %s I2P torunda däl, ýöne daşarky proksi goşulmaýar"}, + {"Unknown outproxy URL", "Näbelli daşarky proksi URL"}, + {"Cannot resolve upstream proxy", "Has ýokary proksi kesgitläp bilmeýär"}, + {"Hostname is too long", "Hoster eýesi ady gaty uzyn"}, + {"Cannot connect to upstream SOCKS proxy", "Ýokary jorap SOCKS proksi bilen birigip bolmaýar"}, + {"Cannot negotiate with SOCKS proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"}, {"CONNECT error", "Bagyr haýyşy säwligi"}, - {"Failed to Connect", "Birikdirip bilmedi"}, - {"socks proxy error", "socks proksi ýalňyşlygy"}, - {"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"}, - {"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"}, - {"cannot connect", "birikdirip bilmedi"}, - {"http out proxy not implemented", "daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"}, - {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"}, + {"Failed to connect", "Birikdirip bilmedi"}, + {"SOCKS proxy error", "SOCKS proksi ýalňyşlygy"}, + {"Failed to send request to upstream", "Öý eýesi proksi üçin haýyş iberip bilmedi"}, + {"No reply from SOCKS proxy", "Jorap SOCKS proksi serwerinden hiç hili jogap ýok"}, + {"Cannot connect", "Birikdirip bilmedi"}, + {"HTTP out proxy not implemented", "Daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"}, + {"Cannot connect to upstream HTTP proxy", "Ýokary jorap HTTP proksi bilen birigip bolmaýar"}, {"Host is down", "Salgy elýeterli däl"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, {"", ""}, diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 991f46ab..c1e222ea 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -40,6 +40,7 @@ namespace ukrainian // language namespace {"established", "працює"}, {"unknown", "невідомо"}, {"exploratory", "дослідницький"}, + {"Purple I2P Webconsole", "Веб-консоль Purple I2P"}, {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Головна"}, {"Router commands", "Команди маршрутизатора"}, @@ -57,10 +58,11 @@ namespace ukrainian // language namespace {"Unknown", "Невідомо"}, {"Proxy", "Проксі"}, {"Mesh", "MESH-мережа"}, - {"Error", "Помилка"}, {"Clock skew", "Неточний час"}, {"Offline", "Офлайн"}, {"Symmetric NAT", "Симетричний NAT"}, + {"Full cone NAT", "Повний NAT"}, + {"No Descriptors", "Немає Описів"}, {"Uptime", "У мережі"}, {"Network status", "Мережевий статус"}, {"Network status v6", "Мережевий статус v6"}, @@ -116,9 +118,10 @@ namespace ukrainian // language namespace {"Gateway", "Шлюз"}, {"TunnelID", "ID тунеля"}, {"EndDate", "Закінчується"}, - {"not floodfill", "не флудфіл"}, + {"floodfill mode is disabled", "режим floodfill вимкнено"}, {"Queue size", "Розмір черги"}, {"Run peer test", "Запустити тестування"}, + {"Reload tunnels configuration", "Перезавантажити налаштування тунелів"}, {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, @@ -146,8 +149,8 @@ namespace ukrainian // language namespace {"Destination not found", "Точка призначення не знайдена"}, {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, {"Return to destination page", "Повернутися на сторінку точки призначення"}, - {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, - {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, + {"You will be redirected in %d seconds", "Ви будете переадресовані через %d секунд"}, + {"Transit tunnels count must not exceed %d", "Кількість транзитних тунелів не повинна перевищувати %d"}, {"Back to commands list", "Повернутися до списку команд"}, {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, {"Description", "Опис"}, @@ -165,32 +168,33 @@ namespace ukrainian // language namespace {"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"}, {"Invalid request", "Некоректний запит"}, {"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"}, - {"addresshelper is not supported", "addresshelper не підтримується"}, - {"Host", "Адреса"}, - {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"}, - {"Click here to proceed:", "Натисніть тут щоб продовжити:"}, - {"Continue", "Продовжити"}, - {"Addresshelper found", "Знайдено addresshelper"}, - {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, - {"Click here to update record:", "Натисніть тут щоб оновити запис:"}, - {"invalid request uri", "некоректний URI запиту"}, + {"Addresshelper is not supported", "Адресна книга не підтримується"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Хост %s вже в адресній книзі маршрутизатора. Будьте обережні: джерело цієї адреси може зашкодити! Натисніть тут, щоб оновити запис: Продовжити."}, + {"Addresshelper forced update rejected", "Адресна книга відхилила примусове оновлення"}, + {"To add host %s in router's addressbook, click here: Continue.", "Щоб додати хост %s в адресі маршрутизатора, натисніть тут: Продовжити."}, + {"Addresshelper request", "Запит на адресну сторінку"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Хост %s доданий в адресну книгу маршрутизатора від помічника. Натисніть тут, щоб продовжити: Продовжити."}, + {"Addresshelper adding", "Адреса додана"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Хост %s вже в адресній книзі маршрутизатора. Натисніть тут, щоб оновити запис: Продовжити."}, + {"Addresshelper update", "Оновлення адресної книги"}, + {"Invalid request URI", "Некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, - {"bad outproxy settings", "некоректні налаштування зовнішнього проксі"}, - {"not inside I2P network, but outproxy is not enabled", "не в I2P мережі, але зовнішній проксі не включений"}, - {"unknown outproxy url", "невідомий URL зовнішнього проксі"}, - {"cannot resolve upstream proxy", "не вдається визначити висхідний проксі"}, - {"hostname too long", "ім'я вузла надто довге"}, - {"cannot connect to upstream socks proxy", "не вдається підключитися до висхідного SOCKS проксі"}, - {"Cannot negotiate with socks proxy", "Не вдається домовитися з висхідним SOCKS проксі"}, + {"Bad outproxy settings", "Некоректні налаштування зовнішнього проксі"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Адрес %s не в I2P мережі, але зовнішній проксі не включений"}, + {"Unknown outproxy URL", "Невідомий URL зовнішнього проксі"}, + {"Cannot resolve upstream proxy", "Не вдається визначити висхідний проксі"}, + {"Hostname is too long", "Ім'я вузла надто довге"}, + {"Cannot connect to upstream SOCKS proxy", "Не вдалося підключитися до висхідного SOCKS проксі сервера"}, + {"Cannot negotiate with SOCKS proxy", "Не вдається домовитися з висхідним SOCKS проксі"}, {"CONNECT error", "Помилка CONNECT запиту"}, - {"Failed to Connect", "Не вдалося підключитися"}, - {"socks proxy error", "помилка SOCKS проксі"}, - {"failed to send request to upstream", "не вдалося відправити запит висхідному проксі"}, - {"No Reply From socks proxy", "Немає відповіді від SOCKS проксі сервера"}, - {"cannot connect", "не вдалося підключитися"}, - {"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"}, - {"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"}, + {"Failed to connect", "Не вдалося підключитися"}, + {"SOCKS proxy error", "Помилка SOCKS проксі"}, + {"Failed to send request to upstream", "Не вдалося відправити запит висхідному проксі"}, + {"No reply from SOCKS proxy", "Немає відповіді від SOCKS проксі сервера"}, + {"Cannot connect", "Не вдалося підключитися"}, + {"HTTP out proxy not implemented", "Підтримка зовнішнього HTTP проксі сервера не реалізована"}, + {"Cannot connect to upstream HTTP proxy", "Не вдалося підключитися до висхідного HTTP проксі сервера"}, {"Host is down", "Вузол недоступний"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, {"", ""}, diff --git a/i18n/Uzbek.cpp b/i18n/Uzbek.cpp index 7355471b..9d798be4 100644 --- a/i18n/Uzbek.cpp +++ b/i18n/Uzbek.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2022, The PurpleI2P Project +* Copyright (c) 2021-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -40,6 +40,7 @@ namespace uzbek // language namespace {"established", "aloqa o'rnatildi"}, {"unknown", "noma'lum"}, {"exploratory", "tadqiqiy"}, + {"Purple I2P Webconsole", "Veb-konsoli Purple I2P"}, {"i2pd webconsole", "i2pd veb-konsoli"}, {"Main page", "Asosiy sahifa"}, {"Router commands", "Router buyruqlari"}, @@ -57,10 +58,11 @@ namespace uzbek // language namespace {"Unknown", "Notanish"}, {"Proxy", "Proksi"}, {"Mesh", "Mesh To'r"}, - {"Error", "Xato"}, {"Clock skew", "Aniq vaqt emas"}, {"Offline", "Oflayn"}, {"Symmetric NAT", "Simmetrik NAT"}, + {"Full cone NAT", "Full cone NAT"}, + {"No Descriptors", "Deskriptorlar yo'q"}, {"Uptime", "Ish vaqti"}, {"Network status", "Tarmoq holati"}, {"Network status v6", "Tarmoq holati v6"}, @@ -116,9 +118,10 @@ namespace uzbek // language namespace {"Gateway", "Kirish yo'li"}, {"TunnelID", "TunnelID"}, {"EndDate", "Tugash Sanasi"}, - {"not floodfill", "floodfill emas"}, + {"floodfill mode is disabled", "floodfill rejimi o'chirilgan"}, {"Queue size", "Navbat hajmi"}, {"Run peer test", "Sinovni boshlang"}, + {"Reload tunnels configuration", "Tunnel konfiguratsiyasini qayta yuklash"}, {"Decline transit tunnels", "Tranzit tunnellarini rad etish"}, {"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"}, {"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qilish"}, @@ -146,8 +149,8 @@ namespace uzbek // language namespace {"Destination not found", "Yo'nalish topilmadi"}, {"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"}, {"Return to destination page", "Manzilgoh sahifasiga qaytish"}, - {"You will be redirected in 5 seconds", "Siz 5 soniya ichida qayta yo'naltirilasiz"}, - {"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"}, + {"You will be redirected in %d seconds", "Siz %d soniyadan so‘ng boshqa yo‘nalishga yo‘naltirilasiz"}, + {"Transit tunnels count must not exceed %d", "Tranzit tunnellar soni %d dan oshmasligi kerak"}, {"Back to commands list", "Buyruqlar ro'yxatiga qaytish"}, {"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"}, {"Description", "Tavsif"}, @@ -165,32 +168,33 @@ namespace uzbek // language namespace {"You may try to find this host on jump services below", "Siz xost quyida o'tish xizmatlari orqali topishga harakat qilishingiz mumkin"}, {"Invalid request", "Noto‘g‘ri so‘rov"}, {"Proxy unable to parse your request", "Proksi sizning so'rovingizni aniqlab ololmayapti"}, - {"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"}, - {"Host", "Xost"}, - {"added to router's addressbook from helper", "'helper'dan routerning 'addressbook'ga qo'shildi"}, - {"Click here to proceed:", "Davom etish uchun shu yerni bosing:"}, - {"Continue", "Davom etish"}, - {"Addresshelper found", "Addresshelper topildi"}, - {"already in router's addressbook", "allaqachon 'addressbook'da yozilgan"}, - {"Click here to update record:", "Yozuvni yangilash uchun shu yerni bosing:"}, - {"invalid request uri", "noto'g'ri URI so'rovi"}, + {"Addresshelper is not supported", "Addresshelper qo'llab-quvvatlanmaydi"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "%s xosti allaqachon routerning manzillar kitobida. Ehtiyot bo'ling: bu URL manbasi zararli bo'lishi mumkin! Yozuvni yangilash uchun bu yerni bosing: Davom etish."}, + {"Addresshelper forced update rejected", "Addresshelperni majburiy yangilash rad etildi"}, + {"To add host %s in router's addressbook, click here: Continue.", "Routerning manzillar kitobiga %s xostini qo'shish uchun bu yerni bosing: Davom etish."}, + {"Addresshelper request", "Addresshelper so'rovi"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Yordamchidan router manzillar kitobiga %s xost qo‘shildi. Davom etish uchun bu yerga bosing: Davom etish."}, + {"Addresshelper adding", "Addresshelperni qo'shish"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "%s xosti allaqachon routerning manzillar kitobida. Yozuvni yangilash uchun shu yerni bosing: Davom etish."}, + {"Addresshelper update", "Addresshelperni yangilash"}, + {"Invalid request URI", "Noto'g'ri URI so'rovi"}, {"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"}, {"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"}, - {"bad outproxy settings", "noto'g'ri tashqi proksi-server sozlamalari"}, - {"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"}, - {"unknown outproxy url", "noma'lum outproxy url"}, - {"cannot resolve upstream proxy", "yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"}, - {"hostname too long", "xost nomi juda uzun"}, - {"cannot connect to upstream socks proxy", "yuqori 'socks proxy'ga ulanib bo'lmayapti"}, - {"Cannot negotiate with socks proxy", "'Socks proxy' bilan muzokara olib bo'lmaydi"}, + {"Bad outproxy settings", "Noto'g'ri tashqi proksi-server sozlamalari"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Xost %s I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"}, + {"Unknown outproxy URL", "Noma'lum outproxy URL"}, + {"Cannot resolve upstream proxy", "Yuqoridagi 'proxy-server'ni aniqlab olib bolmayapti"}, + {"Hostname is too long", "Xost nomi juda uzun"}, + {"Cannot connect to upstream SOCKS proxy", "Yuqori 'SOCKS proxy'ga ulanib bo'lmayapti"}, + {"Cannot negotiate with SOCKS proxy", "'SOCKS proxy' bilan muzokara olib bo'lmaydi"}, {"CONNECT error", "CONNECT xatosi"}, - {"Failed to Connect", "Ulanib bo'lmayapti"}, - {"socks proxy error", "'socks proxy' xatosi"}, - {"failed to send request to upstream", "yuqori http proksi-serveriga so'rovni uborib bo'lmadi"}, - {"No Reply From socks proxy", "'Socks proxy'dan javob yo'q"}, - {"cannot connect", "ulanib bo'lmaydi"}, - {"http out proxy not implemented", "tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"}, - {"cannot connect to upstream http proxy", "yuqori http 'proxy-server'iga ulanib bo'lmayapti"}, + {"Failed to connect", "Ulanib bo'lmayapti"}, + {"SOCKS proxy error", "'SOCKS proxy' xatosi"}, + {"Failed to send request to upstream", "Yuqori proksi-serveriga so'rovni uborib bo'lmadi"}, + {"No reply from SOCKS proxy", "'SOCKS proxy'dan javob yo'q"}, + {"Cannot connect", "Ulanib bo'lmaydi"}, + {"HTTP out proxy not implemented", "Tashqi HTTP proksi-serverni qo'llab-quvvatlash amalga oshirilmagan"}, + {"Cannot connect to upstream HTTP proxy", "Yuqori 'HTTP proxy'ga ulanib bo'lmayapti"}, {"Host is down", "Xost ishlamayapti"}, {"Can't create connection to requested host, it may be down. Please try again later.", "Talab qilingan xost bilan aloqa o'rnatilmadi, u ishlamay qolishi mumkin. Iltimos keyinroq qayta urinib ko'ring."}, {"", ""}, From 1da9e2e1c0d3b6e95f576f933509126e129cb1b1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 15 Feb 2023 21:59:06 +0000 Subject: [PATCH 0117/1160] 2.46.0 Signed-off-by: R4SAS --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4606a69b..1ef24b13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ ## [2.46.0] - 2023-02-15 ### Added - Limit number of acked SSU2 packets to 511 -- Localization to Swedish +- Localization to Swedish, Portuguese, Turkish, Polish - Periodically send Datetime block in NTCP2 and SSU2 - Don't select random port from reserved - In memory table for peer profiles From b8590075e6d341e6a9f5882e3eed2201ee08405c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Feb 2023 22:14:02 -0500 Subject: [PATCH 0118/1160] initial commit for Kademlia DHT --- libi2pd/KadDHT.cpp | 238 +++++++++++++++++++++++++++++++++++++++++++++ libi2pd/KadDHT.h | 64 ++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 libi2pd/KadDHT.cpp create mode 100644 libi2pd/KadDHT.h diff --git a/libi2pd/KadDHT.cpp b/libi2pd/KadDHT.cpp new file mode 100644 index 00000000..29664f79 --- /dev/null +++ b/libi2pd/KadDHT.cpp @@ -0,0 +1,238 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +* +*/ + +#include "KadDHT.h" + +namespace i2p +{ +namespace data +{ + DHTNode::DHTNode (): + zero (nullptr), one (nullptr), hash (nullptr) + { + } + + DHTNode::~DHTNode () + { + if (zero) delete zero; + if (one) delete one; + if (hash) delete hash; + } + + void DHTNode::MoveHashUp (bool fromOne) + { + DHTNode *& side = fromOne ? one : zero; + if (side) + { + if (hash) delete hash; // shouldn't happen + hash = side->hash; + side->hash = nullptr; + delete side; + side = nullptr; + } + } + + DHTTable::DHTTable (): + m_Size (0) + { + m_Root = new DHTNode; + } + + DHTTable::~DHTTable () + { + delete m_Root; + } + + DHTNode * DHTTable::Insert (const IdentHash& h) + { + return Insert (new IdentHash (h), m_Root, 0); + } + + DHTNode * DHTTable::Insert (IdentHash * h, DHTNode * root, int level) + { + if (root->hash) + { + if (*(root->hash) == *h) + { + delete h; + return root; + } + auto h2 = root->hash; + root->hash = nullptr; m_Size--; + int bit1, bit2; + do + { + bit1 = h->GetBit (level); + bit2 = h2->GetBit (level); + if (bit1 == bit2) + { + if (bit1) + { + if (root->one) return nullptr; // someting wrong + root->one = new DHTNode; + root = root->one; + } + else + { + if (root->zero) return nullptr; // someting wrong + root->zero = new DHTNode; + root = root->zero; + } + level++; + } + } + while (bit1 == bit2); + + if (!root->zero) + root->zero = new DHTNode; + if (!root->one) + root->one = new DHTNode; + if (bit1) + { + Insert (h2, root->zero, level + 1); + return Insert (h, root->one, level + 1); + } + else + { + Insert (h2, root->one, level + 1); + return Insert (h, root->zero, level + 1); + } + } + else + { + if (!root->zero && !root->one) + { + root->hash = h; m_Size++; + return root; + } + int bit = h->GetBit (level); + if (bit) + { + if (!root->one) + root->one = new DHTNode; + return Insert (h, root->one, level + 1); + } + else + { + if (!root->zero) + root->zero = new DHTNode; + return Insert (h, root->zero, level + 1); + } + } + return nullptr; + } + + bool DHTTable::Remove (const IdentHash& h) + { + return Remove (h, m_Root, 0); + } + + bool DHTTable::Remove (const IdentHash& h, DHTNode * root, int level) + { + if (root) + { + if (root->hash && *(root->hash) == h) + { + delete root->hash; root->hash = nullptr; + m_Size--; + return true; + } + int bit = h.GetBit (level); + if (bit) + { + if (root->one && Remove (h, root->one, level + 1)) + { + if (root->one->IsEmpty ()) + { + delete root->one; + root->one = nullptr; + if (root->zero && root->zero->hash) + root->MoveHashUp (false); + } + else if (root->one->hash && !root->zero) + root->MoveHashUp (true); + return true; + } + } + else + { + if (root->zero && Remove (h, root->zero, level + 1)) + { + if (root->zero->IsEmpty ()) + { + delete root->zero; + root->zero = nullptr; + if (root->one && root->one->hash) + root->MoveHashUp (true); + } + else if (root->zero->hash && !root->one) + root->MoveHashUp (false); + return true; + } + } + } + return false; + } + + IdentHash * DHTTable::FindClosest (const IdentHash& h) + { + return FindClosest (h, m_Root, 0); + } + + IdentHash * DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) + { + if (root->hash) return root->hash; + int bit = h.GetBit (level); + if (bit) + { + if (root->one) + return FindClosest (h, root->one, level + 1); + if (root->zero) + return FindClosest (h, root->zero, level + 1); + } + else + { + if (root->zero) + return FindClosest (h, root->zero, level + 1); + if (root->one) + return FindClosest (h, root->one, level + 1); + } + return nullptr; + } + + void DHTTable::Print (std::stringstream& s) + { + Print (s, m_Root, 0); + } + + void DHTTable::Print (std::stringstream& s, DHTNode * root, int level) + { + if (!root) return; + s << std::string (level, '-'); + if (root->hash) + { + if (!root->zero && !root->one) + s << '>' << GetIdentHashAbbreviation (*(root->hash)); + else + s << "error"; + } + s << std::endl; + if (root->zero) + { + s << std::string (level, '-') << "0" << std::endl; + Print (s, root->zero, level + 1); + } + if (root->one) + { + s << std::string (level, '-') << "1" << std::endl; + Print (s, root->one, level + 1); + } + } +} +} diff --git a/libi2pd/KadDHT.h b/libi2pd/KadDHT.h new file mode 100644 index 00000000..4a1b61b6 --- /dev/null +++ b/libi2pd/KadDHT.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +* +*/ + +#ifndef KADDHT_H__ +#define KADDHT_H__ + +#include +#include +#include "Identity.h" + +// Kademlia DHT (XOR distance) + +namespace i2p +{ +namespace data +{ + struct DHTNode + { + DHTNode * zero, * one; + IdentHash * hash; + + DHTNode (); + ~DHTNode (); + + bool IsEmpty () const { return !zero && !one && !hash; }; + void MoveHashUp (bool fromOne); + }; + + class DHTTable + { + public: + + DHTTable (); + ~DHTTable (); + + DHTNode * Insert (const IdentHash& h); + bool Remove (const IdentHash& h); + IdentHash * FindClosest (const IdentHash& h); + + void Print (std::stringstream& s); + size_t GetSize () const { return m_Size; }; + + private: + + DHTNode * Insert (IdentHash * h, DHTNode * root, int level); // recursive + bool Remove (const IdentHash& h, DHTNode * root, int level); + IdentHash * FindClosest (const IdentHash& h, DHTNode * root, int level); + void Print (std::stringstream& s, DHTNode * root, int level); + + private: + + DHTNode * m_Root; + size_t m_Size; + }; +} +} + +#endif From bff12b06f417938168951ac7df429d61ebaf462d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Feb 2023 10:34:14 -0500 Subject: [PATCH 0119/1160] fixed race condition --- libi2pd/RouterInfo.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index afa8cbe0..f33e4198 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -945,9 +945,13 @@ namespace data std::shared_ptr RouterInfo::GetProfile () const { - if (!m_Profile) - m_Profile = GetRouterProfile (GetIdentHash ()); - return m_Profile; + auto profile = m_Profile; + if (!profile) + { + profile = GetRouterProfile (GetIdentHash ()); + m_Profile = profile; + } + return profile; } void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted) const From 289c3086003eaf624e1e42bcbe0bc0901f015bb7 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Feb 2023 20:08:05 -0500 Subject: [PATCH 0120/1160] set proper caps if host is unspecified --- libi2pd/RouterInfo.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index f33e4198..3fb95814 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -661,11 +661,16 @@ namespace data addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP2; - addr->caps = 0; addr->date = 0; addr->published = true; memcpy (addr->s, staticKey, 32); memcpy (addr->i, iv, 16); + addr->caps = 0; + if (host.is_unspecified ()) + { + if (host.is_v4 ()) addr->caps |= eV4; + if (host.is_v6 ()) addr->caps |= eV6; + } if (addr->IsV4 ()) { m_SupportedTransports |= eNTCP2V4; @@ -737,12 +742,19 @@ namespace data addr->host = host; addr->port = port; addr->published = true; - addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC; addr->date = 0; addr->ssu.reset (new SSUExt ()); addr->ssu->mtu = 0; memcpy (addr->s, staticKey, 32); memcpy (addr->i, introKey, 32); + if (!host.is_unspecified ()) + addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC; + else + { + addr->caps = 0; + if (host.is_v4 ()) addr->caps |= eV4; + if (host.is_v6 ()) addr->caps |= eV6; + } if (addr->IsV4 ()) { m_SupportedTransports |= eSSU2V4; From e190dab7d69d48ee0bfcc9358fd8489bb81e021a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Feb 2023 21:13:50 -0500 Subject: [PATCH 0121/1160] fixed crash when shows leasesets --- daemon/HTTPServer.cpp | 5 ++++- libi2pd/LeaseSet.cpp | 4 ++-- libi2pd/LeaseSet.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index f78057b3..e42efb36 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -625,7 +625,10 @@ namespace http { if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); else - ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); + { + ls.reset (new i2p::data::LeaseSet2 (storeType)); + ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false); + } if (!ls) return; s << "
IsExpired()) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index d23fdcb8..8ccfa771 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -315,7 +315,7 @@ namespace data { // standard LS2 header std::shared_ptr identity; - if (readIdentity) + if (readIdentity || !GetIdentity ()) { identity = std::make_shared(buf, len); SetIdentity (identity); diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index a79a5870..566c4655 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -145,6 +145,7 @@ namespace data { public: + LeaseSet2 (uint8_t storeType): LeaseSet (true), m_StoreType (storeType) {}; // for update LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; From ce05cce33131be6fcf7f317412bedd7a2d77cb35 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Feb 2023 08:54:36 -0500 Subject: [PATCH 0122/1160] validate LeaseSet if signature verification was not requested --- libi2pd/LeaseSet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8ccfa771..4d756bdb 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -366,6 +366,8 @@ namespace data VerifySignature (identity, buf, len, offset); SetIsValid (verified); } + else + SetIsValid (true); offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen (); if (offset > len) { LogPrint (eLogWarning, "LeaseSet2: short buffer: wanted ", int(offset), "bytes, have ", int(len)); From eaca435a5bd65e40bc0415a7b227bef4fda56fa7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Feb 2023 19:45:31 -0500 Subject: [PATCH 0123/1160] find multiple closest hashes --- libi2pd/KadDHT.cpp | 33 +++++++++++++++++++++++++++++++++ libi2pd/KadDHT.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/libi2pd/KadDHT.cpp b/libi2pd/KadDHT.cpp index 29664f79..c3905b7a 100644 --- a/libi2pd/KadDHT.cpp +++ b/libi2pd/KadDHT.cpp @@ -205,6 +205,39 @@ namespace data } return nullptr; } + + std::vector DHTTable::FindClosest (const IdentHash& h, size_t num) + { + std::vector vec; + if (num > 0) + FindClosest (h, num, m_Root, 0, vec); + return vec; + } + + void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector& hashes) + { + if (hashes.size () >= num) return; + if (root->hash) + { + hashes.push_back (root->hash); + return; + } + int bit = h.GetBit (level); + if (bit) + { + if (root->one) + FindClosest (h, num, root->one, level + 1, hashes); + if (hashes.size () < num && root->zero) + FindClosest (h, num, root->zero, level + 1, hashes); + } + else + { + if (root->zero) + FindClosest (h, num, root->zero, level + 1, hashes); + if (hashes.size () < num && root->one) + FindClosest (h, num, root->one, level + 1, hashes); + } + } void DHTTable::Print (std::stringstream& s) { diff --git a/libi2pd/KadDHT.h b/libi2pd/KadDHT.h index 4a1b61b6..eb12aae7 100644 --- a/libi2pd/KadDHT.h +++ b/libi2pd/KadDHT.h @@ -11,6 +11,7 @@ #define KADDHT_H__ #include +#include #include #include "Identity.h" @@ -42,6 +43,7 @@ namespace data DHTNode * Insert (const IdentHash& h); bool Remove (const IdentHash& h); IdentHash * FindClosest (const IdentHash& h); + std::vector FindClosest (const IdentHash& h, size_t num); void Print (std::stringstream& s); size_t GetSize () const { return m_Size; }; @@ -51,6 +53,7 @@ namespace data DHTNode * Insert (IdentHash * h, DHTNode * root, int level); // recursive bool Remove (const IdentHash& h, DHTNode * root, int level); IdentHash * FindClosest (const IdentHash& h, DHTNode * root, int level); + void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector& hashes); void Print (std::stringstream& s, DHTNode * root, int level); private: From b8a99878b67e93d642a11108a290fe49b10c06cc Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 19 Feb 2023 10:30:07 -0500 Subject: [PATCH 0124/1160] don't create profile for every new non-floodfill --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 34ad5efc..5bc9c47e 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -315,7 +315,7 @@ namespace data else { r = std::make_shared (buf, len); - if (!r->IsUnreachable () && r->HasValidAddresses () && !r->GetProfile ()->IsUnreachable () && + if (!r->IsUnreachable () && r->HasValidAddresses () && (!r->IsFloodfill () || !r->GetProfile ()->IsUnreachable ()) && i2p::util::GetMillisecondsSinceEpoch () + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL > r->GetTimestamp ()) { bool inserted = false; @@ -1398,7 +1398,7 @@ namespace data std::unique_lock l(m_FloodfillsMutex); for (const auto& it: m_Floodfills) { - if (!it->IsUnreachable ()) + if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) { XORMetric m = destKey ^ it->GetIdentHash (); if (closeThanUsOnly && ourMetric < m) continue; From 82ac0aa492f400dfd5a2071c97b8d85e5db010e3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 20 Feb 2023 05:49:59 +0300 Subject: [PATCH 0125/1160] 2.46.1 Signed-off-by: R4SAS --- ChangeLog | 6 ++++++ contrib/i2pd.conf | 3 ++- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ef24b13..a361e198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.46.1] - 2023-02-20 +### Fixed +- Race condition while getting router's peer profile +- Creation of new router.info +- Displaying floodfills in the webconsole + ## [2.46.0] - 2023-02-15 ### Added - Limit number of acked SSU2 packets to 511 diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index c8baa046..84d00347 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -129,7 +129,8 @@ port = 7070 # pass = changeme ## Select webconsole language ## Currently supported english (default), afrikaans, armenian, chinese, czech, french, -## german, italian, russian, spanish, turkmen, ukrainian and uzbek languages +## german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian +## and uzbek languages # lang = english [httpproxy] diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index e902d1fd..e758d42b 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.46.0 +Version: 2.46.1 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Feb 20 2023 r4sas - 2.46.1 +- update to 2.46.1 + * Wed Feb 15 2023 orignal - 2.46.0 - update to 2.46.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5ddd8727..6f413e52 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.46.0 +Version: 2.46.1 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Feb 20 2023 r4sas - 2.46.1 +- update to 2.46.1 + * Wed Feb 15 2023 orignal - 2.46.0 - update to 2.46.0 diff --git a/debian/changelog b/debian/changelog index 91d8f1dc..f13587c6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.46.1-1) unstable; urgency=high + + * updated to version 2.46.1/0.9.57 + + -- r4sas Mon, 20 Feb 2023 02:45:00 +0000 + i2pd (2.46.0-1) unstable; urgency=high * updated to version 2.46.0/0.9.57 diff --git a/libi2pd/version.h b/libi2pd/version.h index e1206d21..b7de21a8 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -17,7 +17,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 46 -#define I2PD_VERSION_MICRO 0 +#define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION GITVER From 200ad5524de253b3739edcedfdc9364fc9070dbe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 20 Feb 2023 02:57:56 +0000 Subject: [PATCH 0126/1160] 2.46.1 Signed-off-by: R4SAS --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a361e198..870f2cc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,7 @@ ### Fixed - Race condition while getting router's peer profile - Creation of new router.info -- Displaying floodfills in the webconsole +- Displaying LeaseSets in the webconsole ## [2.46.0] - 2023-02-15 ### Added From 3adff82d4a3ee40f854615d850955e7ce3f6f091 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 20 Feb 2023 14:55:59 -0500 Subject: [PATCH 0127/1160] don't handle ack request for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index e240e925..7f9fb72d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -335,7 +335,8 @@ namespace garlic case eECIESx25519BlkAckRequest: { LogPrint (eLogDebug, "Garlic: Ack request"); - m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); + if (receiveTagset) + m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); break; } case eECIESx25519BlkTermination: From ebee6c5f1353f71ce3d325f08c29d07783cdc44d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 21 Feb 2023 05:53:51 +0300 Subject: [PATCH 0128/1160] 2.46.1-1 Signed-off-by: R4SAS --- ChangeLog | 1 + contrib/rpm/i2pd.spec | 2 +- debian/changelog | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 870f2cc9..385a3545 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - Race condition while getting router's peer profile - Creation of new router.info - Displaying LeaseSets in the webconsole +- Crash when processing ACK request ## [2.46.0] - 2023-02-15 ### Added diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 6f413e52..32154a9c 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.46.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git diff --git a/debian/changelog b/debian/changelog index f13587c6..13691601 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.46.1-2) unstable; urgency=critical + + * re-pushed release due to new critical bug + + -- r4sas Mon, 20 Feb 2023 23:40:00 +0000 + i2pd (2.46.1-1) unstable; urgency=high * updated to version 2.46.1/0.9.57 From be2629aa5a1a98b64948a24c46d1016d99ef8cd7 Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 21 Feb 2023 11:14:53 +0200 Subject: [PATCH 0129/1160] Remove extra null characters from webconsole output --- i18n/I18N.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/i18n/I18N.h b/i18n/I18N.h index 395c18eb..6ec5b16e 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -95,9 +95,8 @@ std::string tr (TValue&& arg, TArgs&&... args) std::string tr_str = i2p::i18n::translate(std::forward(arg)); size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); - size = size + 1; std::string str(size, 0); - std::snprintf(&str.front(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward(args)...); return str; } @@ -127,9 +126,8 @@ std::string ntr (TValue&& arg, TValue2&& arg2, int& n, TArgs&&... args) std::string tr_str = i2p::i18n::translate(std::forward(arg), std::forward(arg2), std::forward(n)); size_t size = std::snprintf(NULL, 0, tr_str.c_str(), std::forward(args)...); - size = size + 1; std::string str(size, 0); - std::snprintf(&str.front(), size, tr_str.c_str(), std::forward(args)...); + std::snprintf(&str.front(), size + 1, tr_str.c_str(), std::forward(args)...); return str; } From abf687ff095671a52b45832e90613d4ec38840e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Feb 2023 19:08:12 -0500 Subject: [PATCH 0130/1160] store RouterInfo in DHT --- libi2pd/KadDHT.cpp | 213 +++++++++++++++++++++++++++++++++------------ libi2pd/KadDHT.h | 27 +++--- libi2pd/NetDb.cpp | 7 +- libi2pd/NetDb.hpp | 2 +- 4 files changed, 177 insertions(+), 72 deletions(-) diff --git a/libi2pd/KadDHT.cpp b/libi2pd/KadDHT.cpp index c3905b7a..48486675 100644 --- a/libi2pd/KadDHT.cpp +++ b/libi2pd/KadDHT.cpp @@ -14,7 +14,7 @@ namespace i2p namespace data { DHTNode::DHTNode (): - zero (nullptr), one (nullptr), hash (nullptr) + zero (nullptr), one (nullptr) { } @@ -22,17 +22,16 @@ namespace data { if (zero) delete zero; if (one) delete one; - if (hash) delete hash; } - void DHTNode::MoveHashUp (bool fromOne) + void DHTNode::MoveRouterUp (bool fromOne) { DHTNode *& side = fromOne ? one : zero; if (side) { - if (hash) delete hash; // shouldn't happen - hash = side->hash; - side->hash = nullptr; + if (router) router = nullptr; // shouldn't happen + router = side->router; + side->router = nullptr; delete side; side = nullptr; } @@ -49,38 +48,46 @@ namespace data delete m_Root; } - DHTNode * DHTTable::Insert (const IdentHash& h) + void DHTTable::Clear () { - return Insert (new IdentHash (h), m_Root, 0); + m_Size = 0; + delete m_Root; + m_Root = new DHTNode; + } + + void DHTTable::Insert (const std::shared_ptr& r) + { + if (!r) return; + return Insert (r, m_Root, 0); } - DHTNode * DHTTable::Insert (IdentHash * h, DHTNode * root, int level) + void DHTTable::Insert (const std::shared_ptr& r, DHTNode * root, int level) { - if (root->hash) + if (root->router) { - if (*(root->hash) == *h) + if (root->router->GetIdentHash () == r->GetIdentHash ()) { - delete h; - return root; + root->router = r; // replace + return; } - auto h2 = root->hash; - root->hash = nullptr; m_Size--; + auto r2 = root->router; + root->router = nullptr; m_Size--; int bit1, bit2; do { - bit1 = h->GetBit (level); - bit2 = h2->GetBit (level); + bit1 = r->GetIdentHash ().GetBit (level); + bit2 = r2->GetIdentHash ().GetBit (level); if (bit1 == bit2) { if (bit1) { - if (root->one) return nullptr; // someting wrong + if (root->one) return; // someting wrong root->one = new DHTNode; root = root->one; } else { - if (root->zero) return nullptr; // someting wrong + if (root->zero) return; // someting wrong root->zero = new DHTNode; root = root->zero; } @@ -95,37 +102,36 @@ namespace data root->one = new DHTNode; if (bit1) { - Insert (h2, root->zero, level + 1); - return Insert (h, root->one, level + 1); + Insert (r2, root->zero, level + 1); + Insert (r, root->one, level + 1); } else { - Insert (h2, root->one, level + 1); - return Insert (h, root->zero, level + 1); + Insert (r2, root->one, level + 1); + Insert (r, root->zero, level + 1); } } else { if (!root->zero && !root->one) { - root->hash = h; m_Size++; - return root; + root->router = r; m_Size++; + return; } - int bit = h->GetBit (level); + int bit = r->GetIdentHash ().GetBit (level); if (bit) { if (!root->one) root->one = new DHTNode; - return Insert (h, root->one, level + 1); + Insert (r, root->one, level + 1); } else { if (!root->zero) root->zero = new DHTNode; - return Insert (h, root->zero, level + 1); + Insert (r, root->zero, level + 1); } } - return nullptr; } bool DHTTable::Remove (const IdentHash& h) @@ -137,9 +143,9 @@ namespace data { if (root) { - if (root->hash && *(root->hash) == h) + if (root->router && root->router->GetIdentHash () == h) { - delete root->hash; root->hash = nullptr; + root->router = nullptr; m_Size--; return true; } @@ -152,11 +158,11 @@ namespace data { delete root->one; root->one = nullptr; - if (root->zero && root->zero->hash) - root->MoveHashUp (false); + if (root->zero && root->zero->router) + root->MoveRouterUp (false); } - else if (root->one->hash && !root->zero) - root->MoveHashUp (true); + else if (root->one->router && !root->zero) + root->MoveRouterUp (true); return true; } } @@ -168,11 +174,11 @@ namespace data { delete root->zero; root->zero = nullptr; - if (root->one && root->one->hash) - root->MoveHashUp (true); + if (root->one && root->one->router) + root->MoveRouterUp (true); } - else if (root->zero->hash && !root->one) - root->MoveHashUp (false); + else if (root->zero->router && !root->one) + root->MoveRouterUp (false); return true; } } @@ -180,48 +186,95 @@ namespace data return false; } - IdentHash * DHTTable::FindClosest (const IdentHash& h) + std::shared_ptr DHTTable::FindClosest (const IdentHash& h, const Filter& filter) { - return FindClosest (h, m_Root, 0); + if (filter) m_Filter = filter; + auto r = FindClosest (h, m_Root, 0); + m_Filter = nullptr; + return r; } - IdentHash * DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) + std::shared_ptr DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) { - if (root->hash) return root->hash; + bool split = false; + do + { + if (root->router) + return (!m_Filter || m_Filter (root->router)) ? root->router : nullptr; + split = root->zero && root->one; + if (!split) + { + if (root->zero) root = root->zero; + else if (root->one) root = root->one; + else return nullptr; + level++; + } + } + while (!split); int bit = h.GetBit (level); if (bit) { if (root->one) - return FindClosest (h, root->one, level + 1); + { + auto r = FindClosest (h, root->one, level + 1); + if (r) return r; + } if (root->zero) - return FindClosest (h, root->zero, level + 1); + { + auto r = FindClosest (h, root->zero, level + 1); + if (r) return r; + } } else { if (root->zero) - return FindClosest (h, root->zero, level + 1); + { + auto r = FindClosest (h, root->zero, level + 1); + if (r) return r; + } if (root->one) - return FindClosest (h, root->one, level + 1); + { + auto r = FindClosest (h, root->one, level + 1); + if (r) return r; + } } return nullptr; } - std::vector DHTTable::FindClosest (const IdentHash& h, size_t num) + std::vector > DHTTable::FindClosest (const IdentHash& h, size_t num, const Filter& filter) { - std::vector vec; + std::vector > vec; if (num > 0) + { + if (filter) m_Filter = filter; FindClosest (h, num, m_Root, 0, vec); + m_Filter = nullptr; + } return vec; } - void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector& hashes) + void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes) { if (hashes.size () >= num) return; - if (root->hash) + bool split = false; + do { - hashes.push_back (root->hash); - return; - } + if (root->router) + { + if (!m_Filter || m_Filter (root->router)) + hashes.push_back (root->router); + return; + } + split = root->zero && root->one; + if (!split) + { + if (root->zero) root = root->zero; + else if (root->one) root = root->one; + else return; + level++; + } + } + while (!split); int bit = h.GetBit (level); if (bit) { @@ -238,6 +291,54 @@ namespace data FindClosest (h, num, root->one, level + 1, hashes); } } + + void DHTTable::Cleanup (Filter filter) + { + if (filter) + { + m_Filter = filter; + Cleanup (m_Root); + m_Filter = nullptr; + } + else + Clear (); + } + + void DHTTable::Cleanup (DHTNode * root) + { + if (!root) return; + if (root->router) + { + if (!m_Filter || !m_Filter (root->router)) + { + m_Size--; + root->router = nullptr; + } + return; + } + if (root->zero) + { + Cleanup (root->zero); + if (root->zero->IsEmpty ()) + { + delete root->zero; + root->zero = nullptr; + } + } + if (root->one) + { + Cleanup (root->one); + if (root->one->IsEmpty ()) + { + delete root->one; + root->one = nullptr; + if (root->zero && root->zero->router) + root->MoveRouterUp (false); + } + else if (root->one->router && !root->zero) + root->MoveRouterUp (true); + } + } void DHTTable::Print (std::stringstream& s) { @@ -248,10 +349,10 @@ namespace data { if (!root) return; s << std::string (level, '-'); - if (root->hash) + if (root->router) { if (!root->zero && !root->one) - s << '>' << GetIdentHashAbbreviation (*(root->hash)); + s << '>' << GetIdentHashAbbreviation (root->router->GetIdentHash ()); else s << "error"; } diff --git a/libi2pd/KadDHT.h b/libi2pd/KadDHT.h index eb12aae7..c280a1de 100644 --- a/libi2pd/KadDHT.h +++ b/libi2pd/KadDHT.h @@ -13,7 +13,8 @@ #include #include #include -#include "Identity.h" +#include +#include "RouterInfo.h" // Kademlia DHT (XOR distance) @@ -24,42 +25,48 @@ namespace data struct DHTNode { DHTNode * zero, * one; - IdentHash * hash; + std::shared_ptr router; DHTNode (); ~DHTNode (); - bool IsEmpty () const { return !zero && !one && !hash; }; - void MoveHashUp (bool fromOne); + bool IsEmpty () const { return !zero && !one && !router; }; + void MoveRouterUp (bool fromOne); }; class DHTTable { + typedef std::function&)> Filter; public: DHTTable (); ~DHTTable (); - DHTNode * Insert (const IdentHash& h); + void Insert (const std::shared_ptr& r); bool Remove (const IdentHash& h); - IdentHash * FindClosest (const IdentHash& h); - std::vector FindClosest (const IdentHash& h, size_t num); + std::shared_ptr FindClosest (const IdentHash& h, const Filter& filter = nullptr); + std::vector > FindClosest (const IdentHash& h, size_t num, const Filter& filter = nullptr); void Print (std::stringstream& s); size_t GetSize () const { return m_Size; }; + void Clear (); + void Cleanup (Filter filter); private: - DHTNode * Insert (IdentHash * h, DHTNode * root, int level); // recursive + void Insert (const std::shared_ptr& r, DHTNode * root, int level); // recursive bool Remove (const IdentHash& h, DHTNode * root, int level); - IdentHash * FindClosest (const IdentHash& h, DHTNode * root, int level); - void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector& hashes); + std::shared_ptr FindClosest (const IdentHash& h, DHTNode * root, int level); + void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes); + void Cleanup (DHTNode * root); void Print (std::stringstream& s, DHTNode * root, int level); private: DHTNode * m_Root; size_t m_Size; + // transient + Filter m_Filter; }; } } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5bc9c47e..685189ed 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1355,15 +1355,12 @@ namespace data } std::shared_ptr NetDb::GetClosestFloodfill (const IdentHash& destination, - const std::set& excluded, bool closeThanUsOnly) const + const std::set& excluded) const { std::shared_ptr r; XORMetric minMetric; IdentHash destKey = CreateRoutingKey (destination); - if (closeThanUsOnly) - minMetric = destKey ^ i2p::context.GetIdentHash (); - else - minMetric.SetMax (); + minMetric.SetMax (); std::unique_lock l(m_FloodfillsMutex); for (const auto& it: m_Floodfills) { diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index f0315582..192d2644 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -93,7 +93,7 @@ namespace data std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetRandomSSU2PeerTestRouter (bool v4, const std::set& excluded) const; std::shared_ptr GetRandomSSU2Introducer (bool v4, const std::set& excluded) const; - std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; + std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; From 85442831105dac2a879116c4f66b0224b3951dd6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Feb 2023 21:33:30 -0500 Subject: [PATCH 0131/1160] don't expire connected routers --- libi2pd/NetDb.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 685189ed..11cf8066 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -664,21 +664,26 @@ namespace data if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS || isLowRate || (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) it.second->SetUnreachable (false); - // find & mark expired routers - if (!it.second->IsReachable () && (it.second->GetCompatibleTransports (true) & RouterInfo::eSSU2V4)) - // non-reachable router, but reachable by ipv4 SSU2 means introducers - { - if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) - // RouterInfo expires after 1 hour if uses introducer + if (!it.second->IsUnreachable ()) + { + // find & mark expired routers + if (!it.second->IsReachable () && (it.second->GetCompatibleTransports (true) & RouterInfo::eSSU2V4)) + // non-reachable router, but reachable by ipv4 SSU2 means introducers + { + if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) + // RouterInfo expires after 1 hour if uses introducer + it.second->SetUnreachable (true); + } + else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) it.second->SetUnreachable (true); - } - else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) - it.second->SetUnreachable (true); - else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ()) - { - LogPrint (eLogWarning, "NetDb: RouterInfo is from future for ", (it.second->GetTimestamp () - ts)/1000LL, " seconds"); - it.second->SetUnreachable (true); - } + else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ()) + { + LogPrint (eLogWarning, "NetDb: RouterInfo is from future for ", (it.second->GetTimestamp () - ts)/1000LL, " seconds"); + it.second->SetUnreachable (true); + } + if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ())) + it.second->SetUnreachable (false); // don't expire connected router + } if (it.second->IsUnreachable ()) { From 95cc544c92a0d941fdcad62fb730b04280d3431e Mon Sep 17 00:00:00 2001 From: Vort Date: Wed, 22 Feb 2023 19:31:24 +0200 Subject: [PATCH 0132/1160] Check for null pointer before dereferencing it --- libi2pd/NTCP2.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 813ea6d5..eaa186f8 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1457,7 +1457,7 @@ namespace transport void NTCP2Server::HandleAccept (std::shared_ptr conn, const boost::system::error_code& error) { - if (!error) + if (!error && conn) { boost::system::error_code ec; auto ep = conn->GetSocket ().remote_endpoint(ec); @@ -1466,17 +1466,14 @@ namespace transport LogPrint (eLogDebug, "NTCP2: Connected from ", ep); if (!i2p::util::net::IsInReservedRange(ep.address ())) { - if (conn) + if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) { - if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) - { - conn->SetRemoteEndpoint (ep); - conn->ServerLogin (); - conn = nullptr; - } - else - LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending"); + conn->SetRemoteEndpoint (ep); + conn->ServerLogin (); + conn = nullptr; } + else + LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending"); } else LogPrint (eLogError, "NTCP2: Incoming connection from invalid IP ", ep.address ()); @@ -1507,7 +1504,7 @@ namespace transport void NTCP2Server::HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error) { - if (!error) + if (!error && conn) { boost::system::error_code ec; auto ep = conn->GetSocket ().remote_endpoint(ec); @@ -1517,17 +1514,14 @@ namespace transport if (!i2p::util::net::IsInReservedRange(ep.address ()) || i2p::util::net::IsYggdrasilAddress (ep.address ())) { - if (conn) + if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) { - if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) - { - conn->SetRemoteEndpoint (ep); - conn->ServerLogin (); - conn = nullptr; - } - else - LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending"); + conn->SetRemoteEndpoint (ep); + conn->ServerLogin (); + conn = nullptr; } + else + LogPrint (eLogInfo, "NTCP2: Incoming session from ", ep.address (), " is already pending"); } else LogPrint (eLogError, "NTCP2: Incoming connection from invalid IP ", ep.address ()); From d40cd00cdb01ae3080f49bad2ef151fe474e6051 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Feb 2023 15:58:20 -0500 Subject: [PATCH 0133/1160] use DHT table for floodfills --- libi2pd/KadDHT.cpp | 10 ++--- libi2pd/KadDHT.h | 12 ++--- libi2pd/NetDb.cpp | 108 +++++++++++++++------------------------------ libi2pd/NetDb.hpp | 6 +-- 4 files changed, 49 insertions(+), 87 deletions(-) diff --git a/libi2pd/KadDHT.cpp b/libi2pd/KadDHT.cpp index 48486675..b171cdbc 100644 --- a/libi2pd/KadDHT.cpp +++ b/libi2pd/KadDHT.cpp @@ -186,7 +186,7 @@ namespace data return false; } - std::shared_ptr DHTTable::FindClosest (const IdentHash& h, const Filter& filter) + std::shared_ptr DHTTable::FindClosest (const IdentHash& h, const Filter& filter) const { if (filter) m_Filter = filter; auto r = FindClosest (h, m_Root, 0); @@ -194,7 +194,7 @@ namespace data return r; } - std::shared_ptr DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) + std::shared_ptr DHTTable::FindClosest (const IdentHash& h, DHTNode * root, int level) const { bool split = false; do @@ -241,7 +241,7 @@ namespace data return nullptr; } - std::vector > DHTTable::FindClosest (const IdentHash& h, size_t num, const Filter& filter) + std::vector > DHTTable::FindClosest (const IdentHash& h, size_t num, const Filter& filter) const { std::vector > vec; if (num > 0) @@ -253,7 +253,7 @@ namespace data return vec; } - void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes) + void DHTTable::FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes) const { if (hashes.size () >= num) return; bool split = false; @@ -292,7 +292,7 @@ namespace data } } - void DHTTable::Cleanup (Filter filter) + void DHTTable::Cleanup (const Filter& filter) { if (filter) { diff --git a/libi2pd/KadDHT.h b/libi2pd/KadDHT.h index c280a1de..3bc31780 100644 --- a/libi2pd/KadDHT.h +++ b/libi2pd/KadDHT.h @@ -44,20 +44,20 @@ namespace data void Insert (const std::shared_ptr& r); bool Remove (const IdentHash& h); - std::shared_ptr FindClosest (const IdentHash& h, const Filter& filter = nullptr); - std::vector > FindClosest (const IdentHash& h, size_t num, const Filter& filter = nullptr); + std::shared_ptr FindClosest (const IdentHash& h, const Filter& filter = nullptr) const; + std::vector > FindClosest (const IdentHash& h, size_t num, const Filter& filter = nullptr) const; void Print (std::stringstream& s); size_t GetSize () const { return m_Size; }; void Clear (); - void Cleanup (Filter filter); + void Cleanup (const Filter& filter); private: void Insert (const std::shared_ptr& r, DHTNode * root, int level); // recursive bool Remove (const IdentHash& h, DHTNode * root, int level); - std::shared_ptr FindClosest (const IdentHash& h, DHTNode * root, int level); - void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes); + std::shared_ptr FindClosest (const IdentHash& h, DHTNode * root, int level) const; + void FindClosest (const IdentHash& h, size_t num, DHTNode * root, int level, std::vector >& hashes) const; void Cleanup (DHTNode * root); void Print (std::stringstream& s, DHTNode * root, int level); @@ -66,7 +66,7 @@ namespace data DHTNode * m_Root; size_t m_Size; // transient - Filter m_Filter; + mutable Filter m_Filter; }; } } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 11cf8066..09d57bac 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -55,7 +55,7 @@ namespace data Load (); uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); - if (m_RouterInfos.size () < threshold || m_Floodfills.size () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils + if (m_RouterInfos.size () < threshold || m_Floodfills.GetSize () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils { Reseed (); } @@ -66,13 +66,13 @@ namespace data if (it != m_RouterInfos.end ()) { // remove own router - m_Floodfills.remove (it->second); + m_Floodfills.Remove (it->second->GetIdentHash ()); m_RouterInfos.erase (it); } // insert own router m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); if (i2p::context.IsFloodfill ()) - m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ()); + m_Floodfills.Insert (i2p::context.GetSharedRouterInfo ()); i2p::config::GetOption("persist.profiles", m_PersistProfiles); @@ -88,7 +88,7 @@ namespace data SaveProfiles (); DeleteObsoleteProfiles (); m_RouterInfos.clear (); - m_Floodfills.clear (); + m_Floodfills.Clear (); if (m_Thread) { m_IsRunning = false; @@ -289,7 +289,7 @@ namespace data if (wasFloodfill) { std::unique_lock l(m_FloodfillsMutex); - m_Floodfills.remove (r); + m_Floodfills.Remove (r->GetIdentHash ()); } m_Requests.RequestComplete (ident, nullptr); return nullptr; @@ -301,9 +301,9 @@ namespace data LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); std::unique_lock l(m_FloodfillsMutex); if (wasFloodfill) - m_Floodfills.remove (r); + m_Floodfills.Remove (r->GetIdentHash ()); else if (r->IsEligibleFloodfill ()) - m_Floodfills.push_back (r); + m_Floodfills.Insert (r); } } else @@ -329,7 +329,7 @@ namespace data if (r->IsFloodfill () && r->IsEligibleFloodfill ()) { std::unique_lock l(m_FloodfillsMutex); - m_Floodfills.push_back (r); + m_Floodfills.Insert (r); } } else @@ -530,7 +530,7 @@ namespace data if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) { if (r->IsFloodfill () && r->IsEligibleFloodfill ()) - m_Floodfills.push_back (r); + m_Floodfills.Insert (r); } } else @@ -614,7 +614,7 @@ namespace data { // make sure we cleanup netDb from previous attempts m_RouterInfos.clear (); - m_Floodfills.clear (); + m_Floodfills.Clear (); uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); std::vector files; @@ -622,14 +622,14 @@ namespace data for (const auto& path : files) LoadRouterInfo (path, ts); - LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)"); + LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.GetSize (), " floodfils)"); } void NetDb::SaveUpdated () { int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0; auto total = m_RouterInfos.size (); - auto totalFloodfills = m_Floodfills.size (); + auto totalFloodfills = m_Floodfills.GetSize (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); auto uptime = i2p::context.GetUptime (); @@ -721,11 +721,10 @@ namespace data // clean up expired floodfills or not floodfills anymore { std::unique_lock l(m_FloodfillsMutex); - for (auto it = m_Floodfills.begin (); it != m_Floodfills.end ();) - if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ()) - it = m_Floodfills.erase (it); - else - it++; + m_Floodfills.Cleanup ([](const std::shared_ptr& r)->bool + { + return r && r->IsFloodfill () && !r->IsUnreachable (); + }); } } } @@ -1362,75 +1361,38 @@ namespace data std::shared_ptr NetDb::GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const { - std::shared_ptr r; - XORMetric minMetric; IdentHash destKey = CreateRoutingKey (destination); - minMetric.SetMax (); std::unique_lock l(m_FloodfillsMutex); - for (const auto& it: m_Floodfills) - { - if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) + return m_Floodfills.FindClosest (destKey, [&excluded](const std::shared_ptr& r)->bool { - XORMetric m = destKey ^ it->GetIdentHash (); - if (m < minMetric && !excluded.count (it->GetIdentHash ())) - { - minMetric = m; - r = it; - } - } - } - return r; + return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && + !excluded.count (r->GetIdentHash ()); + }); } std::vector NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly) const { - struct Sorted - { - std::shared_ptr r; - XORMetric metric; - bool operator< (const Sorted& other) const { return metric < other.metric; }; - }; - - std::set sorted; + std::vector res; IdentHash destKey = CreateRoutingKey (destination); - XORMetric ourMetric; - if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); + std::vector > v; { std::unique_lock l(m_FloodfillsMutex); - for (const auto& it: m_Floodfills) - { - if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) + v = m_Floodfills.FindClosest (destKey, num, [&excluded](const std::shared_ptr& r)->bool { - XORMetric m = destKey ^ it->GetIdentHash (); - if (closeThanUsOnly && ourMetric < m) continue; - if (sorted.size () < num) - sorted.insert ({it, m}); - else if (m < sorted.rbegin ()->metric) - { - sorted.insert ({it, m}); - sorted.erase (std::prev (sorted.end ())); - } - } - } - } - - std::vector res; - size_t i = 0; - for (const auto& it: sorted) + return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && + !excluded.count (r->GetIdentHash ()); + }); + } + if (v.empty ()) return res; + + XORMetric ourMetric; + if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); + for (auto& it: v) { - if (i < num) - { - const auto& ident = it.r->GetIdentHash (); - if (!excluded.count (ident)) - { - res.push_back (ident); - i++; - } - } - else - break; - } + if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break; + res.push_back (it->GetIdentHash ()); + } return res; } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 192d2644..74774f0d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include "Family.h" #include "version.h" #include "util.h" +#include "KadDHT.h" namespace i2p { @@ -110,7 +110,7 @@ namespace data // for web interface int GetNumRouters () const { return m_RouterInfos.size (); }; - int GetNumFloodfills () const { return m_Floodfills.size (); }; + int GetNumFloodfills () const { return m_Floodfills.GetSize (); }; int GetNumLeaseSets () const { return m_LeaseSets.size (); }; /** visit all lease sets we currently store */ @@ -164,7 +164,7 @@ namespace data mutable std::mutex m_RouterInfosMutex; std::unordered_map > m_RouterInfos; mutable std::mutex m_FloodfillsMutex; - std::list > m_Floodfills; + DHTTable m_Floodfills; bool m_IsRunning; std::thread * m_Thread; From e3fbc246f407e2469b486f0833c2a511fb6ff616 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 23 Feb 2023 00:26:07 +0300 Subject: [PATCH 0134/1160] [gha] try to fix deb build Signed-off-by: R4SAS --- .github/workflows/build-deb.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index bda12dbc..4d981c90 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -13,15 +13,17 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - - name: change debian changelog - run: | - sudo apt-get update - sudo apt-get install devscripts - debchange -v "`git describe --tags`-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "trunk build" + #- name: change debian changelog + # run: | + # sudo apt-get update + # sudo apt-get install devscripts + # debchange -v "`git describe --tags`-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "trunk build" - uses: jtdor/build-deb-action@v1 with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign + before-build-hook: debchange --controlmaint --local="+$(git describe --tags)" "CI build" + extra-build-deps: devscripts - uses: actions/upload-artifact@v3 with: name: i2pd_${{ matrix.dist }} From f33b0cad2e768b6f84787090510fb8cd58977d12 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 23 Feb 2023 14:13:59 +0000 Subject: [PATCH 0135/1160] [gha] update deb build action Signed-off-by: R4SAS --- .github/workflows/build-deb.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index 4d981c90..032cf4c0 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -7,22 +7,18 @@ jobs: name: ${{ matrix.dist }} runs-on: ubuntu-latest strategy: + fail-fast: false matrix: dist: ['buster', 'bullseye', 'bookworm'] steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - #- name: change debian changelog - # run: | - # sudo apt-get update - # sudo apt-get install devscripts - # debchange -v "`git describe --tags`-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "trunk build" - uses: jtdor/build-deb-action@v1 with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign - before-build-hook: debchange --controlmaint --local="+$(git describe --tags)" "CI build" + before-build-hook: debchange -v "$(git describe --tags)-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "CI build" extra-build-deps: devscripts - uses: actions/upload-artifact@v3 with: From db0f2fab117a0684edfaf9d4238659f209b4b672 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 23 Feb 2023 14:24:15 +0000 Subject: [PATCH 0136/1160] [gha] update deb build action Signed-off-by: R4SAS --- .github/workflows/build-deb.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index 032cf4c0..6c659497 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -18,8 +18,8 @@ jobs: with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign - before-build-hook: debchange -v "$(git describe --tags)-${{ matrix.dist }}" -b -M --distribution ${{ matrix.dist }} "CI build" - extra-build-deps: devscripts + before-build-hook: debchange --controlmaint -v "$(git describe --tags)~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" + extra-build-deps: devscripts git - uses: actions/upload-artifact@v3 with: name: i2pd_${{ matrix.dist }} From bd63383d7f97cded3c53130be189bb778a3dbba4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 23 Feb 2023 14:31:50 +0000 Subject: [PATCH 0137/1160] [gha] update deb build action Signed-off-by: R4SAS --- .github/workflows/build-deb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index 6c659497..4d95b849 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -18,7 +18,7 @@ jobs: with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign - before-build-hook: debchange --controlmaint -v "$(git describe --tags)~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" + before-build-hook: debchange --controlmaint --local"+$(git rev-parse --short $GITHUB_SHA)~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" extra-build-deps: devscripts git - uses: actions/upload-artifact@v3 with: From 5657079355f306d0f14305203f11f52506abfd14 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 23 Feb 2023 14:35:38 +0000 Subject: [PATCH 0138/1160] [gha] update deb build action Signed-off-by: R4SAS --- .github/workflows/build-deb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index 4d95b849..f8fd249c 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -18,7 +18,7 @@ jobs: with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign - before-build-hook: debchange --controlmaint --local"+$(git rev-parse --short $GITHUB_SHA)~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" + before-build-hook: debchange --controlmaint --local "+${{ github.sha }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" extra-build-deps: devscripts git - uses: actions/upload-artifact@v3 with: From 2e62f9532f57f75525f6cc8d01f2cb96dbff2b09 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Feb 2023 13:58:06 -0500 Subject: [PATCH 0139/1160] separate thread for processing router's messages --- daemon/Daemon.cpp | 6 +++++- libi2pd/RouterContext.cpp | 40 +++++++++++++++++++++++++-------------- libi2pd/RouterContext.h | 12 +++++++----- libi2pd/api.cpp | 6 +++++- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index a0d7cf1a..b6ce396e 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -334,10 +334,12 @@ namespace util } } - LogPrint(eLogInfo, "Daemon: Starting Tunnels"); i2p::tunnel::tunnels.Start(); + LogPrint(eLogInfo, "Daemon: Starting Router context"); + i2p::context.Start(); + LogPrint(eLogInfo, "Daemon: Starting Client"); i2p::client::context.Start (); @@ -366,6 +368,8 @@ namespace util LogPrint(eLogInfo, "Daemon: Shutting down"); LogPrint(eLogInfo, "Daemon: Stopping Client"); i2p::client::context.Stop(); + LogPrint(eLogInfo, "Daemon: Stopping Router context"); + i2p::context.Stop(); LogPrint(eLogInfo, "Daemon: Stopping Tunnels"); i2p::tunnel::tunnels.Stop(); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 72b723ea..088f91d2 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -26,7 +26,7 @@ namespace i2p { RouterContext context; - RouterContext::RouterContext (): + RouterContext::RouterContext (): RunnableServiceWithWork ("Router"), m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID) @@ -47,6 +47,16 @@ namespace i2p m_ECIESSession = std::make_shared(m_InitialNoiseState); } + void RouterContext::Start () + { + StartIOService (); + } + + void RouterContext::Stop () + { + StopIOService (); + } + void RouterContext::CreateNewRouter () { m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, @@ -1087,12 +1097,6 @@ namespace i2p bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { - if (typeID == eI2NPGarlic) - { - // TODO: implement - LogPrint (eLogWarning, "Router: garlic message in garlic clove. Dropped"); - return false; - } auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); @@ -1101,7 +1105,11 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { - std::unique_lock l(m_GarlicMutex); + GetIOService ().post (std::bind (&RouterContext::PostGarlicMessage, this, msg)); + } + + void RouterContext::PostGarlicMessage (std::shared_ptr msg) + { uint8_t * buf = msg->GetPayload (); uint32_t len = bufbe32toh (buf); if (len > msg->GetLength ()) @@ -1118,23 +1126,27 @@ namespace i2p else LogPrint (eLogError, "Router: Session is not set for ECIES router"); } - } - + } + void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) i2p::data::netdb.PostI2NPMsg (msg); else { - std::unique_lock l(m_GarlicMutex); - i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + GetIOService ().post ([msg, this]() + { + this->i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + }); } } void RouterContext::CleanupDestination () { - std::unique_lock l(m_GarlicMutex); - i2p::garlic::GarlicDestination::CleanupExpiredTags (); + GetIOService ().post ([this]() + { + this->i2p::garlic::GarlicDestination::CleanupExpiredTags (); + }); } uint32_t RouterContext::GetUptime () const diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 9fbbb178..c054bd79 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -12,12 +12,12 @@ #include #include #include -#include #include #include #include "Identity.h" #include "RouterInfo.h" #include "Garlic.h" +#include "util.h" namespace i2p { @@ -52,7 +52,7 @@ namespace garlic eRouterErrorNoDescriptors = 5 }; - class RouterContext: public i2p::garlic::GarlicDestination + class RouterContext: public i2p::garlic::GarlicDestination, private i2p::util::RunnableServiceWithWork { private: @@ -74,7 +74,9 @@ namespace garlic RouterContext (); void Init (); - + void Start (); + void Stop (); + const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; i2p::data::LocalRouterInfo& GetRouterInfo () { return m_RouterInfo; }; std::shared_ptr GetSharedRouterInfo () @@ -183,7 +185,8 @@ namespace garlic void PublishNTCP2Address (std::shared_ptr address, int port, bool publish) const; bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize); - + void PostGarlicMessage (std::shared_ptr msg); + private: i2p::data::LocalRouterInfo m_RouterInfo; @@ -198,7 +201,6 @@ namespace garlic RouterStatus m_Status, m_StatusV6; RouterError m_Error, m_ErrorV6; int m_NetID; - std::mutex m_GarlicMutex; std::unique_ptr m_NTCP2Keys; std::unique_ptr m_SSU2Keys; std::unique_ptr m_NTCP2StaticKeys, m_SSU2StaticKeys; diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index a298e4b4..3bfb801c 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -67,11 +67,15 @@ namespace api i2p::transport::transports.Start(); LogPrint(eLogInfo, "API: Starting Tunnels"); i2p::tunnel::tunnels.Start(); + LogPrint(eLogInfo, "API: Starting Router context"); + i2p::context.Start(); } void StopI2P () { LogPrint(eLogInfo, "API: Shutting down"); + LogPrint(eLogInfo, "API: Stopping Router context"); + i2p::context.Stop(); LogPrint(eLogInfo, "API: Stopping Tunnels"); i2p::tunnel::tunnels.Stop(); LogPrint(eLogInfo, "API: Stopping Transports"); From f84d88ac6391cdd830e362d682adaf350968d50b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Feb 2023 18:28:30 -0500 Subject: [PATCH 0140/1160] publish own RouterInfo in router's thread --- libi2pd/NetDb.cpp | 87 +------------------------- libi2pd/NetDb.hpp | 11 ---- libi2pd/RouterContext.cpp | 128 ++++++++++++++++++++++++++++++++++---- libi2pd/RouterContext.h | 23 ++++++- 4 files changed, 142 insertions(+), 107 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 09d57bac..2302dc86 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -36,7 +36,7 @@ namespace data { NetDb netdb; - NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true), m_HiddenMode(false) + NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true) { } @@ -106,7 +106,7 @@ namespace data { i2p::util::SetThreadName("NetDB"); - uint64_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; + uint64_t lastSave = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch (); int16_t profilesCleanupVariance = 0; @@ -132,9 +132,6 @@ namespace data case eI2NPDatabaseLookup: HandleDatabaseLookupMsg (msg); break; - case eI2NPDeliveryStatus: - HandleDeliveryStatusMsg (msg); - break; case eI2NPDummyMsg: // plain RouterInfo from NTCP2 with flags for now HandleNTCP2RouterInfoMsg (msg); @@ -184,33 +181,6 @@ namespace data profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE); } - // publish - if (!m_HiddenMode && i2p::transport::transports.IsOnline ()) - { - bool publish = false; - if (m_PublishReplyToken) - { - // next publishing attempt - if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true; - } - else if (i2p::context.GetLastUpdateTime () > lastPublish || - ts - lastPublish >= NETDB_PUBLISH_INTERVAL || - ts + NETDB_PUBLISH_INTERVAL < lastPublish) - { - // new publish - m_PublishExcluded.clear (); - if (i2p::context.IsFloodfill ()) - m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // do publish to ourselves - publish = true; - } - if (publish) // update timestamp and publish - { - i2p::context.UpdateTimestamp (ts); - Publish (); - lastPublish = ts; - } - } - if (ts - lastExploratory >= 30 || ts + 30 < lastExploratory) // exploratory every 30 seconds { auto numRouters = m_RouterInfos.size (); @@ -224,7 +194,7 @@ namespace data if (numRouters < 1) numRouters = 1; if (numRouters > 9) numRouters = 9; m_Requests.ManageRequests (); - if(!m_HiddenMode) + if(!i2p::context.IsHidden ()) Explore (numRouters); lastExploratory = ts; } @@ -237,12 +207,6 @@ namespace data } } - void NetDb::SetHidden(bool hide) - { - // TODO: remove reachable addresses from router info - m_HiddenMode = hide; - } - std::shared_ptr NetDb::AddRouterInfo (const uint8_t * buf, int len) { bool updated; @@ -1125,16 +1089,6 @@ namespace data } } - void NetDb::HandleDeliveryStatusMsg (std::shared_ptr msg) - { - if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) - { - LogPrint (eLogInfo, "NetDb: Publishing confirmed. reply token=", m_PublishReplyToken); - m_PublishExcluded.clear (); - m_PublishReplyToken = 0; - } - } - void NetDb::Explore (int numDestinations) { // new requests @@ -1185,41 +1139,6 @@ namespace data outbound->SendTunnelDataMsg (msgs); } - void NetDb::Publish () - { - i2p::context.UpdateStats (); // for floodfill - - if (m_PublishExcluded.size () > NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS) - { - LogPrint (eLogError, "NetDb: Couldn't publish our RouterInfo to ", NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again"); - m_PublishExcluded.clear (); - } - - auto floodfill = GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded); - if (floodfill) - { - uint32_t replyToken; - RAND_bytes ((uint8_t *)&replyToken, 4); - LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); - m_PublishExcluded.insert (floodfill->GetIdentHash ()); - m_PublishReplyToken = replyToken; - if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect? - i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ? - // send directly - transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); - else - { - // otherwise through exploratory - auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); - 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)); - } - } - } - void NetDb::Flood (const IdentHash& ident, std::shared_ptr floodMsg) { std::set excluded; diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 74774f0d..7958e36d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -45,9 +45,6 @@ namespace data const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days const int NETDB_EXPIRATION_TIMEOUT_THRESHOLD = 2*60; // 2 minutes - const int NETDB_PUBLISH_INTERVAL = 60 * 40; - const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds - const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 @@ -86,7 +83,6 @@ namespace data void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void HandleDatabaseLookupMsg (std::shared_ptr msg); void HandleNTCP2RouterInfoMsg (std::shared_ptr m); - void HandleDeliveryStatusMsg (std::shared_ptr msg); std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; @@ -102,9 +98,6 @@ namespace data void PostI2NPMsg (std::shared_ptr msg); - /** set hidden mode, aka don't publish our RI to netdb and don't explore */ - void SetHidden(bool hide); - void Reseed (); Families& GetFamilies () { return m_Families; }; @@ -144,7 +137,6 @@ namespace data void SaveUpdated (); void Run (); // exploratory thread void Explore (int numDestinations); - void Publish (); void Flood (const IdentHash& ident, std::shared_ptr floodMsg); void ManageLeaseSets (); void ManageRequests (); @@ -183,9 +175,6 @@ namespace data /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ std::shared_ptr m_FloodfillBootstrap; - /** true if in hidden mode */ - bool m_HiddenMode; - std::set m_PublishExcluded; uint32_t m_PublishReplyToken = 0; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 088f91d2..77985a11 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -20,6 +20,8 @@ #include "Log.h" #include "Family.h" #include "ECIESX25519AEADRatchetSession.h" +#include "Transports.h" +#include "Tunnel.h" #include "RouterContext.h" namespace i2p @@ -29,7 +31,8 @@ namespace i2p RouterContext::RouterContext (): RunnableServiceWithWork ("Router"), m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), - m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID) + m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID), + m_PublishTimer (GetIOService ()), m_PublishReplyToken (0), m_IsHiddenMode (false) { } @@ -49,11 +52,19 @@ namespace i2p void RouterContext::Start () { - StartIOService (); + if (!IsRunning ()) + { + StartIOService (); + if (!m_IsHiddenMode) + ScheduleInitialPublish (); + } } void RouterContext::Stop () { + if (IsRunning ()) + m_PublishTimer.cancel (); + StopIOService (); } @@ -1130,17 +1141,22 @@ namespace i2p void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) - i2p::data::netdb.PostI2NPMsg (msg); - else - { - GetIOService ().post ([msg, this]() - { - this->i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); - }); - } + GetIOService ().post (std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); } + void RouterContext::PostDeliveryStatusMessage (std::shared_ptr msg) + { + if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) + { + LogPrint (eLogInfo, "Router: Publishing confirmed. reply token=", m_PublishReplyToken); + m_PublishExcluded.clear (); + m_PublishReplyToken = 0; + SchedulePublish (); + } + else + i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + } + void RouterContext::CleanupDestination () { GetIOService ().post ([this]() @@ -1221,4 +1237,94 @@ namespace i2p } return *m_SSU2StaticKeys; } + + void RouterContext::ScheduleInitialPublish () + { + m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL)); + m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishTimer, + this, std::placeholders::_1)); + } + + void RouterContext::SchedulePublish () + { + m_PublishTimer.cancel (); + m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL + + rand () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE)); + m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishTimer, + this, std::placeholders::_1)); + } + + void RouterContext::HandlePublishTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + m_PublishExcluded.clear (); + m_PublishReplyToken = 0; + if (IsFloodfill ()) + { + UpdateStats (); // for floodfill + m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // don't publish to ourselves + } + UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); + Publish (); + SchedulePublishResend (); + } + } + + void RouterContext::Publish () + { + if (!i2p::transport::transports.IsOnline ()) return; + if (m_PublishExcluded.size () > ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS) + { + LogPrint (eLogError, "Router: Couldn't publish our RouterInfo to ", ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again"); + m_PublishExcluded.clear (); + UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); + } + + auto floodfill = i2p::data::netdb.GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded); + if (floodfill) + { + uint32_t replyToken; + RAND_bytes ((uint8_t *)&replyToken, 4); + LogPrint (eLogInfo, "Router: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); + if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect? + i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ? + // send directly + i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); + else + { + // otherwise through exploratory + auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); + 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)); + else + LogPrint (eLogInfo, "Router: Can't publish our RouterInfo. No tunnles. Try again in ", ROUTER_INFO_CONFIRMATION_TIMEOUT, " seconds"); + } + m_PublishExcluded.insert (floodfill->GetIdentHash ()); + m_PublishReplyToken = replyToken; + } + else + LogPrint (eLogInfo, "Router: Can't find floodfill to publish our RouterInfo"); + } + + void RouterContext::SchedulePublishResend () + { + m_PublishTimer.cancel (); + m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONFIRMATION_TIMEOUT)); + m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishResendTimer, + this, std::placeholders::_1)); + } + + void RouterContext::HandlePublishResendTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + i2p::context.UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); + Publish (); + SchedulePublishResend (); + } + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index c054bd79..94b7dcca 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "Identity.h" #include "RouterInfo.h" @@ -30,7 +31,12 @@ namespace garlic const char ROUTER_KEYS[] = "router.keys"; const char NTCP2_KEYS[] = "ntcp2.keys"; const char SSU2_KEYS[] = "ssu2.keys"; - const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes + const int ROUTER_INFO_UPDATE_INTERVAL = 30*60; // 30 minutes + const int ROUTER_INFO_PUBLISH_INTERVAL = 39*60; // in seconds + const int ROUTER_INFO_INITIAL_PUBLISH_INTERVAL = 10; // in seconds + const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds + const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 5; // in seconds + const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; enum RouterStatus { @@ -143,6 +149,8 @@ namespace garlic void SetSupportsV4 (bool supportsV4); void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); void SetMTU (int mtu, bool v4); + void SetHidden(bool hide) { m_IsHiddenMode = hide; }; + bool IsHidden() const { return m_IsHiddenMode; }; i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove @@ -186,6 +194,14 @@ namespace garlic bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize); void PostGarlicMessage (std::shared_ptr msg); + void PostDeliveryStatusMessage (std::shared_ptr msg); + + void ScheduleInitialPublish (); + void SchedulePublish (); + void HandlePublishTimer (const boost::system::error_code& ecode); + void Publish (); + void SchedulePublishResend (); + void HandlePublishResendTimer (const boost::system::error_code& ecode); private: @@ -206,6 +222,11 @@ namespace garlic std::unique_ptr m_NTCP2StaticKeys, m_SSU2StaticKeys; // for ECIESx25519 i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; + // publish + boost::asio::deadline_timer m_PublishTimer; + std::set m_PublishExcluded; + uint32_t m_PublishReplyToken; + bool m_IsHiddenMode; // not publish }; extern RouterContext context; From 4b421d3feb434dbb38db3e8a6f80f7386a0fb789 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Feb 2023 18:33:33 -0500 Subject: [PATCH 0141/1160] publish own RouterInfo in router's thread --- daemon/Daemon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index b6ce396e..2a70dd1f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -269,7 +269,7 @@ namespace util if (hidden) { LogPrint(eLogInfo, "Daemon: Hidden mode enabled"); - i2p::data::netdb.SetHidden(true); + i2p::context.SetHidden(true); } std::string httpLang; i2p::config::GetOption("http.lang", httpLang); From de82b3ae19a82b430544ec6ab82fa9392f10d3c6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 25 Feb 2023 17:19:14 -0500 Subject: [PATCH 0142/1160] don't publish non-reachable router --- libi2pd/RouterContext.cpp | 25 ++++++++++++++++++++++--- libi2pd/RouterContext.h | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 77985a11..e69fb21f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1241,9 +1241,22 @@ namespace i2p void RouterContext::ScheduleInitialPublish () { m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL)); - m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishTimer, + m_PublishTimer.async_wait (std::bind (&RouterContext::HandleInitialPublishTimer, this, std::placeholders::_1)); } + + void RouterContext::HandleInitialPublishTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + if (m_RouterInfo.IsReachableBy (i2p::data::RouterInfo::eAllTransports)) + HandlePublishTimer (ecode); + else if (!ecode) + ScheduleInitialPublish (); + else + LogPrint (eLogError, "Router: initial publish timer error ", ecode.message ()); + } + } void RouterContext::SchedulePublish () { @@ -1267,7 +1280,10 @@ namespace i2p } UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); Publish (); - SchedulePublishResend (); + if (!ecode) + SchedulePublishResend (); + else + LogPrint (eLogError, "Router: publish timer error ", ecode.message ()); } } @@ -1324,7 +1340,10 @@ namespace i2p { i2p::context.UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); Publish (); - SchedulePublishResend (); + if (!ecode) + SchedulePublishResend (); + else + LogPrint (eLogError, "Router: publish resend timer error ", ecode.message ()); } } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 94b7dcca..6af5c3de 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -197,6 +197,7 @@ namespace garlic void PostDeliveryStatusMessage (std::shared_ptr msg); void ScheduleInitialPublish (); + void HandleInitialPublishTimer (const boost::system::error_code& ecode); void SchedulePublish (); void HandlePublishTimer (const boost::system::error_code& ecode); void Publish (); From 3c9a574e90c72e901434d74402391b33c15eb508 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Feb 2023 08:46:01 -0500 Subject: [PATCH 0143/1160] create io_service after daemonization --- libi2pd/RouterContext.cpp | 99 ++++++++++++++++++++++++--------------- libi2pd/RouterContext.h | 15 +++++- 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index e69fb21f..5e32d703 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -28,11 +28,11 @@ namespace i2p { RouterContext context; - RouterContext::RouterContext (): RunnableServiceWithWork ("Router"), + RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID), - m_PublishTimer (GetIOService ()), m_PublishReplyToken (0), m_IsHiddenMode (false) + m_PublishReplyToken (0), m_IsHiddenMode (false) { } @@ -52,20 +52,26 @@ namespace i2p void RouterContext::Start () { - if (!IsRunning ()) - { - StartIOService (); + if (!m_Service) + { + m_Service.reset (new RouterService); + m_Service->Start (); if (!m_IsHiddenMode) + { + m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); ScheduleInitialPublish (); + } } } void RouterContext::Stop () { - if (IsRunning ()) - m_PublishTimer.cancel (); - - StopIOService (); + if (m_Service) + { + if (m_PublishTimer) + m_PublishTimer->cancel (); + m_Service->Stop (); + } } void RouterContext::CreateNewRouter () @@ -1116,7 +1122,10 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { - GetIOService ().post (std::bind (&RouterContext::PostGarlicMessage, this, msg)); + if (m_Service) + m_Service->GetService ().post (std::bind (&RouterContext::PostGarlicMessage, this, msg)); + else + LogPrint (eLogError, "Router: service is NULL"); } void RouterContext::PostGarlicMessage (std::shared_ptr msg) @@ -1141,7 +1150,10 @@ namespace i2p void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - GetIOService ().post (std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); + if (m_Service) + m_Service->GetService ().post (std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); + else + LogPrint (eLogError, "Router: service is NULL"); } void RouterContext::PostDeliveryStatusMessage (std::shared_ptr msg) @@ -1159,10 +1171,13 @@ namespace i2p void RouterContext::CleanupDestination () { - GetIOService ().post ([this]() - { - this->i2p::garlic::GarlicDestination::CleanupExpiredTags (); - }); + if (m_Service) + m_Service->GetService ().post ([this]() + { + this->i2p::garlic::GarlicDestination::CleanupExpiredTags (); + }); + else + LogPrint (eLogError, "Router: service is NULL"); } uint32_t RouterContext::GetUptime () const @@ -1240,9 +1255,14 @@ namespace i2p void RouterContext::ScheduleInitialPublish () { - m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL)); - m_PublishTimer.async_wait (std::bind (&RouterContext::HandleInitialPublishTimer, - this, std::placeholders::_1)); + if (m_PublishTimer) + { + m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL)); + m_PublishTimer->async_wait (std::bind (&RouterContext::HandleInitialPublishTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Publish timer is NULL"); } void RouterContext::HandleInitialPublishTimer (const boost::system::error_code& ecode) @@ -1251,20 +1271,22 @@ namespace i2p { if (m_RouterInfo.IsReachableBy (i2p::data::RouterInfo::eAllTransports)) HandlePublishTimer (ecode); - else if (!ecode) - ScheduleInitialPublish (); - else - LogPrint (eLogError, "Router: initial publish timer error ", ecode.message ()); + ScheduleInitialPublish (); } } void RouterContext::SchedulePublish () { - m_PublishTimer.cancel (); - m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL + - rand () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE)); - m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishTimer, - this, std::placeholders::_1)); + if (m_PublishTimer) + { + m_PublishTimer->cancel (); + m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL + + rand () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE)); + m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Publish timer is NULL"); } void RouterContext::HandlePublishTimer (const boost::system::error_code& ecode) @@ -1280,10 +1302,7 @@ namespace i2p } UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); Publish (); - if (!ecode) - SchedulePublishResend (); - else - LogPrint (eLogError, "Router: publish timer error ", ecode.message ()); + SchedulePublishResend (); } } @@ -1328,10 +1347,15 @@ namespace i2p void RouterContext::SchedulePublishResend () { - m_PublishTimer.cancel (); - m_PublishTimer.expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONFIRMATION_TIMEOUT)); - m_PublishTimer.async_wait (std::bind (&RouterContext::HandlePublishResendTimer, - this, std::placeholders::_1)); + if (m_PublishTimer) + { + m_PublishTimer->cancel (); + m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONFIRMATION_TIMEOUT)); + m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishResendTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Publish timer is NULL"); } void RouterContext::HandlePublishResendTimer (const boost::system::error_code& ecode) @@ -1340,10 +1364,7 @@ namespace i2p { i2p::context.UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); Publish (); - if (!ecode) - SchedulePublishResend (); - else - LogPrint (eLogError, "Router: publish resend timer error ", ecode.message ()); + SchedulePublishResend (); } } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 6af5c3de..4b6d917e 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -58,7 +58,7 @@ namespace garlic eRouterErrorNoDescriptors = 5 }; - class RouterContext: public i2p::garlic::GarlicDestination, private i2p::util::RunnableServiceWithWork + class RouterContext: public i2p::garlic::GarlicDestination { private: @@ -76,6 +76,16 @@ namespace garlic uint8_t intro[32]; }; + class RouterService: public i2p::util::RunnableServiceWithWork + { + public: + + RouterService (): RunnableServiceWithWork ("Router") {}; + boost::asio::io_service& GetService () { return GetIOService (); }; + void Start () { StartIOService (); }; + void Stop () { StopIOService (); }; + }; + public: RouterContext (); @@ -224,7 +234,8 @@ namespace garlic // for ECIESx25519 i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; // publish - boost::asio::deadline_timer m_PublishTimer; + std::unique_ptr m_Service; + std::unique_ptr m_PublishTimer; std::set m_PublishExcluded; uint32_t m_PublishReplyToken; bool m_IsHiddenMode; // not publish From 93d89a1fe0e6eeebf5f714e691f112a69fa4378e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Feb 2023 09:07:53 -0500 Subject: [PATCH 0144/1160] fixed typo --- libi2pd/RouterContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 5e32d703..f2b8f4fb 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1271,7 +1271,8 @@ namespace i2p { if (m_RouterInfo.IsReachableBy (i2p::data::RouterInfo::eAllTransports)) HandlePublishTimer (ecode); - ScheduleInitialPublish (); + else + ScheduleInitialPublish (); } } From 3ff1adf597ed6b29533fb7f3501975e74dc65c0a Mon Sep 17 00:00:00 2001 From: polistern Date: Sun, 26 Feb 2023 16:51:56 +0000 Subject: [PATCH 0145/1160] feat: Added SAM UDP port parameter. --- contrib/i2pd.conf | 3 ++- libi2pd/Config.cpp | 3 ++- libi2pd_client/ClientContext.cpp | 9 +++++---- libi2pd_client/SAM.cpp | 6 +++--- libi2pd_client/SAM.h | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 84d00347..c6e52c1f 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -168,9 +168,10 @@ port = 4447 [sam] ## Comment or set to 'false' to disable SAM Bridge enabled = true -## Address and port service will listen on +## Address and ports service will listen on # address = 127.0.0.1 # port = 7656 +# portudp = 7655 [bob] ## Uncomment and set to 'true' to enable BOB command channel diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 8df08118..267763a9 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -149,7 +149,8 @@ namespace config { sam.add_options() ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") - ("sam.port", value()->default_value(7656), "SAM listen port") + ("sam.port", value()->default_value(7656), "SAM listen TCP port") + ("sam.portudp", value()->default_value(0), "SAM listen UDP port") ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") ; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 3881f2e1..41bd1d49 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -63,18 +63,19 @@ namespace client if (sam) { std::string samAddr; i2p::config::GetOption("sam.address", samAddr); - uint16_t samPort; i2p::config::GetOption("sam.port", samPort); + uint16_t samPortTCP; i2p::config::GetOption("sam.port", samPortTCP); + uint16_t samPortUDP; i2p::config::GetOption("sam.portudp", samPortUDP); bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); - LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":", samPort); + LogPrint(eLogInfo, "Clients: Starting SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP, "]"); try { - m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); + m_SamBridge = new SAMBridge (samAddr, samPortTCP, samPortUDP, singleThread); m_SamBridge->Start (); } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); - ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); + ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP,"]: ", e.what ()); } } diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 93df59fb..4e19990a 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1244,10 +1244,10 @@ namespace client // TODO: implement datagrams } - SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): + SAMBridge::SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), - m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), - m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), portTCP)), + m_DatagramEndpoint (boost::asio::ip::address::from_string(address), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index b6ac23a6..97ac0b8e 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -233,7 +233,7 @@ namespace client { public: - SAMBridge (const std::string& address, int port, bool singleThread); + SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread); ~SAMBridge (); void Start (); From b7f0d87dafa8957131b496c38fbe65d8cb378a9d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 26 Feb 2023 20:38:23 +0000 Subject: [PATCH 0146/1160] GHA and Cmake changes (#1888) Done with Vort's (https://github.com/Vort) cooperation Signed-off-by: R4SAS --- .editorconfig | 4 + .github/workflows/build-deb.yml | 17 ++- .github/workflows/build-freebsd.yml | 10 +- .github/workflows/build-osx.yml | 7 +- .github/workflows/build-windows.yml | 82 +++++++++++++-- .github/workflows/build.yml | 25 +++-- .github/workflows/docker.yml | 155 ++++++++++++++-------------- Makefile | 12 ++- Makefile.bsd | 3 +- Makefile.linux | 5 +- Makefile.mingw | 16 +-- Makefile.osx | 8 +- Win32/Resource.rc | 72 ++++++------- Win32/Resource.rc2 | 4 +- build/.gitignore | 7 +- build/CMakeLists.txt | 110 ++++++++++++++------ build/cmake_modules/Version.cmake | 16 +++ libi2pd/version.h | 4 +- 18 files changed, 369 insertions(+), 188 deletions(-) create mode 100644 build/cmake_modules/Version.cmake diff --git a/.editorconfig b/.editorconfig index ed3973c5..e1f1243a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -30,3 +30,7 @@ indent_size = 4 indent_style = space indent_size = 2 trim_trailing_whitespace = false + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index f8fd249c..ebc3df4d 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -6,25 +6,34 @@ jobs: build: name: ${{ matrix.dist }} runs-on: ubuntu-latest + strategy: fail-fast: false matrix: dist: ['buster', 'bullseye', 'bookworm'] + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: jtdor/build-deb-action@v1 + + - name: Build package + uses: jtdor/build-deb-action@v1 with: docker-image: debian:${{ matrix.dist }}-slim buildpackage-opts: --build=binary --no-sign before-build-hook: debchange --controlmaint --local "+${{ github.sha }}~${{ matrix.dist }}" -b --distribution ${{ matrix.dist }} "CI build" extra-build-deps: devscripts git - - uses: actions/upload-artifact@v3 + + - name: Upload package + uses: actions/upload-artifact@v3 with: name: i2pd_${{ matrix.dist }} path: debian/artifacts/i2pd_*.deb - - uses: actions/upload-artifact@v3 + + - name: Upload debugging symbols + uses: actions/upload-artifact@v3 with: name: i2pd-dbgsym_${{ matrix.dist }} path: debian/artifacts/i2pd-dbgsym_*.deb diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml index 557a9b13..76b496ad 100644 --- a/.github/workflows/build-freebsd.yml +++ b/.github/workflows/build-freebsd.yml @@ -6,8 +6,11 @@ jobs: build: runs-on: macos-12 name: with UPnP + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + - name: Test in FreeBSD id: test uses: vmactions/freebsd-vm@v0.3.0 @@ -21,8 +24,9 @@ jobs: cd build cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . gmake -j2 + - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: i2pd-freebsd - path: build/i2pd \ No newline at end of file + path: build/i2pd diff --git a/.github/workflows/build-osx.yml b/.github/workflows/build-osx.yml index afddb7e9..266f2c54 100644 --- a/.github/workflows/build-osx.yml +++ b/.github/workflows/build-osx.yml @@ -6,16 +6,21 @@ jobs: build: name: With USE_UPNP=${{ matrix.with_upnp }} runs-on: macOS-latest + strategy: fail-fast: true matrix: with_upnp: ['yes', 'no'] + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + - name: install packages run: | find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete brew update brew install boost miniupnpc openssl@1.1 + - name: build application run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3 diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index e7752d55..7a9a40c7 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -10,42 +10,104 @@ jobs: build: name: Building using ${{ matrix.arch }} toolchain runs-on: windows-latest + strategy: - fail-fast: true + fail-fast: false matrix: include: [ - { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt }, - { msystem: MINGW64, arch: x86_64, arch_short: x64 }, - { msystem: MINGW32, arch: i686, arch_short: x86 } + { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc }, + { msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang }, + { msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc }, + { msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc } ] + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup MSYS2 uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} - install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc + install: base-devel git mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc update: true + + - name: Install additional clang packages + if: ${{ matrix.msystem == 'CLANG64' }} + run: pacman --noconfirm -S mingw-w64-${{ matrix.arch }}-gcc-compat + - name: Build application run: | mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes -j3 + - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: i2pd-${{ matrix.arch_short }}.exe path: i2pd.exe + + build-cmake: + name: Building using ${{ matrix.arch }} toolchain using CMake + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + include: [ + { msystem: UCRT64, arch: ucrt-x86_64, arch_short: x64-ucrt, compiler: gcc }, + { msystem: CLANG64, arch: clang-x86_64, arch_short: x64-clang, compiler: clang }, + { msystem: MINGW64, arch: x86_64, arch_short: x64, compiler: gcc }, + { msystem: MINGW32, arch: i686, arch_short: x86, compiler: gcc } + ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: base-devel git mingw-w64-${{ matrix.arch }}-cmake mingw-w64-${{ matrix.arch }}-ninja mingw-w64-${{ matrix.arch }}-${{ matrix.compiler }} mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc + update: true + + - name: Build application + run: | + cd build + cmake -DWITH_GIT_VERSION=ON -DWITH_STATIC=ON -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . + cmake --build . -- -j3 + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: i2pd-cmake-${{ matrix.arch_short }}.exe + path: build/i2pd.exe + build-xp: name: Building for Windows XP runs-on: windows-latest + + strategy: + fail-fast: false + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup MSYS2 uses: msys2/setup-msys2@v2 with: msystem: MINGW32 install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-miniupnpc update: true + - name: Build WinXP-capable CRT packages run: | git clone https://github.com/msys2/MINGW-packages @@ -64,12 +126,14 @@ jobs: pacman --noconfirm -U mingw-w64-i686-libwinpthread-git-*-any.pkg.tar.zst mingw-w64-i686-winpthreads-git-*-any.pkg.tar.zst popd popd + - name: Build application run: | mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon make USE_UPNP=yes DEBUG=no USE_GIT_VERSION=yes USE_WINXP_FLAGS=yes -j3 + - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: i2pd-xp.exe path: i2pd.exe diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8828f61..935c2f93 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,34 +5,43 @@ on: [push, pull_request] jobs: build-make: name: Make with USE_UPNP=${{ matrix.with_upnp }} - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + strategy: fail-fast: true matrix: with_upnp: ['yes', 'no'] + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + - name: install packages run: | - sudo add-apt-repository ppa:mhier/libboost-latest sudo apt-get update - sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev + sudo apt-get install build-essential libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application run: make USE_UPNP=${{ matrix.with_upnp }} -j3 + build-cmake: name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }} - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + strategy: fail-fast: true matrix: with_upnp: ['ON', 'OFF'] + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + - name: install packages run: | - sudo add-apt-repository ppa:mhier/libboost-latest sudo apt-get update - sudo apt-get install build-essential cmake libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev + sudo apt-get install build-essential cmake libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application run: | cd build diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1f3142e4..28e4e8b0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,6 +10,7 @@ on: jobs: build: + name: Building container for ${{ matrix.platform }} runs-on: ubuntu-latest permissions: packages: write @@ -25,42 +26,44 @@ jobs: ] steps: - - name: Checkout - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Login to GitHub Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to GitHub Container registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build container for ${{ matrix.archname }} - uses: docker/build-push-action@v3 - with: - context: ./contrib/docker - file: ./contrib/docker/Dockerfile - platforms: ${{ matrix.platform }} - push: true - tags: | - purplei2p/i2pd:latest-${{ matrix.archname }} - ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }} - provenance: false + - name: Build container for ${{ matrix.archname }} + uses: docker/build-push-action@v3 + with: + context: ./contrib/docker + file: ./contrib/docker/Dockerfile + platforms: ${{ matrix.platform }} + push: true + tags: | + purplei2p/i2pd:latest-${{ matrix.archname }} + ghcr.io/purplei2p/i2pd:latest-${{ matrix.archname }} + provenance: false push: + name: Pushing merged manifest runs-on: ubuntu-latest + permissions: packages: write contents: read @@ -68,60 +71,60 @@ jobs: needs: build steps: - - name: Checkout - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Login to GitHub Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to GitHub Container registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Create and push latest manifest image to Docker Hub - if: ${{ !startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - inputs: purplei2p/i2pd:latest - images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 - push: true + - name: Create and push latest manifest image to Docker Hub + if: ${{ !startsWith(github.ref, 'refs/tags/') }} + uses: Noelware/docker-manifest-action@master + with: + inputs: purplei2p/i2pd:latest + images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + push: true - - name: Create and push latest manifest image to GHCR - if: ${{ !startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - inputs: ghcr.io/purplei2p/i2pd:latest - images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 - push: true + - name: Create and push latest manifest image to GHCR + if: ${{ !startsWith(github.ref, 'refs/tags/') }} + uses: Noelware/docker-manifest-action@master + with: + inputs: ghcr.io/purplei2p/i2pd:latest + images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + push: true - - name: Store release version to env - if: ${{ startsWith(github.ref, 'refs/tags/') }} - run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV + - name: Store release version to env + if: ${{ startsWith(github.ref, 'refs/tags/') }} + run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV - - name: Create and push release manifest to Docker Hub - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 - push: true + - name: Create and push release manifest to Docker Hub + if: ${{ startsWith(github.ref, 'refs/tags/') }} + uses: Noelware/docker-manifest-action@master + with: + inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + push: true - - name: Create and push release manifest to GHCR - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: Noelware/docker-manifest-action@master - with: - inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 - push: true + - name: Create and push release manifest to GHCR + if: ${{ startsWith(github.ref, 'refs/tags/') }} + uses: Noelware/docker-manifest-action@master + with: + inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + push: true diff --git a/Makefile b/Makefile index 520a56ba..0861ec0b 100644 --- a/Makefile +++ b/Makefile @@ -71,13 +71,15 @@ else # not supported $(error Not supported platform) endif +INCFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) +DEFINES += -DOPENSSL_SUPPRESS_DEPRECATED +NEEDED_CXXFLAGS += -MMD -MP + ifeq ($(USE_GIT_VERSION),yes) GIT_VERSION := $(shell git describe --tags) - NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\" + DEFINES += -DGITVER=$(GIT_VERSION) endif -NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) -DOPENSSL_SUPPRESS_DEPRECATED - LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) @@ -110,13 +112,13 @@ wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## custom FLAGS to work at build-time. obj/%.o: %.cpp | mk_obj_dir - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(DEFINES) $(INCFLAGS) -c -o $@ $< # '-' is 'ignore if missing' on first run -include $(DEPS) $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) - $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) + $(CXX) -o $@ $(DEFINES) $(LDFLAGS) $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) diff --git a/Makefile.bsd b/Makefile.bsd index 39e5651a..00543193 100644 --- a/Makefile.bsd +++ b/Makefile.bsd @@ -6,7 +6,8 @@ CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misl ## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove ## -std=c++11. If you want to remove this variable please do so in a way that allows setting ## custom FLAGS to work at build-time. -NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 +NEEDED_CXXFLAGS = -std=c++11 +DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1 INCFLAGS = -I/usr/include/ -I/usr/local/include/ LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread diff --git a/Makefile.linux b/Makefile.linux index d01f2b73..6c7a4619 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -58,12 +58,13 @@ endif # UPNP Support (miniupnpc 1.5 and higher) ifeq ($(USE_UPNP),yes) - NEEDED_CXXFLAGS += -DUSE_UPNP + DEFINES += -DUSE_UPNP endif ifeq ($(USE_AESNI),yes) ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that - NEEDED_CXXFLAGS += -D__AES__ -maes + NEEDED_CXXFLAGS += -maes + DEFINES += -D__AES__ endif endif diff --git a/Makefile.mingw b/Makefile.mingw index a1a861e6..6cd19080 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -4,17 +4,18 @@ USE_WIN32_APP := yes WINDRES = windres CXXFLAGS := $(CXX_DEBUG) -fPIC -msse -INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32 +INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32 LDFLAGS := ${LD_DEBUG} -static -NEEDED_CXXFLAGS += -std=c++17 -DWIN32_LEAN_AND_MEAN +NEEDED_CXXFLAGS += -std=c++17 +DEFINES += -DWIN32_LEAN_AND_MEAN # Boost libraries suffix BOOST_SUFFIX = -mt # UPNP Support ifeq ($(USE_UPNP),yes) - CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB + DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB LDLIBS = -lminiupnpc endif @@ -35,18 +36,19 @@ LDLIBS += \ -lpthread ifeq ($(USE_WIN32_APP), yes) - NEEDED_CXXFLAGS += -DWIN32_APP + DEFINES += -DWIN32_APP LDFLAGS += -mwindows DAEMON_RC += Win32/Resource.rc DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) endif ifeq ($(USE_WINXP_FLAGS), yes) - NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 + DEFINES += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 endif ifeq ($(USE_AESNI),yes) - NEEDED_CXXFLAGS += -D__AES__ -maes + NEEDED_CXXFLAGS += -maes + DEFINES += -D__AES__ endif ifeq ($(USE_ASLR),yes) @@ -54,4 +56,4 @@ ifeq ($(USE_ASLR),yes) endif obj/%.o : %.rc | mk_obj_dir - $(WINDRES) -i $< -o $@ + $(WINDRES) $(DEFINES) $(INCFLAGS) --preprocessor-arg=-MMD --preprocessor-arg=-MP --preprocessor-arg=-MF$@.d -i $< -o $@ diff --git a/Makefile.osx b/Makefile.osx index 2e52585e..b91008d6 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -1,6 +1,7 @@ CXX = clang++ -CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX +CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 INCFLAGS = -I/usr/local/include +DEFINES := -DMAC_OSX LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib LDFLAGS += -Wl,-dead_strip LDFLAGS += -Wl,-dead_strip_dylibs @@ -14,7 +15,7 @@ endif ifeq ($(USE_UPNP),yes) LDFLAGS += -ldl - CXXFLAGS += -DUSE_UPNP + DEFINES += -DUSE_UPNP ifeq ($(USE_STATIC),yes) LDLIBS += /usr/local/lib/libminiupnpc.a else @@ -23,7 +24,8 @@ ifeq ($(USE_UPNP),yes) endif ifeq ($(USE_AESNI),yes) - CXXFLAGS += -D__AES__ -maes + CXXFLAGS += -maes + DEFINES += -D__AES__ else CXXFLAGS += -msse endif diff --git a/Win32/Resource.rc b/Win32/Resource.rc index 5d394d1a..c9266b08 100644 --- a/Win32/Resource.rc +++ b/Win32/Resource.rc @@ -1,36 +1,36 @@ -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -#include "winres.h" -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END -#endif // APSTUDIO_INVOKED - -MAINICON ICON "mask.ico" -#endif // English (United States) resources - -#ifndef APSTUDIO_INVOKED -#include "Resource.rc2" -#endif // not APSTUDIO_INVOKED - +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END +#endif // APSTUDIO_INVOKED + +MAINICON ICON "mask.ico" +#endif // English (United States) resources + +#ifndef APSTUDIO_INVOKED +#include "Resource.rc2" +#endif // not APSTUDIO_INVOKED + diff --git a/Win32/Resource.rc2 b/Win32/Resource.rc2 index 873d6402..32744584 100644 --- a/Win32/Resource.rc2 +++ b/Win32/Resource.rc2 @@ -2,7 +2,7 @@ #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO_INVOKED -#include "../libi2pd/version.h" +#include "version.h" VS_VERSION_INFO VERSIONINFO FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "C++ I2P daemon" VALUE "FileVersion", I2PD_VERSION VALUE "InternalName", CODENAME - VALUE "LegalCopyright", "Copyright (C) 2013-2022, The PurpleI2P Project" + VALUE "LegalCopyright", "Copyright (C) 2013-2023, The PurpleI2P Project" VALUE "OriginalFilename", "i2pd" VALUE "ProductName", "Purple I2P" VALUE "ProductVersion", I2P_VERSION diff --git a/build/.gitignore b/build/.gitignore index 7689cc88..d51958d6 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -2,7 +2,12 @@ /CMakeFiles/ /Testing/ /tests/ +/.ninja_* +/arch.c +/build.ninja /i2pd +/i2pd.exe +/i2pd.exe.debug /libi2pd.a /libi2pdclient.a /libi2pdlang.a @@ -12,7 +17,7 @@ /CPackSourceConfig.cmake /CTestTestfile.cmake /install_manifest.txt -/arch.c +/Makefile # windows build script i2pd*.zip build*.log diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index f6f52001..3ac2f61a 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -1,14 +1,32 @@ cmake_minimum_required(VERSION 3.7) -cmake_policy(VERSION 3.7) -project("i2pd") + +if(${CMAKE_VERSION} VERSION_LESS 3.22) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.22) +endif() # for debugging #set(CMAKE_VERBOSE_MAKEFILE on) -# Win32 build with cmake is not supported -if(WIN32 OR MSVC OR MSYS OR MINGW) - message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.") -endif() +# paths +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") +set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") + +set(LIBI2PD_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd) +set(LIBI2PD_CLIENT_SRC_DIR ${CMAKE_SOURCE_DIR}/libi2pd_client) +set(LANG_SRC_DIR ${CMAKE_SOURCE_DIR}/i18n) +set(DAEMON_SRC_DIR ${CMAKE_SOURCE_DIR}/daemon) + +include(Version) +set_version("${LIBI2PD_SRC_DIR}/version.h" PROJECT_VERSION) + +project( + i2pd + VERSION ${PROJECT_VERSION} + HOMEPAGE_URL "https://i2pd.website/" + LANGUAGES CXX +) # configurable options option(WITH_AESNI "Use AES-NI instructions set" ON) @@ -26,27 +44,16 @@ IF(BUILD_TESTING) enable_testing() ENDIF() -# paths -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") -set(CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") - # Handle paths nicely include(GNUInstallDirs) -# architecture +# Architecture include(TargetArch) target_architecture(ARCHITECTURE) -set(LIBI2PD_SRC_DIR ../libi2pd) -set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) -set(LANG_SRC_DIR ../i18n) -set(DAEMON_SRC_DIR ../daemon) +include(CheckAtomic) include_directories(${LIBI2PD_SRC_DIR}) -include_directories(${LIBI2PD_CLIENT_SRC_DIR}) -include_directories(${LANG_SRC_DIR}) -include_directories(${DAEMON_SRC_DIR}) - FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp) add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") @@ -57,11 +64,9 @@ if(WITH_LIBRARY) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) -# TODO Make libi2pd available to 3rd party projects via CMake as imported target -# FIXME This pulls stdafx -# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() +include_directories(${LIBI2PD_CLIENT_SRC_DIR}) FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp) add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") @@ -74,6 +79,7 @@ if(WITH_LIBRARY) COMPONENT Libraries) endif() +include_directories(${LANG_SRC_DIR}) FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp) add_library(libi2pdlang ${LANG_SRC}) set_target_properties(libi2pdlang PROPERTIES PREFIX "") @@ -86,6 +92,8 @@ if(WITH_LIBRARY) COMPONENT Libraries) endif() +include_directories(${DAEMON_SRC_DIR}) + set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" "${DAEMON_SRC_DIR}/HTTPServer.cpp" @@ -95,6 +103,22 @@ set(DAEMON_SRC "${DAEMON_SRC_DIR}/UPnP.cpp" ) +if(WIN32) + set(WIN32_SRC_DIR ${CMAKE_SOURCE_DIR}/Win32) + include_directories(${WIN32_SRC_DIR}) + + list(APPEND DAEMON_SRC + "${WIN32_SRC_DIR}/DaemonWin32.cpp" + "${WIN32_SRC_DIR}/Win32App.cpp" + "${WIN32_SRC_DIR}/Win32Service.cpp" + "${WIN32_SRC_DIR}/Win32NetState.cpp" + ) + + file(GLOB WIN32_RC ${WIN32_SRC_DIR}/*.rc) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN") + +endif() + if(WITH_UPNP) add_definitions(-DUSE_UPNP) endif() @@ -102,14 +126,14 @@ endif() if(WITH_GIT_VERSION) include(GetGitRevisionDescription) git_describe(GIT_VERSION) - add_definitions(-DGITVER="${GIT_VERSION}") + add_definitions(-DGITVER=${GIT_VERSION}) endif() if(APPLE) add_definitions(-DMAC_OSX) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. # Multiple definitions of __stack_chk_fail(libssp & libc) @@ -118,8 +142,10 @@ set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from # check for c++17 & c++11 support include(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED) CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED) + if(CXX17_SUPPORTED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") elseif(CXX11_SUPPORTED) @@ -188,10 +214,23 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) if(WITH_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_STATIC_RUNTIME ON) + set(Boost_USE_STATIC_RUNTIME OFF) + set(OPENSSL_USE_STATIC_LIBS ON) + + set(ZLIB_USE_STATIC_LIBS ON) + set(ZLIB_NAMES libz zlibstatic zlibstat zlib z) + + if(WITH_UPNP) + set(MINIUPNPC_USE_STATIC_LIBS ON) + add_definitions(-DMINIUPNP_STATICLIB) + endif() + set(BUILD_SHARED_LIBS OFF) + if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") # set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive") @@ -236,8 +275,6 @@ endif() # load includes include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) -include(CheckAtomic) - # show summary message(STATUS "---------------------------------------") message(STATUS "Build type : ${CMAKE_BUILD_TYPE}") @@ -259,7 +296,15 @@ message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS "---------------------------------------") if(WITH_BINARY) - add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) + if(WIN32) + add_executable("${PROJECT_NAME}" WIN32 ${DAEMON_SRC} ${WIN32_RC}) + else() + add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) + endif() + + if (WIN32) + set(MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi") + endif () if(WITH_STATIC) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") @@ -275,11 +320,18 @@ if(WITH_BINARY) list(REMOVE_AT Boost_LIBRARIES -1) endif() + # synchronization library is incompatible with Windows 7 + if(WIN32) + get_target_property(BOOSTFSLIBS Boost::filesystem INTERFACE_LINK_LIBRARIES) + list(REMOVE_ITEM BOOSTFSLIBS synchronization) + set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}") + endif() + if(WITH_STATIC) set(DL_LIB ${CMAKE_DL_LIBS}) endif() - target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") diff --git a/build/cmake_modules/Version.cmake b/build/cmake_modules/Version.cmake new file mode 100644 index 00000000..cb9551db --- /dev/null +++ b/build/cmake_modules/Version.cmake @@ -0,0 +1,16 @@ +# read version + +function(set_version version_file output_var) + file(READ "${version_file}" version_data) + + string(REGEX MATCH "I2PD_VERSION_MAJOR ([0-9]*)" _ ${version_data}) + set(version_major ${CMAKE_MATCH_1}) + + string(REGEX MATCH "I2PD_VERSION_MINOR ([0-9]*)" _ ${version_data}) + set(version_minor ${CMAKE_MATCH_1}) + + string(REGEX MATCH "I2PD_VERSION_MICRO ([0-9]*)" _ ${version_data}) + set(version_micro ${CMAKE_MATCH_1}) + + set(${output_var} "${version_major}.${version_minor}.${version_micro}" PARENT_SCOPE) +endfunction() diff --git a/libi2pd/version.h b/libi2pd/version.h index b7de21a8..8d91c5c8 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -11,7 +11,9 @@ #define CODENAME "Purple" +#define XSTRINGIZE(x) STRINGIZE(x) #define STRINGIZE(x) #x + #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) @@ -20,7 +22,7 @@ #define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #ifdef GITVER - #define I2PD_VERSION GITVER + #define I2PD_VERSION XSTRINGIZE(GITVER) #else #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #endif From 10dfe39f5fa3ecb78a5b809a4ac30740b1096827 Mon Sep 17 00:00:00 2001 From: Vort Date: Mon, 27 Feb 2023 14:32:42 +0200 Subject: [PATCH 0147/1160] Fix architecture detection in cmake build (#1890) --- build/cmake_modules/TargetArch.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cmake_modules/TargetArch.cmake b/build/cmake_modules/TargetArch.cmake index d59925c8..e611c4f7 100644 --- a/build/cmake_modules/TargetArch.cmake +++ b/build/cmake_modules/TargetArch.cmake @@ -18,7 +18,7 @@ set(archdetect_c_code " || defined(_M_ARM64) \\ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8) #error cmake_ARCH arm64 - #if defined(__ARM_ARCH_7__) \\ + #elif defined(__ARM_ARCH_7__) \\ || defined(__ARM_ARCH_7A__) \\ || defined(__ARM_ARCH_7R__) \\ || defined(__ARM_ARCH_7M__) \\ From 5f8820d9d6412470d1eeeadef9591f4d0db62f74 Mon Sep 17 00:00:00 2001 From: Vort Date: Mon, 27 Feb 2023 21:35:06 +0200 Subject: [PATCH 0148/1160] Silence several compiler warnings --- Win32/Win32Service.cpp | 2 +- libi2pd/util.cpp | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index d4ba0d76..a9ecf477 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -21,7 +21,7 @@ BOOL I2PService::isService() HWINSTA hWinStation = GetProcessWindowStation(); if (hWinStation != NULL) { - USEROBJECTFLAGS uof = { 0 }; + USEROBJECTFLAGS uof = { FALSE, FALSE, 0 }; if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0)) { bIsService = TRUE; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 369f999e..6d49c6c9 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -200,13 +200,11 @@ namespace net pCurrAddresses = pAddresses; while(pCurrAddresses) { - PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress; - pUnicast = pCurrAddresses->FirstUnicastAddress; if(pUnicast == nullptr) LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv4 address, this is not supported"); - for(int i = 0; pUnicast != nullptr; ++i) + while(pUnicast != nullptr) { LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; sockaddr_in* localInterfaceAddress = (sockaddr_in*) lpAddr; @@ -264,12 +262,11 @@ namespace net pCurrAddresses = pAddresses; while (pCurrAddresses) { - PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress; pUnicast = pCurrAddresses->FirstUnicastAddress; if (pUnicast == nullptr) LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv6 address, this is not supported"); - for (int i = 0; pUnicast != nullptr; ++i) + while (pUnicast != nullptr) { LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr; @@ -533,10 +530,9 @@ namespace net pCurrAddresses = pAddresses; while(pCurrAddresses) { - PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress; pUnicast = pCurrAddresses->FirstUnicastAddress; - for(int i = 0; pUnicast != nullptr; ++i) + while(pUnicast != nullptr) { LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr; From 34617bcb442f2b0c246fd94a73ecae0ce29a491d Mon Sep 17 00:00:00 2001 From: Vort Date: Mon, 27 Feb 2023 21:35:23 +0200 Subject: [PATCH 0149/1160] Code style unification across file --- libi2pd/util.cpp | 65 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 6d49c6c9..daf7fcbf 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -75,7 +75,8 @@ const char *inet_ntop_xp(int af, const void *src, char *dst, socklen_t size) ZeroMemory(&ss, sizeof(ss)); ss.ss_family = af; - switch(af) { + switch (af) + { case AF_INET: ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; break; @@ -179,7 +180,7 @@ namespace net PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr; - if(GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) + if (GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) { FREE(pAddresses); @@ -190,7 +191,7 @@ namespace net AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen ); - if(dwRetVal != NO_ERROR) + if (dwRetVal != NO_ERROR) { LogPrint(eLogError, "NetIface: GetMTU: Enclosed GetAdaptersAddresses() call has failed"); FREE(pAddresses); @@ -198,17 +199,17 @@ namespace net } pCurrAddresses = pAddresses; - while(pCurrAddresses) + while (pCurrAddresses) { pUnicast = pCurrAddresses->FirstUnicastAddress; - if(pUnicast == nullptr) + if (pUnicast == nullptr) LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv4 address, this is not supported"); - while(pUnicast != nullptr) + while (pUnicast != nullptr) { LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; sockaddr_in* localInterfaceAddress = (sockaddr_in*) lpAddr; - if(localInterfaceAddress->sin_addr.S_un.S_addr == inputAddress.sin_addr.S_un.S_addr) + if (localInterfaceAddress->sin_addr.S_un.S_addr == inputAddress.sin_addr.S_un.S_addr) { char addr[INET_ADDRSTRLEN]; inetntop(AF_INET, &(((struct sockaddr_in *)localInterfaceAddress)->sin_addr), addr, INET_ADDRSTRLEN); @@ -314,13 +315,13 @@ namespace net IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found - if(localAddress.is_v4()) + if (localAddress.is_v4()) { sockaddr_in inputAddress; inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } - else if(localAddress.is_v6()) + else if (localAddress.is_v6()) { sockaddr_in6 inputAddress; inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); @@ -336,7 +337,7 @@ namespace net int GetMTUUnix (const boost::asio::ip::address& localAddress, int fallback) { ifaddrs* ifaddr, *ifa = nullptr; - if(getifaddrs(&ifaddr) == -1) + if (getifaddrs(&ifaddr) == -1) { LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno)); return fallback; @@ -344,34 +345,34 @@ namespace net int family = 0; // look for interface matching local address - for(ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { - if(!ifa->ifa_addr) + if (!ifa->ifa_addr) continue; family = ifa->ifa_addr->sa_family; - if(family == AF_INET && localAddress.is_v4()) + if (family == AF_INET && localAddress.is_v4()) { sockaddr_in* sa = (sockaddr_in*) ifa->ifa_addr; - if(!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4)) + if (!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4)) break; // address matches } - else if(family == AF_INET6 && localAddress.is_v6()) + else if (family == AF_INET6 && localAddress.is_v6()) { sockaddr_in6* sa = (sockaddr_in6*) ifa->ifa_addr; - if(!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16)) + if (!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16)) break; // address matches } } int mtu = fallback; - if(ifa && family) + if (ifa && family) { // interface found? int fd = socket(family, SOCK_DGRAM, 0); - if(fd > 0) + if (fd > 0) { ifreq ifr; strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ-1); // set interface for query - if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0) + if (ioctl(fd, SIOCGIFMTU, &ifr) >= 0) mtu = ifr.ifr_mtu; // MTU else LogPrint (eLogError, "NetIface: Failed to run ioctl: ", strerror(errno)); @@ -404,7 +405,7 @@ namespace net { #ifdef _WIN32 LogPrint(eLogError, "NetIface: Cannot get address by interface name, not implemented on WIN32"); - if(ipv6) + if (ipv6) return boost::asio::ip::address::from_string("::1"); else return boost::asio::ip::address::from_string("127.0.0.1"); @@ -423,7 +424,7 @@ namespace net // match char addr[INET6_ADDRSTRLEN]; memset (addr, 0, INET6_ADDRSTRLEN); - if(af == AF_INET) + if (af == AF_INET) inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN); else inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN); @@ -439,9 +440,9 @@ namespace net LogPrint(eLogError, "NetIface: Exception while searching address using ifaddr: ", ex.what()); } - if(addrs) freeifaddrs(addrs); + if (addrs) freeifaddrs(addrs); std::string fallback; - if(ipv6) + if (ipv6) { fallback = "::1"; LogPrint(eLogWarning, "NetIface: Cannot find IPv6 address for interface ", ifname); @@ -509,7 +510,7 @@ namespace net PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr; - if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) + if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) { FREE(pAddresses); @@ -520,7 +521,7 @@ namespace net AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen ); - if(dwRetVal != NO_ERROR) + if (dwRetVal != NO_ERROR) { LogPrint(eLogError, "NetIface: GetYggdrasilAddress(): enclosed GetAdaptersAddresses() call has failed"); FREE(pAddresses); @@ -528,11 +529,11 @@ namespace net } pCurrAddresses = pAddresses; - while(pCurrAddresses) + while (pCurrAddresses) { pUnicast = pCurrAddresses->FirstUnicastAddress; - while(pUnicast != nullptr) + while (pUnicast != nullptr) { LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr; @@ -576,7 +577,7 @@ namespace net LogPrint(eLogError, "NetIface: Exception while searching Yggdrasill address using ifaddr: ", ex.what()); } LogPrint(eLogWarning, "NetIface: Interface with Yggdrasil network address not found"); - if(addrs) freeifaddrs(addrs); + if (addrs) freeifaddrs(addrs); return boost::asio::ip::address_v6 (); #endif } @@ -596,7 +597,7 @@ namespace net { // https://en.wikipedia.org/wiki/Reserved_IP_addresses if (host.is_unspecified ()) return false; - if(host.is_v4()) + if (host.is_v4()) { static const std::vector< std::pair > reservedIPv4Ranges { address_pair_v4("0.0.0.0", "0.255.255.255"), @@ -616,12 +617,12 @@ namespace net }; uint32_t ipv4_address = host.to_v4 ().to_ulong (); - for(const auto& it : reservedIPv4Ranges) { + for (const auto& it : reservedIPv4Ranges) { if (ipv4_address >= it.first && ipv4_address <= it.second) return true; } } - if(host.is_v6()) + if (host.is_v6()) { static const std::vector< std::pair > reservedIPv6Ranges { address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), @@ -633,7 +634,7 @@ namespace net }; boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); - for(const auto& it : reservedIPv6Ranges) { + for (const auto& it : reservedIPv6Ranges) { if (ipv6_address >= it.first && ipv6_address <= it.second) return true; } From 64f0a545fdf99bb1967d99ccd402e28db571d1f7 Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 28 Feb 2023 19:41:17 +0200 Subject: [PATCH 0150/1160] Improve MSVC 2015 compatibility --- libi2pd/I2PEndian.h | 18 ++++++++++++++++++ libi2pd/Streaming.cpp | 2 +- libi2pd/util.cpp | 31 ++++++++++++++++++++++++++++++- libi2pd_client/HTTPProxy.cpp | 2 +- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index d97bd055..06abf29a 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -36,6 +36,23 @@ #define le64toh(x) OSSwapLittleToHostInt64(x) #elif defined(_WIN32) +#if defined(_MSC_VER) +#include +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) +#else #define htobe16(x) __builtin_bswap16(x) #define htole16(x) (x) #define be16toh(x) __builtin_bswap16(x) @@ -50,6 +67,7 @@ #define htole64(x) (x) #define be64toh(x) __builtin_bswap64(x) #define le64toh(x) (x) +#endif #else #define NEEDS_LOCAL_ENDIAN diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 62c4acc7..1049abce 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -384,7 +384,7 @@ namespace stream memset (p.buf, 0, 22); // minimal header all zeroes memcpy (p.buf + 4, packet->buf, 4); // but receiveStreamID is the sendStreamID from the ping htobe16buf (p.buf + 18, PACKET_FLAG_ECHO); // and echo flag - ssize_t payloadLen = packet->len - (packet->GetPayload () - packet->buf); + auto payloadLen = int(packet->len) - (packet->GetPayload () - packet->buf); if (payloadLen > 0) memcpy (p.buf + 22, packet->GetPayload (), payloadLen); else diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index daf7fcbf..2426f13a 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -15,7 +15,7 @@ #include "Log.h" #include "I2PEndian.h" -#if not defined (__FreeBSD__) +#if !defined (__FreeBSD__) && !defined(_MSC_VER) #include #endif @@ -37,6 +37,19 @@ #include #include +#if defined(_MSC_VER) +const DWORD MS_VC_EXCEPTION = 0x406D1388; +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; +} THREADNAME_INFO; +#pragma pack(pop) +#endif + #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) @@ -162,7 +175,23 @@ namespace util #elif defined(__NetBSD__) pthread_setname_np(pthread_self(), "%s", (void *)name); #elif !defined(__gnu_hurd__) + #if defined(_MSC_VER) + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = -1; + info.dwFlags = 0; + #pragma warning(push) + #pragma warning(disable: 6320 6322) + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + } + #pragma warning(pop) + #else pthread_setname_np(pthread_self(), name); + #endif #endif } diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 3e5ab595..61930876 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -113,7 +113,7 @@ namespace proxy { i2p::http::URL m_ProxyURL; i2p::http::URL m_RequestURL; uint8_t m_socks_buf[255+8]; // for socks request/response - ssize_t m_req_len; + int m_req_len; i2p::http::URL m_ClientRequestURL; i2p::http::HTTPReq m_ClientRequest; i2p::http::HTTPRes m_ClientResponse; From a199084c99daa963eabfd65d9a9a47b4a57712b6 Mon Sep 17 00:00:00 2001 From: Vort Date: Wed, 1 Mar 2023 08:52:40 +0200 Subject: [PATCH 0151/1160] Add MSVC support to CMake build --- build/CMakeLists.txt | 61 ++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 3ac2f61a..999e0a76 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -53,6 +53,12 @@ target_architecture(ARCHITECTURE) include(CheckAtomic) +if(WITH_STATIC) + if(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif() +endif() + include_directories(${LIBI2PD_SRC_DIR}) FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp) add_library(libi2pd ${LIBI2PD_SRC}) @@ -133,25 +139,30 @@ if(APPLE) add_definitions(-DMAC_OSX) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") -# TODO: The following is incompatible with static build and enabled hardening for OpenWRT. -# Multiple definitions of __stack_chk_fail(libssp & libc) -set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections") -set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above - -# check for c++17 & c++11 support -include(CheckCXXCompilerFlag) - -CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED) -CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED) - -if(CXX17_SUPPORTED) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") -elseif(CXX11_SUPPORTED) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +if(MSVC) + add_definitions(-DWINVER=0x0501) + add_definitions(-D_WIN32_WINNT=0x0501) else() - message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") + # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. + # Multiple definitions of __stack_chk_fail(libssp & libc) + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections") + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above + + # check for c++17 & c++11 support + include(CheckCXXCompilerFlag) + + CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED) + CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED) + + if(CXX17_SUPPORTED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + elseif(CXX11_SUPPORTED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + else() + message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") + endif() endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -217,7 +228,11 @@ if(WITH_STATIC) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_STATIC_RUNTIME OFF) + if(MSVC) + set(Boost_USE_STATIC_RUNTIME ON) + else() + set(Boost_USE_STATIC_RUNTIME OFF) + endif() set(OPENSSL_USE_STATIC_LIBS ON) @@ -244,7 +259,7 @@ else() add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) endif() -find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED) +find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic) if(NOT DEFINED Boost_INCLUDE_DIRS) message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!") endif() @@ -307,7 +322,9 @@ if(WITH_BINARY) endif () if(WITH_STATIC) - set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") + if(NOT MSVC) + set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") + endif() endif() if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -324,7 +341,7 @@ if(WITH_BINARY) if(WIN32) get_target_property(BOOSTFSLIBS Boost::filesystem INTERFACE_LINK_LIBRARIES) list(REMOVE_ITEM BOOSTFSLIBS synchronization) - set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}") + set_target_properties(Boost::filesystem PROPERTIES INTERFACE_LINK_LIBRARIES "${BOOSTFSLIBS}") endif() if(WITH_STATIC) From 231c02c058ee59e26d50ce5873b6919be8d51616 Mon Sep 17 00:00:00 2001 From: Vort Date: Wed, 1 Mar 2023 22:41:31 +0200 Subject: [PATCH 0152/1160] Make Win32NetState compatible with MSVC --- Win32/Win32NetState.cpp | 4 ++++ build/CMakeLists.txt | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Win32/Win32NetState.cpp b/Win32/Win32NetState.cpp index 5c56711d..216c36b6 100644 --- a/Win32/Win32NetState.cpp +++ b/Win32/Win32NetState.cpp @@ -29,7 +29,11 @@ void SubscribeToEvents() if (SUCCEEDED(Result)) { VARIANT_BOOL IsConnect = VARIANT_FALSE; +#if defined(_MSC_VER) + Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect); +#else Result = pNetworkListManager->IsConnectedToInternet(&IsConnect); +#endif if (SUCCEEDED(Result)) { i2p::transport::transports.SetOnline (true); LogPrint(eLogInfo, "NetState: Current state: ", IsConnect == VARIANT_TRUE ? "connected" : "disconnected"); diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 999e0a76..2379f9cb 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -140,8 +140,8 @@ if(APPLE) endif() if(MSVC) - add_definitions(-DWINVER=0x0501) - add_definitions(-D_WIN32_WINNT=0x0501) + add_definitions(-DWINVER=0x0600) + add_definitions(-D_WIN32_WINNT=0x0600) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter -Wno-uninitialized") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") From 1b921a2eac8a297eb266ab6ad1dad153f33a63bb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Mar 2023 22:05:24 -0500 Subject: [PATCH 0153/1160] removed some SSU1 code --- libi2pd/RouterInfo.cpp | 11 ++--------- libi2pd/RouterInfo.h | 3 +-- libi2pd/SSU2.cpp | 1 - 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3fb95814..8117b9fb 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -336,11 +336,7 @@ namespace data address->ssu->introducers.resize (index + 1); } Introducer& introducer = address->ssu->introducers.at (index); - if (!strcmp (key, "ihost")) - introducer.isH = false; // SSU1 - else if (!strcmp (key, "iport")) - introducer.isH = false; // SSU1 - else if (!strcmp (key, "itag")) + if (!strcmp (key, "itag")) { try { @@ -352,10 +348,7 @@ namespace data } } else if (!strcmp (key, "ih")) - { Base64ToByteStream (value, strlen (value), introducer.iH, 32); - introducer.isH = true; - } else if (!strcmp (key, "iexp")) { try @@ -411,7 +404,7 @@ namespace data int numValid = 0; for (auto& it: address->ssu->introducers) { - if (it.iTag && ts < it.iExp && it.isH) + if (it.iTag && ts < it.iExp) numValid++; else it.iTag = 0; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 1024cda8..ffab8e10 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -110,11 +110,10 @@ namespace data struct Introducer { - Introducer (): iTag (0), iExp (0), isH (false) {}; + Introducer (): iTag (0), iExp (0) {}; IdentHash iH; uint32_t iTag; uint32_t iExp; - bool isH; // TODO: remove later }; struct SSUExt diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 3773f03d..4abf0c17 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1017,7 +1017,6 @@ namespace transport i2p::data::RouterInfo::Introducer introducer; introducer.iTag = it->GetRelayTag (); introducer.iH = it->GetRemoteIdentity ()->GetIdentHash (); - introducer.isH = true; introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION; excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ()); if (i2p::context.AddSSU2Introducer (introducer, v4)) From 9e0389df1bd0671f608ba493a6adc88195da6e9d Mon Sep 17 00:00:00 2001 From: Vort Date: Thu, 2 Mar 2023 12:14:49 +0200 Subject: [PATCH 0154/1160] Fix several warnings --- libi2pd/Gzip.cpp | 2 +- libi2pd/SSU2.cpp | 4 ++-- libi2pd/Streaming.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 35676f5c..4be8684c 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -139,7 +139,7 @@ namespace data if (m_IsDirty) deflateReset (&m_Deflator); m_IsDirty = true; size_t offset = 0; - int err; + int err = 0; for (const auto& it: bufs) { m_Deflator.next_in = const_cast(it.first); diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 4abf0c17..b50284a6 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -918,7 +918,7 @@ namespace transport } uint64_t token; RAND_bytes ((uint8_t *)&token, 8); - m_IncomingTokens.emplace (ep, std::make_pair (token, ts + SSU2_TOKEN_EXPIRATION_TIMEOUT)); + m_IncomingTokens.emplace (ep, std::make_pair (token, uint32_t(ts + SSU2_TOKEN_EXPIRATION_TIMEOUT))); return token; } @@ -927,7 +927,7 @@ namespace transport m_IncomingTokens.erase (ep); // drop previous uint64_t token; RAND_bytes ((uint8_t *)&token, 8); - auto ret = std::make_pair (token, i2p::util::GetSecondsSinceEpoch () + SSU2_NEXT_TOKEN_EXPIRATION_TIMEOUT); + auto ret = std::make_pair (token, uint32_t(i2p::util::GetSecondsSinceEpoch () + SSU2_NEXT_TOKEN_EXPIRATION_TIMEOUT)); m_IncomingTokens.emplace (ep, ret); return ret; } diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 1049abce..67ed925d 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -51,8 +51,8 @@ namespace stream { // partially rem = len - offset; - memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset); - nextBuffer->offset += (len - offset); + memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem); + nextBuffer->offset += rem; offset = len; // break } } From 064c013a72da56bd879913aafc74a086eec22cee Mon Sep 17 00:00:00 2001 From: Vort Date: Thu, 2 Mar 2023 21:25:29 +0200 Subject: [PATCH 0155/1160] Remove unreachable reseed --- libi2pd/Config.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 8df08118..f9d894fa 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -215,7 +215,6 @@ namespace config { "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," "https://reseed.i2pgit.org/," - "https://i2p.novg.net/," "https://banana.incognet.io/," "https://reseed-pl.i2pd.xyz/," "https://www2.mk16.de/" From 4db643aa8e91d82bf9026391a3bacfb418402f85 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Mar 2023 16:18:25 -0500 Subject: [PATCH 0156/1160] limited number of acked packets to 511 --- libi2pd/SSU2Session.cpp | 2 +- libi2pd/SSU2Session.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index f2b002cd..46acf05b 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1661,7 +1661,7 @@ namespace transport // ranges len -= 5; const uint8_t * ranges = buf + 5; - while (len > 0 && firstPacketNum) + while (len > 0 && firstPacketNum && ackThrough - firstPacketNum < SSU2_MAX_NUM_ACK_PACKETS) { uint32_t lastPacketNum = firstPacketNum - 1; if (*ranges > lastPacketNum) break; diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 363cb982..304efdab 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -49,10 +49,10 @@ namespace transport const float SSU2_kAPPA = 1.8; const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages const int SSU2_MAX_NUM_ACNT = 255; // acnt, acks or nacks - const int SSU2_MAX_NUM_ACK_PACKETS = 510; // 2*255 ack + nack + const int SSU2_MAX_NUM_ACK_PACKETS = 511; // ackthrough + acnt + 1 range const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64; - const int SSU2_SEND_DATETIME_NUM_PACKETS = 250; + const int SSU2_SEND_DATETIME_NUM_PACKETS = 256; // flags const uint8_t SSU2_FLAG_IMMEDIATE_ACK_REQUESTED = 0x01; From 6610af08c28380cafa584cf2e3204dee8d30998d Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 3 Mar 2023 21:26:38 +0200 Subject: [PATCH 0157/1160] Correct processing of reseed.floodfill option --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 2302dc86..18f948ac 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -431,8 +431,8 @@ namespace data } // try reseeding from floodfill first if specified - std::string riPath; - if(i2p::config::GetOption("reseed.floodfill", riPath)) + std::string riPath; i2p::config::GetOption("reseed.floodfill", riPath); + if (!riPath.empty()) { auto ri = std::make_shared(riPath); if (ri->IsFloodfill()) From a4759694c819a0fa92613813734e31da93ce5514 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 3 Mar 2023 21:28:22 +0200 Subject: [PATCH 0158/1160] Prevent out of bounds array access --- libi2pd/Reseed.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 4c23b4cc..4a6e5a7e 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -320,7 +320,7 @@ namespace data uint16_t fileNameLength, extraFieldLength; s.read ((char *)&fileNameLength, 2); fileNameLength = le16toh (fileNameLength); - if ( fileNameLength > 255 ) { + if ( fileNameLength >= 255 ) { // too big LogPrint(eLogError, "Reseed: SU3 fileNameLength too large: ", fileNameLength); return numFiles; From d50cf0ad83dfea3b00b27dc1789ff6032f985f3f Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Mar 2023 20:21:56 -0500 Subject: [PATCH 0159/1160] recognize congestion caps --- libi2pd/NetDb.cpp | 2 +- libi2pd/RouterInfo.cpp | 38 +++++++++++++++++++++++++++++++++++--- libi2pd/RouterInfo.h | 20 +++++++++++++++++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 18f948ac..5dfb7889 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1210,7 +1210,7 @@ namespace data router->IsReachableFrom (*compatibleWith)) && (router->GetCaps () & RouterInfo::eHighBandwidth) && router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && - router->IsECIES (); + router->IsECIES () && !router->IsHighCongestion (); }); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 8117b9fb..e6197061 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -43,7 +43,7 @@ namespace data RouterInfo::RouterInfo (const std::string& fullPath): m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0),m_ReachableTransports (0), - m_Caps (0), m_Version (0) + m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = NewBuffer (); // always RouterInfo's @@ -53,7 +53,7 @@ namespace data RouterInfo::RouterInfo (std::shared_ptr&& buf, size_t len): m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_ReachableTransports (0), - m_Caps (0), m_Version (0) + m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { if (len <= MAX_RI_BUFFER_SIZE) { @@ -202,7 +202,7 @@ namespace data void RouterInfo::ReadFromStream (std::istream& s) { if (!s) return; - m_Caps = 0; + m_Caps = 0; m_Congestion = eLowCongestion; s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); m_Timestamp = be64toh (m_Timestamp); // read addresses @@ -535,6 +535,15 @@ namespace data case CAPS_FLAG_UNREACHABLE: m_Caps |= Caps::eUnreachable; break; + case CAPS_FLAG_MEDIUM_COGNESTION: + m_Congestion = eMediumCongestion; + break; + case CAPS_FLAG_HIGH_COGNESTION: + m_Congestion = eHighCongestion; + break; + case CAPS_FLAG_REJECT_ALL_COGNESTION: + m_Congestion = eRejectAll; + break; default: ; } cap++; @@ -1057,6 +1066,15 @@ namespace data m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); } + bool RouterInfo::IsHighCongestion () const + { + if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false; + if (m_Congestion == eRejectAll) return true; + if (m_Congestion == eHighCongestion) + return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_COGNESION_INTERVAL*1000LL) ? true : false; + return false; + } + void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) { RefreshTimestamp (); @@ -1108,6 +1126,20 @@ namespace data if (c & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable if (c & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable + switch (GetCongestion ()) + { + case eMediumCongestion: + caps += CAPS_FLAG_MEDIUM_COGNESTION; + break; + case eHighCongestion: + caps += CAPS_FLAG_HIGH_COGNESTION; + break; + case eRejectAll: + caps += CAPS_FLAG_REJECT_ALL_COGNESTION; + break; + default: ; + }; + SetProperty ("caps", caps); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ffab8e10..e0ca53e5 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -44,7 +44,11 @@ namespace data const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */ const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */ const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */ - + // congesion flags + const char CAPS_FLAG_MEDIUM_COGNESTION = 'D'; + const char CAPS_FLAG_HIGH_COGNESTION = 'E'; + const char CAPS_FLAG_REJECT_ALL_COGNESTION = 'G'; + const char CAPS_FLAG_V4 = '4'; const char CAPS_FLAG_V6 = '6'; const char CAPS_FLAG_SSU2_TESTING = 'B'; @@ -56,6 +60,8 @@ namespace data const uint8_t COST_SSU2_NON_PUBLISHED = 15; const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later + const int HIGH_COGNESION_INTERVAL = 15*60; // in seconds, 15 minutes + class RouterInfo: public RoutingDestination { public: @@ -93,6 +99,14 @@ namespace data eUnreachable = 0x20 }; + enum Congestion + { + eLowCongestion = 0, + eMediumCongestion, + eHighCongestion, + eRejectAll + }; + enum AddressCaps { eV4 = 0x01, @@ -234,10 +248,13 @@ namespace data bool IsEligibleFloodfill () const; bool IsSSU2PeerTesting (bool v4) const; bool IsSSU2Introducer (bool v4) const; + bool IsHighCongestion () const; uint8_t GetCaps () const { return m_Caps; }; void SetCaps (uint8_t caps) { m_Caps = caps; }; + Congestion GetCongestion () const { return m_Congestion; }; + void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; bool IsUnreachable () const { return m_IsUnreachable; }; @@ -302,6 +319,7 @@ namespace data CompatibleTransports m_SupportedTransports, m_ReachableTransports; uint8_t m_Caps; int m_Version; + Congestion m_Congestion; mutable std::shared_ptr m_Profile; }; From 3154eda6a648730db30553287037a50f851e9f11 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Mar 2023 15:46:44 -0500 Subject: [PATCH 0160/1160] fixed typos --- libi2pd/RouterInfo.cpp | 14 +++++++------- libi2pd/RouterInfo.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index e6197061..e9df01bb 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -535,13 +535,13 @@ namespace data case CAPS_FLAG_UNREACHABLE: m_Caps |= Caps::eUnreachable; break; - case CAPS_FLAG_MEDIUM_COGNESTION: + case CAPS_FLAG_MEDIUM_CONGESTION: m_Congestion = eMediumCongestion; break; - case CAPS_FLAG_HIGH_COGNESTION: + case CAPS_FLAG_HIGH_CONGESTION: m_Congestion = eHighCongestion; break; - case CAPS_FLAG_REJECT_ALL_COGNESTION: + case CAPS_FLAG_REJECT_ALL_CONGESTION: m_Congestion = eRejectAll; break; default: ; @@ -1071,7 +1071,7 @@ namespace data if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false; if (m_Congestion == eRejectAll) return true; if (m_Congestion == eHighCongestion) - return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_COGNESION_INTERVAL*1000LL) ? true : false; + return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESION_INTERVAL*1000LL) ? true : false; return false; } @@ -1129,13 +1129,13 @@ namespace data switch (GetCongestion ()) { case eMediumCongestion: - caps += CAPS_FLAG_MEDIUM_COGNESTION; + caps += CAPS_FLAG_MEDIUM_CONGESTION; break; case eHighCongestion: - caps += CAPS_FLAG_HIGH_COGNESTION; + caps += CAPS_FLAG_HIGH_CONGESTION; break; case eRejectAll: - caps += CAPS_FLAG_REJECT_ALL_COGNESTION; + caps += CAPS_FLAG_REJECT_ALL_CONGESTION; break; default: ; }; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index e0ca53e5..3b74eaf3 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -45,9 +45,9 @@ namespace data const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */ const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */ // congesion flags - const char CAPS_FLAG_MEDIUM_COGNESTION = 'D'; - const char CAPS_FLAG_HIGH_COGNESTION = 'E'; - const char CAPS_FLAG_REJECT_ALL_COGNESTION = 'G'; + const char CAPS_FLAG_MEDIUM_CONGESTION = 'D'; + const char CAPS_FLAG_HIGH_CONGESTION = 'E'; + const char CAPS_FLAG_REJECT_ALL_CONGESTION = 'G'; const char CAPS_FLAG_V4 = '4'; const char CAPS_FLAG_V6 = '6'; @@ -60,7 +60,7 @@ namespace data const uint8_t COST_SSU2_NON_PUBLISHED = 15; const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later - const int HIGH_COGNESION_INTERVAL = 15*60; // in seconds, 15 minutes + const int HIGH_CONGESION_INTERVAL = 15*60; // in seconds, 15 minutes class RouterInfo: public RoutingDestination { From c02c9c3c2448a87ede1527e3d95a9fc52df57580 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Sun, 5 Mar 2023 23:50:03 +0800 Subject: [PATCH 0161/1160] Makefile.osx: do not use Intel flags on PPC --- Makefile.osx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.osx b/Makefile.osx index b91008d6..e069aaff 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -23,9 +23,12 @@ ifeq ($(USE_UPNP),yes) endif endif -ifeq ($(USE_AESNI),yes) - CXXFLAGS += -maes - DEFINES += -D__AES__ -else - CXXFLAGS += -msse +OSARCH = $(shell uname -p) + +ifneq ($(OSARCH),powerpc) + ifeq ($(USE_AESNI),yes) + CXXFLAGS += -D__AES__ -maes + else + CXXFLAGS += -msse + endif endif From 5470a3a4533c8b382fab958bf16fe33942dc24e4 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 3 Mar 2023 21:02:54 +0200 Subject: [PATCH 0162/1160] Eliminate memory leak in Win32NetState --- Win32/DaemonWin32.cpp | 2 +- Win32/Win32App.cpp | 11 ++++++++--- Win32/Win32App.h | 2 +- Win32/Win32NetState.cpp | 9 +++++++-- Win32/Win32NetState.h | 7 ++----- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index affc301a..e8052f14 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -64,7 +64,7 @@ namespace util //setlocale(LC_ALL, "Russian"); setlocale(LC_TIME, "C"); #ifdef WIN32_APP - if (!i2p::win32::StartWin32App ()) return false; + if (!i2p::win32::StartWin32App (isDaemon)) return false; #endif bool ret = Daemon_Singleton::start(); if (ret && i2p::log::Logger().GetLogType() == eLogFile) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 37458046..9eae7a95 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -45,6 +45,7 @@ namespace i2p namespace win32 { DWORD g_GracefulShutdownEndtime = 0; + bool g_isWinService; static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) { @@ -416,8 +417,9 @@ namespace win32 return DefWindowProc( hWnd, uMsg, wParam, lParam); } - bool StartWin32App () + bool StartWin32App (bool isWinService) { + g_isWinService = isWinService; if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"))) { MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK); @@ -446,7 +448,9 @@ namespace win32 MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); return false; } - SubscribeToEvents(); + // COM requires message loop to work, which is not implemented in service mode + if (!g_isWinService) + SubscribeToEvents(); return true; } @@ -466,7 +470,8 @@ namespace win32 HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); if (hWnd) PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); - // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app + else if(!g_isWinService) + UnSubscribeFromEvents(); UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); } diff --git a/Win32/Win32App.h b/Win32/Win32App.h index ebe49efd..614de738 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -17,7 +17,7 @@ namespace win32 { extern DWORD g_GracefulShutdownEndtime; - bool StartWin32App (); + bool StartWin32App (bool isWinService); void StopWin32App (); int RunWin32App (); bool GracefulShutdown (); diff --git a/Win32/Win32NetState.cpp b/Win32/Win32NetState.cpp index 216c36b6..794dc4b9 100644 --- a/Win32/Win32NetState.cpp +++ b/Win32/Win32NetState.cpp @@ -15,6 +15,7 @@ IUnknown *pUnknown = nullptr; INetworkListManager *pNetworkListManager = nullptr; IConnectionPointContainer *pCPContainer = nullptr; IConnectionPoint *pConnectPoint = nullptr; +CNetworkListManagerEvent *pNetEvent = nullptr; DWORD Cookie = 0; void SubscribeToEvents() @@ -45,8 +46,8 @@ void SubscribeToEvents() Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint); if(SUCCEEDED(Result)) { - CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent; - Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie); + pNetEvent = new CNetworkListManagerEvent; + Result = pConnectPoint->Advise((IUnknown *)pNetEvent, &Cookie); if (SUCCEEDED(Result)) LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages"); else @@ -63,6 +64,7 @@ void SubscribeToEvents() void UnSubscribeFromEvents() { + LogPrint(eLogInfo, "NetState: Unsubscribing from NetworkListManagerEvents"); try { if (pConnectPoint) { @@ -70,6 +72,9 @@ void UnSubscribeFromEvents() pConnectPoint->Release(); } + if (pNetEvent) + pNetEvent->Release(); + if (pCPContainer) pCPContainer->Release(); diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h index c2ddaee4..1414a324 100644 --- a/Win32/Win32NetState.h +++ b/Win32/Win32NetState.h @@ -19,21 +19,18 @@ class CNetworkListManagerEvent : public INetworkListManagerEvents { public: CNetworkListManagerEvent() : m_ref(1) { } - ~CNetworkListManagerEvent() { } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { - HRESULT Result = S_OK; if (IsEqualIID(riid, IID_IUnknown)) { *ppvObject = (IUnknown *)this; } else if (IsEqualIID(riid ,IID_INetworkListManagerEvents)) { *ppvObject = (INetworkListManagerEvents *)this; } else { - Result = E_NOINTERFACE; + return E_NOINTERFACE; } AddRef(); - - return Result; + return S_OK; } ULONG STDMETHODCALLTYPE AddRef() From 24a14e3440128fec355b4785d88b899e7d26c210 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Mar 2023 20:08:15 -0500 Subject: [PATCH 0163/1160] moved max num transit tunnels to Tunnels --- daemon/Daemon.cpp | 2 +- daemon/HTTPServer.cpp | 4 ++-- libi2pd/I2NPProtocol.cpp | 19 ++----------------- libi2pd/I2NPProtocol.h | 6 +----- libi2pd/Tunnel.cpp | 11 ++++++++++- libi2pd/Tunnel.h | 8 +++++++- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 2a70dd1f..84f197fb 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -179,7 +179,7 @@ namespace util uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels")) transitTunnels *= 2; // double default number of transit tunnels for floodfill - SetMaxNumTransitTunnels (transitTunnels); + i2p::tunnel::tunnels.SetMaxNumTransitTunnels (transitTunnels); /* this section also honors 'floodfill' flag, if set above */ std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index e42efb36..3d5ff1a0 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -754,7 +754,7 @@ namespace http { s << " info \r\n"; s << " debug
\r\n
\r\n"; - uint16_t maxTunnels = GetMaxNumTransitTunnels (); + uint16_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels (); s << "" << tr("Transit tunnels limit") << "
\r\n"; s << "
\r\n"; s << " \r\n"; @@ -1314,7 +1314,7 @@ namespace http { { uint32_t limit = std::stoul(params["limit"], nullptr); if (limit > 0 && limit <= TRANSIT_TUNNELS_LIMIT) - SetMaxNumTransitTunnels (limit); + i2p::tunnel::tunnels.SetMaxNumTransitTunnels (limit); else { s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed %d", TRANSIT_TUNNELS_LIMIT) << "\r\n
\r\n
\r\n"; s << "" << tr("Back to commands list") << "\r\n
\r\n"; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 4d1ab6d4..c1724b39 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -353,21 +353,6 @@ namespace i2p return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo } - static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO: - void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) - { - if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels) - { - LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); - g_MaxNumTransitTunnels = maxNumTransitTunnels; - } - } - - uint16_t GetMaxNumTransitTunnels () - { - return g_MaxNumTransitTunnels; - } - static bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) @@ -380,7 +365,7 @@ namespace i2p uint8_t retCode = 0; // replace record to reply if (i2p::context.AcceptsTunnels () && - i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && + !i2p::tunnel::tunnels.IsTooManyTransitTunnels () && !i2p::transport::transports.IsBandwidthExceeded () && !i2p::transport::transports.IsTransitBandwidthExceeded ()) { @@ -577,7 +562,7 @@ namespace i2p // check if we accept this tunnel uint8_t retCode = 0; if (!i2p::context.AcceptsTunnels () || - i2p::tunnel::tunnels.GetTransitTunnels ().size () > g_MaxNumTransitTunnels || + i2p::tunnel::tunnels.IsTooManyTransitTunnels () || i2p::transport::transports.IsBandwidthExceeded () || i2p::transport::transports.IsTransitBandwidthExceeded ()) retCode = 30; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index a388dc52..80757501 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -308,10 +308,6 @@ namespace tunnel std::vector > m_TunnelMsgs, m_TunnelGatewayMsgs; }; - - const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 5000; - void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); - uint16_t GetMaxNumTransitTunnels (); } #endif diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 372c3ff9..3e952bbe 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -331,7 +331,7 @@ namespace tunnel Tunnels tunnels; - Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), + Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_MaxNumTransitTunnels (DEFAULT_MAX_NUM_TRANSIT_TUNNELS), m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal avarage m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) { @@ -970,5 +970,14 @@ namespace tunnel // TODO: locking return m_OutboundTunnels.size(); } + + void Tunnels::SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) + { + if (maxNumTransitTunnels > 0 && m_MaxNumTransitTunnels != maxNumTransitTunnels) + { + LogPrint (eLogDebug, "Tunnel: Max number of transit tunnels set to ", maxNumTransitTunnels); + m_MaxNumTransitTunnels = maxNumTransitTunnels; + } + } } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index b690d1eb..5ac410ea 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -41,10 +41,11 @@ namespace tunnel const int MAX_NUM_RECORDS = 8; const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds const int MAX_TUNNEL_MSGS_BATCH_SIZE = 100; // handle messages without interrupt + const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 5000; const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds - + 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 @@ -229,6 +230,10 @@ namespace tunnel std::shared_ptr NewI2NPTunnelMessage (bool endpoint); + void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); + uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; + bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; }; + private: template @@ -287,6 +292,7 @@ namespace tunnel i2p::util::Queue > m_Queue; i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; + uint16_t m_MaxNumTransitTunnels; // count of tunnels for total TCSR algorithm int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; From 716926f0d7f22a203c21355e837a2d7e6ed508c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Mar 2023 19:48:04 -0500 Subject: [PATCH 0164/1160] publish high congestion cap --- libi2pd/I2NPProtocol.cpp | 12 +++--------- libi2pd/RouterContext.cpp | 33 +++++++++++++++++++++++++++++++++ libi2pd/RouterContext.h | 6 +++++- libi2pd/RouterInfo.cpp | 18 +++++++++++++++++- libi2pd/RouterInfo.h | 8 +++++--- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index c1724b39..5ae89c23 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -364,10 +364,7 @@ namespace i2p if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; // replace record to reply - if (i2p::context.AcceptsTunnels () && - !i2p::tunnel::tunnels.IsTooManyTransitTunnels () && - !i2p::transport::transports.IsBandwidthExceeded () && - !i2p::transport::transports.IsTransitBandwidthExceeded ()) + if (i2p::context.AcceptsTunnels () && !i2p::context.IsHighCongestion ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -561,11 +558,8 @@ namespace i2p // check if we accept this tunnel uint8_t retCode = 0; - if (!i2p::context.AcceptsTunnels () || - i2p::tunnel::tunnels.IsTooManyTransitTunnels () || - i2p::transport::transports.IsBandwidthExceeded () || - i2p::transport::transports.IsTransitBandwidthExceeded ()) - retCode = 30; + if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ()) + retCode = 30; if (!retCode) { // create new transit tunnel diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index f2b8f4fb..b6806fb3 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -60,6 +60,8 @@ namespace i2p { m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); ScheduleInitialPublish (); + m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); + ScheduleCongestionUpdate (); } } } @@ -70,6 +72,8 @@ namespace i2p { if (m_PublishTimer) m_PublishTimer->cancel (); + if (m_CongestionUpdateTimer) + m_CongestionUpdateTimer->cancel (); m_Service->Stop (); } } @@ -1107,6 +1111,13 @@ namespace i2p return i2p::tunnel::tunnels.GetExploratoryPool (); } + bool RouterContext::IsHighCongestion () const + { + return i2p::tunnel::tunnels.IsTooManyTransitTunnels () || + i2p::transport::transports.IsBandwidthExceeded () || + i2p::transport::transports.IsTransitBandwidthExceeded (); + } + void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len) { i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); @@ -1368,4 +1379,26 @@ namespace i2p SchedulePublishResend (); } } + + void RouterContext::ScheduleCongestionUpdate () + { + if (m_CongestionUpdateTimer) + { + m_CongestionUpdateTimer->cancel (); + m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONGESTION_UPDATE_INTERVAL)); + m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Congestion update timer is NULL"); + } + + void RouterContext::HandleCongestionUpdateTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + m_RouterInfo.SetHighCongestion (IsHighCongestion ()); + ScheduleCongestionUpdate (); + } + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 4b6d917e..b8183339 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -37,6 +37,7 @@ namespace garlic const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 5; // in seconds const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; + const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 12*60; // in seconds enum RouterStatus { @@ -152,6 +153,7 @@ namespace garlic void SetShareRatio (int percents); // 0 - 100 bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; + bool IsHighCongestion () const; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; bool SupportsMesh () const { return m_RouterInfo.IsMesh (); }; @@ -213,6 +215,8 @@ namespace garlic void Publish (); void SchedulePublishResend (); void HandlePublishResendTimer (const boost::system::error_code& ecode); + void ScheduleCongestionUpdate (); + void HandleCongestionUpdateTimer (const boost::system::error_code& ecode); private: @@ -235,7 +239,7 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; // publish std::unique_ptr m_Service; - std::unique_ptr m_PublishTimer; + std::unique_ptr m_PublishTimer, m_CongestionUpdateTimer; std::set m_PublishExcluded; uint32_t m_PublishReplyToken; bool m_IsHiddenMode; // not publish diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index e9df01bb..41c69b09 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1071,9 +1071,15 @@ namespace data if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false; if (m_Congestion == eRejectAll) return true; if (m_Congestion == eHighCongestion) - return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESION_INTERVAL*1000LL) ? true : false; + return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL) ? true : false; return false; } + + LocalRouterInfo::LocalRouterInfo (const std::string& fullPath): + RouterInfo (fullPath) + { + SetHighCongestion (false); // drop congestion + } void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) { @@ -1143,6 +1149,16 @@ namespace data SetProperty ("caps", caps); } + void LocalRouterInfo::SetHighCongestion (bool highCongestion) + { + Congestion c = highCongestion ? eHighCongestion : eLowCongestion; + if (c != GetCongestion ()) + { + SetCongestion (c); + UpdateCapsProperty (); + } + } + void LocalRouterInfo::WriteToStream (std::ostream& s) const { auto addresses = GetAddresses (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 3b74eaf3..2e9e67b5 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -60,7 +60,7 @@ namespace data const uint8_t COST_SSU2_NON_PUBLISHED = 15; const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later - const int HIGH_CONGESION_INTERVAL = 15*60; // in seconds, 15 minutes + const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes class RouterInfo: public RoutingDestination { @@ -291,7 +291,8 @@ namespace data void RefreshTimestamp (); CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; }; void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; }; - + void SetCongestion (Congestion c) { m_Congestion = c; }; + private: bool LoadFile (const std::string& fullPath); @@ -328,9 +329,10 @@ namespace data public: LocalRouterInfo () = default; - LocalRouterInfo (const std::string& fullPath): RouterInfo (fullPath) {}; + LocalRouterInfo (const std::string& fullPath); void CreateBuffer (const PrivateKeys& privateKeys); void UpdateCaps (uint8_t caps); + void SetHighCongestion (bool highCongestion); void SetProperty (const std::string& key, const std::string& value) override; void DeleteProperty (const std::string& key); From 4b7fcdc7199c987faf52e7d6808a81e71ea9afb0 Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 7 Mar 2023 12:06:50 +0200 Subject: [PATCH 0165/1160] Prevent leaking of ExploratoryPool --- libi2pd/Tunnel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 3e952bbe..58e13ad3 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -339,6 +339,7 @@ namespace tunnel Tunnels::~Tunnels () { + DeleteTunnelPool(m_ExploratoryPool); } std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) From 46e4f4aea55b57dd653a028e1516f4c58869e90d Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Mar 2023 13:09:07 -0500 Subject: [PATCH 0166/1160] update RouterInfo if congestion cap changed --- libi2pd/RouterContext.cpp | 3 ++- libi2pd/RouterInfo.cpp | 4 +++- libi2pd/RouterInfo.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b6806fb3..084e8c77 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1397,7 +1397,8 @@ namespace i2p { if (ecode != boost::asio::error::operation_aborted) { - m_RouterInfo.SetHighCongestion (IsHighCongestion ()); + if (m_RouterInfo.SetHighCongestion (IsHighCongestion ())) + UpdateRouterInfo (); ScheduleCongestionUpdate (); } } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 41c69b09..db0a7de6 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1149,14 +1149,16 @@ namespace data SetProperty ("caps", caps); } - void LocalRouterInfo::SetHighCongestion (bool highCongestion) + bool LocalRouterInfo::SetHighCongestion (bool highCongestion) { Congestion c = highCongestion ? eHighCongestion : eLowCongestion; if (c != GetCongestion ()) { SetCongestion (c); UpdateCapsProperty (); + return true; } + return false; } void LocalRouterInfo::WriteToStream (std::ostream& s) const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 2e9e67b5..3e8e0613 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -332,7 +332,7 @@ namespace data LocalRouterInfo (const std::string& fullPath); void CreateBuffer (const PrivateKeys& privateKeys); void UpdateCaps (uint8_t caps); - void SetHighCongestion (bool highCongestion); + bool SetHighCongestion (bool highCongestion); // returns true if updated void SetProperty (const std::string& key, const std::string& value) override; void DeleteProperty (const std::string& key); From 0a8da6bc2f698ee945dd9c2c328e9510cec63124 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 8 Mar 2023 11:41:01 +0000 Subject: [PATCH 0167/1160] [cmake] msvc build revision Signed-off-by: R4SAS --- build/.gitignore | 4 ++++ build/CMakeLists.txt | 35 ++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/build/.gitignore b/build/.gitignore index d51958d6..39b8094c 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -21,3 +21,7 @@ # windows build script i2pd*.zip build*.log +# MVS project files +*.vcxproj +*.vcxproj.filters +*.sln diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2379f9cb..bc65b41e 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -194,6 +194,12 @@ endif() # Note: AES-NI and AVX is available on x86-based CPU's. # Here also ARM64 implementation, but currently we don't support it. +# MSVC is not supported. +if(MSVC) + message(STATUS "AES-NI is not supported on MSVC, option was disabled") + set(WITH_AESNI OFF) +endif() + if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386")) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") add_definitions(-D__AES__) @@ -225,7 +231,9 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) if(WITH_STATIC) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + if(NOT MSVC) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + endif() set(Boost_USE_STATIC_LIBS ON) if(MSVC) @@ -234,10 +242,17 @@ if(WITH_STATIC) set(Boost_USE_STATIC_RUNTIME OFF) endif() + if(MSVC) + set(OPENSSL_MSVC_STATIC_RT ON) + endif() set(OPENSSL_USE_STATIC_LIBS ON) set(ZLIB_USE_STATIC_LIBS ON) - set(ZLIB_NAMES libz zlibstatic zlibstat zlib z) + if(MSVC) + set(ZLIB_NAMES zlibstatic zlibstat) + else() + set(ZLIB_NAMES libz zlibstatic zlibstat zlib z) + endif() if(WITH_UPNP) set(MINIUPNPC_USE_STATIC_LIBS ON) @@ -255,8 +270,10 @@ else() # TODO: Consider separate compilation for LIBI2PD_SRC for library. # No need in -fPIC overhead for binary if not interested in library # HINT: revert c266cff CMakeLists.txt: compilation speed up - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) + if(NOT MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + endif() + add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) endif() find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic) @@ -317,9 +334,13 @@ if(WITH_BINARY) add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) endif() - if (WIN32) - set(MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi") - endif () + if(WIN32) + list(APPEND MINGW_EXTRA "wsock32" "ws2_32" "iphlpapi") + # OpenSSL may require Crypt32 library on MSVC build, which is not added by CMake lesser than 3.21 + if(MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.21) + list(APPEND MINGW_EXTRA "crypt32") + endif() + endif() if(WITH_STATIC) if(NOT MSVC) From 0a564d153ae8719f16066ed764651587ac273e0b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 8 Mar 2023 18:23:32 -0500 Subject: [PATCH 0168/1160] reseed update --- .../reseed/arnavbhatt288_at_mail.i2p.crt | 34 +++++++++++++++++++ .../certificates/reseed/igor_at_novg.net.crt | 33 ------------------ libi2pd/Config.cpp | 3 +- 3 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt delete mode 100644 contrib/certificates/reseed/igor_at_novg.net.crt diff --git a/contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt b/contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt new file mode 100644 index 00000000..9068afb9 --- /dev/null +++ b/contrib/certificates/reseed/arnavbhatt288_at_mail.i2p.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQIHQPtSoFU+cUpYD8PZaWZjANBgkqhkiG9w0BAQsFADB2 +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEfMB0GA1UEAwwW +YXJuYXZiaGF0dDI4OEBtYWlsLmkycDAeFw0yMzAxMjUxODUzNDFaFw0zMzAxMjUx +ODUzNDFaMHYxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx +HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR8w +HQYDVQQDDBZhcm5hdmJoYXR0Mjg4QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAtwG73sC0jYd3fgEzZh0SveAdUd5yD35nINJRrdPSrSwY +n3i1qGe3fNLj877PvUDU+qiHH0fFZfyFkXTaq3TUp1u4YkmvaoPHy6FZlojB08lK +FBm+iJ1hifQ7MFmvIKUGv+cjlN6xSoQ0U6B2QOy6iZnBgFZ/7jbRY4iZOIj7VJtY +aodeHfy0bWe447VJovbkUi7NJPFZQS65LMcAIWcWTxrC0Gj8SmdxL3a5+hxpmmg0 ++KCQvWQDdxAQjsc16sgUCdUc6cWYO4yw9H6fgdq9GJX+LnXR9OB58GsAjjlLlFoI +CZxdARDpoqcIj6AoKIanALf8yfbIyrqqJE47cuaqV9bht5MWKnXbwHplEkT4ZNkh +PnRDia7B5HY3uwbt39CBm264PEWXvWG2sozTWKQqBjmMN2cj/NFDUEqKv6BggMY1 +HcqxWFKRcgKCtRvrmTmfp5l0/ou+OtUaFUg0a6Qhtb93Hj10vK6wZzidBqj0ggzB +eJDI95b89u8JgzRoOBriuMKTc91WTkOvBLkB3dgUbUpx2p8KHjvf/pppBH9u0oxp +qJFFK840DbnJydEvjKezeVe5Ax6YRSRxyEdKzRoWdvKVxb3qBBKMdCKTYEPxHPBu +JMEQVUCXJMti++1KEiQGhcfWvLyT7OewbcIZNk9XWNrxlKcGrTp9AOwaaNC5m1kC +AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB8GA1UdDgQYBBZhcm5hdmJoYXR0Mjg4 +QG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAHiK0ld/1PF9DIhutD660/bzBg +mF2Z76hcBqDZ8tnQai/u/RXYrH9wso9BYyrVsvk3fr6tpGT49Ian0MVpPOxMoTU2 +oBEmQlYrfclQLFsOLmA0y2r1ggXzIrt69jB710Vhwdnz09oOE8rS4E2T5oDD8Wvy +Kony+AarRceqtkOlzyquc42KjzdrbHsosF7G2iGhNI6t+T3BfWJ+Q+d5sj3OIh6e +gSfvHL44E4vZt6dtofRN3MAZ60kNLF5YWyaUo3Snv9Lso1IwIz3AVr5ehv+8sFL/ +KxaXdkZ5Yn2YUX7p1t4VQd+eXVPYjf1befg4PvrwSkylu3Jpee3fllZSKXeSVx9x +jpJiq5vIakqk22pnWb1Vn7xzSW1vtEG7QLjobOr1WrcGiwdv+HKiWcXJXDzKoWXs +h3VEfr51Kap8cIJv+D6lJIG9IcIhiQ6CXWBmtjWJvbdVwFBy1/3Fhaou9liHi+gK +4Yh5a5OGCzc7xjtpGaTmoLEz7NzDNOdd/r840qRDOh70izzmFZd5Gwq4hoVcPJcS +EAySwtgqK0/4d0zDd2Wg9ASJV9DnDf8QuSmHZgZ9Efs47XcWz9TvkWUS1E66AJsN +mmI1NDQ3mv3dv5+WPq+dqqYFsnx3xWL1g5Z3buk0opeuXMzoHwM7UfN8h7Q1M5+t ++XBgkaYA4iEwYKqlCQ== +-----END CERTIFICATE----- diff --git a/contrib/certificates/reseed/igor_at_novg.net.crt b/contrib/certificates/reseed/igor_at_novg.net.crt deleted file mode 100644 index 12ce7a61..00000000 --- a/contrib/certificates/reseed/igor_at_novg.net.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK -ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN -aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x -CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT -FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p -Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4 -cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF -x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h -vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm -w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw -MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy -Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy -f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b -mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d -Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP -0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq -jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/ -BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E -BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC -AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk -5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o -3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS -AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal -zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs -0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ -cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4 -4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6 -GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW -dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5 -qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w== ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index f9d894fa..346fb659 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -217,7 +217,8 @@ namespace config { "https://reseed.i2pgit.org/," "https://banana.incognet.io/," "https://reseed-pl.i2pd.xyz/," - "https://www2.mk16.de/" + "https://www2.mk16.de/", + "https://i2p.ghativega.in/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From ec5c13a95ecd6d31f2a49477d20ae2bca1cf711b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 8 Mar 2023 18:38:49 -0500 Subject: [PATCH 0169/1160] add back i2p.novg.net with new certificate --- .../certificates/reseed/igor_at_novg.net.crt | 33 +++++++++++++++++++ libi2pd/Config.cpp | 5 +-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 contrib/certificates/reseed/igor_at_novg.net.crt diff --git a/contrib/certificates/reseed/igor_at_novg.net.crt b/contrib/certificates/reseed/igor_at_novg.net.crt new file mode 100644 index 00000000..c6a05e8b --- /dev/null +++ b/contrib/certificates/reseed/igor_at_novg.net.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFvjCCA6agAwIBAgIQBnsUOmOu2oZZIwHBmQc1BDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN +aWdvckBub3ZnLm5ldDAeFw0yMzAxMjgxNDM4MzFaFw0zMzAxMjgxNDM4MzFaMG0x +CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT +FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p +Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLkf +bM3uiYfp9m0vgdoftyXtk2/9bHf3u5iaM0WfoJIsw1iizo/mxJl+Iy7SxLC16nV0 +v5FpncVv+Z8x9dgoAYVuLq9zKfsAbpj6kuxAqw6vJMlD1TiIL3nSODV9BJLk47X5 +tmvoOSj9BgvemYThTE3nj+DbuJRW5q90KyBV/LdLrQJX3k5R3FFL5tTad2LKFNZ4 +vEOcYwwx6mvrkJ2lly6bAQUCtfc648Jyq+NO3Rba1fmn7gcP9zXXc5KYsj/ovyY2 +OaocSF5wMhzBuPxO+M2HqbYLMAkc6/GesGds8Rm8wofuhJoI5YtqJuLKZm6nQXSc +fx6PKgbKcTIUWNFMsxyfghz9hpbg0rkvC7PtfAjtV0yaDtUum1eZeNEx1HbRWN2n +TQNCVuv0yaKC41qxqzhEybkdjL9JlgUh7VuskaCelB0lz+kgYjGu8ezOa0ua2iKq +4FC/1MbPulxN8NOt4pmbGqqoxmCdShp38wdnOBM3DsAS9f0JaQZd4CDyY4DCSfVn +xPdWk31+VXVt3Ixh1EUqZWYTRSsZApkCyYzkiZ/qPGG6FR9Hq2SuhC5o4P44k7eo +6wwBWD8a5RjsZhvr05E5yBrKXh/PjLwmtG73QC+ouR54/5xtedvdTwNS94FnNctX +FT6QGZnRwCkhPaRe1oQMzP+88pGoCfO33GBAuwUCAwEAAaNaMFgwDgYDVR0PAQH/ +BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E +BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC +AQCteAb5/bqhHr/i5CJbDzlofprXFC826c19GxQ/9Hw0kA52l0J9Q8Vz8Vy7VQyP +QNa8MCv6FeNy8a/wXp6cafyFsBtvehVQO8lFlpCgMEl2Bma43+GaCwkrM6bFNXeW +iQ9h4e1KjsUZ8cQDNEcamiJ80+xbMhBrj5bAZwKmZs8MoGEMyXKEZmcmwA+/fy1c +cx4izsOsmRXmEHXsvB9ydJHZZeKW8+r0DAtgPslwXuXHG6MuBQo7dKCqn+iMxHXV +Jxriq3yvNffdGx4maSLJrjQ1ealt/UMzql7huVSItnVFWoYf7GAELXNJ/PmqVyaK +q11LQ8W/Aud6s/bblaJrFJnK8PbPpaw4RvHoWVLYaZYmQnV2msWs5EuESBlEADbv +UklQXLMc2f9HKWPA5678nvYPrmu8IL5pMkAxgGRqmd+7vCz4lU9M5z3HObU+WRBt +qEMYyXywV8o3tbmnlDS5S5Xxf+tLZn1cxz3ZrmcHPHDbLBNdvszF3CTJH/R2sQvD +bizvYJM+p5F+GWM5mt6w0HrOut5MRlpOws/NRrkbijuVA/A45nzTtKplIFYE3qe8 +q5SAbwYLc8cJcZCN3PxtWwbEv81V33abMt5QcjnWGLH5t2+1Z2KLCgKLSCQTxM8s +zBPHtUe8qtSQaElnNLILYbtJ1w67dPnGYTphHihC+CXjBg== +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 346fb659..a083e0ea 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -217,8 +217,9 @@ namespace config { "https://reseed.i2pgit.org/," "https://banana.incognet.io/," "https://reseed-pl.i2pd.xyz/," - "https://www2.mk16.de/", - "https://i2p.ghativega.in/" + "https://www2.mk16.de/," + "https://i2p.ghativega.in/," + "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From 58ef08310d29441db19f7ee4027b4855630dfd94 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 9 Mar 2023 15:48:15 +0000 Subject: [PATCH 0170/1160] [reseed] skip records in reserved IP ranges, check Yggdrasil avalability if domain resolves in ygg address Signed-off-by: R4SAS --- libi2pd/Reseed.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 4a6e5a7e..f0a4cc29 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -687,8 +687,18 @@ namespace data while (it != end) { boost::asio::ip::tcp::endpoint ep = *it; - if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) || - (ep.address ().is_v6 () && i2p::context.SupportsV6 ())) + if ( + ( + !i2p::util::net::IsInReservedRange(ep.address ()) && ( + (ep.address ().is_v4 () && i2p::context.SupportsV4 ()) || + (ep.address ().is_v6 () && i2p::context.SupportsV6 ()) + ) + ) || + ( + i2p::util::net::IsYggdrasilAddress (ep.address ()) && + i2p::context.SupportsMesh () + ) + ) { s.lowest_layer().connect (ep, ecode); if (!ecode) From 7b35c793f303dafe918ddee0e823f5981d24e7a6 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Mar 2023 01:19:09 +0000 Subject: [PATCH 0171/1160] [reseed] support domains in yggdrasil reseeder, fix IPv6 URL host parsing Signed-off-by: R4SAS --- libi2pd/HTTP.cpp | 34 +++++++++++++++++++++++++++------- libi2pd/HTTP.h | 3 ++- libi2pd/Reseed.cpp | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 7cc87df8..f4c3dcb9 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -93,15 +93,18 @@ namespace http std::size_t pos_c = 0; /* < work position */ if(url.at(0) != '/' || pos_p > 0) { std::size_t pos_s = 0; + /* schema */ pos_c = url.find("://"); if (pos_c != std::string::npos) { schema = url.substr(0, pos_c); pos_p = pos_c + 3; } + /* user[:pass] */ pos_s = url.find('/', pos_p); /* find first slash */ pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */ + if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) { std::size_t delim = url.find(':', pos_p); if (delim && delim != std::string::npos && delim < pos_c) { @@ -113,21 +116,28 @@ namespace http } pos_p = pos_c + 1; } + /* hostname[:port][/path] */ - if (url[pos_p] == '[') // ipv6 + if (url.at(pos_p) == '[') // ipv6 { auto pos_b = url.find(']', pos_p); if (pos_b == std::string::npos) return false; + ipv6 = true; pos_c = url.find_first_of(":/", pos_b); } else pos_c = url.find_first_of(":/", pos_p); + if (pos_c == std::string::npos) { /* only hostname, without post and path */ - host = url.substr(pos_p, std::string::npos); + host = ipv6 ? + url.substr(pos_p + 1, url.length() - 1) : + url.substr(pos_p, std::string::npos); return true; } else if (url.at(pos_c) == ':') { - host = url.substr(pos_p, pos_c - pos_p); + host = ipv6 ? + url.substr(pos_p + 1, pos_c - pos_p - 2) : + url.substr(pos_p, pos_c - pos_p); /* port[/path] */ pos_p = pos_c + 1; pos_c = url.find('/', pos_p); @@ -147,7 +157,9 @@ namespace http pos_p = pos_c; } else { /* start of path part found */ - host = url.substr(pos_p, pos_c - pos_p); + host = ipv6 ? + url.substr(pos_p + 1, pos_c - pos_p - 2) : + url.substr(pos_p, pos_c - pos_p); pos_p = pos_c; } } @@ -212,10 +224,18 @@ namespace http } else if (user != "") { out += user + "@"; } - if (port) { - out += host + ":" + std::to_string(port); + if (ipv6) { + if (port) { + out += "[" + host + "]:" + std::to_string(port); + } else { + out += "[" + host + "]"; + } } else { - out += host; + if (port) { + out += host + ":" + std::to_string(port); + } else { + out += host; + } } } out += path; diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index f9d5d009..41f0560a 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -36,8 +36,9 @@ namespace http bool hasquery; std::string query; std::string frag; + bool ipv6; - URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag("") {}; + URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag(""), ipv6(false) {}; /** * @brief Tries to parse url from string diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index f0a4cc29..dfc10043 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -703,6 +703,7 @@ namespace data s.lowest_layer().connect (ep, ecode); if (!ecode) { + LogPrint (eLogDebug, "Reseed: Resolved to ", ep.address ()); connected = true; break; } @@ -790,17 +791,45 @@ namespace data boost::asio::io_service service; boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6()); - if (url.host.length () < 2) return ""; // assume [] - auto host = url.host.substr (1, url.host.length () - 2); - LogPrint (eLogDebug, "Reseed: Connecting to Yggdrasil ", url.host, ":", url.port); - s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (host), url.port), ecode); + auto it = boost::asio::ip::tcp::resolver(service).resolve ( + boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode); + if (!ecode) { - LogPrint (eLogDebug, "Reseed: Connected to Yggdrasil ", url.host, ":", url.port); + bool connected = false; + boost::asio::ip::tcp::resolver::iterator end; + while (it != end) + { + boost::asio::ip::tcp::endpoint ep = *it; + if ( + i2p::util::net::IsYggdrasilAddress (ep.address ()) && + i2p::context.SupportsMesh () + ) + { + LogPrint (eLogDebug, "Reseed: Yggdrasil: Resolved to ", ep.address ()); + s.connect (ep, ecode); + if (!ecode) + { + connected = true; + break; + } + } + it++; + } + if (!connected) + { + LogPrint(eLogError, "Reseed: Yggdrasil: Failed to connect to ", url.host); + return ""; + } + } + + if (!ecode) + { + LogPrint (eLogDebug, "Reseed: Yggdrasil: Connected to ", url.host, ":", url.port); return ReseedRequest (s, url.to_string()); } else - LogPrint (eLogError, "Reseed: Couldn't connect to Yggdrasil ", url.host, ": ", ecode.message ()); + LogPrint (eLogError, "Reseed: Yggdrasil: Couldn't connect to ", url.host, ": ", ecode.message ()); return ""; } From b6d1d8117b21485314fd1fd5acc7e45154ad9e31 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Mar 2023 01:32:07 +0000 Subject: [PATCH 0172/1160] [GHA] Windows MSVC workflow (#1904) --- .github/workflows/build-windows-msvc.yml | 52 ++++++++++++++++++++++++ .github/workflows/build-windows.yml | 6 +-- build/CMakeLists.txt | 5 ++- 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/build-windows-msvc.yml diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml new file mode 100644 index 00000000..356bb466 --- /dev/null +++ b/.github/workflows/build-windows-msvc.yml @@ -0,0 +1,52 @@ +name: Build on Windows with MSVC + +on: [push, pull_request] + +jobs: + build: + name: Build + runs-on: windows-latest + + strategy: + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build and install zlib + run: | + powershell -Command "(Invoke-WebRequest -Uri https://raw.githubusercontent.com/r4sas/zlib.install/master/install.bat -OutFile install_zlib.bat)" + powershell -Command "(Get-Content install_zlib.bat) | Set-Content install_zlib.bat" # fixing line endings + set BUILD_TYPE=Debug + ./install_zlib.bat + set BUILD_TYPE=Release + ./install_zlib.bat + del install_zlib.bat + + - name: Install Boost + uses: crazy-max/ghaction-chocolatey@v2 + with: + args: install boost-msvc-14.3 + + - name: Install OpenSSL + uses: crazy-max/ghaction-chocolatey@v2 + with: + args: install openssl + + - name: Configure + working-directory: build + run: cmake -DWITH_STATIC=ON . + + - name: Build + working-directory: build + run: cmake --build . --config Debug -- -m + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: i2pd-msvc + path: build/Debug/i2pd.* + diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 7a9a40c7..66c846c1 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -8,7 +8,7 @@ defaults: jobs: build: - name: Building using ${{ matrix.arch }} toolchain + name: ${{ matrix.arch }} runs-on: windows-latest strategy: @@ -50,7 +50,7 @@ jobs: path: i2pd.exe build-cmake: - name: Building using ${{ matrix.arch }} toolchain using CMake + name: CMake ${{ matrix.arch }} runs-on: windows-latest strategy: @@ -89,7 +89,7 @@ jobs: path: build/i2pd.exe build-xp: - name: Building for Windows XP + name: XP runs-on: windows-latest strategy: diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index bc65b41e..4100c23f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -147,7 +147,10 @@ else() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. # Multiple definitions of __stack_chk_fail(libssp & libc) - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections") + if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s") + endif() + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -ffunction-sections -fdata-sections") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above # check for c++17 & c++11 support From 6f01ebc0a51a04d756371030138e82acd7bd982f Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Mar 2023 08:44:07 -0500 Subject: [PATCH 0173/1160] check target destination --- libi2pd/Streaming.cpp | 26 +++++++++++++++++++++++--- libi2pd/Streaming.h | 3 ++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 67ed925d..42f71798 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -139,7 +139,16 @@ namespace stream { m_NumReceivedBytes += packet->GetLength (); if (!m_SendStreamID) + { m_SendStreamID = packet->GetReceiveStreamID (); + if (!m_RemoteIdentity && packet->GetNACKCount () == 8 && // first incoming packet + memcmp (packet->GetNACKs (), m_LocalDestination.GetOwner ()->GetIdentHash (), 32)) + { + LogPrint (eLogWarning, "Streaming: Destination mismatch for ", m_LocalDestination.GetOwner ()->GetIdentHash ().ToBase32 ()); + m_LocalDestination.DeletePacket (packet); + return; + } + } if (!packet->IsNoAck ()) // ack received ProcessAck (packet); @@ -560,8 +569,19 @@ namespace stream else htobe32buf (packet + size, m_LastReceivedSequenceNumber); size += 4; // ack Through - packet[size] = 0; - size++; // NACK count + if (m_Status == eStreamStatusNew && !m_SendStreamID && m_RemoteIdentity) + { + // first SYN packet + packet[size] = 8; + size++; // NACK count + memcpy (packet + size, m_RemoteIdentity->GetIdentHash (), 32); + size += 32; + } + else + { + packet[size] = 0; + size++; // NACK count + } packet[size] = m_RTO/1000; size++; // resend delay if (m_Status == eStreamStatusNew) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 0e1f7e88..dc0ca6db 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -80,6 +80,7 @@ namespace stream uint32_t GetAckThrough () const { return bufbe32toh (buf + 12); }; uint8_t GetNACKCount () const { return buf[16]; }; uint32_t GetNACK (int i) const { return bufbe32toh (buf + 17 + 4 * i); }; + const uint8_t * GetNACKs () const { return buf + 17; }; const uint8_t * GetOption () const { return buf + 17 + GetNACKCount ()*4 + 3; }; // 3 = resendDelay + flags uint16_t GetFlags () const { return bufbe16toh (GetOption () - 2); }; uint16_t GetOptionSize () const { return bufbe16toh (GetOption ()); }; From a6bd8275ca496c75c84d7eb890c0071569d28f55 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Mar 2023 10:35:55 -0500 Subject: [PATCH 0174/1160] 2.47.0 --- ChangeLog | 15 +++++++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 6 +++--- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 385a3545..b6005d4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,21 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.47.0] - 2023-03-11 +### Added +- Congestion caps +- SAM UDP port parameter +- Support domain addresses for yggdrasil reseeds +### Changed +- DHT for floodfills instead plain list +- Process router's messages in separate thread +- Don't publish non-reachable router +- Send and check target destination in first streaming SYN packet +- Reseeds list +### Fixed +- Memory leak in windows network state detection +- Reseed attempts from invalid address + ## [2.46.1] - 2023-02-20 ### Fixed - Race condition while getting router's peer profile diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index e758d42b..4ee7a8df 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.46.1 +Version: 2.47.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Mar 11 2023 orignal - 2.47.0 +- update to 2.47.0 + * Mon Feb 20 2023 r4sas - 2.46.1 - update to 2.46.1 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 32154a9c..e0ac9d03 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.46.1 +Version: 2.47.0 Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Mar 11 2023 orignal - 2.47.0 +- update to 2.47.0 + * Mon Feb 20 2023 r4sas - 2.46.1 - update to 2.46.1 diff --git a/debian/changelog b/debian/changelog index 13691601..44b0b8b5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.47.0-1) unstable; urgency=high + + * updated to version 2.47.0/0.9.58 + + -- orignal Sat, 11 Mar 2023 16:00:00 +0000 + i2pd (2.46.1-2) unstable; urgency=critical * re-pushed release due to new critical bug diff --git a/libi2pd/version.h b/libi2pd/version.h index 8d91c5c8..7d5e79fb 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -18,8 +18,8 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 46 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MINOR 47 +#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION XSTRINGIZE(GITVER) @@ -33,7 +33,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 57 +#define I2P_VERSION_MICRO 58 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 227697c388cae57a04d69d6e962ad379e55a3abd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Mar 2023 21:53:11 +0000 Subject: [PATCH 0175/1160] [i18n] update translations Signed-off-by: R4SAS --- i18n/German.cpp | 14 ++++++++++++++ i18n/Italian.cpp | 10 ++++++++++ i18n/Portuguese.cpp | 8 ++++---- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/i18n/German.cpp b/i18n/German.cpp index 0db3d6be..02662e8e 100644 --- a/i18n/German.cpp +++ b/i18n/German.cpp @@ -61,6 +61,7 @@ namespace german // language namespace {"Clock skew", "Zeitabweichung"}, {"Offline", "Offline"}, {"Symmetric NAT", "Symmetrisches NAT"}, + {"No Descriptors", "Keine Beschreibungen"}, {"Uptime", "Laufzeit"}, {"Network status", "Netzwerkstatus"}, {"Network status v6", "Netzwerkstatus v6"}, @@ -116,8 +117,10 @@ namespace german // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "Enddatum"}, + {"floodfill mode is disabled", "Floodfill Modus ist deaktiviert"}, {"Queue size", "Größe der Warteschlange"}, {"Run peer test", "Peer-Test durchführen"}, + {"Reload tunnels configuration", "Tunnel Konfiguration neu laden"}, {"Decline transit tunnels", "Transittunnel ablehnen"}, {"Accept transit tunnels", "Transittunnel akzeptieren"}, {"Cancel graceful shutdown", "Beende das kontrollierte Herunterfahren"}, @@ -145,6 +148,8 @@ namespace german // language namespace {"Destination not found", "Ziel nicht gefunden"}, {"StreamID can't be null", "StreamID kann nicht null sein"}, {"Return to destination page", "Zurück zur Ziel-Seite"}, + {"You will be redirected in %d seconds", "Du wirst umgeleitet in %d Sekunden"}, + {"Transit tunnels count must not exceed %d", "Die Anzahl der Transittunnel darf nicht über %d gehen"}, {"Back to commands list", "Zurück zur Befehlsliste"}, {"Register at reg.i2p", "Auf reg.i2p registrieren"}, {"Description", "Beschreibung"}, @@ -162,6 +167,15 @@ namespace german // language namespace {"You may try to find this host on jump services below", "Vielleicht kannst du diesen Host auf einem der nachfolgenden Jump-Services finden"}, {"Invalid request", "Ungültige Anfrage"}, {"Proxy unable to parse your request", "Proxy konnte die Anfrage nicht verarbeiten"}, + {"Addresshelper is not supported", "Adresshelfer wird nicht unterstützt"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Host %s ist bereits im Adressbuch des Routers. Vorsicht: Die Quelle dieser URL kann schädlich sein! Klicken Sie hier, um den Datensatz zu aktualisieren: Weiter."}, + {"Addresshelper forced update rejected", "Adresshelfer gezwungene Aktualisierung abgelehnt"}, + {"To add host %s in router's addressbook, click here: Continue.", "Um den Host %s im Adressbuch des Routers hinzuzufügen, klicken Sie hier: Weiter."}, + {"Addresshelper request", "Adresshelfer gefunden"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Host %s wurde vom Helfer zum Adressbuch des Routers hinzugefügt. Klicken Sie hier, um fortzufahren: Weiter."}, + {"Addresshelper adding", "Adresshelfer hinzufügen"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Host %s ist bereits im Adressbuch des Routers. Klicken Sie hier, um den Eintrag zu aktualisieren: Weiter."}, + {"Addresshelper update", "Adresshelfer aktualisieren"}, {"Invalid request URI", "Ungültige Anfrage-URI"}, {"Can't detect destination host from request", "Kann den Ziel-Host von der Anfrage nicht erkennen"}, {"Outproxy failure", "Outproxy-Fehler"}, diff --git a/i18n/Italian.cpp b/i18n/Italian.cpp index c51e15a5..386372d5 100644 --- a/i18n/Italian.cpp +++ b/i18n/Italian.cpp @@ -61,6 +61,8 @@ namespace italian // language namespace {"Clock skew", "Orologio disallineato"}, {"Offline", "Disconnesso"}, {"Symmetric NAT", "NAT simmetrico"}, + {"Full cone NAT", "Cono completo NAT"}, + {"No Descriptors", "Nessun descrittore"}, {"Uptime", "In funzione da"}, {"Network status", "Stato della rete"}, {"Network status v6", "Stato della rete v6"}, @@ -116,6 +118,7 @@ namespace italian // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "Data di fine"}, + {"floodfill mode is disabled", "la modalità floodfill è disabilitata"}, {"Queue size", "Dimensione della coda"}, {"Run peer test", "Esegui il test dei peer"}, {"Reload tunnels configuration", "Ricarica la configurazione dei tunnel"}, @@ -165,8 +168,15 @@ namespace italian // language namespace {"You may try to find this host on jump services below", "Si può provare a trovare questo host sui servizi di salto qui sotto"}, {"Invalid request", "Richiesta non valida"}, {"Proxy unable to parse your request", "Il proxy non è in grado di elaborare la tua richiesta"}, + {"Addresshelper is not supported", "Addresshelper non è supportato"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "L'host %s è già nella rubrica del router. Attenzione: la fonte di questo URL potrebbe essere dannosa! Fai clic qui per aggiornare il record: Continua."}, + {"Addresshelper forced update rejected", "Aggiornamento forzato dell'helper degli indirizzi rifiutato"}, {"To add host %s in router's addressbook, click here: Continue.", "Per aggiungere host %s nella rubrica del router, clicca qui: Continua."}, + {"Addresshelper request", "Richiesta di indirizzo helper"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "L'host %s viene aggiunto alla rubrica del router dall'helper. Fai clic qui per procedere: Continua."}, + {"Addresshelper adding", "Aggiunta di Addresshelper"}, {"Host %s is already in router's addressbook. Click here to update record: Continue.", "L'host %s è già nella rubrica del router. Clicca qui per aggiornare il record: Continua."}, + {"Addresshelper update", "Aggiornamento dell'helper degli indirizzi"}, {"Invalid request URI", "URI della richiesta non valido"}, {"Can't detect destination host from request", "Impossibile determinare l'host di destinazione dalla richiesta"}, {"Outproxy failure", "Fallimento del proxy di uscita"}, diff --git a/i18n/Portuguese.cpp b/i18n/Portuguese.cpp index 528be389..8ba7f0cd 100644 --- a/i18n/Portuguese.cpp +++ b/i18n/Portuguese.cpp @@ -73,7 +73,7 @@ namespace portuguese // language namespace {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Enviado"}, {"Transit", "Trânsito"}, - {"Data path", "Caminho dos dados"}, + {"Data path", "Diretório dos dados"}, {"Hidden content. Press on text to see.", "Conteúdo oculto. Clique no texto para revelar."}, {"Router Ident", "Identidade do Roteador"}, {"Router Family", "Família do Roteador"}, @@ -122,15 +122,15 @@ namespace portuguese // language namespace {"Queue size", "Tamanho da fila"}, {"Run peer test", "Executar teste de peers"}, {"Reload tunnels configuration", "Recarregar a configuração dos túneis"}, - {"Decline transit tunnels", "Negar túnel de trânsito"}, - {"Accept transit tunnels", "Aceitar túnel de trânsito"}, + {"Decline transit tunnels", "Negar túneis de trânsito"}, + {"Accept transit tunnels", "Aceitar túneis de trânsito"}, {"Cancel graceful shutdown", "Cancelar desligamento gracioso"}, {"Start graceful shutdown", "Iniciar desligamento gracioso"}, {"Force shutdown", "Forçar desligamento"}, {"Reload external CSS styles", "Recarregar estilos CSS externos"}, {"Note: any action done here are not persistent and not changes your config files.", " Nota: Qualquer ação feita aqui não será permanente e não altera os seus arquivos de configuração."}, {"Logging level", "Nível de registro"}, - {"Transit tunnels limit", "Limite nos túneis de trânsito"}, + {"Transit tunnels limit", "Limite de túneis de trânsito"}, {"Change", "Mudar"}, {"Change language", "Trocar idioma"}, {"no transit tunnels currently built", "Nenhum túnel de trânsito construido no momento"}, From b97ef1af495456484008ff54c1e5594c008dabf3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Mar 2023 21:54:32 +0000 Subject: [PATCH 0176/1160] 2.47.0 Signed-off-by: R4SAS --- contrib/rpm/i2pd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index e0ac9d03..407e2d43 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.47.0 -Release: 2%{?dist} +Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git From 8677cd54bd4d145e3bba7044484dcba4eed73a85 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 12 Mar 2023 21:41:07 +0000 Subject: [PATCH 0177/1160] [cmake] win32: do not use static boost libs without WITH_STATIC Signed-off-by: R4SAS --- build/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4100c23f..94688761 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -277,15 +277,19 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() add_definitions(-DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) + if(WIN32) + set(Boost_USE_STATIC_LIBS OFF) + set(Boost_USE_STATIC_RUNTIME OFF) + endif() endif() find_package(Boost REQUIRED COMPONENTS system filesystem program_options date_time OPTIONAL_COMPONENTS atomic) -if(NOT DEFINED Boost_INCLUDE_DIRS) +if(NOT DEFINED Boost_FOUND) message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!") endif() find_package(OpenSSL REQUIRED) -if(NOT DEFINED OPENSSL_INCLUDE_DIR) +if(NOT DEFINED OPENSSL_FOUND) message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!") endif() @@ -372,7 +376,7 @@ if(WITH_BINARY) set(DL_LIB ${CMAKE_DL_LIBS}) endif() - target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang Boost::system Boost::filesystem Boost::program_options Boost::date_time OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") From e96f0bfb142a9a252e060aead451166cd335a65e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 13 Mar 2023 18:34:45 +0000 Subject: [PATCH 0178/1160] [msvc] fix warnings, revert cmake boost libs linking list Signed-off-by: R4SAS --- build/CMakeLists.txt | 2 +- libi2pd/Ed25519.cpp | 4 ++-- libi2pd/Family.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 94688761..05401b1f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -376,7 +376,7 @@ if(WITH_BINARY) set(DL_LIB ${CMAKE_DL_LIBS}) endif() - target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang Boost::system Boost::filesystem Boost::program_options Boost::date_time OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto ${MINIUPNPC_LIBRARY} ZLIB::ZLIB Threads::Threads ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 0c6eb4f7..3e0795d5 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -413,7 +413,7 @@ namespace crypto BIGNUM * y = BN_new (); BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y); BIGNUM * x = RecoverX (y, ctx); - if (BN_is_bit_set (x, 0) != isHighestBitSet) + if ((bool)BN_is_bit_set (x, 0) != isHighestBitSet) BN_sub (x, q, x); // x = q - x BIGNUM * z = BN_new (), * t = BN_new (); BN_one (z); BN_mod_mul (t, x, y, q, ctx); // pre-calculate t diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index 9a0700d0..8c6d3ba4 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -88,7 +88,7 @@ namespace data } EVP_PKEY_free (pkey); if (verifier && cn) - m_SigningKeys.emplace (cn, std::make_pair(verifier, m_SigningKeys.size () + 1)); + m_SigningKeys.emplace (cn, std::make_pair(verifier, (int)m_SigningKeys.size () + 1)); } SSL_free (ssl); } From 5ad9c8e74097f1ec97476198a31db4397b5f48b0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Mar 2023 19:19:57 -0400 Subject: [PATCH 0179/1160] create I2NP tunnel message for first fragment --- libi2pd/SSU2Session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 46acf05b..9a2fea9a 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1766,8 +1766,8 @@ namespace transport void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len) { + auto msg = (buf[0] == eI2NPTunnelData) ? NewI2NPTunnelMessage (true) : NewI2NPShortMessage (); uint32_t msgID; memcpy (&msgID, buf + 1, 4); - auto msg = NewI2NPShortMessage (); // same format as I2NP message block msg->len = msg->offset + len + 7; memcpy (msg->GetNTCP2Header (), buf, len); From 55b2f2c625ae3b7de2d6f20716c908bba801c370 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Mar 2023 21:32:53 -0400 Subject: [PATCH 0180/1160] memory pool for IdentityEx --- libi2pd/Identity.cpp | 78 +++++++++++++----------------------------- libi2pd/Identity.h | 13 +++---- libi2pd/LeaseSet.cpp | 4 +-- libi2pd/NetDb.cpp | 1 + libi2pd/NetDb.hpp | 2 ++ libi2pd/RouterInfo.cpp | 13 +++++-- libi2pd/RouterInfo.h | 2 ++ 7 files changed, 46 insertions(+), 67 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index bf9c26c5..073d8c06 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -187,7 +187,6 @@ namespace data IdentityEx::~IdentityEx () { - delete m_Verifier; } IdentityEx& IdentityEx::operator=(const IdentityEx& other) @@ -201,9 +200,8 @@ namespace data if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); } - - delete m_Verifier; m_Verifier = nullptr; + CreateVerifier (); return *this; } @@ -212,11 +210,10 @@ namespace data { m_StandardIdentity = standard; m_IdentHash = m_StandardIdentity.Hash (); - m_ExtendedLen = 0; - delete m_Verifier; m_Verifier = nullptr; + CreateVerifier (); return *this; } @@ -249,8 +246,8 @@ namespace data m_ExtendedLen = 0; SHA256(buf, GetFullLen (), m_IdentHash); - delete m_Verifier; m_Verifier = nullptr; + CreateVerifier (); return GetFullLen (); } @@ -286,7 +283,6 @@ namespace data size_t IdentityEx::GetSigningPublicKeyLen () const { - if (!m_Verifier) CreateVerifier (); if (m_Verifier) return m_Verifier->GetPublicKeyLen (); return 128; @@ -301,7 +297,6 @@ namespace data size_t IdentityEx::GetSigningPrivateKeyLen () const { - if (!m_Verifier) CreateVerifier (); if (m_Verifier) return m_Verifier->GetPrivateKeyLen (); return GetSignatureLen ()/2; @@ -309,14 +304,12 @@ namespace data size_t IdentityEx::GetSignatureLen () const { - if (!m_Verifier) CreateVerifier (); if (m_Verifier) return m_Verifier->GetSignatureLen (); return i2p::crypto::DSA_SIGNATURE_LENGTH; } bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { - if (!m_Verifier) CreateVerifier (); if (m_Verifier) return m_Verifier->Verify (buf, len, signature); return false; @@ -373,52 +366,29 @@ namespace data return nullptr; } - void IdentityEx::CreateVerifier () const + void IdentityEx::CreateVerifier () { - if (m_Verifier) return; // don't create again - auto verifier = CreateVerifier (GetSigningKeyType ()); - if (verifier) - { - auto keyLen = verifier->GetPublicKeyLen (); - if (keyLen <= 128) - verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen); - else + if (!m_Verifier) + { + auto verifier = CreateVerifier (GetSigningKeyType ()); + if (verifier) { - // for P521 - uint8_t * signingKey = new uint8_t[keyLen]; - memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = keyLen - 128; - memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - verifier->SetPublicKey (signingKey); - delete[] signingKey; + auto keyLen = verifier->GetPublicKeyLen (); + if (keyLen <= 128) + verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen); + else + { + // for P521 + uint8_t * signingKey = new uint8_t[keyLen]; + memcpy (signingKey, m_StandardIdentity.signingKey, 128); + size_t excessLen = keyLen - 128; + memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types + verifier->SetPublicKey (signingKey); + delete[] signingKey; + } } - } - UpdateVerifier (verifier); - } - - void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const - { - bool del = false; - { - std::lock_guard l(m_VerifierMutex); - if (!m_Verifier) - m_Verifier = verifier; - else - del = true; - } - if (del) - delete verifier; - } - - void IdentityEx::DropVerifier () const - { - i2p::crypto::Verifier * verifier; - { - std::lock_guard l(m_VerifierMutex); - verifier = m_Verifier; - m_Verifier = nullptr; - } - delete verifier; + m_Verifier.reset (verifier); + } } std::shared_ptr IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index d5a2da21..97d596d8 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -13,9 +13,7 @@ #include #include #include -#include #include -#include #include "Base.h" #include "Signature.h" #include "CryptoKey.h" @@ -118,7 +116,6 @@ namespace data SigningKeyType GetSigningKeyType () const; bool IsRSA () const; // signing key type CryptoKeyType GetCryptoKeyType () const; - void DropVerifier () const; // to save memory bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); } void RecalculateIdentHash(uint8_t * buff=nullptr); @@ -128,15 +125,13 @@ namespace data private: - void CreateVerifier () const; - void UpdateVerifier (i2p::crypto::Verifier * verifier) const; - + void CreateVerifier (); + private: Identity m_StandardIdentity; IdentHash m_IdentHash; - mutable i2p::crypto::Verifier * m_Verifier = nullptr; - mutable std::mutex m_VerifierMutex; + std::unique_ptr m_Verifier; size_t m_ExtendedLen; uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; }; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 4d756bdb..c47f23d8 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -50,7 +50,7 @@ namespace data void LeaseSet::ReadFromBuffer (bool readIdentity, bool verifySignature) { if (readIdentity || !m_Identity) - m_Identity = std::make_shared(m_Buffer, m_BufferLen); + m_Identity = netdb.NewIdentity (m_Buffer, m_BufferLen); size_t size = m_Identity->GetFullLen (); if (size + 256 > m_BufferLen) { @@ -317,7 +317,7 @@ namespace data std::shared_ptr identity; if (readIdentity || !GetIdentity ()) { - identity = std::make_shared(buf, len); + identity = netdb.NewIdentity (buf, len); SetIdentity (identity); } else diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5dfb7889..82e15304 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -662,6 +662,7 @@ namespace data m_RouterInfoBuffersPool.CleanUpMt (); m_RouterInfoAddressesPool.CleanUpMt (); m_RouterInfoAddressVectorsPool.CleanUpMt (); + m_IdentitiesPool.CleanUpMt (); if (updatedCount > 0) LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers"); diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 7958e36d..71694d8d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -127,6 +127,7 @@ namespace data &m_RouterInfoAddressVectorsPool, std::placeholders::_1)); }; std::shared_ptr NewLease (const Lease& lease) { return m_LeasesPool.AcquireSharedMt (lease); }; + std::shared_ptr NewIdentity (const uint8_t * buf, size_t len) { return m_IdentitiesPool.AcquireSharedMt (buf, len); }; uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; @@ -182,6 +183,7 @@ namespace data i2p::util::MemoryPoolMt m_RouterInfoAddressesPool; i2p::util::MemoryPoolMt m_RouterInfoAddressVectorsPool; i2p::util::MemoryPoolMt m_LeasesPool; + i2p::util::MemoryPoolMt m_IdentitiesPool; }; extern NetDb netdb; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index db0a7de6..b006cdc0 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -161,7 +161,7 @@ namespace data m_IsUnreachable = true; return; } - m_RouterIdentity = std::make_shared(m_Buffer->data (), m_BufferLen); + m_RouterIdentity = NewIdentity (m_Buffer->data (), m_BufferLen); size_t identityLen = m_RouterIdentity->GetFullLen (); if (identityLen >= m_BufferLen) { @@ -186,7 +186,6 @@ namespace data m_IsUnreachable = true; return; } - m_RouterIdentity->DropVerifier (); } // parse RI std::stringstream str; @@ -1061,6 +1060,11 @@ namespace data return netdb.NewRouterInfoAddresses (); } + std::shared_ptr RouterInfo::NewIdentity (const uint8_t * buf, size_t len) const + { + return netdb.NewIdentity (buf, len); + } + void RouterInfo::RefreshTimestamp () { m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); @@ -1393,6 +1397,11 @@ namespace data return boost::make_shared (); } + std::shared_ptr LocalRouterInfo::NewIdentity (const uint8_t * buf, size_t len) const + { + return std::make_shared (buf, len); + } + bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) { auto addresses = GetAddresses (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 3e8e0613..ef145496 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -307,6 +307,7 @@ namespace data virtual std::shared_ptr NewBuffer () const; virtual std::shared_ptr
NewAddress () const; virtual boost::shared_ptr NewAddresses () const; + virtual std::shared_ptr NewIdentity (const uint8_t * buf, size_t len) const; private: @@ -350,6 +351,7 @@ namespace data std::shared_ptr NewBuffer () const override; std::shared_ptr
NewAddress () const override; boost::shared_ptr NewAddresses () const override; + std::shared_ptr NewIdentity (const uint8_t * buf, size_t len) const override; private: From 084663d6ead53cb94b2244ef48be28ac0cdd4d3b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Mar 2023 15:32:05 -0400 Subject: [PATCH 0181/1160] mediam size I2NP messages --- libi2pd/I2NPProtocol.cpp | 10 +++++++++- libi2pd/I2NPProtocol.h | 2 ++ libi2pd/SSU2Session.cpp | 2 +- libi2pd/TunnelEndpoint.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5ae89c23..369107b4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,6 +36,11 @@ namespace i2p return std::make_shared >(); } + std::shared_ptr NewI2NPMediumMessage () + { + return std::make_shared >(); + } + std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint); @@ -43,7 +48,10 @@ namespace i2p std::shared_ptr NewI2NPMessage (size_t len) { - return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); + len += I2NP_HEADER_SIZE + 2; + if (len <= I2NP_MAX_SHORT_MESSAGE_SIZE) return NewI2NPShortMessage (); + if (len <= I2NP_MAX_MEDIUM_MESSAGE_SIZE) return NewI2NPMediumMessage (); + return NewI2NPMessage (); } void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 80757501..c0685190 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -140,6 +140,7 @@ namespace tunnel const size_t I2NP_MAX_MESSAGE_SIZE = 62708; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; + const size_t I2NP_MAX_MEDIUM_MESSAGE_SIZE = 16384; const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT) const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds @@ -262,6 +263,7 @@ namespace tunnel std::shared_ptr NewI2NPMessage (); std::shared_ptr NewI2NPShortMessage (); + std::shared_ptr NewI2NPMediumMessage (); std::shared_ptr NewI2NPTunnelMessage (bool endpoint); std::shared_ptr NewI2NPMessage (size_t len); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 9a2fea9a..4d3a9866 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -23,7 +23,7 @@ namespace transport if (msg->len + fragmentSize > msg->maxLen) { LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg->len + fragmentSize); *newMsg = *msg; msg = newMsg; } diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 9c294374..7d3b3cbe 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -208,7 +208,7 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg.data->len + size); *newMsg = *(msg.data); msg.data = newMsg; } @@ -297,11 +297,11 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); + auto newMsg = NewI2NPMessage (msg.data->len + size); *newMsg = *(msg.data); msg.data = newMsg; } - if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment + if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); if (it->second->isLastFragment) // message complete From 32b54fa1f82c2141154dc8f9d5fbae2d565f0cdb Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 19 Mar 2023 15:47:50 -0400 Subject: [PATCH 0182/1160] handle i2p.streaming.answerPings properly --- libi2pd/Destination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5d6b71b9..b6dbeaed 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1000,7 +1000,7 @@ namespace client m_StreamingAckDelay = std::stoi(it->second); it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS); if (it != params->end ()) - m_IsStreamingAnswerPings = (it->second == "true"); + m_IsStreamingAnswerPings = std::stoi (it->second); // 1 for true if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { From f41563a7005363bbfea18f9ec38811cb657e1c5a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 19 Mar 2023 17:42:53 -0400 Subject: [PATCH 0183/1160] check packet number for SessionConfirmed --- libi2pd/SSU2Session.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 4d3a9866..bc8b5486 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -608,7 +608,7 @@ namespace transport * payload = m_SentHandshakePacket->payload; // fill packet header.h.connID = m_DestConnID; // dest id - header.h.packetNum = 0; + RAND_bytes (header.buf + 8, 4); // random packet num header.h.type = eSSU2SessionRequest; header.h.flags[0] = 2; // ver header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID @@ -636,7 +636,7 @@ namespace transport m_EphemeralKeys->Agree (m_Address->s, sharedSecret); m_NoiseState->MixKey (sharedSecret); // encrypt - const uint8_t nonce[12] = {0}; + const uint8_t nonce[12] = {0}; // always 0 i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true); payloadSize += 16; header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24)); @@ -721,7 +721,7 @@ namespace transport uint8_t * headerX = m_SentHandshakePacket->headerX, * payload = m_SentHandshakePacket->payload; header.h.connID = m_DestConnID; // dest id - header.h.packetNum = 0; + RAND_bytes (header.buf + 8, 4); // random packet num header.h.type = eSSU2SessionCreated; header.h.flags[0] = 2; // ver header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID @@ -760,7 +760,7 @@ namespace transport m_EphemeralKeys->Agree (X, sharedSecret); m_NoiseState->MixKey (sharedSecret); // encrypt - const uint8_t nonce[12] = {0}; + const uint8_t nonce[12] = {0}; // always zero i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true); payloadSize += 16; m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || encrypted Noise payload from Session Created) @@ -832,7 +832,7 @@ namespace transport // fill packet Header& header = m_SentHandshakePacket->header; header.h.connID = m_DestConnID; // dest id - header.h.packetNum = 0; + header.h.packetNum = 0; // always zero header.h.type = eSSU2SessionConfirmed; memset (header.h.flags, 0, 3); header.h.flags[0] = 1; // frag, total fragments always 1 @@ -855,7 +855,7 @@ namespace transport // Encrypt part 1 uint8_t * part1 = m_SentHandshakePacket->headerX; uint8_t nonce[12]; - CreateNonce (1, nonce); + CreateNonce (1, nonce); // always one i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetSSU2StaticPublicKey (), 32, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, part1, 48, true); m_NoiseState->MixHash (part1, 48); // h = SHA256(h || ciphertext); // KDF for Session Confirmed part 2 @@ -863,7 +863,7 @@ namespace transport i2p::context.GetSSU2StaticKeys ().Agree (Y, sharedSecret); m_NoiseState->MixKey (sharedSecret); // Encrypt part2 - memset (nonce, 0, 12); + memset (nonce, 0, 12); // always zero i2p::crypto::AEADChaCha20Poly1305 (payload, payloadSize, m_NoiseState->m_H, 32, m_NoiseState->m_CK + 32, nonce, payload, payloadSize + 16, true); payloadSize += 16; m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || ciphertext); @@ -920,6 +920,12 @@ namespace transport // TODO: queue up return true; } + // packet num must be aways zero + if (header.h.packetNum) + { + LogPrint (eLogError, "SSU2: Non zero packet number in SessionConfirmed"); + return false; + } // check if fragmented uint8_t numFragments = header.h.flags[0] & 0x0F; if (numFragments > 1) From 644d65054d5fcafc0a9b4cb36c27b69558f84f45 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Mar 2023 21:25:00 -0400 Subject: [PATCH 0184/1160] create smaller I2NP packets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 ++-- libi2pd/I2NPProtocol.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7f9fb72d..3b3ed485 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1150,7 +1150,7 @@ namespace garlic std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { - auto m = NewI2NPMessage (); + auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128); m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length size_t offset = 0; @@ -1176,7 +1176,7 @@ namespace garlic // Noise_N, we are Alice, routerPublicKey is Bob's i2p::crypto::NoiseSymmetricState noiseState; i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); - auto m = NewI2NPMessage (); + auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128); m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length size_t offset = 0; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 369107b4..5303edbf 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -134,7 +134,8 @@ namespace i2p std::shared_ptr CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory, std::set * excludedPeers) { - auto m = excludedPeers ? NewI2NPMessage () : NewI2NPShortMessage (); + int cnt = excludedPeers ? excludedPeers->size () : 0; + auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); memcpy (buf, key, 32); // key buf += 32; @@ -155,7 +156,6 @@ namespace i2p if (excludedPeers) { - int cnt = excludedPeers->size (); htobe16buf (buf, cnt); buf += 2; for (auto& it: *excludedPeers) From 5fee6df87af09566f72d975593b001fd3b4ddd14 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Mar 2023 19:52:39 -0400 Subject: [PATCH 0185/1160] handle reset in reposnse to SYN --- libi2pd/Streaming.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 42f71798..785ab6bb 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -154,8 +154,7 @@ namespace stream ProcessAck (packet); int32_t receivedSeqn = packet->GetSeqn (); - bool isSyn = packet->IsSYN (); - if (!receivedSeqn && !isSyn) + if (!receivedSeqn && !packet->GetFlags ()) { // plain ack LogPrint (eLogDebug, "Streaming: Plain ACK received"); @@ -197,7 +196,7 @@ namespace stream shared_from_this (), std::placeholders::_1)); } } - else if (isSyn) + else if (packet->IsSYN ()) // we have to send SYN back to incoming connection SendBuffer (); // also sets m_IsOpen } From d91d734b5c43f174038a5ca2bdad7fb929ba5a7f Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Fri, 24 Mar 2023 22:15:47 +0200 Subject: [PATCH 0186/1160] Fix typos --- libi2pd/KadDHT.cpp | 4 ++-- libi2pd/SSU2Session.cpp | 2 +- libi2pd/Tunnel.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/KadDHT.cpp b/libi2pd/KadDHT.cpp index b171cdbc..0f9df8e4 100644 --- a/libi2pd/KadDHT.cpp +++ b/libi2pd/KadDHT.cpp @@ -81,13 +81,13 @@ namespace data { if (bit1) { - if (root->one) return; // someting wrong + if (root->one) return; // something wrong root->one = new DHTNode; root = root->one; } else { - if (root->zero) return; // someting wrong + if (root->zero) return; // something wrong root->zero = new DHTNode; root = root->zero; } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index bc8b5486..c492279d 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -920,7 +920,7 @@ namespace transport // TODO: queue up return true; } - // packet num must be aways zero + // packet num must be always zero if (header.h.packetNum) { LogPrint (eLogError, "SSU2: Non zero packet number in SessionConfirmed"); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 58e13ad3..09358179 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -332,7 +332,7 @@ namespace tunnel Tunnels tunnels; Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_MaxNumTransitTunnels (DEFAULT_MAX_NUM_TRANSIT_TUNNELS), - m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal avarage + m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal average m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) { } @@ -544,7 +544,7 @@ namespace tunnel ManageTunnels (ts); lastTs = ts; } - if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 secondsts + if (ts - lastPoolsTs >= TUNNEL_POOLS_MANAGE_INTERVAL || // manage pools every 5 seconds ts + TUNNEL_POOLS_MANAGE_INTERVAL < lastPoolsTs) { ManageTunnelPools (ts); @@ -698,7 +698,7 @@ namespace tunnel if (m_OutboundTunnels.size () < 3) { - // trying to create one more oubound tunnel + // trying to create one more outbound tunnel auto inboundTunnel = GetNextInboundTunnel (); auto router = i2p::transport::transports.RoutesRestricted() ? i2p::transport::transports.GetRestrictedPeer() : From 71bad23906f47113b8cfb9f906e0d76cc8d6c3b5 Mon Sep 17 00:00:00 2001 From: ralsei Date: Sun, 26 Mar 2023 05:41:56 +0000 Subject: [PATCH 0187/1160] add dinit service Signed-off-by: R4SAS --- contrib/dinit/i2pd | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 contrib/dinit/i2pd diff --git a/contrib/dinit/i2pd b/contrib/dinit/i2pd new file mode 100644 index 00000000..63d877c1 --- /dev/null +++ b/contrib/dinit/i2pd @@ -0,0 +1,8 @@ +type = bgprocess +run-as = i2pd +command = /usr/bin/i2pd --conf=/var/lib/i2pd/i2pd.conf --pidfile=/var/lib/i2pd/i2pd.pid --daemon --service +smooth-recovery = true +depends-on = ntpd +# uncomment if you want to use i2pd with yggdrasil +# depends-on = yggdrasil +pid-file = /var/lib/i2pd/i2pd.pid From 6d204b4d7b9083512a571c329d6be855c8f15451 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Mar 2023 22:12:43 -0400 Subject: [PATCH 0188/1160] shorter streaming I2NP data messages --- libi2pd/Streaming.cpp | 2 +- libi2pd/Streaming.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 785ab6bb..1deca8a6 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1447,7 +1447,7 @@ namespace stream const uint8_t * payload, size_t len, uint16_t toPort, bool checksum, bool gzip) { size_t size; - auto msg = m_I2NPMsgsPool.AcquireShared (); + auto msg = (len <= STREAMING_MTU_RATCHETS) ? m_I2NPMsgsPool.AcquireShared () : NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for lengthlength msg->len += 4; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index dc0ca6db..3609df92 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -313,7 +313,7 @@ namespace stream std::unordered_map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; - i2p::util::MemoryPool > m_I2NPMsgsPool; + i2p::util::MemoryPool > m_I2NPMsgsPool; public: From c45e31b1b27cfac3f9c164bbe64c9e60d0a7a9fb Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Mar 2023 22:00:17 -0400 Subject: [PATCH 0189/1160] validate new router --- libi2pd/RouterContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 084e8c77..20ac589b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -229,6 +229,7 @@ namespace i2p routerInfo.CreateBuffer (m_Keys); m_RouterInfo.SetRouterIdentity (GetIdentity ()); m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); + m_RouterInfo.SetUnreachable (false); } uint16_t RouterContext::SelectRandomPort () const From 60e648bf9a8c0caedaab74e184211c6a34032cad Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Mar 2023 13:40:12 -0400 Subject: [PATCH 0190/1160] set cap 6 for unspecified ipv6 address --- libi2pd/RouterInfo.cpp | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index b006cdc0..7462ef0e 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1201,44 +1201,37 @@ namespace data s.write ((const char *)&cost, sizeof (cost)); s.write ((const char *)&address.date, sizeof (address.date)); std::stringstream properties; - bool isPublished = false; + bool isPublished = address.published && !address.host.is_unspecified () && address.port; if (address.transportStyle == eTransportNTCP2) { - if (address.IsNTCP2 ()) + WriteString ("NTCP2", s); + // caps + if (!isPublished) { - WriteString ("NTCP2", s); - if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port) - isPublished = true; - else - { - WriteString ("caps", properties); - properties << '='; - std::string caps; - if (address.IsV4 ()) caps += CAPS_FLAG_V4; - if (address.IsV6 ()) caps += CAPS_FLAG_V6; - if (caps.empty ()) caps += CAPS_FLAG_V4; - WriteString (caps, properties); - properties << ';'; - } + WriteString ("caps", properties); + properties << '='; + std::string caps; + if (address.IsV4 ()) caps += CAPS_FLAG_V4; + if (address.IsV6 () || address.host.is_v6 ()) caps += CAPS_FLAG_V6; // we set 6 for unspecified ipv6 + if (caps.empty ()) caps += CAPS_FLAG_V4; + WriteString (caps, properties); + properties << ';'; } - else - continue; // don't write NTCP address } else if (address.transportStyle == eTransportSSU2) { WriteString ("SSU2", s); // caps std::string caps; - if (address.published) + if (isPublished) { - isPublished = true; if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU2_TESTING; if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU2_INTRODUCER; } else { if (address.IsV4 ()) caps += CAPS_FLAG_V4; - if (address.IsV6 ()) caps += CAPS_FLAG_V6; + if (address.IsV6 () || address.host.is_v6 ()) caps += CAPS_FLAG_V6; // we set 6 for unspecified ipv6 if (caps.empty ()) caps += CAPS_FLAG_V4; } if (!caps.empty ()) From cd1af85e39e0e683af0ea74980d6bb3874bead71 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Mar 2023 15:54:53 -0400 Subject: [PATCH 0191/1160] bypass slow transport sessions --- daemon/HTTPServer.cpp | 1 + libi2pd/NTCP2.cpp | 4 ++++ libi2pd/SSU2Session.cpp | 4 ++++ libi2pd/TransportSession.h | 10 ++++++++-- libi2pd/Transports.cpp | 5 +++-- libi2pd/Transports.h | 10 ++++++++-- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 3d5ff1a0..29f3f569 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -838,6 +838,7 @@ namespace http { tmp_s << " [itag:" << it->GetRelayTag () << "]"; if (it->GetSendQueueSize () > 0) tmp_s << " [queue:" << it->GetSendQueueSize () << "]"; + if (it->IsSlow ()) tmp_s << " [slow]"; tmp_s << "
\r\n" << std::endl; cnt++; } diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index eaa186f8..48c905ca 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -452,6 +452,7 @@ namespace transport { m_Establisher->CreateSessionRequestMessage (); // send message + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch (); boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionRequestBuffer, m_Establisher->m_SessionRequestBufferLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -529,6 +530,7 @@ namespace transport { m_Establisher->CreateSessionCreatedMessage (); // send message + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch (); boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionCreatedBuffer, m_Establisher->m_SessionCreatedBufferLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -542,6 +544,7 @@ namespace transport } else { + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred); uint16_t paddingLen = 0; if (m_Establisher->ProcessSessionCreatedMessage (paddingLen)) @@ -646,6 +649,7 @@ namespace transport } else { + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); // part 1 uint8_t nonce[12]; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index c492279d..c618d136 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -648,6 +648,7 @@ namespace transport if (m_State == eSSU2SessionStateTokenReceived || m_Server.AddPendingOutgoingSession (shared_from_this ())) { m_State = eSSU2SessionStateSessionRequestSent; + m_HandshakeInterval = ts; m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint); } else @@ -770,6 +771,7 @@ namespace transport m_State = eSSU2SessionStateSessionCreatedSent; m_SentHandshakePacket->payloadSize = payloadSize; // send + m_HandshakeInterval = ts; m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint); } @@ -790,6 +792,7 @@ namespace transport LogPrint (eLogWarning, "SSU2: SessionCreated message too short ", len); return false; } + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; const uint8_t nonce[12] = {0}; uint8_t headerX[48]; i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX); @@ -995,6 +998,7 @@ namespace transport if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr); return false; } + m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; // KDF for Session Confirmed part 1 m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header) // decrypt part1 diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 83b6cacd..7d2f2653 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -69,6 +69,8 @@ namespace transport std::stringstream m_Stream; }; + const int64_t TRANSPORT_SESSION_SLOWNESS_THRESHOLD = 500; // in milliseconds + const int64_t TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL = 10000; // in milliseconds class TransportSession { public: @@ -76,7 +78,8 @@ namespace transport TransportSession (std::shared_ptr router, int terminationTimeout): m_NumSentBytes (0), m_NumReceivedBytes (0), m_SendQueueSize (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), - m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()) + m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()), + m_HandshakeInterval (0) { if (router) m_RemoteIdentity = router->GetRouterIdentity (); @@ -103,7 +106,9 @@ namespace transport size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; size_t GetSendQueueSize () const { return m_SendQueueSize; }; bool IsOutgoing () const { return m_IsOutgoing; }; - + bool IsSlow () const { return m_HandshakeInterval > TRANSPORT_SESSION_SLOWNESS_THRESHOLD && + m_HandshakeInterval < TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL; }; + int GetTerminationTimeout () const { return m_TerminationTimeout; }; void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; }; bool IsTerminationTimeoutExpired (uint64_t ts) const @@ -129,6 +134,7 @@ namespace transport int m_TerminationTimeout; uint64_t m_LastActivityTimestamp; uint32_t m_CreationTime; // seconds since epoch + int64_t m_HandshakeInterval; // in milliseconds between SessionRequest->SessionCreated or SessionCreated->SessionConfirmed }; // SOCKS5 proxy diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index aa326a92..4e97bb26 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -906,9 +906,10 @@ namespace transport return GetRandomPeer ( [isHighBandwidth](const Peer& peer)->bool { - // connected and not overloaded - return !peer.router && !peer.sessions.empty () && + // connected, not overloaded and not slow + return !peer.router && !peer.sessions.empty () && peer.isReachable && peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE && + !peer.sessions.front ()->IsSlow () && (!isHighBandwidth || peer.isHighBandwidth); }); } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index dc97a952..1058d31b 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -72,15 +72,18 @@ namespace transport uint64_t creationTime, nextRouterInfoUpdateTime; std::vector > delayedMessages; std::vector priority; - bool isHighBandwidth; + bool isHighBandwidth, isReachable; Peer (std::shared_ptr r, uint64_t ts): numAttempts (0), router (r), creationTime (ts), nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL), - isHighBandwidth (false) + isHighBandwidth (false), isReachable (false) { if (router) + { isHighBandwidth = router->IsHighBandwidth (); + isReachable = (bool)router->GetCompatibleTransports (true); + } } void Done () @@ -93,7 +96,10 @@ namespace transport { router = r; if (router) + { isHighBandwidth = router->IsHighBandwidth (); + isReachable = (bool)router->GetCompatibleTransports (true); + } } }; From a80aeb67155f73bc408f6960358a4632e30a4725 Mon Sep 17 00:00:00 2001 From: weko Date: Thu, 30 Mar 2023 21:31:12 +0000 Subject: [PATCH 0192/1160] add critical log level --- contrib/i2pd.conf | 2 +- libi2pd/Log.cpp | 26 +++++++++++++++----------- libi2pd/Log.h | 1 + 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index c6e52c1f..5d09c90a 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -33,7 +33,7 @@ # log = file ## Path to logfile (default - autodetect) # logfile = /var/log/i2pd/i2pd.log -## Log messages above this level (debug, info, *warn, error, none) +## Log messages above this level (debug, info, *warn, error, critical, none) ## If you set it to none, logging will be disabled # loglevel = warn ## Write full CLF-formatted date and time to log (default: write only time) diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 65b00e10..dfb507c9 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -20,11 +20,12 @@ namespace log { */ static const char *g_LogLevelStr[eNumLogLevels] = { - "none", // eLogNone - "error", // eLogError - "warn", // eLogWarning - "info", // eLogInfo - "debug" // eLogDebug + "none", // eLogNone + "critical", // eLogCritical + "error", // eLogError + "warn", // eLogWarning + "info", // eLogInfo + "debug" // eLogDebug }; /** @@ -32,10 +33,11 @@ namespace log { * @note Using ISO 6429 (ANSI) color sequences */ #ifdef _WIN32 - static const char *LogMsgColors[] = { "", "", "", "", "", "" }; + static const char *LogMsgColors[] = { "", "", "", "", "", "", "" }; #else /* UNIX */ static const char *LogMsgColors[] = { "\033[1;32m", /* none: green */ + "\033[1;41m", /* critical: red background */ "\033[1;31m", /* error: red */ "\033[1;33m", /* warning: yellow */ "\033[1;36m", /* info: cyan */ @@ -53,6 +55,7 @@ namespace log { int priority = LOG_DEBUG; switch (l) { case eLogNone : priority = LOG_CRIT; break; + case eLogCritical: priority = LOG_CRIT; break; case eLogError : priority = LOG_ERR; break; case eLogWarning : priority = LOG_WARNING; break; case eLogInfo : priority = LOG_INFO; break; @@ -123,11 +126,12 @@ namespace log { void Log::SetLogLevel (const std::string& level_) { std::string level=str_tolower(level_); - if (level == "none") { m_MinLevel = eLogNone; } - else if (level == "error") { m_MinLevel = eLogError; } - else if (level == "warn") { m_MinLevel = eLogWarning; } - else if (level == "info") { m_MinLevel = eLogInfo; } - else if (level == "debug") { m_MinLevel = eLogDebug; } + if (level == "none") { m_MinLevel = eLogNone; } + else if (level == "critical") { m_MinLevel = eLogCritical} + else if (level == "error") { m_MinLevel = eLogError; } + else if (level == "warn") { m_MinLevel = eLogWarning; } + else if (level == "info") { m_MinLevel = eLogInfo; } + else if (level == "debug") { m_MinLevel = eLogDebug; } else { LogPrint(eLogError, "Log: Unknown loglevel: ", level); return; diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 465e10bc..1ec0c5fe 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -27,6 +27,7 @@ enum LogLevel { eLogNone = 0, + eLogCritical, eLogError, eLogWarning, eLogInfo, From 354a04f0f6f03478518148c7172cc37e18470afa Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 31 Mar 2023 11:29:04 +0000 Subject: [PATCH 0193/1160] Up level for some logs to critical --- Win32/DaemonWin32.cpp | 2 +- Win32/Win32Service.cpp | 18 +++++++++--------- daemon/Daemon.cpp | 12 ++++++------ daemon/HTTPServer.cpp | 19 ++++++++++--------- daemon/I2PControl.cpp | 2 +- daemon/UPnP.cpp | 2 +- daemon/UnixDaemon.cpp | 18 +++++++++--------- libi2pd/Blinding.cpp | 4 ++-- libi2pd/Destination.cpp | 16 ++++++++-------- libi2pd/Family.cpp | 12 ++++++------ libi2pd/Identity.cpp | 6 +++--- libi2pd/LeaseSet.cpp | 2 +- libi2pd/Log.cpp | 6 +++--- libi2pd/NTCP2.cpp | 6 +++--- libi2pd/Reseed.cpp | 14 +++++++------- libi2pd/SSU2.cpp | 4 ++-- libi2pd/SSU2Session.cpp | 10 +++++----- libi2pd/Transports.cpp | 8 ++++---- libi2pd_client/AddressBook.cpp | 2 +- libi2pd_client/ClientContext.cpp | 24 ++++++++++++------------ libi2pd_client/SAM.cpp | 2 +- 21 files changed, 95 insertions(+), 94 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index e8052f14..48f65c27 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -47,7 +47,7 @@ namespace util I2PService service((PSTR)SERVICE_NAME); if (!I2PService::Run(service)) { - LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); + LogPrint(eLogCritical, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); return false; } return false; diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index a9ecf477..057a1edd 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -119,12 +119,12 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv) } catch (DWORD dwError) { - LogPrint(eLogError, "Win32Service: Start error: ", dwError); + LogPrint(eLogCritical, "Win32Service: Start error: ", dwError); SetServiceStatus(SERVICE_STOPPED, dwError); } catch (...) { - LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE); + LogPrint(eLogCritical, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE); SetServiceStatus(SERVICE_STOPPED); } } @@ -162,7 +162,7 @@ void I2PService::Stop() } catch (...) { - LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE); + LogPrint(eLogCritical, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE); SetServiceStatus(dwOriginalState); } } @@ -191,12 +191,12 @@ void I2PService::Pause() } catch (DWORD dwError) { - LogPrint(eLogError, "Win32Service: Pause error: ", dwError); + LogPrint(eLogCritical, "Win32Service: Pause error: ", dwError); SetServiceStatus(SERVICE_RUNNING); } catch (...) { - LogPrint(eLogError, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE); + LogPrint(eLogCritical, "Win32Service: Failed to pause: ", EVENTLOG_ERROR_TYPE); SetServiceStatus(SERVICE_RUNNING); } } @@ -215,12 +215,12 @@ void I2PService::Continue() } catch (DWORD dwError) { - LogPrint(eLogError, "Win32Service: Continue error: ", dwError); + LogPrint(eLogCritical, "Win32Service: Continue error: ", dwError); SetServiceStatus(SERVICE_PAUSED); } catch (...) { - LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE); + LogPrint(eLogCritical, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE); SetServiceStatus(SERVICE_PAUSED); } } @@ -238,11 +238,11 @@ void I2PService::Shutdown() } catch (DWORD dwError) { - LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError); + LogPrint(eLogCritical, "Win32Service: Shutdown error: ", dwError); } catch (...) { - LogPrint(eLogError, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE); + LogPrint(eLogCritical, "Win32Service: Failed to shut down: ", EVENTLOG_ERROR_TYPE); } } diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 84f197fb..02aee72d 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -262,7 +262,7 @@ namespace util restricted = idents.size() > 0; } if(!restricted) - LogPrint(eLogError, "Daemon: No trusted routers of families specified"); + LogPrint(eLogCritical, "Daemon: No trusted routers of families specified"); } bool hidden; i2p::config::GetOption("trust.hidden", hidden); @@ -310,7 +310,7 @@ namespace util LogPrint(eLogInfo, "Daemon: Transports started"); else { - LogPrint(eLogError, "Daemon: Failed to start Transports"); + LogPrint(eLogCritical, "Daemon: Failed to start Transports"); /** shut down netdb right away */ i2p::transport::transports.Stop(); i2p::data::netdb.Stop(); @@ -329,7 +329,7 @@ namespace util } catch (std::exception& ex) { - LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ()); + LogPrint (eLogCritical, "Daemon: Failed to start Webconsole: ", ex.what ()); ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } @@ -338,8 +338,8 @@ namespace util i2p::tunnel::tunnels.Start(); LogPrint(eLogInfo, "Daemon: Starting Router context"); - i2p::context.Start(); - + i2p::context.Start(); + LogPrint(eLogInfo, "Daemon: Starting Client"); i2p::client::context.Start (); @@ -356,7 +356,7 @@ namespace util } catch (std::exception& ex) { - LogPrint (eLogError, "Daemon: Failed to start I2PControl: ", ex.what ()); + LogPrint (eLogCritical, "Daemon: Failed to start I2PControl: ", ex.what ()); ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); } } diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 29f3f569..8b034332 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -156,7 +156,7 @@ namespace http { static void SetLogLevel (const std::string& level) { - if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug") + if (level == "none" || level == "critical" || level == "error" || level == "warn" || level == "info" || level == "debug") i2p::log::Logger().SetLogLevel(level); else { LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted"); @@ -625,10 +625,10 @@ namespace http { if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); else - { + { ls.reset (new i2p::data::LeaseSet2 (storeType)); ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false); - } + } if (!ls) return; s << "
IsExpired()) @@ -748,11 +748,12 @@ namespace http { auto loglevel = i2p::log::Logger().GetLogLevel(); s << "" << tr("Logging level") << "
\r\n"; - s << " none \r\n"; - s << " error \r\n"; - s << " warn \r\n"; - s << " info \r\n"; - s << " debug
\r\n
\r\n"; + s << " none \r\n"; + s << " none \r\n"; + s << " error \r\n"; + s << " warn \r\n"; + s << " info \r\n"; + s << " debug
\r\n
\r\n"; uint16_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels (); s << "" << tr("Transit tunnels limit") << "
\r\n"; @@ -1481,7 +1482,7 @@ namespace http { } catch (std::exception& ex) { - LogPrint (eLogError, "HTTPServer: Runtime exception: ", ex.what ()); + LogPrint (eLogCritical, "HTTPServer: Runtime exception: ", ex.what ()); } } } diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index da2443fd..354c19d4 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -115,7 +115,7 @@ namespace client try { m_Service.run (); } catch (std::exception& ex) { - LogPrint (eLogError, "I2PControl: Runtime exception: ", ex.what ()); + LogPrint (eLogCritical, "I2PControl: Runtime exception: ", ex.what ()); } } } diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index dbaf864a..2c915024 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -72,7 +72,7 @@ namespace transport } catch (std::exception& ex) { - LogPrint (eLogError, "UPnP: Runtime exception: ", ex.what ()); + LogPrint (eLogCritical, "UPnP: Runtime exception: ", ex.what ()); PortMapping (); } } diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index e6bad5a0..3c17fd14 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -81,7 +81,7 @@ namespace i2p if (pid < 0) // error { - LogPrint(eLogError, "Daemon: Could not fork: ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Could not fork: ", strerror(errno)); std::cerr << "i2pd: Could not fork: " << strerror(errno) << std::endl; return false; } @@ -91,7 +91,7 @@ namespace i2p int sid = setsid(); if (sid < 0) { - LogPrint(eLogError, "Daemon: Could not create process group."); + LogPrint(eLogCritical, "Daemon: Could not create process group."); std::cerr << "i2pd: Could not create process group." << std::endl; return false; } @@ -121,10 +121,10 @@ namespace i2p LogPrint(eLogInfo, "Daemon: Set max number of open files to ", nfiles, " (system limit is ", limit.rlim_max, ")"); } else { - LogPrint(eLogError, "Daemon: Can't set max number of open files: ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Can't set max number of open files: ", strerror(errno)); } } else { - LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); + LogPrint(eLogCritical, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); } uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); if (cfsize) // core file size set @@ -134,14 +134,14 @@ namespace i2p if (cfsize <= limit.rlim_max) { limit.rlim_cur = cfsize; if (setrlimit(RLIMIT_CORE, &limit) != 0) { - LogPrint(eLogError, "Daemon: Can't set max size of coredump: ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Can't set max size of coredump: ", strerror(errno)); } else if (cfsize == 0) { LogPrint(eLogInfo, "Daemon: coredumps disabled"); } else { LogPrint(eLogInfo, "Daemon: Set max size of core files to ", cfsize / 1024, "Kb"); } } else { - LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); + LogPrint(eLogCritical, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); } } @@ -155,7 +155,7 @@ namespace i2p pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); if (pidFH < 0) { - LogPrint(eLogError, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno)); std::cerr << "i2pd: Could not create pid file " << pidfile << ": " << strerror(errno) << std::endl; return false; } @@ -163,7 +163,7 @@ namespace i2p #ifndef ANDROID if (lockf(pidFH, F_TLOCK, 0) != 0) { - LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno)); std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl; return false; } @@ -173,7 +173,7 @@ namespace i2p ftruncate(pidFH, 0); if (write(pidFH, pid, strlen(pid)) < 0) { - LogPrint(eLogError, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno)); + LogPrint(eLogCritical, "Daemon: Could not write pidfile ", pidfile, ": ", strerror(errno)); std::cerr << "i2pd: Could not write pidfile " << pidfile << ": " << strerror(errno) << std::endl; return false; } diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index ced086e1..1f15cf14 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -259,7 +259,7 @@ namespace data publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; break; default: - LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType); + LogPrint (eLogCritical, "Blinding: Can't blind signature type ", (int)m_SigType); } return publicKeyLength; } @@ -289,7 +289,7 @@ namespace data break; } default: - LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType); + LogPrint (eLogCritical, "Blinding: Can't blind signature type ", (int)m_SigType); } return publicKeyLength; } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b6dbeaed..0be25512 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -108,7 +108,7 @@ namespace client if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) m_AuthType = authType; else - LogPrint (eLogError, "Destination: Unknown auth type ", authType); + LogPrint (eLogCritical, "Destination: Unknown auth type ", authType); } } it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); @@ -117,7 +117,7 @@ namespace client m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>()); if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32) { - LogPrint(eLogError, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second); + LogPrint(eLogCritical, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second); m_LeaseSetPrivKey.reset (nullptr); } } @@ -125,7 +125,7 @@ namespace client } catch (std::exception & ex) { - LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what()); + LogPrint(eLogCritical, "Destination: Unable to parse parameters for destination: ", ex.what()); } SetNumTags (numTags); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty, inVar, outVar); @@ -1014,12 +1014,12 @@ namespace client else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else - LogPrint (eLogError, "Destination: Unexpected auth type ", authType); + LogPrint (eLogCritical, "Destination: Unexpected auth type ", authType); if (m_AuthKeys->size ()) LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); else { - LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType); + LogPrint (eLogCritical, "Destination: No auth keys read for auth type ", authType); m_AuthKeys = nullptr; } } @@ -1028,7 +1028,7 @@ namespace client } catch (std::exception & ex) { - LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what()); + LogPrint(eLogCritical, "Destination: Unable to parse parameters for destination: ", ex.what()); } } @@ -1336,7 +1336,7 @@ namespace client f1.write ((char *)keys->priv, 256); return; } - LogPrint(eLogError, "Destinations: Can't save keys to ", path); + LogPrint(eLogCritical, "Destinations: Can't save keys to ", path); } void ClientDestination::CreateNewLeaseSet (const std::vector >& tunnels) @@ -1413,7 +1413,7 @@ namespace client if (pubKey.FromBase64 (it.second.substr (pos+1))) m_AuthKeys->push_back (pubKey); else - LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1)); + LogPrint (eLogCritical, "Destination: Unexpected auth key ", it.second.substr (pos+1)); } } } diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index 8c6d3ba4..bca9e231 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -77,14 +77,14 @@ namespace data verifier->SetPublicKey (signingKey); } else - LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogCritical, "Family: elliptic curve ", curve, " is not supported"); } EC_KEY_free (ecKey); } break; } default: - LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported"); + LogPrint (eLogCritical, "Family: Certificate key type ", keyType, " is not supported"); } EVP_PKEY_free (pkey); if (verifier && cn) @@ -93,7 +93,7 @@ namespace data SSL_free (ssl); } else - LogPrint (eLogError, "Family: Can't open certificate file ", filename); + LogPrint (eLogCritical, "Family: Can't open certificate file ", filename); SSL_CTX_free (ctx); } @@ -105,7 +105,7 @@ namespace data int numCertificates = 0; if (!i2p::fs::ReadDir(certDir, files)) { - LogPrint(eLogWarning, "Family: Can't load family certificates from ", certDir); + LogPrint(eLogError, "Family: Can't load family certificates from ", certDir); return; } @@ -185,13 +185,13 @@ namespace data delete[] b64; } else - LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogCritical, "Family: elliptic curve ", curve, " is not supported"); } } SSL_free (ssl); } else - LogPrint (eLogError, "Family: Can't open keys file: ", filename); + LogPrint (eLogCritical, "Family: Can't open keys file: ", filename); SSL_CTX_free (ctx); return sig; } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 073d8c06..7a73f02a 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -369,7 +369,7 @@ namespace data void IdentityEx::CreateVerifier () { if (!m_Verifier) - { + { auto verifier = CreateVerifier (GetSigningKeyType ()); if (verifier) { @@ -388,7 +388,7 @@ namespace data } } m_Verifier.reset (verifier); - } + } } std::shared_ptr IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key) @@ -755,7 +755,7 @@ namespace data i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: - LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported"); + LogPrint (eLogCritical, "Identity: Crypto key type ", (int)type, " is not supported"); } } diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index c47f23d8..675f6503 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -76,7 +76,7 @@ namespace data LogPrint (eLogDebug, "LeaseSet: Read num=", (int)num); if (!num || num > MAX_NUM_LEASES) { - LogPrint (eLogError, "LeaseSet: Rncorrect number of leases", (int)num); + LogPrint (eLogError, "LeaseSet: Incorrect number of leases", (int)num); m_IsValid = false; return; } diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index dfb507c9..76e85d4a 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -127,13 +127,13 @@ namespace log { void Log::SetLogLevel (const std::string& level_) { std::string level=str_tolower(level_); if (level == "none") { m_MinLevel = eLogNone; } - else if (level == "critical") { m_MinLevel = eLogCritical} + else if (level == "critical") { m_MinLevel = eLogCritical; } else if (level == "error") { m_MinLevel = eLogError; } else if (level == "warn") { m_MinLevel = eLogWarning; } else if (level == "info") { m_MinLevel = eLogInfo; } else if (level == "debug") { m_MinLevel = eLogDebug; } else { - LogPrint(eLogError, "Log: Unknown loglevel: ", level); + LogPrint(eLogCritical, "Log: Unknown loglevel: ", level); return; } LogPrint(eLogInfo, "Log: Logging level set to ", level); @@ -216,7 +216,7 @@ namespace log { m_LogStream = os; return; } - LogPrint(eLogError, "Log: Can't open file ", path); + LogPrint(eLogCritical, "Log: Can't open file ", path); } void Log::SendTo (std::shared_ptr os) { diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 48c905ca..91bc9b3d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1242,7 +1242,7 @@ namespace transport boost::system::error_code e; auto itr = m_Resolver.resolve(q, e); if(e) - LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message()); + LogPrint(eLogCritical, "NTCP2: Failed to resolve proxy ", e.message()); else { m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr)); @@ -1270,7 +1270,7 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); + LogPrint(eLogCritical, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); ThrowFatal ("Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } @@ -1313,7 +1313,7 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to v6 port ", address->port, ": ", ex.what()); + LogPrint(eLogCritical, "NTCP2: Failed to bind to v6 port ", address->port, ": ", ex.what()); ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index dfc10043..28e4db24 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -153,7 +153,7 @@ namespace data return ProcessSU3Stream (s); else { - LogPrint (eLogError, "Reseed: Can't open file ", filename); + LogPrint (eLogCritical, "Reseed: Can't open file ", filename); return 0; } } @@ -170,7 +170,7 @@ namespace data } else { - LogPrint (eLogError, "Reseed: Can't open file ", filename); + LogPrint (eLogCritical, "Reseed: Can't open file ", filename); return 0; } } @@ -278,7 +278,7 @@ namespace data if (verify) // not verified { - LogPrint (eLogError, "Reseed: SU3 verification failed"); + LogPrint (eLogCritical, "Reseed: SU3 verification failed"); return 0; } @@ -492,7 +492,7 @@ namespace data SSL_free (ssl); } else - LogPrint (eLogError, "Reseed: Can't open certificate file ", filename); + LogPrint (eLogCritical, "Reseed: Can't open certificate file ", filename); SSL_CTX_free (ctx); } @@ -534,17 +534,17 @@ namespace data } // check for valid proxy url schema if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") { - LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy); + LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy); return ""; } } else { - LogPrint(eLogError, "Reseed: Bad proxy url: ", proxy); + LogPrint(eLogCritical, "Reseed: Bad proxy url: ", proxy); return ""; } } i2p::http::URL url; if (!url.parse(address)) { - LogPrint(eLogError, "Reseed: Failed to parse url: ", address); + LogPrint(eLogCritical, "Reseed: Failed to parse url: ", address); return ""; } url.schema = "https"; diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index b50284a6..5df4d33a 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -99,7 +99,7 @@ namespace transport } } else - LogPrint (eLogError, "SSU2: Can't start server because port not specified"); + LogPrint (eLogCritical, "SSU2: Can't start server because port not specified"); } } if (found) @@ -224,7 +224,7 @@ namespace transport } catch (std::exception& ex ) { - LogPrint (eLogError, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what()); + LogPrint (eLogCritical, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what()); ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ()); } return socket; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index c618d136..47d59ea4 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -84,7 +84,7 @@ namespace transport m_Server (server), m_Address (addr), m_RemoteTransports (0), m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown), m_SendPacketNum (0), m_ReceivePacketNum (0), m_LastDatetimeSentPacketNum (0), - m_IsDataReceived (false), m_WindowSize (SSU2_MIN_WINDOW_SIZE), + m_IsDataReceived (false), m_WindowSize (SSU2_MIN_WINDOW_SIZE), m_RTT (SSU2_RESEND_INTERVAL), m_RTO (SSU2_RESEND_INTERVAL*SSU2_kAPPA), m_RelayTag (0), m_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose), m_MaxPayloadSize (SSU2_MIN_PACKET_SIZE - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - 32) // min size @@ -928,7 +928,7 @@ namespace transport { LogPrint (eLogError, "SSU2: Non zero packet number in SessionConfirmed"); return false; - } + } // check if fragmented uint8_t numFragments = header.h.flags[0] & 0x0F; if (numFragments > 1) @@ -1884,7 +1884,7 @@ namespace transport auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); // Alice's RI if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found"); - + uint8_t payload[SSU2_MAX_PACKET_SIZE]; size_t payloadSize = r ? CreateRouterInfoBlock (payload, m_MaxPayloadSize - len - 32, r) : 0; if (!payloadSize && r) @@ -2817,13 +2817,13 @@ namespace transport uint8_t payload[SSU2_MAX_PACKET_SIZE]; size_t payloadSize = 0; if (m_SendPacketNum > m_LastDatetimeSentPacketNum + SSU2_SEND_DATETIME_NUM_PACKETS) - { + { payload[0] = eSSU2BlkDateTime; htobe16buf (payload + 1, 4); htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); payloadSize += 7; m_LastDatetimeSentPacketNum = m_SendPacketNum; - } + } payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); SendData (payload, payloadSize); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 4e97bb26..c2aeb964 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -200,10 +200,10 @@ namespace transport i2p::context.SetStatusV6 (eRouterStatusProxy); } else - LogPrint(eLogError, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy); + LogPrint(eLogCritical, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy); } else - LogPrint(eLogError, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy); + LogPrint(eLogCritical, "Transports: Invalid NTCP2 proxy URL ", ntcp2proxy); } else m_NTCP2Server = new NTCP2Server (); @@ -225,10 +225,10 @@ namespace transport i2p::context.SetStatusV6 (eRouterStatusProxy); } else - LogPrint(eLogError, "Transports: Can't set SSU2 proxy ", ssu2proxy); + LogPrint(eLogCritical, "Transports: Can't set SSU2 proxy ", ssu2proxy); } else - LogPrint(eLogError, "Transports: Invalid SSU2 proxy URL ", ssu2proxy); + LogPrint(eLogCritical, "Transports: Invalid SSU2 proxy URL ", ssu2proxy); } } diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 652dfb8d..055311a9 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -661,7 +661,7 @@ namespace client this, std::placeholders::_1)); } else - LogPrint (eLogError, "Addressbook: Can't start subscriptions: missing shared local destination"); + LogPrint (eLogCritical, "Addressbook: Can't start subscriptions: missing shared local destination"); } void AddressBook::StopSubscriptions () diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 41bd1d49..b90386db 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -74,7 +74,7 @@ namespace client } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); + LogPrint(eLogCritical, "Clients: Exception in SAM bridge: ", e.what()); ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":[", samPortTCP, "|", samPortUDP,"]: ", e.what ()); } } @@ -92,7 +92,7 @@ namespace client } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); + LogPrint(eLogCritical, "Clients: Exception in BOB bridge: ", e.what()); ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); } } @@ -112,7 +112,7 @@ namespace client } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); + LogPrint(eLogCritical, "Clients: Exception in I2CP: ", e.what()); ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); } } @@ -279,7 +279,7 @@ namespace client s.read ((char *)buf, len); if(!keys.FromBuffer (buf, len)) { - LogPrint (eLogError, "Clients: Failed to load keyfile ", filename); + LogPrint (eLogCritical, "Clients: Failed to load keyfile ", filename); success = false; } else @@ -288,7 +288,7 @@ namespace client } else { - LogPrint (eLogError, "Clients: Can't open file ", fullPath, " Creating new one with signature type ", sigType, " crypto type ", cryptoType); + LogPrint (eLogCritical, "Clients: Can't open file ", fullPath, " Creating new one with signature type ", sigType, " crypto type ", cryptoType); keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType, true); std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); size_t len = keys.GetFullLen (); @@ -633,7 +633,7 @@ namespace client ins.first->second->Start (); } ins.first->second->isUpdated = true; - LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); + LogPrint(eLogCritical, "Clients: I2P Client forward for endpoint ", end, " already exists"); } } else { @@ -785,7 +785,7 @@ namespace client else { ins.first->second->isUpdated = true; - LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); + LogPrint(eLogCritical, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); } continue; @@ -851,7 +851,7 @@ namespace client } catch (std::exception& ex) { - LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); + LogPrint (eLogCritical, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); ThrowFatal ("Unable to start tunnel ", name, ": ", ex.what ()); } } @@ -883,7 +883,7 @@ namespace client if (localDestination) localDestination->Acquire (); } else - LogPrint(eLogError, "Clients: Failed to load HTTP Proxy key"); + LogPrint(eLogCritical, "Clients: Failed to load HTTP Proxy key"); } try { @@ -892,7 +892,7 @@ namespace client } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); + LogPrint(eLogCritical, "Clients: Exception in HTTP Proxy: ", e.what()); ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); } } @@ -930,7 +930,7 @@ namespace client if (localDestination) localDestination->Acquire (); } else - LogPrint(eLogError, "Clients: Failed to load SOCKS Proxy key"); + LogPrint(eLogCritical, "Clients: Failed to load SOCKS Proxy key"); } try { @@ -940,7 +940,7 @@ namespace client } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); + LogPrint(eLogCritical, "Clients: Exception in SOCKS Proxy: ", e.what()); ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); } } diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 4e19990a..37577fcc 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1283,7 +1283,7 @@ namespace client } catch (const std::exception& ex) { - LogPrint (eLogError, "SAM: Runtime exception: ", ex.what ()); + LogPrint (eLogCritical, "SAM: Runtime exception: ", ex.what ()); } { From e36d5634e7f7ac7e36e4ef9d5297d43c5dca290b Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 31 Mar 2023 11:40:07 +0000 Subject: [PATCH 0194/1160] fix log level show in webconsole --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8b034332..edfa80df 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -749,7 +749,7 @@ namespace http { auto loglevel = i2p::log::Logger().GetLogLevel(); s << "" << tr("Logging level") << "
\r\n"; s << " none \r\n"; - s << " none \r\n"; + s << " critical \r\n"; s << " error \r\n"; s << " warn \r\n"; s << " info \r\n"; From 710a35993db02644f7f28dbee739fe1e7a68a5a5 Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 31 Mar 2023 12:16:32 +0000 Subject: [PATCH 0195/1160] change some log level to error back --- daemon/Daemon.cpp | 2 +- daemon/HTTPServer.cpp | 2 +- daemon/I2PControl.cpp | 2 +- daemon/UPnP.cpp | 2 +- daemon/UnixDaemon.cpp | 16 ++++++++-------- libi2pd/Blinding.cpp | 4 ++-- libi2pd/Destination.cpp | 12 ++++++------ libi2pd/Family.cpp | 10 +++++----- libi2pd/Identity.cpp | 2 +- libi2pd_client/ClientContext.cpp | 4 ++-- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 02aee72d..8e9721db 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -262,7 +262,7 @@ namespace util restricted = idents.size() > 0; } if(!restricted) - LogPrint(eLogCritical, "Daemon: No trusted routers of families specified"); + LogPrint(eLogError, "Daemon: No trusted routers of families specified"); } bool hidden; i2p::config::GetOption("trust.hidden", hidden); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index edfa80df..dceee06a 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1482,7 +1482,7 @@ namespace http { } catch (std::exception& ex) { - LogPrint (eLogCritical, "HTTPServer: Runtime exception: ", ex.what ()); + LogPrint (eLogError, "HTTPServer: Runtime exception: ", ex.what ()); } } } diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 354c19d4..da2443fd 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -115,7 +115,7 @@ namespace client try { m_Service.run (); } catch (std::exception& ex) { - LogPrint (eLogCritical, "I2PControl: Runtime exception: ", ex.what ()); + LogPrint (eLogError, "I2PControl: Runtime exception: ", ex.what ()); } } } diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 2c915024..dbaf864a 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -72,7 +72,7 @@ namespace transport } catch (std::exception& ex) { - LogPrint (eLogCritical, "UPnP: Runtime exception: ", ex.what ()); + LogPrint (eLogError, "UPnP: Runtime exception: ", ex.what ()); PortMapping (); } } diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index 3c17fd14..bf4a7662 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -81,7 +81,7 @@ namespace i2p if (pid < 0) // error { - LogPrint(eLogCritical, "Daemon: Could not fork: ", strerror(errno)); + LogPrint(eLogError, "Daemon: Could not fork: ", strerror(errno)); std::cerr << "i2pd: Could not fork: " << strerror(errno) << std::endl; return false; } @@ -91,7 +91,7 @@ namespace i2p int sid = setsid(); if (sid < 0) { - LogPrint(eLogCritical, "Daemon: Could not create process group."); + LogPrint(eLogError, "Daemon: Could not create process group."); std::cerr << "i2pd: Could not create process group." << std::endl; return false; } @@ -121,10 +121,10 @@ namespace i2p LogPrint(eLogInfo, "Daemon: Set max number of open files to ", nfiles, " (system limit is ", limit.rlim_max, ")"); } else { - LogPrint(eLogCritical, "Daemon: Can't set max number of open files: ", strerror(errno)); + LogPrint(eLogError, "Daemon: Can't set max number of open files: ", strerror(errno)); } } else { - LogPrint(eLogCritical, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); + LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); } uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); if (cfsize) // core file size set @@ -134,14 +134,14 @@ namespace i2p if (cfsize <= limit.rlim_max) { limit.rlim_cur = cfsize; if (setrlimit(RLIMIT_CORE, &limit) != 0) { - LogPrint(eLogCritical, "Daemon: Can't set max size of coredump: ", strerror(errno)); + LogPrint(eLogError, "Daemon: Can't set max size of coredump: ", strerror(errno)); } else if (cfsize == 0) { LogPrint(eLogInfo, "Daemon: coredumps disabled"); } else { LogPrint(eLogInfo, "Daemon: Set max size of core files to ", cfsize / 1024, "Kb"); } } else { - LogPrint(eLogCritical, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); + LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); } } @@ -155,7 +155,7 @@ namespace i2p pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); if (pidFH < 0) { - LogPrint(eLogCritical, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno)); + LogPrint(eLogError, "Daemon: Could not create pid file ", pidfile, ": ", strerror(errno)); std::cerr << "i2pd: Could not create pid file " << pidfile << ": " << strerror(errno) << std::endl; return false; } @@ -163,7 +163,7 @@ namespace i2p #ifndef ANDROID if (lockf(pidFH, F_TLOCK, 0) != 0) { - LogPrint(eLogCritical, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno)); + LogPrint(eLogError, "Daemon: Could not lock pid file ", pidfile, ": ", strerror(errno)); std::cerr << "i2pd: Could not lock pid file " << pidfile << ": " << strerror(errno) << std::endl; return false; } diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 1f15cf14..ced086e1 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -259,7 +259,7 @@ namespace data publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; break; default: - LogPrint (eLogCritical, "Blinding: Can't blind signature type ", (int)m_SigType); + LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType); } return publicKeyLength; } @@ -289,7 +289,7 @@ namespace data break; } default: - LogPrint (eLogCritical, "Blinding: Can't blind signature type ", (int)m_SigType); + LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType); } return publicKeyLength; } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 0be25512..4175f54c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -108,7 +108,7 @@ namespace client if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) m_AuthType = authType; else - LogPrint (eLogCritical, "Destination: Unknown auth type ", authType); + LogPrint (eLogCritical, "Destination: Unknown auth type: ", authType); } } it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); @@ -117,7 +117,7 @@ namespace client m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>()); if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32) { - LogPrint(eLogCritical, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second); + LogPrint(eLogCritical, "Destination: Invalid value i2cp.leaseSetPrivKey: ", it->second); m_LeaseSetPrivKey.reset (nullptr); } } @@ -125,7 +125,7 @@ namespace client } catch (std::exception & ex) { - LogPrint(eLogCritical, "Destination: Unable to parse parameters for destination: ", ex.what()); + LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what()); } SetNumTags (numTags); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty, inVar, outVar); @@ -1014,12 +1014,12 @@ namespace client else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else - LogPrint (eLogCritical, "Destination: Unexpected auth type ", authType); + LogPrint (eLogCritical, "Destination: Unexpected auth type: ", authType); if (m_AuthKeys->size ()) LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); else { - LogPrint (eLogCritical, "Destination: No auth keys read for auth type ", authType); + LogPrint (eLogCritical, "Destination: No auth keys read for auth type: ", authType); m_AuthKeys = nullptr; } } @@ -1413,7 +1413,7 @@ namespace client if (pubKey.FromBase64 (it.second.substr (pos+1))) m_AuthKeys->push_back (pubKey); else - LogPrint (eLogCritical, "Destination: Unexpected auth key ", it.second.substr (pos+1)); + LogPrint (eLogCritical, "Destination: Unexpected auth key: ", it.second.substr (pos+1)); } } } diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index bca9e231..6564901e 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -77,14 +77,14 @@ namespace data verifier->SetPublicKey (signingKey); } else - LogPrint (eLogCritical, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogError, "Family: elliptic curve ", curve, " is not supported"); } EC_KEY_free (ecKey); } break; } default: - LogPrint (eLogCritical, "Family: Certificate key type ", keyType, " is not supported"); + LogPrint (eLogError, "Family: Certificate key type ", keyType, " is not supported"); } EVP_PKEY_free (pkey); if (verifier && cn) @@ -93,7 +93,7 @@ namespace data SSL_free (ssl); } else - LogPrint (eLogCritical, "Family: Can't open certificate file ", filename); + LogPrint (eLogError, "Family: Can't open certificate file ", filename); SSL_CTX_free (ctx); } @@ -185,13 +185,13 @@ namespace data delete[] b64; } else - LogPrint (eLogCritical, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogError, "Family: elliptic curve ", curve, " is not supported"); } } SSL_free (ssl); } else - LogPrint (eLogCritical, "Family: Can't open keys file: ", filename); + LogPrint (eLogError, "Family: Can't open keys file: ", filename); SSL_CTX_free (ctx); return sig; } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 7a73f02a..ca47e797 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -755,7 +755,7 @@ namespace data i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: - LogPrint (eLogCritical, "Identity: Crypto key type ", (int)type, " is not supported"); + LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported"); } } diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index b90386db..dadb9ae5 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -633,7 +633,7 @@ namespace client ins.first->second->Start (); } ins.first->second->isUpdated = true; - LogPrint(eLogCritical, "Clients: I2P Client forward for endpoint ", end, " already exists"); + LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); } } else { @@ -785,7 +785,7 @@ namespace client else { ins.first->second->isUpdated = true; - LogPrint(eLogCritical, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); + LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); } continue; From 2abc997af8785229450cee88dbf594c37afb7da3 Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 31 Mar 2023 12:29:13 +0000 Subject: [PATCH 0196/1160] change some log levels back --- libi2pd/Family.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index 6564901e..8c6d3ba4 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -77,14 +77,14 @@ namespace data verifier->SetPublicKey (signingKey); } else - LogPrint (eLogError, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } EC_KEY_free (ecKey); } break; } default: - LogPrint (eLogError, "Family: Certificate key type ", keyType, " is not supported"); + LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported"); } EVP_PKEY_free (pkey); if (verifier && cn) @@ -105,7 +105,7 @@ namespace data int numCertificates = 0; if (!i2p::fs::ReadDir(certDir, files)) { - LogPrint(eLogError, "Family: Can't load family certificates from ", certDir); + LogPrint(eLogWarning, "Family: Can't load family certificates from ", certDir); return; } @@ -185,7 +185,7 @@ namespace data delete[] b64; } else - LogPrint (eLogError, "Family: elliptic curve ", curve, " is not supported"); + LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } } SSL_free (ssl); From a3bdc4ddc1142b60da03e6f01d2a7766e96312dc Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 31 Mar 2023 12:40:38 +0000 Subject: [PATCH 0197/1160] change some log levels back --- libi2pd/Destination.cpp | 4 ++-- libi2pd_client/SAM.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 4175f54c..8002e6f9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -108,7 +108,7 @@ namespace client if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) m_AuthType = authType; else - LogPrint (eLogCritical, "Destination: Unknown auth type: ", authType); + LogPrint (eLogError, "Destination: Unknown auth type: ", authType); } } it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); @@ -1014,7 +1014,7 @@ namespace client else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else - LogPrint (eLogCritical, "Destination: Unexpected auth type: ", authType); + LogPrint (eLogError, "Destination: Unexpected auth type: ", authType); if (m_AuthKeys->size ()) LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); else diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 37577fcc..4e19990a 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1283,7 +1283,7 @@ namespace client } catch (const std::exception& ex) { - LogPrint (eLogCritical, "SAM: Runtime exception: ", ex.what ()); + LogPrint (eLogError, "SAM: Runtime exception: ", ex.what ()); } { From b8032e7fbfd6cf2a91bf8fee0b970dd4ede767a7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 2 Apr 2023 11:27:51 -0400 Subject: [PATCH 0198/1160] publish congestion cap G --- libi2pd/RouterContext.cpp | 9 ++++++++- libi2pd/RouterInfo.cpp | 9 +-------- libi2pd/RouterInfo.h | 3 +-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 20ac589b..de103910 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1090,6 +1090,8 @@ namespace i2p UpdateSSU2Keys (); updated = true; } + if (m_RouterInfo.UpdateCongestion (i2p::data::RouterInfo::eLowCongestion)) + updated = true; if (updated) UpdateRouterInfo (); @@ -1398,7 +1400,12 @@ namespace i2p { if (ecode != boost::asio::error::operation_aborted) { - if (m_RouterInfo.SetHighCongestion (IsHighCongestion ())) + auto c = i2p::data::RouterInfo::eLowCongestion; + if (!AcceptsTunnels ()) + c = i2p::data::RouterInfo::eRejectAll; + else if (IsHighCongestion ()) + c = i2p::data::RouterInfo::eHighCongestion; + if (m_RouterInfo.UpdateCongestion (c)) UpdateRouterInfo (); ScheduleCongestionUpdate (); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 7462ef0e..3ae5abd9 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1077,12 +1077,6 @@ namespace data if (m_Congestion == eHighCongestion) return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL) ? true : false; return false; - } - - LocalRouterInfo::LocalRouterInfo (const std::string& fullPath): - RouterInfo (fullPath) - { - SetHighCongestion (false); // drop congestion } void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) @@ -1153,9 +1147,8 @@ namespace data SetProperty ("caps", caps); } - bool LocalRouterInfo::SetHighCongestion (bool highCongestion) + bool LocalRouterInfo::UpdateCongestion (Congestion c) { - Congestion c = highCongestion ? eHighCongestion : eLowCongestion; if (c != GetCongestion ()) { SetCongestion (c); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ef145496..f258b018 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -330,10 +330,9 @@ namespace data public: LocalRouterInfo () = default; - LocalRouterInfo (const std::string& fullPath); void CreateBuffer (const PrivateKeys& privateKeys); void UpdateCaps (uint8_t caps); - bool SetHighCongestion (bool highCongestion); // returns true if updated + bool UpdateCongestion (Congestion c); // returns true if updated void SetProperty (const std::string& key, const std::string& value) override; void DeleteProperty (const std::string& key); From 7c2da75197deebee232090d80e5d177a6eb438d1 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Apr 2023 19:05:35 -0400 Subject: [PATCH 0199/1160] don't recreate existing streaming destination --- libi2pd_client/I2PTunnel.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5558cd8d..db0d0c04 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -691,7 +691,10 @@ namespace client int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { - m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip); + if (!inport) inport = port; + m_PortDestination = localDestination->GetStreamingDestination (inport); + if (!m_PortDestination) + m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip); } void I2PServerTunnel::Start () From 0c8a80b6f8179e84a910d8cb5926f0282d5ea120 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Apr 2023 21:35:10 -0400 Subject: [PATCH 0200/1160] fixed warnings --- libi2pd/TransitTunnel.h | 18 +++++++++--------- libi2pd/Tunnel.h | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index 60e2f450..fb2dad21 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -34,9 +34,9 @@ namespace tunnel virtual size_t GetNumTransmittedBytes () const { return 0; }; // implements TunnelBase - void SendTunnelDataMsg (std::shared_ptr msg); - void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); - void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); + void SendTunnelDataMsg (std::shared_ptr msg) override; + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; + void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) override; private: i2p::crypto::AESKey m_LayerKey, m_IVKey; @@ -55,8 +55,8 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; - void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); - void FlushTunnelDataMsgs (); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; + void FlushTunnelDataMsgs () override; private: @@ -74,8 +74,8 @@ namespace tunnel TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), m_Gateway(this) {}; - void SendTunnelDataMsg (std::shared_ptr msg); - void FlushTunnelDataMsgs (); + void SendTunnelDataMsg (std::shared_ptr msg) override; + void FlushTunnelDataMsgs () override; size_t GetNumTransmittedBytes () const { return m_Gateway.GetNumSentBytes (); }; private: @@ -96,7 +96,7 @@ namespace tunnel void Cleanup () { m_Endpoint.Cleanup (); } - void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } private: diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 5ac410ea..561b81a3 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -103,8 +103,8 @@ namespace tunnel bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); // implements TunnelBase - void SendTunnelDataMsg (std::shared_ptr msg); - void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); + void SendTunnelDataMsg (std::shared_ptr msg) override; + void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) override; /** @brief add latency sample */ void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; } @@ -144,9 +144,9 @@ namespace tunnel virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; // implements TunnelBase - void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; - bool IsInbound() const { return false; } + bool IsInbound() const override { return false; } private: @@ -160,9 +160,9 @@ 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) override; virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; - bool IsInbound() const { return true; } + bool IsInbound() const override { return true; } // override TunnelBase void Cleanup () { m_Endpoint.Cleanup (); }; @@ -177,8 +177,8 @@ namespace tunnel public: ZeroHopsInboundTunnel (); - void SendTunnelDataMsg (std::shared_ptr msg); - size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; + void SendTunnelDataMsg (std::shared_ptr msg) override; + size_t GetNumReceivedBytes () const override { return m_NumReceivedBytes; }; private: @@ -190,8 +190,8 @@ namespace tunnel public: ZeroHopsOutboundTunnel (); - void SendTunnelDataMsg (const std::vector& msgs); - size_t GetNumSentBytes () const { return m_NumSentBytes; }; + void SendTunnelDataMsg (const std::vector& msgs) override; + size_t GetNumSentBytes () const override { return m_NumSentBytes; }; private: From dc6499aa981bdb4c475ac9e0ca93590150b59366 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Apr 2023 22:50:31 -0400 Subject: [PATCH 0201/1160] fixed warnings --- libi2pd/TransitTunnel.h | 2 +- libi2pd/Tunnel.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index fb2dad21..20aff500 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -94,7 +94,7 @@ namespace tunnel TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), m_Endpoint (false) {}; // transit endpoint is always outbound - void Cleanup () { m_Endpoint.Cleanup (); } + void Cleanup () override { m_Endpoint.Cleanup (); } void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 561b81a3..cd12369e 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -165,7 +165,7 @@ namespace tunnel bool IsInbound() const override { return true; } // override TunnelBase - void Cleanup () { m_Endpoint.Cleanup (); }; + void Cleanup () override { m_Endpoint.Cleanup (); }; private: From 922e5915b16f07b6dea56704f660cb1237c2efa1 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Apr 2023 13:19:08 -0400 Subject: [PATCH 0202/1160] rename SendTunnelDataMsg to SendTunnelDataMsgs for multiple messages --- libi2pd/Datagram.cpp | 4 ++-- libi2pd/Destination.cpp | 2 +- libi2pd/NetDb.cpp | 2 +- libi2pd/Streaming.cpp | 2 +- libi2pd/Tunnel.cpp | 6 +++--- libi2pd/Tunnel.h | 4 ++-- libi2pd_client/I2CP.cpp | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 30635b09..64738ebe 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -425,7 +425,7 @@ namespace datagram if (m) send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m}); } - routingPath->outboundTunnel->SendTunnelDataMsg(send); + routingPath->outboundTunnel->SendTunnelDataMsgs(send); } m_SendQueue.clear(); } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 8002e6f9..efda499f 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -835,7 +835,7 @@ namespace client AddSessionKey (replyKey, replyTag); auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES)); - request->outboundTunnel->SendTunnelDataMsg ( + request->outboundTunnel->SendTunnelDataMsgs ( { i2p::tunnel::TunnelMessageBlock { diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 82e15304..ecae4f24 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1137,7 +1137,7 @@ namespace data m_Requests.RequestComplete (randomHash, nullptr); } if (throughTunnels && msgs.size () > 0) - outbound->SendTunnelDataMsg (msgs); + outbound->SendTunnelDataMsgs (msgs); } void NetDb::Flood (const IdentHash& ident, std::shared_ptr floodMsg) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 1deca8a6..c2cf3a0a 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -925,7 +925,7 @@ namespace stream }); m_NumSentBytes += it->GetLength (); } - m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs); + m_CurrentOutboundTunnel->SendTunnelDataMsgs (msgs); } else { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 09358179..9c880378 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -284,10 +284,10 @@ namespace tunnel block.deliveryType = eDeliveryTypeLocal; block.data = msg; - SendTunnelDataMsg ({block}); + SendTunnelDataMsgs ({block}); } - void OutboundTunnel::SendTunnelDataMsg (const std::vector& msgs) + void OutboundTunnel::SendTunnelDataMsgs (const std::vector& msgs) { std::unique_lock l(m_SendMutex); for (auto& it : msgs) @@ -306,7 +306,7 @@ namespace tunnel { } - void ZeroHopsOutboundTunnel::SendTunnelDataMsg (const std::vector& msgs) + void ZeroHopsOutboundTunnel::SendTunnelDataMsgs (const std::vector& msgs) { for (auto& msg : msgs) { diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index cd12369e..bf0274db 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -139,7 +139,7 @@ namespace tunnel Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {}; void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg); - virtual void SendTunnelDataMsg (const std::vector& msgs); // multiple messages + virtual void SendTunnelDataMsgs (const std::vector& msgs); // multiple messages const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; }; virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; @@ -190,7 +190,7 @@ namespace tunnel public: ZeroHopsOutboundTunnel (); - void SendTunnelDataMsg (const std::vector& msgs) override; + void SendTunnelDataMsgs (const std::vector& msgs) override; size_t GetNumSentBytes () const override { return m_NumSentBytes; }; private: diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index cc0837b7..87f37e5e 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -230,7 +230,7 @@ namespace client remoteLease->tunnelGateway, remoteLease->tunnelID, garlic }); - outboundTunnel->SendTunnelDataMsg (msgs); + outboundTunnel->SendTunnelDataMsgs (msgs); return true; } else From 8178df752b1432de7b45c72820b56694b4f526c7 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Apr 2023 13:42:54 -0400 Subject: [PATCH 0203/1160] fixed warning --- libi2pd/TransitTunnel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index 20aff500..cbab8d5b 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -54,7 +54,7 @@ namespace tunnel layerKey, ivKey), m_NumTransmittedBytes (0) {}; ~TransitTunnelParticipant (); - size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; + size_t GetNumTransmittedBytes () const override { return m_NumTransmittedBytes; }; void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; void FlushTunnelDataMsgs () override; @@ -76,7 +76,7 @@ namespace tunnel void SendTunnelDataMsg (std::shared_ptr msg) override; void FlushTunnelDataMsgs () override; - size_t GetNumTransmittedBytes () const { return m_Gateway.GetNumSentBytes (); }; + size_t GetNumTransmittedBytes () const override { return m_Gateway.GetNumSentBytes (); }; private: From 220ef283dea2af174c1fb62aa501d5752c6910dd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Apr 2023 13:48:00 -0400 Subject: [PATCH 0204/1160] rename SendTunnelDataMsg to SendTunnelDataMsgTo for router tunnel delivery types --- libi2pd/Destination.cpp | 2 +- libi2pd/Garlic.cpp | 6 +++--- libi2pd/NetDb.cpp | 8 ++++---- libi2pd/NetDbRequests.cpp | 4 ++-- libi2pd/RouterContext.cpp | 2 +- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/Tunnel.h | 2 +- libi2pd/TunnelPool.cpp | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index efda499f..9e5fbe20 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -635,7 +635,7 @@ namespace client m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); - outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, msg); m_LastSubmissionTime = ts; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 9daea1f0..c351f6d6 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -709,7 +709,7 @@ namespace garlic else LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); if (tunnel) // we have sent it through an outbound tunnel - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); + tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, msg); else LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); } @@ -1075,7 +1075,7 @@ namespace garlic { auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); if (tunnel) - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID)); + tunnel->SendTunnelDataMsgTo (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID)); else LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index ecae4f24..447eb873 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -717,7 +717,7 @@ namespace data 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)); + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); else { LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); @@ -792,7 +792,7 @@ namespace data auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; if (outbound) - outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus); + outbound->SendTunnelDataMsgTo (buf + offset, tunnelID, deliveryStatus); else LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); } @@ -901,7 +901,7 @@ namespace data { // request destination LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); - outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, + outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, dest->CreateRequestMessage (nextFloodfill, inbound)); deleteDest = false; } @@ -1081,7 +1081,7 @@ namespace data auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; if (outbound) - outbound->SendTunnelDataMsg (replyIdent, replyTunnelID, replyMsg); + outbound->SendTunnelDataMsgTo (replyIdent, replyTunnelID, replyMsg); else transports.SendMessage (replyIdent, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg)); } diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index e7aab34c..4011b8aa 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -137,7 +137,7 @@ namespace data auto inbound = pool->GetNextInboundTunnel (); auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); if (nextFloodfill && outbound && inbound) - outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, + outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, dest->CreateRequestMessage (nextFloodfill, inbound)); else { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index de103910..d6c3c57b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1348,7 +1348,7 @@ namespace i2p 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, + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound)); else LogPrint (eLogInfo, "Router: Can't publish our RouterInfo. No tunnles. Try again in ", ROUTER_INFO_CONFIRMATION_TIMEOUT, " seconds"); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 9c880378..05359390 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -103,7 +103,7 @@ namespace tunnel if (msg1) msg = msg1; } } - outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); + outboundTunnel->SendTunnelDataMsgTo (GetNextIdentHash (), 0, msg); } else { @@ -266,7 +266,7 @@ namespace tunnel } } - void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg) + void OutboundTunnel::SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg) { TunnelMessageBlock block; if (gwHash) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index bf0274db..5810a7a8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -138,7 +138,7 @@ namespace tunnel OutboundTunnel (std::shared_ptr config): Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {}; - void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg); + void SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg); virtual void SendTunnelDataMsgs (const std::vector& msgs); // multiple messages const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; }; virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index bafc1c2d..cf146218 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -383,7 +383,7 @@ namespace tunnel std::unique_lock l(m_TestsMutex); m_Tests[msgID] = std::make_pair (*it1, *it2); } - (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), + (*it1)->SendTunnelDataMsgTo ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), CreateDeliveryStatusMsg (msgID)); ++it1; ++it2; } From e3fb9d84835cc95092b5cea998d8d543dcb42a9b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Apr 2023 13:57:46 -0400 Subject: [PATCH 0205/1160] fixed warning --- libi2pd/TransitTunnel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index cbab8d5b..f83007a9 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -97,7 +97,7 @@ namespace tunnel void Cleanup () override { m_Endpoint.Cleanup (); } void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; - size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } + size_t GetNumTransmittedBytes () const override { return m_Endpoint.GetNumReceivedBytes (); } private: From 9475a2272830fd98ec22675076e9864845026a6a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 5 Apr 2023 21:30:36 -0400 Subject: [PATCH 0206/1160] update introducers. cleanup unreachable routers --- libi2pd/NetDb.cpp | 30 ++++++++++++++---------- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterInfo.cpp | 53 +++++++++++++++++++++++++++++++++--------- libi2pd/RouterInfo.h | 6 +++-- libi2pd/TunnelPool.cpp | 7 +++--- 5 files changed, 69 insertions(+), 29 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 447eb873..9fd9923a 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -106,7 +106,7 @@ namespace data { i2p::util::SetThreadName("NetDB"); - uint64_t lastSave = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; + uint64_t lastManage = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch (); int16_t profilesCleanupVariance = 0; @@ -155,14 +155,14 @@ namespace data lastManageRequest = ts; } - if (ts - lastSave >= 60 || ts + 60 < lastSave) // save routers, manage leasesets and validate subscriptions every minute + if (ts - lastManage >= 60 || ts + 60 < lastManage) // manage routers and leasesets every minute { - if (lastSave) + if (lastManage) { - SaveUpdated (); + ManageRouterInfos (); ManageLeaseSets (); } - lastSave = ts; + lastManage = ts; } if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT || @@ -631,13 +631,8 @@ namespace data if (!it.second->IsUnreachable ()) { // find & mark expired routers - if (!it.second->IsReachable () && (it.second->GetCompatibleTransports (true) & RouterInfo::eSSU2V4)) - // non-reachable router, but reachable by ipv4 SSU2 means introducers - { - if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) - // RouterInfo expires after 1 hour if uses introducer - it.second->SetUnreachable (true); - } + if (it.second->GetCompatibleTransports (true)) // non reachable by any transport + it.second->SetUnreachable (true); else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) it.second->SetUnreachable (true); else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ()) @@ -1348,6 +1343,17 @@ namespace data return r; } + void NetDb::ManageRouterInfos () + { + auto ts = i2p::util::GetSecondsSinceEpoch (); + { + std::unique_lock l(m_RouterInfosMutex); + for (auto& it: m_RouterInfos) + it.second->UpdateIntroducers (ts); + } + SaveUpdated (); + } + void NetDb::ManageLeaseSets () { auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 71694d8d..d98d487e 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -40,7 +40,6 @@ namespace data const int NETDB_MIN_FLOODFILLS = 5; const int NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE = 8; // in percents const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds - const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60; const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days @@ -139,6 +138,7 @@ namespace data void Run (); // exploratory thread void Explore (int numDestinations); void Flood (const IdentHash& ident, std::shared_ptr floodMsg); + void ManageRouterInfos (); void ManageLeaseSets (); void ManageRequests (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3ae5abd9..eb186ec9 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -400,18 +400,9 @@ namespace data { // exclude invalid introducers uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - int numValid = 0; - for (auto& it: address->ssu->introducers) - { - if (it.iTag && ts < it.iExp) - numValid++; - else - it.iTag = 0; - } - if (numValid) + UpdateIntroducers (address, ts); + if (!address->ssu->introducers.empty ()) // still has something m_ReachableTransports |= supportedTransports; - else - address->ssu->introducers.resize (0); } } if (supportedTransports) @@ -576,6 +567,21 @@ namespace data return caps; } + void RouterInfo::UpdateIntroducers (std::shared_ptr
address, uint64_t ts) + { + if (!address || !address->ssu) return; + int numValid = 0; + for (auto& it: address->ssu->introducers) + { + if (it.iTag && ts < it.iExp) + numValid++; + else + it.iTag = 0; + } + if (!numValid) + address->ssu->introducers.resize (0); + } + bool RouterInfo::IsNewer (const uint8_t * buf, size_t len) const { if (!m_RouterIdentity) return false; @@ -1036,6 +1042,31 @@ namespace data } } + void RouterInfo::UpdateIntroducers (uint64_t ts) + { + if (ts*1000 < m_Timestamp + INTRODUCER_UPDATE_INTERVAL) return; + if (m_ReachableTransports & eSSU2V4) + { + auto addr = (*GetAddresses ())[eSSU2V4Idx]; + if (addr && addr->UsesIntroducer ()) + { + UpdateIntroducers (addr, ts); + if (!addr->UsesIntroducer ()) // no more valid introducers + m_ReachableTransports &= ~eSSU2V4; + } + } + if (m_ReachableTransports & eSSU2V6) + { + auto addr = (*GetAddresses ())[eSSU2V6Idx]; + if (addr && addr->UsesIntroducer ()) + { + UpdateIntroducers (addr, ts); + if (!addr->UsesIntroducer ()) // no more valid introducers + m_ReachableTransports &= ~eSSU2V6; + } + } + } + void RouterInfo::UpdateBuffer (const uint8_t * buf, size_t len) { if (!m_Buffer) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f258b018..273e7a75 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -61,6 +61,7 @@ namespace data const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes + const int INTRODUCER_UPDATE_INTERVAL = 20*60*1000; // in milliseconds, 20 minutes class RouterInfo: public RoutingDestination { @@ -221,8 +222,8 @@ namespace data void RemoveSSU2Address (bool v4); void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps void UpdateSupportedTransports (); + void UpdateIntroducers (uint64_t ts); // ts in seconds bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; - bool IsReachable () const { return m_Caps & Caps::eReachable; }; bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsNTCP2 (bool v4only = true) const; bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; }; @@ -302,6 +303,7 @@ namespace data size_t ReadString (char* str, size_t len, std::istream& s) const; void ExtractCaps (const char * value); uint8_t ExtractAddressCaps (const char * value) const; + void UpdateIntroducers (std::shared_ptr
address, uint64_t ts); template std::shared_ptr GetAddress (Filter filter) const; virtual std::shared_ptr NewBuffer () const; @@ -315,7 +317,7 @@ namespace data std::shared_ptr m_RouterIdentity; std::shared_ptr m_Buffer; size_t m_BufferLen; - uint64_t m_Timestamp; + uint64_t m_Timestamp; // in milliseconds boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 bool m_IsUpdated, m_IsUnreachable; CompatibleTransports m_SupportedTransports, m_ReachableTransports; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index cf146218..c1102d25 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -498,7 +498,8 @@ namespace tunnel { auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ()); if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && - (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable + (numHops > 1 || (r->IsV4 () && (!inbound || + r->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4))))) // first inbound must be reachable { prevHop = r; path.Add (r); @@ -520,8 +521,8 @@ namespace tunnel LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); return false; } - if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4 - (inbound && !hop->IsReachable ()))) // IBGW is not reachable + if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && // doesn't support ipv4 + !hop->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4)))) // IBGW is not reachable { auto hop1 = nextHop (prevHop, true); if (hop1) hop = hop1; From d580c0155ac8ff31f26ac0378719b63750f555e5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 5 Apr 2023 21:49:49 -0400 Subject: [PATCH 0207/1160] fixed typo --- libi2pd/NetDb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9fd9923a..3847f24f 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -631,7 +631,7 @@ namespace data if (!it.second->IsUnreachable ()) { // find & mark expired routers - if (it.second->GetCompatibleTransports (true)) // non reachable by any transport + if (!it.second->GetCompatibleTransports (true)) // non reachable by any transport it.second->SetUnreachable (true); else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) it.second->SetUnreachable (true); From caff003a85c0cfbd807d7c71333ac9ac34f1eba7 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Apr 2023 16:03:15 -0400 Subject: [PATCH 0208/1160] check for published ipv4 addresses for floodfills and IBGW --- libi2pd/RouterInfo.cpp | 20 ++++++++++++++++---- libi2pd/RouterInfo.h | 1 + libi2pd/TunnelPool.cpp | 6 ++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index eb186ec9..ad1de04a 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -366,7 +366,7 @@ namespace data { if (isStaticKey) { - if (isHost) + if (isHost && address->port) { if (address->host.is_v6 ()) supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); @@ -374,8 +374,9 @@ namespace data supportedTransports |= eNTCP2V4; m_ReachableTransports |= supportedTransports; } - else if (!address->published) + else { + address->published = false; if (address->caps) { if (address->caps & AddressCaps::eV4) supportedTransports |= eNTCP2V4; @@ -982,11 +983,22 @@ namespace data bool RouterInfo::IsEligibleFloodfill () const { - // floodfill must be reachable by ipv4, >= 0.9.38 and not DSA - return IsReachableBy (eNTCP2V4 | eSSU2V4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION && + // floodfill must have published ipv4, >= 0.9.38 and not DSA + return m_Version >= NETDB_MIN_FLOODFILL_VERSION && IsPublished (true) && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } + bool RouterInfo::IsPublished (bool v4) const + { + auto addr = GetAddresses (); + if (v4) + return ((*addr)[eNTCP2V4] && ((*addr)[eNTCP2V4])->published) || + ((*addr)[eSSU2V4] && ((*addr)[eSSU2V4])->published); + else + return ((*addr)[eNTCP2V6] && ((*addr)[eNTCP2V6])->published) || + ((*addr)[eSSU2V6] && ((*addr)[eSSU2V6])->published); + } + bool RouterInfo::IsSSU2PeerTesting (bool v4) const { if (!(m_SupportedTransports & (v4 ? eSSU2V4 : eSSU2V6))) return false; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 273e7a75..3789438d 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -247,6 +247,7 @@ namespace data bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; + bool IsPublished (bool v4) const; bool IsSSU2PeerTesting (bool v4) const; bool IsSSU2Introducer (bool v4) const; bool IsHighCongestion () const; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index c1102d25..aee466a1 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -498,8 +498,7 @@ namespace tunnel { auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ()); if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && - (numHops > 1 || (r->IsV4 () && (!inbound || - r->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4))))) // first inbound must be reachable + (numHops > 1 || (r->IsV4 () && (!inbound || r->IsPublished (true))))) // first inbound must be published ipv4 { prevHop = r; path.Add (r); @@ -521,8 +520,7 @@ namespace tunnel LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); return false; } - if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && // doesn't support ipv4 - !hop->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4)))) // IBGW is not reachable + if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && !hop->IsPublished (true)))) // IBGW is not published ipv4 { auto hop1 = nextHop (prevHop, true); if (hop1) hop = hop1; From c1f19cb2582bb51d1fe1c9b49459557da1e45ab3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Apr 2023 16:19:56 -0400 Subject: [PATCH 0209/1160] fixed typo --- libi2pd/RouterInfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ad1de04a..34bd705d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -992,11 +992,11 @@ namespace data { auto addr = GetAddresses (); if (v4) - return ((*addr)[eNTCP2V4] && ((*addr)[eNTCP2V4])->published) || - ((*addr)[eSSU2V4] && ((*addr)[eSSU2V4])->published); + return ((*addr)[eNTCP2V4Idx] && ((*addr)[eNTCP2V4Idx])->published) || + ((*addr)[eSSU2V4Idx] && ((*addr)[eSSU2V4Idx])->published); else - return ((*addr)[eNTCP2V6] && ((*addr)[eNTCP2V6])->published) || - ((*addr)[eSSU2V6] && ((*addr)[eSSU2V6])->published); + return ((*addr)[eNTCP2V6Idx] && ((*addr)[eNTCP2V6Idx])->published) || + ((*addr)[eSSU2V6Idx] && ((*addr)[eSSU2V6Idx])->published); } bool RouterInfo::IsSSU2PeerTesting (bool v4) const From 572694b141720183ff65bdb5e081ff60772c224e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 9 Apr 2023 21:32:44 -0400 Subject: [PATCH 0210/1160] check routers' congestion before recreating a tunnel --- libi2pd/TunnelPool.cpp | 31 ++++++++++++++++++++++++++----- libi2pd/TunnelPool.h | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index aee466a1..d21347e6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -637,8 +637,13 @@ namespace tunnel outboundTunnel = tunnels.GetNextOutboundTunnel (); 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 (), tunnel->GetFarEndTransports ()); + if (m_NumInboundHops > 0) + { + auto peers = tunnel->GetPeers(); + if (peers.size ()&& ValidatePeers (peers)) + config = std::make_shared(tunnel->GetPeers (), + tunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); + } if (!m_NumInboundHops || config) { auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); @@ -702,10 +707,12 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); std::shared_ptr config; - if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) + if (m_NumOutboundHops > 0) { - config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), - inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); + auto peers = tunnel->GetPeers(); + if (peers.size () && ValidatePeers (peers)) + config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); } if (!m_NumOutboundHops || config) { @@ -746,6 +753,20 @@ namespace tunnel return m_CustomPeerSelector != nullptr; } + bool TunnelPool::ValidatePeers (std::vector >& peers) + { + for (auto it: peers) + { + auto r = i2p::data::netdb.FindRouter (it->GetIdentHash ()); + if (r) + { + if (r->IsHighCongestion ()) return false; + it = r->GetIdentity (); // use identity from updated RouterInfo + } + } + return true; + } + std::shared_ptr TunnelPool::GetLowestLatencyInboundTunnel(std::shared_ptr exclude) const { std::shared_ptr tun = nullptr; diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 7d952559..f49ce309 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -126,6 +126,7 @@ namespace tunnel typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const; bool SelectPeers (Path& path, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound); + static bool ValidatePeers (std::vector >& peers); private: From 4ebc7c970a168257c21f823b9fff792458a1ab25 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 Apr 2023 23:04:38 -0400 Subject: [PATCH 0211/1160] bypass medium congestion(D) routers for client tunnels --- libi2pd/NetDb.cpp | 4 ++-- libi2pd/RouterInfo.cpp | 24 ++++++++++++++++++------ libi2pd/RouterInfo.h | 2 +- libi2pd/TunnelPool.cpp | 5 +++-- libi2pd/TunnelPool.h | 2 +- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 3847f24f..c9c92b64 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1172,7 +1172,7 @@ namespace data return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : router->IsReachableFrom (*compatibleWith)) && - router->IsECIES (); + router->IsECIES () && !router->IsHighCongestion (false); }); } @@ -1206,7 +1206,7 @@ namespace data router->IsReachableFrom (*compatibleWith)) && (router->GetCaps () & RouterInfo::eHighBandwidth) && router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && - router->IsECIES () && !router->IsHighCongestion (); + router->IsECIES () && !router->IsHighCongestion (true); }); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 34bd705d..c18e0521 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1113,13 +1113,25 @@ namespace data m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); } - bool RouterInfo::IsHighCongestion () const + bool RouterInfo::IsHighCongestion (bool highBandwidth) const { - if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false; - if (m_Congestion == eRejectAll) return true; - if (m_Congestion == eHighCongestion) - return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL) ? true : false; - return false; + switch (m_Congestion) + { + case eLowCongestion: + return false; + break; + case eMediumCongestion: + return highBandwidth; + break; + case eHighCongestion: + return i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL; + break; + case eRejectAll: + return true; + break; + default: + return false; + } } void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 3789438d..070737e8 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -250,7 +250,7 @@ namespace data bool IsPublished (bool v4) const; bool IsSSU2PeerTesting (bool v4) const; bool IsSSU2Introducer (bool v4) const; - bool IsHighCongestion () const; + bool IsHighCongestion (bool highBandwidth) const; uint8_t GetCaps () const { return m_Caps; }; void SetCaps (uint8_t caps) { m_Caps = caps; }; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index d21347e6..3dc0256e 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -753,14 +753,15 @@ namespace tunnel return m_CustomPeerSelector != nullptr; } - bool TunnelPool::ValidatePeers (std::vector >& peers) + bool TunnelPool::ValidatePeers (std::vector >& peers) const { + bool highBandwidth = !IsExploratory (); for (auto it: peers) { auto r = i2p::data::netdb.FindRouter (it->GetIdentHash ()); if (r) { - if (r->IsHighCongestion ()) return false; + if (r->IsHighCongestion (highBandwidth)) return false; it = r->GetIdentity (); // use identity from updated RouterInfo } } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index f49ce309..e9dd142e 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -126,7 +126,7 @@ namespace tunnel typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const; bool SelectPeers (Path& path, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound); - static bool ValidatePeers (std::vector >& peers); + bool ValidatePeers (std::vector >& peers) const; private: From b8d21a1282cc00f4808cedbf3442b42eac820002 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 Apr 2023 07:46:50 -0400 Subject: [PATCH 0212/1160] create non-default port destination explicitly --- libi2pd_client/I2PTunnel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index db0d0c04..07cb0224 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -693,7 +693,7 @@ namespace client { if (!inport) inport = port; m_PortDestination = localDestination->GetStreamingDestination (inport); - if (!m_PortDestination) + if (!m_PortDestination || (inport && (m_PortDestination == localDestination->GetStreamingDestination ()))) // default destination m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip); } From 132557f941eded30e5e3a21df1c9c7cf5ab3d4ab Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 Apr 2023 13:33:20 -0400 Subject: [PATCH 0213/1160] don't return default destination if port is specified explicitly --- libi2pd/Destination.cpp | 6 ++++-- libi2pd_client/I2PTunnel.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 9e5fbe20..1a93f163 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1083,6 +1083,7 @@ namespace client { // streaming protocol auto dest = GetStreamingDestination (toPort); + if (!dest) dest = m_StreamingDestination; // if no destination on port use default if (dest) dest->HandleDataMessagePayload (buf, length); else @@ -1236,8 +1237,9 @@ namespace client if (it != m_StreamingDestinationsByPorts.end ()) return it->second; } - // if port is zero or not found, use default destination - return m_StreamingDestination; + else // if port is zero, use default destination + return m_StreamingDestination; + return nullptr; } void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 07cb0224..78634b7e 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -693,7 +693,7 @@ namespace client { if (!inport) inport = port; m_PortDestination = localDestination->GetStreamingDestination (inport); - if (!m_PortDestination || (inport && (m_PortDestination == localDestination->GetStreamingDestination ()))) // default destination + if (!m_PortDestination) // default destination m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip); } From e20acb93cfdb7880ad200fe55b6d5d58a07093a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 Apr 2023 15:28:15 -0400 Subject: [PATCH 0214/1160] don't lookup streaming destination for each message --- libi2pd/Destination.cpp | 16 +++++++++++----- libi2pd/Destination.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 1a93f163..7b878fbe 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -930,7 +930,7 @@ namespace client bool isPublic, const std::map * params): LeaseSetDestination (service, isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), - m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), + m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), m_LastPort (0), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(service) { @@ -1058,6 +1058,7 @@ namespace client //it.second->SetOwner (nullptr); } m_StreamingDestinationsByPorts.clear (); + m_LastStreamingDestination = nullptr; if (m_DatagramDestination) { delete m_DatagramDestination; @@ -1082,10 +1083,15 @@ namespace client case PROTOCOL_TYPE_STREAMING: { // streaming protocol - auto dest = GetStreamingDestination (toPort); - if (!dest) dest = m_StreamingDestination; // if no destination on port use default - if (dest) - dest->HandleDataMessagePayload (buf, length); + if (toPort != m_LastPort || !m_LastStreamingDestination) + { + m_LastStreamingDestination = GetStreamingDestination (toPort); + if (!m_LastStreamingDestination) + m_LastStreamingDestination = m_StreamingDestination; // if no destination on port use default + m_LastPort = toPort; + } + if (m_LastStreamingDestination) + m_LastStreamingDestination->HandleDataMessagePayload (buf, length); else LogPrint (eLogError, "Destination: Missing streaming destination"); } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 9e2d171f..96b20a54 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -297,6 +297,7 @@ namespace client bool m_IsStreamingAnswerPings; std::shared_ptr m_StreamingDestination; // default std::map > m_StreamingDestinationsByPorts; + std::shared_ptr m_LastStreamingDestination; uint16_t m_LastPort; // for server tunnels i2p::datagram::DatagramDestination * m_DatagramDestination; int m_RefCounter; // how many clients(tunnels) use this destination From cd5bfaabb5b209f3d7239568e5e2d975a1d9bc16 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 15 Apr 2023 22:16:31 -0400 Subject: [PATCH 0215/1160] mark and check unreachable ident hashes --- libi2pd/Transports.cpp | 21 +++++++++++++++------ libi2pd/Transports.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c2aeb964..940e17d8 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -458,8 +458,20 @@ namespace transport it->second.sessions.front ()->SendI2NPMessages (msgs); else { - if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES) + auto sz = it->second.delayedMessages.size (); + if (sz < MAX_NUM_DELAYED_MESSAGES) { + if (sz > CHECK_PROFILE_NUM_DELAYED_MESSAGES) + { + auto profile = i2p::data::GetRouterProfile (ident); + if (profile && profile->IsUnreachable ()) + { + LogPrint (eLogWarning, "Transports: Peer profile for ", ident.ToBase64 (), "reports unreachable. Dropped"); + std::unique_lock l(m_PeersMutex); + m_Peers.erase (it); + return; + } + } for (auto& it1: msgs) it->second.delayedMessages.push_back (it1); } @@ -775,11 +787,8 @@ namespace transport if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) { LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); - auto profile = i2p::data::GetRouterProfile(it->first); - if (profile) - { - profile->TunnelNonReplied(); - } + auto profile = i2p::data::GetRouterProfile (it->first); + if (profile) profile->Unreachable (); std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 1058d31b..a8f2a16a 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -106,6 +106,7 @@ namespace transport const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds const int PEER_TEST_INTERVAL = 71; // in minutes const int MAX_NUM_DELAYED_MESSAGES = 150; + const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after class Transports { public: From 527ee3b3c5435553e3172fdcfe44f8c941a7bf01 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 16 Apr 2023 08:18:41 -0400 Subject: [PATCH 0216/1160] check if ident is unrechable only once --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 940e17d8..fcdfc105 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -461,7 +461,7 @@ namespace transport auto sz = it->second.delayedMessages.size (); if (sz < MAX_NUM_DELAYED_MESSAGES) { - if (sz > CHECK_PROFILE_NUM_DELAYED_MESSAGES) + if (sz < CHECK_PROFILE_NUM_DELAYED_MESSAGES && sz + msgs.size () >= CHECK_PROFILE_NUM_DELAYED_MESSAGES) { auto profile = i2p::data::GetRouterProfile (ident); if (profile && profile->IsUnreachable ()) From b77ae0838859505182f99a80a8a12d575f49cb10 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Apr 2023 14:35:13 -0400 Subject: [PATCH 0217/1160] exclude previously non-reachable transports --- libi2pd/NetDb.cpp | 20 +++++++++++++++----- libi2pd/NetDb.hpp | 1 + libi2pd/RouterInfo.h | 1 + libi2pd/Transports.cpp | 11 +++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index c9c92b64..1f9797f2 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -409,19 +409,29 @@ namespace data void NetDb::SetUnreachable (const IdentHash& ident, bool unreachable) { - auto it = m_RouterInfos.find (ident); - if (it != m_RouterInfos.end ()) + auto r = FindRouter (ident); + if (r) { - it->second->SetUnreachable (unreachable); + r->SetUnreachable (unreachable); if (unreachable) { - auto profile = it->second->GetProfile (); + auto profile = r->GetProfile (); if (profile) profile->Unreachable (); } - } + } } + void NetDb::ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports) + { + auto r = FindRouter (ident); + if (r) + { + std::unique_lock l(m_RouterInfosMutex); + r->ExcludeReachableTransports (transports); + } + } + void NetDb::Reseed () { if (!m_Reseeder) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index d98d487e..b6dc8ce7 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -94,6 +94,7 @@ namespace data std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; std::shared_ptr GetRandomRouterInFamily (FamilyID fam) const; void SetUnreachable (const IdentHash& ident, bool unreachable); + void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports); void PostI2NPMsg (std::shared_ptr msg); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 070737e8..35737c9b 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -259,6 +259,7 @@ namespace data void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; bool IsUnreachable () const { return m_IsUnreachable; }; + void ExcludeReachableTransports (CompatibleTransports transports) { m_ReachableTransports &= ~transports; }; const uint8_t * GetBuffer () const { return m_Buffer ? m_Buffer->data () : nullptr; }; const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index fcdfc105..258ceca3 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -700,6 +700,17 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { + if (it->second.numAttempts > 1) + { + // exclude failed transports + i2p::data::RouterInfo::CompatibleTransports transports = 0; + int numExcluded = it->second.numAttempts - 1; + if (numExcluded > (int)it->second.priority.size ()) numExcluded = it->second.priority.size (); + for (int i = 0; i < numExcluded; i++) + transports |= it->second.priority[i]; + i2p::data::netdb.ExcludeReachableTransports (ident, transports); + } + it->second.numAttempts = 0; it->second.router = nullptr; // we don't need RouterInfo after successive connect bool sendDatabaseStore = true; if (it->second.delayedMessages.size () > 0) From 7a12b5ca4beb13dbc4f8a6c7148f94f927eb47ed Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Apr 2023 19:25:15 -0400 Subject: [PATCH 0218/1160] handle incomplete HTTP header lines --- libi2pd_client/I2PTunnel.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 78634b7e..23a3ad52 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -346,7 +346,12 @@ namespace client } } else + { + // insert incomplete line back + m_InHeader.clear (); + m_InHeader << line; break; + } } if (endOfHeader) @@ -409,7 +414,7 @@ namespace client matched = true; break; } - if (matched) break; + if (matched) continue; // replace some headers if (!m_Host.empty () && boost::iequals (line.substr (0, 5), "Host:")) @@ -428,7 +433,12 @@ namespace client } } else + { + // insert incomplete line back + m_InHeader.clear (); + m_InHeader << line; break; + } } if (endOfHeader) @@ -496,7 +506,12 @@ namespace client } } else + { + // insert incomplete line back + m_InHeader.clear (); + m_InHeader << line; break; + } } if (endOfHeader) From 6206616347f36f099c5b146cac6febfa1cbe7d67 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Apr 2023 20:21:22 -0400 Subject: [PATCH 0219/1160] don't set unreachable twice --- libi2pd/Transports.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 258ceca3..304081ba 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -466,7 +466,7 @@ namespace transport auto profile = i2p::data::GetRouterProfile (ident); if (profile && profile->IsUnreachable ()) { - LogPrint (eLogWarning, "Transports: Peer profile for ", ident.ToBase64 (), "reports unreachable. Dropped"); + LogPrint (eLogWarning, "Transports: Peer profile for ", ident.ToBase64 (), " reports unreachable. Dropped"); std::unique_lock l(m_PeersMutex); m_Peers.erase (it); return; @@ -798,8 +798,12 @@ namespace transport if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) { LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); - auto profile = i2p::data::GetRouterProfile (it->first); - if (profile) profile->Unreachable (); + if (!it->second.router) + { + // if router for ident not found mark it unreachable + auto profile = i2p::data::GetRouterProfile (it->first); + if (profile) profile->Unreachable (); + } std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } From c22fc7537052260b11f9f1c3015b0600cc846975 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Apr 2023 19:48:09 -0400 Subject: [PATCH 0220/1160] set router properties from incoming connections --- libi2pd/Transports.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 304081ba..e66a831c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -729,7 +729,7 @@ namespace transport session->SendI2NPMessages (it->second.delayedMessages); it->second.delayedMessages.clear (); } - else // incoming connection + else // incoming connection or peer test { if(RoutesRestricted() && ! IsRestrictedPeer(ident)) { // not trusted @@ -737,11 +737,14 @@ namespace transport session->Done(); return; } - session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore + if (!session->IsOutgoing ()) // incoming + session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore + auto r = i2p::data::netdb.FindRouter (ident); // router should be in netdb after SessionConfirmed auto ts = i2p::util::GetSecondsSinceEpoch (); std::unique_lock l(m_PeersMutex); - auto it = m_Peers.insert (std::make_pair (ident, Peer{ nullptr, ts })).first; + auto it = m_Peers.insert (std::make_pair (ident, Peer{ r, ts })).first; it->second.sessions.push_back (session); + it->second.router = nullptr; } }); } From dc265367dcb33c54480389972ea08b5afb9fdabe Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Apr 2023 14:23:41 -0400 Subject: [PATCH 0221/1160] drop unexpected I2NP messages --- libi2pd/I2NPProtocol.cpp | 24 +++++++++++++++++++----- libi2pd/Transports.cpp | 4 ++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5303edbf..1a5b1cde 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -785,10 +785,12 @@ namespace i2p switch (typeID) { case eI2NPTunnelData: - i2p::tunnel::tunnels.PostTunnelData (msg); + if (!msg->from) + i2p::tunnel::tunnels.PostTunnelData (msg); break; case eI2NPTunnelGateway: - i2p::tunnel::tunnels.PostTunnelData (msg); + if (!msg->from) + i2p::tunnel::tunnels.PostTunnelData (msg); break; case eI2NPGarlic: { @@ -799,11 +801,19 @@ namespace i2p break; } case eI2NPDatabaseStore: + // forward to netDb if came directly or through exploratory tunnel as response to our request + if (!msg->from || !msg->from->GetTunnelPool () || msg->from->GetTunnelPool ()->IsExploratory ()) + i2p::data::netdb.PostI2NPMsg (msg); + break; case eI2NPDatabaseSearchReply: - case eI2NPDatabaseLookup: // forward to netDb i2p::data::netdb.PostI2NPMsg (msg); break; + case eI2NPDatabaseLookup: + // forward to netDb if floodfill and came directly + if (!msg->from && i2p::context.IsFloodfill ()) + i2p::data::netdb.PostI2NPMsg (msg); + break; case eI2NPDeliveryStatus: { if (msg->from && msg->from->GetTunnelPool ()) @@ -813,10 +823,14 @@ namespace i2p break; } case eI2NPVariableTunnelBuild: - case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: - case eI2NPTunnelBuildReply: case eI2NPShortTunnelBuild: + // forward to tunnel thread + if (!msg->from) + i2p::tunnel::tunnels.PostTunnelData (msg); + break; + case eI2NPVariableTunnelBuildReply: + case eI2NPTunnelBuildReply: case eI2NPShortTunnelBuildReply: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index e66a831c..c6e9f372 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -801,12 +801,12 @@ namespace transport if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) { LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); - if (!it->second.router) + /* if (!it->second.router) { // if router for ident not found mark it unreachable auto profile = i2p::data::GetRouterProfile (it->first); if (profile) profile->Unreachable (); - } + } */ std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } From 5769a41208dc696fb64ea519bfbceb9c2b7e46ff Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Apr 2023 14:54:54 -0400 Subject: [PATCH 0222/1160] use unordered_map for LeaseSets --- libi2pd/Destination.cpp | 11 ----------- libi2pd/Destination.h | 5 +++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 7b878fbe..6bcedb4e 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -262,17 +262,6 @@ namespace client return nullptr; } } - else - { - auto ls = i2p::data::netdb.FindLeaseSet (ident); - if (ls && !ls->IsExpired ()) - { - ls->PopulateLeases (); // since we don't store them in netdb - std::lock_guard _lock(m_RemoteLeaseSetsMutex); - m_RemoteLeaseSets[ident] = ls; - return ls; - } - } return nullptr; } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 96b20a54..76508e49 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -184,8 +185,8 @@ namespace client boost::asio::io_service& m_Service; mutable std::mutex m_RemoteLeaseSetsMutex; - std::map > m_RemoteLeaseSets; - std::map > m_LeaseSetRequests; + std::unordered_map > m_RemoteLeaseSets; + std::unordered_map > m_LeaseSetRequests; std::shared_ptr m_Pool; std::mutex m_LeaseSetMutex; From c34df2090cc2921736d0667bb635a53183844bbe Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Apr 2023 21:31:14 -0400 Subject: [PATCH 0223/1160] don't reply to DatabaseStore messages extracted from transit --- libi2pd/Tunnel.cpp | 12 +++++++++--- libi2pd/TunnelEndpoint.cpp | 14 +++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 05359390..76bdb4c7 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -586,10 +586,16 @@ namespace tunnel auto typeID = msg->GetTypeID (); LogPrint (eLogDebug, "Tunnel: Gateway of ", (int) len, " bytes for tunnel ", tunnel->GetTunnelID (), ", msg type ", (int)typeID); - if (IsRouterInfoMsg (msg) || typeID == eI2NPDatabaseSearchReply) - // transit DatabaseStore my contain new/updated RI - // or DatabaseSearchReply with new routers + if (typeID == eI2NPDatabaseSearchReply) + // DatabaseSearchReply with new routers i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg)); + else if (IsRouterInfoMsg (msg)) + { + // transit DatabaseStore might contain new/updated RI + auto m = CopyI2NPMessage (msg); + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // no reply + i2p::data::netdb.PostI2NPMsg (m); + } tunnel->SendTunnelDataMsg (msg); } diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 7d3b3cbe..f2d8a085 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -324,9 +324,17 @@ namespace tunnel uint8_t typeID = msg.data->GetTypeID (); LogPrint (eLogDebug, "TunnelMessage: Handle fragment of ", msg.data->GetLength (), " bytes, msg type ", (int)typeID); // catch RI or reply with new list of routers - if ((IsRouterInfoMsg (msg.data) || typeID == eI2NPDatabaseSearchReply) && - !m_IsInbound && msg.deliveryType != eDeliveryTypeLocal) - i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg.data)); + if (!m_IsInbound && msg.deliveryType != eDeliveryTypeLocal) + { + if (typeID == eI2NPDatabaseSearchReply) + i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg.data)); + else if (IsRouterInfoMsg (msg.data)) + { + auto m = CopyI2NPMessage (msg.data); + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // no reply + i2p::data::netdb.PostI2NPMsg (m); + } + } switch (msg.deliveryType) { From 786c27c8eca566bdbd57c429f1c1ad57a2147108 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Apr 2023 22:27:55 -0400 Subject: [PATCH 0224/1160] publish encrypted RouterInfo --- libi2pd/RouterContext.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index d6c3c57b..3e7d7a2c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1348,8 +1348,12 @@ namespace i2p auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (inbound && outbound) - outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound)); + { + // encrypt for floodfill + auto msg = CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound); + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, + i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); + } else LogPrint (eLogInfo, "Router: Can't publish our RouterInfo. No tunnles. Try again in ", ROUTER_INFO_CONFIRMATION_TIMEOUT, " seconds"); } From f21e1c75d571d52a1a880116d3c3f8e1501c9d59 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 Apr 2023 15:31:24 -0400 Subject: [PATCH 0225/1160] check tagset for null --- libi2pd/Garlic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index c351f6d6..3f885186 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -588,7 +588,7 @@ namespace garlic auto it = m_ECIESx25519Tags.find (tag); if (it != m_ECIESx25519Tags.end ()) { - if (it->second.tagset->HandleNextMessage (buf, len, it->second.index)) + if (it->second.tagset && it->second.tagset->HandleNextMessage (buf, len, it->second.index)) m_LastTagset = it->second.tagset; else LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message"); From edfcd23b01c04b6b7cb1b29fd7cfe26acd13002c Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 24 Apr 2023 14:01:21 +0300 Subject: [PATCH 0226/1160] [webconsole] added a button to prematurely release a leaseset Signed-off-by: r4sas --- daemon/HTTPServer.cpp | 52 +++++++++++++++++++++++++++++++++++++++---- libi2pd/LeaseSet.h | 3 +++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index dceee06a..f9b034ae 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -87,6 +87,7 @@ namespace http { const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css"; + const char HTTP_COMMAND_EXPIRELEASE[] = "expirelease"; static std::string ConvertTime (uint64_t time) { @@ -434,12 +435,11 @@ namespace http { if (dest->IsPublic() && token && !dest->IsEncryptedLeaseSet ()) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - auto base32 = dest->GetIdentHash ().ToBase32 (); s << "
\r\n\r\n
\r\n" "\r\n" " \r\n" " \r\n" - " \r\n" + " GetIdentHash ().ToBase32 () << "\">\r\n" " " << tr("Domain") << ":\r\n\r\n" " \r\n" "\r\n" << tr("Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "\r\n
\r\n
\r\n
\r\n"; @@ -448,9 +448,23 @@ namespace http { if (dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n
\r\n"; + << "\r\n\r\n
\r\n" + << "
"<< tr("Address") << "" << tr("Type") << "" << tr("EncType") << "
" + << "" + << "" // LeaseSet expiration button column + << "" + << "" + << ""; for(auto& it: dest->GetLeaseSets ()) - s << "\r\n"; + { + s << "" + << "" + << "" + << "" + << "" + << "\r\n"; + } s << "
" << tr("Address") << " " << tr("Type") << "" << tr("EncType") << "
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n
\r\n
\r\n
\r\n"; } else s << "" << tr("LeaseSets") << ": 0
\r\n
\r\n"; @@ -1312,6 +1326,36 @@ namespace http { res.add_header("Refresh", redirect.c_str()); return; } + else if (cmd == HTTP_COMMAND_EXPIRELEASE) + { + std::string b32 = params["b32"]; + std::string lease = params["lease"]; + + i2p::data::IdentHash ident, leaseident; + ident.FromBase32 (b32); + leaseident.FromBase32 (lease); + auto dest = i2p::client::context.FindLocalDestination (ident); + + if (dest) + { + auto leaseset = dest->FindLeaseSet (leaseident); + if (leaseset) + { + leaseset->ExpireLease (); + s << "" << tr("SUCCESS") << ": " << tr("LeaseSet expiration time updated") << "
\r\n
\r\n"; + } + else + s << "" << tr("ERROR") << ": " << tr("LeaseSet is not found or already expired") << "
\r\n
\r\n"; + } + else + s << "" << tr("ERROR") << ": " << tr("Destination not found") << "
\r\n
\r\n"; + + s << "" << tr("Return to destination page") << "
\r\n"; + s << "

" << tr("You will be redirected in %d seconds", COMMAND_REDIRECT_TIMEOUT) << ""; + redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=local_destination&b32=" + b32; + res.add_header("Refresh", redirect.c_str()); + return; + } else if (cmd == HTTP_COMMAND_LIMITTRANSIT) { uint32_t limit = std::stoul(params["limit"], nullptr); diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 566c4655..4b1311a5 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -96,6 +96,9 @@ namespace data void Encrypt (const uint8_t * data, uint8_t * encrypted) const; bool IsDestination () const { return true; }; + // used in webconsole + void ExpireLease () { m_ExpirationTime = i2p::util::GetSecondsSinceEpoch (); }; + protected: void UpdateLeasesBegin (); From 76adac31c3b8f717622e3b2d00bbc6cff90b1aa9 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Apr 2023 19:25:26 -0400 Subject: [PATCH 0227/1160] enrcrypt lookup if being sent through a tunnel --- libi2pd/NetDb.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 1f9797f2..1abe9748 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -722,7 +722,11 @@ namespace data auto outbound = pool ? pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; auto inbound = pool ? pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (outbound && inbound) - outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); + { + auto msg = dest->CreateRequestMessage (floodfill, inbound); + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, + i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); + } else { LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); From 0ce15ffc91971a21bcf73adaf7c2f906a097a38f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 26 Apr 2023 21:34:22 -0400 Subject: [PATCH 0228/1160] check for incomplete HTTP header --- libi2pd_client/I2PTunnel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 23a3ad52..d1006f26 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -397,7 +397,8 @@ namespace client while (!endOfHeader) { std::getline(m_InHeader, line); - if (!m_InHeader.fail ()) + if (m_InHeader.fail ()) break; + if (!m_InHeader.eof ()) { if (line == "\r") endOfHeader = true; else @@ -485,7 +486,8 @@ namespace client while (!endOfHeader) { std::getline(m_InHeader, line); - if (!m_InHeader.fail ()) + if (m_InHeader.fail ()) break; + if (!m_InHeader.eof ()) { if (line == "\r") endOfHeader = true; else From ead6a6dca35c7a4036bc775f1bfe215f6a866583 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 27 Apr 2023 21:37:30 -0400 Subject: [PATCH 0229/1160] correct parsing of caught RouterInfo at IBGW and OBEP --- libi2pd/NetDb.cpp | 25 ++++++++++++++----------- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelEndpoint.cpp | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 1abe9748..a271d459 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -791,20 +791,23 @@ namespace data LogPrint (eLogError, "NetDb: Database store msg with reply token is too short ", len, ". Dropped"); return; } - auto deliveryStatus = CreateDeliveryStatusMsg (replyToken); uint32_t tunnelID = bufbe32toh (buf + offset); offset += 4; - if (!tunnelID) // send response directly - transports.SendMessage (buf + offset, deliveryStatus); - else - { - auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; - if (outbound) - outbound->SendTunnelDataMsgTo (buf + offset, tunnelID, deliveryStatus); + if (replyToken != 0xFFFFFFFFU) // if not caught on OBEP or IBGW + { + auto deliveryStatus = CreateDeliveryStatusMsg (replyToken); + if (!tunnelID) // send response directly + transports.SendMessage (buf + offset, deliveryStatus); else - LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); - } + { + auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; + if (outbound) + outbound->SendTunnelDataMsgTo (buf + offset, tunnelID, deliveryStatus); + else + LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); + } + } offset += 32; } // we must send reply back before this check diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 76bdb4c7..bf1bad46 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -593,7 +593,7 @@ namespace tunnel { // transit DatabaseStore might contain new/updated RI auto m = CopyI2NPMessage (msg); - memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // no reply + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply i2p::data::netdb.PostI2NPMsg (m); } tunnel->SendTunnelDataMsg (msg); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index f2d8a085..fe90da60 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -331,7 +331,7 @@ namespace tunnel else if (IsRouterInfoMsg (msg.data)) { auto m = CopyI2NPMessage (msg.data); - memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // no reply + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply i2p::data::netdb.PostI2NPMsg (m); } } From 2af4a2b58dcf39f26bcf775d1494e3ec350e1eaa Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Apr 2023 08:01:02 -0400 Subject: [PATCH 0230/1160] override reply token only if non-zero --- libi2pd/Tunnel.cpp | 3 ++- libi2pd/TunnelEndpoint.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index bf1bad46..249f0a31 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -593,7 +593,8 @@ namespace tunnel { // transit DatabaseStore might contain new/updated RI auto m = CopyI2NPMessage (msg); - memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply + if (bufbe32toh (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET)) + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply i2p::data::netdb.PostI2NPMsg (m); } tunnel->SendTunnelDataMsg (msg); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index fe90da60..b2a0c837 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -331,7 +331,8 @@ namespace tunnel else if (IsRouterInfoMsg (msg.data)) { auto m = CopyI2NPMessage (msg.data); - memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply + if (bufbe32toh (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET)) + memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply i2p::data::netdb.PostI2NPMsg (m); } } From 7c535159bc442b2ad539c4eb22eda00b018cc47d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 30 Apr 2023 20:05:35 -0400 Subject: [PATCH 0231/1160] static keys table --- libi2pd/NTCP2.cpp | 1 + libi2pd/Profiling.cpp | 28 ++++++++++++++++++++++++++++ libi2pd/Profiling.h | 4 ++++ libi2pd/SSU2Session.cpp | 1 + libi2pd/Transports.cpp | 15 +++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 91bc9b3d..aceef0f5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -714,6 +714,7 @@ namespace transport Terminate (); return; } + i2p::data::UpdateStaticKey (addr->s, ri.GetIdentHash ()); // good static key i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 311d1c86..3144bd9c 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -301,5 +301,33 @@ namespace data } } } + +// static keys + + struct StaticKeyProfile + { + i2p::data::IdentHash ident; + boost::posix_time::ptime lastUpdateTime; + }; + //static i2p::fs::HashedStorage g_StaticKeysProfilesStorage("statickeysProfiles", "s", "statickey-", "txt"); + static std::unordered_map, std::shared_ptr > g_StaticKeysProfiles; + static std::mutex g_StaticKeysProfilesMutex; + + bool CheckStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident) + { + std::unique_lock l(g_StaticKeysProfilesMutex); + auto it = g_StaticKeysProfiles.find (staticKey); + if (it != g_StaticKeysProfiles.end ()) + return it->second->ident == ident; + return true; + } + + void UpdateStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident) + { + std::unique_lock l(g_StaticKeysProfilesMutex); + auto res = g_StaticKeysProfiles.emplace (staticKey, std::make_shared(StaticKeyProfile{ident, GetTime ()})); + if (!res.second) + res.first->second->lastUpdateTime = GetTime (); + } } } diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 752d6190..2f60f961 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -85,6 +85,10 @@ namespace data void DeleteObsoleteProfiles (); void SaveProfiles (); void PersistProfiles (); + + // static keys + bool CheckStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident); + void UpdateStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident); } } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 47d59ea4..46319bd9 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1073,6 +1073,7 @@ namespace transport return false; } SetRemoteIdentity (ri->GetRouterIdentity ()); + i2p::data::UpdateStaticKey (m_Address->s, ri->GetIdentHash ()); // good static key AdjustMaxPayloadSize (); m_Server.AddSessionByRouterHash (shared_from_this ()); // we know remote router now m_RemoteTransports = ri->GetCompatibleTransports (false); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c6e9f372..5693719c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -507,6 +507,11 @@ namespace transport peer.router->GetPublishedNTCP2V6Address () : peer.router->GetPublishedNTCP2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; + if (address && !i2p::data::CheckStaticKey (address->s, ident)) + { + LogPrint (eLogWarning, "Transports: NTCP2 address static key router mismatch ", ident.ToBase64 ()); + address = nullptr; + } if (address) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); @@ -526,6 +531,11 @@ namespace transport peer.router->GetSSU2V6Address () : peer.router->GetSSU2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; + if (address && !i2p::data::CheckStaticKey (address->s, ident)) + { + LogPrint (eLogWarning, "Transports: SSU2 address static key router mismatch ", ident.ToBase64 ()); + address = nullptr; + } if (address && address->IsReachableSSU ()) { if (m_SSU2Server->CreateSession (peer.router, address)) @@ -537,6 +547,11 @@ namespace transport { if (!m_NTCP2Server) continue; auto address = peer.router->GetYggdrasilAddress (); + if (address && !i2p::data::CheckStaticKey (address->s, ident)) + { + LogPrint (eLogWarning, "Transports: Yggdrasil address static key router mismatch ", ident.ToBase64 ()); + address = nullptr; + } if (address) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); From ec2297ed9dd87c1690ff0bce3565fbeee173b35f Mon Sep 17 00:00:00 2001 From: weko Date: Mon, 1 May 2023 19:28:32 +0000 Subject: [PATCH 0232/1160] Recognize invalid static key --- libi2pd/RouterInfo.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index c18e0521..9334ed60 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -362,6 +362,10 @@ namespace data } if (!s) return; } + + if (!i2p::data::CheckStaticKey(address->s, (*m_RouterIdentity).GetIdentHash())) + continue; // skip address + if (address->transportStyle == eTransportNTCP2) { if (isStaticKey) From dab34e90519062a0cc91e0ea5a0433e131d6acbd Mon Sep 17 00:00:00 2001 From: weko Date: Mon, 1 May 2023 20:08:08 +0000 Subject: [PATCH 0233/1160] get indent hash directly --- libi2pd/RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9334ed60..f72c3322 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -363,7 +363,7 @@ namespace data if (!s) return; } - if (!i2p::data::CheckStaticKey(address->s, (*m_RouterIdentity).GetIdentHash())) + if (!i2p::data::CheckStaticKey(address->s, GetIdentHash())) continue; // skip address if (address->transportStyle == eTransportNTCP2) From 7418f11651c9673b98bf5cc0b27301de08094a10 Mon Sep 17 00:00:00 2001 From: contextswap Date: Wed, 3 May 2023 19:04:16 +0900 Subject: [PATCH 0234/1160] limit aesni inline asm to x86 Signed-off-by: contextswap --- libi2pd/Crypto.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index c9670f6c..4a4d5ef4 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -555,7 +555,7 @@ namespace crypto } // AES -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) #define KeyExpansion256(round0,round1) \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \ "movaps %%xmm1, %%xmm4 \n" \ @@ -580,7 +580,7 @@ namespace crypto "movaps %%xmm3, "#round1"(%[sched]) \n" #endif -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) void ECBCryptoAESNI::ExpandKey (const AESKey& key) { __asm__ @@ -621,7 +621,7 @@ namespace crypto #endif -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) #define EncryptAES256(sched) \ "pxor (%["#sched"]), %%xmm0 \n" \ "aesenc 16(%["#sched"]), %%xmm0 \n" \ @@ -642,7 +642,7 @@ namespace crypto void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -660,7 +660,7 @@ namespace crypto } } -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) #define DecryptAES256(sched) \ "pxor 224(%["#sched"]), %%xmm0 \n" \ "aesdec 208(%["#sched"]), %%xmm0 \n" \ @@ -681,7 +681,7 @@ namespace crypto void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -699,7 +699,7 @@ namespace crypto } } -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) #define CallAESIMC(offset) \ "movaps "#offset"(%[shed]), %%xmm0 \n" \ "aesimc %%xmm0, %%xmm0 \n" \ @@ -708,7 +708,7 @@ namespace crypto void ECBEncryption::SetKey (const AESKey& key) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { ExpandKey (key); @@ -722,7 +722,7 @@ namespace crypto void ECBDecryption::SetKey (const AESKey& key) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { ExpandKey (key); // expand encryption key first @@ -754,7 +754,7 @@ namespace crypto void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -799,7 +799,7 @@ namespace crypto void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -823,7 +823,7 @@ namespace crypto void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -869,7 +869,7 @@ namespace crypto void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -893,7 +893,7 @@ namespace crypto void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -934,7 +934,7 @@ namespace crypto void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ +#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ From 12d0abda55d19ce87e6eedbb402961ba8b1c7fb6 Mon Sep 17 00:00:00 2001 From: contextswap Date: Wed, 3 May 2023 19:10:16 +0900 Subject: [PATCH 0235/1160] [ Signed-off-by: contextswap --- libi2pd/Crypto.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 4a4d5ef4..4a78f2b1 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -555,7 +555,7 @@ namespace crypto } // AES -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) #define KeyExpansion256(round0,round1) \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \ "movaps %%xmm1, %%xmm4 \n" \ @@ -580,7 +580,7 @@ namespace crypto "movaps %%xmm3, "#round1"(%[sched]) \n" #endif -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) void ECBCryptoAESNI::ExpandKey (const AESKey& key) { __asm__ @@ -621,7 +621,7 @@ namespace crypto #endif -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) #define EncryptAES256(sched) \ "pxor (%["#sched"]), %%xmm0 \n" \ "aesenc 16(%["#sched"]), %%xmm0 \n" \ @@ -642,7 +642,7 @@ namespace crypto void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -660,7 +660,7 @@ namespace crypto } } -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) #define DecryptAES256(sched) \ "pxor 224(%["#sched"]), %%xmm0 \n" \ "aesdec 208(%["#sched"]), %%xmm0 \n" \ @@ -681,7 +681,7 @@ namespace crypto void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -699,7 +699,7 @@ namespace crypto } } -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) #define CallAESIMC(offset) \ "movaps "#offset"(%[shed]), %%xmm0 \n" \ "aesimc %%xmm0, %%xmm0 \n" \ @@ -708,7 +708,7 @@ namespace crypto void ECBEncryption::SetKey (const AESKey& key) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { ExpandKey (key); @@ -722,7 +722,7 @@ namespace crypto void ECBDecryption::SetKey (const AESKey& key) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { ExpandKey (key); // expand encryption key first @@ -754,7 +754,7 @@ namespace crypto void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -799,7 +799,7 @@ namespace crypto void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -823,7 +823,7 @@ namespace crypto void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -869,7 +869,7 @@ namespace crypto void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -893,7 +893,7 @@ namespace crypto void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ @@ -934,7 +934,7 @@ namespace crypto void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#ifdef __AES__ && (defined(__x86_64__) || defined(__i386__)) +#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) if(i2p::cpu::aesni) { __asm__ From 4ce2ef1d8381c2d93ebcdd77e8017123ae3a23c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 May 2023 07:43:28 -0400 Subject: [PATCH 0236/1160] make router unreachable if AEAD fails in SessionCreated --- libi2pd/NTCP2.cpp | 4 ++++ libi2pd/NetDb.cpp | 2 +- libi2pd/SSU2Session.cpp | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index aceef0f5..3f80bcd2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -566,7 +566,11 @@ namespace transport SendSessionConfirmed (); } else + { + if (GetRemoteIdentity ()) + i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key Terminate (); + } } } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index a271d459..d3346236 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -607,7 +607,7 @@ namespace data uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); auto uptime = i2p::context.GetUptime (); - bool isLowRate = i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () < NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE; + bool isLowRate = false; // i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () < NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE; // routers don't expire if less than 90 or uptime is less than 1 hour bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes if (checkForExpiration && uptime > 3600) // 1 hour diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 46319bd9..9bfa4ce0 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -809,6 +809,8 @@ namespace transport m_NoiseState->m_CK + 32, nonce, decryptedPayload.data (), decryptedPayload.size (), false)) { LogPrint (eLogWarning, "SSU2: SessionCreated AEAD verification failed "); + if (GetRemoteIdentity ()) + i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key return false; } m_NoiseState->MixHash (payload, len - 64); // h = SHA256(h || encrypted payload from SessionCreated) for SessionConfirmed From 3b13a3f2a1f177f1caf0614c574c5d4c3936df39 Mon Sep 17 00:00:00 2001 From: SidorKozlov Date: Wed, 3 May 2023 15:59:35 +0200 Subject: [PATCH 0237/1160] Configurable minimum successful tunnels --- libi2pd/Config.cpp | 1 + libi2pd/NetDb.cpp | 56 ++++++++++++++++++++++++---------------------- libi2pd/NetDb.hpp | 1 - libi2pd/Tunnel.h | 9 ++++---- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 39af997b..6b515ef9 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -78,6 +78,7 @@ namespace config { ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.openfiles", value()->default_value(0), "Maximum number of open files (0 - use system default)") ("limits.transittunnels", value()->default_value(5000), "Maximum active transit tunnels (default:5000)") + ("limits.zombies", value()->default_value(0), "Minimum percentage of successfully created tunnels under which tunnel cleanup is paused (default [%]: 0.00)") ("limits.ntcpsoft", value()->default_value(0), "Ignored") ("limits.ntcphard", value()->default_value(0), "Ignored") ("limits.ntcpthreads", value()->default_value(1), "Ignored") diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index d3346236..aea97adc 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -245,19 +245,19 @@ namespace data updated = false; m_Requests.RequestComplete (ident, r); return r; - } + } if (r->IsUnreachable ()) { // delete router as invalid after update m_RouterInfos.erase (ident); if (wasFloodfill) - { + { std::unique_lock l(m_FloodfillsMutex); m_Floodfills.Remove (r->GetIdentHash ()); - } + } m_Requests.RequestComplete (ident, nullptr); - return nullptr; - } + return nullptr; + } } LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64()); if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated @@ -419,7 +419,7 @@ namespace data if (profile) profile->Unreachable (); } - } + } } void NetDb::ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports) @@ -429,9 +429,9 @@ namespace data { std::unique_lock l(m_RouterInfosMutex); r->ExcludeReachableTransports (transports); - } - } - + } + } + void NetDb::Reseed () { if (!m_Reseeder) @@ -607,7 +607,9 @@ namespace data uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); auto uptime = i2p::context.GetUptime (); - bool isLowRate = false; // i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () < NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE; + double minTunnelCreationSuccessRate; + i2p::config::GetOption("limits.zombies", minTunnelCreationSuccessRate); + bool isLowRate = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < minTunnelCreationSuccessRate; // routers don't expire if less than 90 or uptime is less than 1 hour bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes if (checkForExpiration && uptime > 3600) // 1 hour @@ -622,12 +624,12 @@ namespace data if (it.second->IsUpdated ()) { if (it.second->GetBuffer ()) - { + { // we have something to save it.second->SaveToFile (m_Storage.Path(ident)); it.second->SetUnreachable (false); it.second->DeleteBuffer (); - } + } it.second->SetUpdated (false); updatedCount++; continue; @@ -639,7 +641,7 @@ namespace data (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) it.second->SetUnreachable (false); if (!it.second->IsUnreachable ()) - { + { // find & mark expired routers if (!it.second->GetCompatibleTransports (true)) // non reachable by any transport it.second->SetUnreachable (true); @@ -652,7 +654,7 @@ namespace data } if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ())) it.second->SetUnreachable (false); // don't expire connected router - } + } if (it.second->IsUnreachable ()) { @@ -667,7 +669,7 @@ namespace data m_RouterInfoBuffersPool.CleanUpMt (); m_RouterInfoAddressesPool.CleanUpMt (); m_RouterInfoAddressVectorsPool.CleanUpMt (); - m_IdentitiesPool.CleanUpMt (); + m_IdentitiesPool.CleanUpMt (); if (updatedCount > 0) LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers"); @@ -682,10 +684,10 @@ namespace data if (it->second->IsUnreachable ()) it = m_RouterInfos.erase (it); else - { + { it->second->DropProfile (); it++; - } + } } } // clean up expired floodfills or not floodfills anymore @@ -724,9 +726,9 @@ namespace data if (outbound && inbound) { auto msg = dest->CreateRequestMessage (floodfill, inbound); - outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, + outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); - } + } else { LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); @@ -794,7 +796,7 @@ namespace data uint32_t tunnelID = bufbe32toh (buf + offset); offset += 4; if (replyToken != 0xFFFFFFFFU) // if not caught on OBEP or IBGW - { + { auto deliveryStatus = CreateDeliveryStatusMsg (replyToken); if (!tunnelID) // send response directly transports.SendMessage (buf + offset, deliveryStatus); @@ -807,7 +809,7 @@ namespace data else LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); } - } + } offset += 32; } // we must send reply back before this check @@ -1315,16 +1317,16 @@ namespace data return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && !excluded.count (r->GetIdentHash ()); }); - } + } if (v.empty ()) return res; - + XORMetric ourMetric; if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); for (auto& it: v) { if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break; res.push_back (it->GetIdentHash ()); - } + } return res; } @@ -1367,10 +1369,10 @@ namespace data std::unique_lock l(m_RouterInfosMutex); for (auto& it: m_RouterInfos) it.second->UpdateIntroducers (ts); - } + } SaveUpdated (); - } - + } + void NetDb::ManageLeaseSets () { auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index b6dc8ce7..0222de0d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -38,7 +38,6 @@ namespace data { const int NETDB_MIN_ROUTERS = 90; const int NETDB_MIN_FLOODFILLS = 5; - const int NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE = 8; // in percents const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 5810a7a8..e6e3c3a5 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -45,7 +45,7 @@ namespace tunnel const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds - + 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 @@ -232,8 +232,8 @@ namespace tunnel void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; - bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; }; - + bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; }; + private: template @@ -292,7 +292,7 @@ namespace tunnel i2p::util::Queue > m_Queue; i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; - uint16_t m_MaxNumTransitTunnels; + uint16_t m_MaxNumTransitTunnels; // count of tunnels for total TCSR algorithm int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; @@ -311,6 +311,7 @@ namespace tunnel int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents + double GetPreciseTunnelCreationSuccessRate () const { return m_TunnelCreationSuccessRate * 100; } // in percents int GetTotalTunnelCreationSuccessRate () const // in percents { int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations; From 1bd6390f7801addfa9e4d2a80c864afa8c9e0b03 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 May 2023 08:20:38 -0400 Subject: [PATCH 0238/1160] check if s is x25519 public key --- libi2pd/RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index f72c3322..7f8abec3 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -363,7 +363,7 @@ namespace data if (!s) return; } - if (!i2p::data::CheckStaticKey(address->s, GetIdentHash())) + if ((address->s[31] & 0x80) || !i2p::data::CheckStaticKey(address->s, GetIdentHash())) continue; // skip address if (address->transportStyle == eTransportNTCP2) From c1168c2aa0f3dec34aa2a1c35d9bf45e0d14443e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 May 2023 09:39:37 -0400 Subject: [PATCH 0239/1160] don't catch RouterInfo at OBEP --- libi2pd/TunnelEndpoint.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index b2a0c837..3dc0dc07 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -323,20 +323,7 @@ namespace tunnel } uint8_t typeID = msg.data->GetTypeID (); LogPrint (eLogDebug, "TunnelMessage: Handle fragment of ", msg.data->GetLength (), " bytes, msg type ", (int)typeID); - // catch RI or reply with new list of routers - if (!m_IsInbound && msg.deliveryType != eDeliveryTypeLocal) - { - if (typeID == eI2NPDatabaseSearchReply) - i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg.data)); - else if (IsRouterInfoMsg (msg.data)) - { - auto m = CopyI2NPMessage (msg.data); - if (bufbe32toh (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET)) - memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply - i2p::data::netdb.PostI2NPMsg (m); - } - } - + switch (msg.deliveryType) { case eDeliveryTypeLocal: From 2f74e670a5948c6318c685d62fed2fcc9b53ed46 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 May 2023 15:32:19 -0400 Subject: [PATCH 0240/1160] invalidate routers with incorrect family signature --- libi2pd/RouterInfo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 7f8abec3..0cf5a0c5 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -487,7 +487,10 @@ namespace data if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value)) m_FamilyID = netdb.GetFamilies ().GetFamilyID (family); else + { LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed"); + SetUnreachable (true); + } } if (!s) return; From b6de474fdafbfffe020852d4db95a1aaf81885f8 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 May 2023 16:14:54 -0400 Subject: [PATCH 0241/1160] don't include unconfirmed floodfill to the list if we have enough floodfills already --- libi2pd/NTCP2.cpp | 1 + libi2pd/NetDb.cpp | 6 ++++-- libi2pd/NetDb.hpp | 1 + libi2pd/Profiling.cpp | 10 +++++++++- libi2pd/Profiling.h | 6 +++++- libi2pd/SSU2Session.cpp | 1 + 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 3f80bcd2..be584eb1 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -718,6 +718,7 @@ namespace transport Terminate (); return; } + ri.GetProfile ()->Connected (); i2p::data::UpdateStaticKey (addr->s, ri.GetIdentHash ()); // good static key i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index aea97adc..3575b052 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -290,8 +290,10 @@ namespace data if (inserted) { LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); - if (r->IsFloodfill () && r->IsEligibleFloodfill ()) - { + if (r->IsFloodfill () && r->IsEligibleFloodfill () && + (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || + r->GetProfile ()->IsReal ())) // don't insert floodfill until it's known real if we have enough + { std::unique_lock l(m_FloodfillsMutex); m_Floodfills.Insert (r); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 0222de0d..4aa69d59 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -38,6 +38,7 @@ namespace data { const int NETDB_MIN_ROUTERS = 90; const int NETDB_MIN_FLOODFILLS = 5; + const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1000; const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 3144bd9c..d20e48b9 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -35,7 +35,7 @@ namespace data m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), - m_NumTimesTaken (0), m_NumTimesRejected (0) + m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false) { } @@ -52,6 +52,7 @@ namespace data participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed); participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined); participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied); + participation.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); boost::property_tree::ptree usage; usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); @@ -112,6 +113,7 @@ namespace data m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); + m_HasConnected = participations.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -167,6 +169,12 @@ namespace data UpdateTime (); } + void RouterProfile::Connected () + { + m_HasConnected = true; + UpdateTime (); + } + bool RouterProfile::IsLowPartcipationRate () const { return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 2f60f961..08721bec 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -28,7 +28,8 @@ namespace data const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied"; const char PEER_PROFILE_USAGE_TAKEN[] = "taken"; const char PEER_PROFILE_USAGE_REJECTED[] = "rejected"; - + const char PEER_PROFILE_USAGE_CONNECTED[] = "connected"; + const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days) const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour) @@ -48,11 +49,13 @@ namespace data bool IsBad (); bool IsUnreachable (); + bool IsReal () const { return m_HasConnected || m_NumTunnelsAgreed > 0 || m_NumTunnelsDeclined > 0; } void TunnelBuildResponse (uint8_t ret); void TunnelNonReplied (); void Unreachable (); + void Connected (); boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; bool IsUpdated () const { return m_IsUpdated; }; @@ -78,6 +81,7 @@ namespace data // usage uint32_t m_NumTimesTaken; uint32_t m_NumTimesRejected; + bool m_HasConnected; // incoming connection received }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 9bfa4ce0..efe7117d 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1075,6 +1075,7 @@ namespace transport return false; } SetRemoteIdentity (ri->GetRouterIdentity ()); + ri->GetProfile ()->Connected (); i2p::data::UpdateStaticKey (m_Address->s, ri->GetIdentHash ()); // good static key AdjustMaxPayloadSize (); m_Server.AddSessionByRouterHash (shared_from_this ()); // we know remote router now From 7646147ed26319e6dd64697f6fd7663921cfefc9 Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 5 May 2023 21:30:44 +0000 Subject: [PATCH 0242/1160] save only non-default peer profile --- libi2pd/Profiling.cpp | 14 +++++++++----- libi2pd/Profiling.h | 4 ++++ libi2pd/RouterInfo.cpp | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index d20e48b9..63d39004 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -35,7 +35,7 @@ namespace data m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), - m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false) + m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false), m_IsUseful (0) { } @@ -145,22 +145,25 @@ namespace data UpdateTime (); if (ret > 0) { - m_NumTunnelsDeclined++; + if (++m_NumTunnelsDeclined > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); } else { - m_NumTunnelsAgreed++; + if (++m_NumTunnelsAgreed > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; m_LastDeclineTime = 0; } } void RouterProfile::TunnelNonReplied () { - m_NumTunnelsNonReplied++; + if (++m_NumTunnelsNonReplied > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; UpdateTime (); if (m_NumTunnelsNonReplied > 2*m_NumTunnelsAgreed && m_NumTunnelsNonReplied > 3) + { m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); + m_IsUseful = true; + } } void RouterProfile::Unreachable () @@ -206,6 +209,7 @@ namespace data m_NumTunnelsAgreed = 0; m_NumTunnelsDeclined = 0; m_NumTunnelsNonReplied = 0; + m_IsUseful = false; isBad = false; } if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; @@ -275,7 +279,7 @@ namespace data } auto ts = GetTime (); for (auto& it: tmp) - if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + if (it.second->IsUseful() && it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it.second->Save (it.first); } diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 08721bec..c8654805 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -36,6 +36,7 @@ namespace data const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes) const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) + const int PEER_PROFILE_USEFUL_THRESHOLD = 3; class RouterProfile { @@ -59,6 +60,7 @@ namespace data boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; bool IsUpdated () const { return m_IsUpdated; }; + bool IsUseful() const { return m_IsUseful; }; private: @@ -82,6 +84,8 @@ namespace data uint32_t m_NumTimesTaken; uint32_t m_NumTimesRejected; bool m_HasConnected; // incoming connection received + // is need to be saved + bool m_IsUseful; }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0cf5a0c5..3352f262 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -363,7 +363,11 @@ namespace data if (!s) return; } +<<<<<<< HEAD if ((address->s[31] & 0x80) || !i2p::data::CheckStaticKey(address->s, GetIdentHash())) +======= + if (!i2p::data::CheckStaticKey(address->s, GetIdentHash())) +>>>>>>> 146e446b (save only non-default peer profile) continue; // skip address if (address->transportStyle == eTransportNTCP2) From 8fcab7b0c1c832d2c5dabce6b272cf3048d9ce8a Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 5 May 2023 21:55:31 +0000 Subject: [PATCH 0243/1160] fix incorrect merge conflict resolve --- libi2pd/RouterInfo.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3352f262..0cf5a0c5 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -363,11 +363,7 @@ namespace data if (!s) return; } -<<<<<<< HEAD if ((address->s[31] & 0x80) || !i2p::data::CheckStaticKey(address->s, GetIdentHash())) -======= - if (!i2p::data::CheckStaticKey(address->s, GetIdentHash())) ->>>>>>> 146e446b (save only non-default peer profile) continue; // skip address if (address->transportStyle == eTransportNTCP2) From c757b6d0201f7353807136f7ff07dde070c34c89 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 May 2023 18:22:11 -0400 Subject: [PATCH 0244/1160] reset floodfill cap for unknown floodfills --- libi2pd/NetDb.cpp | 21 +++++++++++++++------ libi2pd/RouterInfo.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 3575b052..18b6694b 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -267,7 +267,12 @@ namespace data if (wasFloodfill) m_Floodfills.Remove (r->GetIdentHash ()); else if (r->IsEligibleFloodfill ()) - m_Floodfills.Insert (r); + { + if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ()) + m_Floodfills.Insert (r); + else + r->ResetFlooldFill (); + } } } else @@ -290,12 +295,16 @@ namespace data if (inserted) { LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); - if (r->IsFloodfill () && r->IsEligibleFloodfill () && - (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || - r->GetProfile ()->IsReal ())) // don't insert floodfill until it's known real if we have enough + if (r->IsFloodfill () && r->IsEligibleFloodfill ()) { - std::unique_lock l(m_FloodfillsMutex); - m_Floodfills.Insert (r); + if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || + r->GetProfile ()->IsReal ()) // don't insert floodfill until it's known real if we have enough + { + std::unique_lock l(m_FloodfillsMutex); + m_Floodfills.Insert (r); + } + else + r->ResetFlooldFill (); } } else diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 35737c9b..47ee1dae 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -224,6 +224,7 @@ namespace data void UpdateSupportedTransports (); void UpdateIntroducers (uint64_t ts); // ts in seconds bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; + void ResetFlooldFill () { m_Caps &= ~Caps::eFloodfill; }; bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsNTCP2 (bool v4only = true) const; bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; }; From 2e2cbe7803d2e324d882fba4aa55a9557feadc3b Mon Sep 17 00:00:00 2001 From: weko Date: Fri, 5 May 2023 22:46:48 +0000 Subject: [PATCH 0245/1160] save profile if has connected --- libi2pd/Profiling.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 63d39004..a290aa0a 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -175,6 +175,7 @@ namespace data void RouterProfile::Connected () { m_HasConnected = true; + m_IsUseful = true; UpdateTime (); } @@ -209,7 +210,8 @@ namespace data m_NumTunnelsAgreed = 0; m_NumTunnelsDeclined = 0; m_NumTunnelsNonReplied = 0; - m_IsUseful = false; + // we do not reset m_HasConnected here + // m_IsUseful = false; isBad = false; } if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; From e068a3cf22089484cff82af0649cf9dad4d3edd8 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 May 2023 19:58:58 -0400 Subject: [PATCH 0246/1160] store 'connected' in 'usage' section --- libi2pd/Profiling.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index d20e48b9..b3617db5 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -52,10 +52,10 @@ namespace data participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed); participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined); participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied); - participation.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); boost::property_tree::ptree usage; usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); + usage.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); @@ -113,7 +113,6 @@ namespace data m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); - m_HasConnected = participations.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -125,6 +124,7 @@ namespace data auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); + m_HasConnected = usage.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { From 3bc56ba4238e458889860c4f7a7b256e6f300312 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 May 2023 19:58:58 -0400 Subject: [PATCH 0247/1160] store 'connected' in 'usage' section --- libi2pd/Profiling.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index a290aa0a..dc11df4a 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -52,10 +52,10 @@ namespace data participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed); participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined); participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied); - participation.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); boost::property_tree::ptree usage; usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); + usage.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); @@ -113,7 +113,6 @@ namespace data m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); - m_HasConnected = participations.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -125,6 +124,7 @@ namespace data auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); + m_HasConnected = usage.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { From 1d8a91c5cccdbb0134d2cf8a1eb182e48a272e0a Mon Sep 17 00:00:00 2001 From: weko Date: Sat, 6 May 2023 07:59:40 +0000 Subject: [PATCH 0248/1160] redo no save useless profiles --- libi2pd/Profiling.cpp | 25 +++++++++++++++---------- libi2pd/Profiling.h | 5 ++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index dc11df4a..9d795451 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -35,7 +35,7 @@ namespace data m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), - m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false), m_IsUseful (0) + m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false) { } @@ -52,10 +52,10 @@ namespace data participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed); participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined); participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied); + participation.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); boost::property_tree::ptree usage; usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); - usage.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); @@ -113,6 +113,7 @@ namespace data m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); + m_HasConnected = participations.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -124,7 +125,6 @@ namespace data auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); - m_HasConnected = usage.get (PEER_PROFILE_USAGE_CONNECTED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -145,24 +145,23 @@ namespace data UpdateTime (); if (ret > 0) { - if (++m_NumTunnelsDeclined > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; + m_NumTunnelsDeclined++; m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); } else { - if (++m_NumTunnelsAgreed > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; + m_NumTunnelsAgreed++; m_LastDeclineTime = 0; } } void RouterProfile::TunnelNonReplied () { - if (++m_NumTunnelsNonReplied > PEER_PROFILE_USEFUL_THRESHOLD) m_IsUseful = true; + m_NumTunnelsNonReplied++; UpdateTime (); if (m_NumTunnelsNonReplied > 2*m_NumTunnelsAgreed && m_NumTunnelsNonReplied > 3) { m_LastDeclineTime = i2p::util::GetSecondsSinceEpoch (); - m_IsUseful = true; } } @@ -175,7 +174,6 @@ namespace data void RouterProfile::Connected () { m_HasConnected = true; - m_IsUseful = true; UpdateTime (); } @@ -210,8 +208,6 @@ namespace data m_NumTunnelsAgreed = 0; m_NumTunnelsDeclined = 0; m_NumTunnelsNonReplied = 0; - // we do not reset m_HasConnected here - // m_IsUseful = false; isBad = false; } if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; @@ -227,6 +223,15 @@ namespace data m_LastUnreachableTime = 0; return (bool)m_LastUnreachableTime; } + + bool RouterProfile::IsUseful() const { + return + m_NumTunnelsAgreed >= PEER_PROFILE_USEFUL_THRESHOLD || + m_NumTunnelsDeclined >= PEER_PROFILE_USEFUL_THRESHOLD || + m_NumTunnelsNonReplied >= PEER_PROFILE_USEFUL_THRESHOLD || + m_HasConnected; + } + std::shared_ptr GetRouterProfile (const IdentHash& identHash) { diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index c8654805..2520a6af 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -60,7 +60,8 @@ namespace data boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; bool IsUpdated () const { return m_IsUpdated; }; - bool IsUseful() const { return m_IsUseful; }; + + bool IsUseful() const; private: @@ -84,8 +85,6 @@ namespace data uint32_t m_NumTimesTaken; uint32_t m_NumTimesRejected; bool m_HasConnected; // incoming connection received - // is need to be saved - bool m_IsUseful; }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); From 8a52295882ced0e7080dda57e6c0f2456f937d00 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 May 2023 16:43:09 -0400 Subject: [PATCH 0249/1160] make router real upon successive outgoing NTCP2 session. Eliminate static keys table --- libi2pd/NTCP2.cpp | 2 -- libi2pd/Profiling.cpp | 28 ---------------------------- libi2pd/Profiling.h | 6 +----- libi2pd/RouterInfo.cpp | 8 +++----- libi2pd/SSU2Session.cpp | 2 -- libi2pd/Transports.cpp | 25 +++++++++---------------- 6 files changed, 13 insertions(+), 58 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index be584eb1..5e1cbaf6 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -718,8 +718,6 @@ namespace transport Terminate (); return; } - ri.GetProfile ()->Connected (); - i2p::data::UpdateStaticKey (addr->s, ri.GetIdentHash ()); // good static key i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 45e4ae22..754a2ce3 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -320,33 +320,5 @@ namespace data } } } - -// static keys - - struct StaticKeyProfile - { - i2p::data::IdentHash ident; - boost::posix_time::ptime lastUpdateTime; - }; - //static i2p::fs::HashedStorage g_StaticKeysProfilesStorage("statickeysProfiles", "s", "statickey-", "txt"); - static std::unordered_map, std::shared_ptr > g_StaticKeysProfiles; - static std::mutex g_StaticKeysProfilesMutex; - - bool CheckStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident) - { - std::unique_lock l(g_StaticKeysProfilesMutex); - auto it = g_StaticKeysProfiles.find (staticKey); - if (it != g_StaticKeysProfiles.end ()) - return it->second->ident == ident; - return true; - } - - void UpdateStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident) - { - std::unique_lock l(g_StaticKeysProfilesMutex); - auto res = g_StaticKeysProfiles.emplace (staticKey, std::make_shared(StaticKeyProfile{ident, GetTime ()})); - if (!res.second) - res.first->second->lastUpdateTime = GetTime (); - } } } diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 2520a6af..6b814893 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -84,7 +84,7 @@ namespace data // usage uint32_t m_NumTimesTaken; uint32_t m_NumTimesRejected; - bool m_HasConnected; // incoming connection received + bool m_HasConnected; // successful trusted(incoming or NTCP2) connection }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); @@ -92,10 +92,6 @@ namespace data void DeleteObsoleteProfiles (); void SaveProfiles (); void PersistProfiles (); - - // static keys - bool CheckStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident); - void UpdateStaticKey (const i2p::data::Tag<32>& staticKey, const i2p::data::IdentHash& ident); } } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0cf5a0c5..5ba8a5b1 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -293,7 +293,8 @@ namespace data else if (!strcmp (key, "s")) // ntcp2 or ssu2 static key { Base64ToByteStream (value, strlen (value), address->s, 32); - isStaticKey = true; + if (!(address->s[31] & 0x80)) // check if x25519 public key + isStaticKey = true; } else if (!strcmp (key, "i")) // ntcp2 iv or ssu2 intro { @@ -363,9 +364,6 @@ namespace data if (!s) return; } - if ((address->s[31] & 0x80) || !i2p::data::CheckStaticKey(address->s, GetIdentHash())) - continue; // skip address - if (address->transportStyle == eTransportNTCP2) { if (isStaticKey) @@ -391,7 +389,7 @@ namespace data } } } - else if (address->transportStyle == eTransportSSU2 && isV2) + else if (address->transportStyle == eTransportSSU2 && isV2 && isStaticKey) { if (address->IsV4 ()) supportedTransports |= eSSU2V4; if (address->IsV6 ()) supportedTransports |= eSSU2V6; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index efe7117d..49004437 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1075,8 +1075,6 @@ namespace transport return false; } SetRemoteIdentity (ri->GetRouterIdentity ()); - ri->GetProfile ()->Connected (); - i2p::data::UpdateStaticKey (m_Address->s, ri->GetIdentHash ()); // good static key AdjustMaxPayloadSize (); m_Server.AddSessionByRouterHash (shared_from_this ()); // we know remote router now m_RemoteTransports = ri->GetCompatibleTransports (false); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5693719c..f66a8f96 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -507,11 +507,6 @@ namespace transport peer.router->GetPublishedNTCP2V6Address () : peer.router->GetPublishedNTCP2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; - if (address && !i2p::data::CheckStaticKey (address->s, ident)) - { - LogPrint (eLogWarning, "Transports: NTCP2 address static key router mismatch ", ident.ToBase64 ()); - address = nullptr; - } if (address) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); @@ -531,11 +526,6 @@ namespace transport peer.router->GetSSU2V6Address () : peer.router->GetSSU2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; - if (address && !i2p::data::CheckStaticKey (address->s, ident)) - { - LogPrint (eLogWarning, "Transports: SSU2 address static key router mismatch ", ident.ToBase64 ()); - address = nullptr; - } if (address && address->IsReachableSSU ()) { if (m_SSU2Server->CreateSession (peer.router, address)) @@ -547,11 +537,6 @@ namespace transport { if (!m_NTCP2Server) continue; auto address = peer.router->GetYggdrasilAddress (); - if (address && !i2p::data::CheckStaticKey (address->s, ident)) - { - LogPrint (eLogWarning, "Transports: Yggdrasil address static key router mismatch ", ident.ToBase64 ()); - address = nullptr; - } if (address) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); @@ -606,7 +591,7 @@ namespace transport peer.router->GetCompatibleTransports (true); peer.numAttempts = 0; peer.priority.clear (); - bool ssu2 = rand () & 1; + bool ssu2 = peer.router->GetProfile ()->IsReal () ? (rand () & 1) : false; // try NTCP2 if router is not confirmed real const auto& priority = ssu2 ? ssu2Priority : ntcp2Priority; for (auto transport: priority) if (transport & compatibleTransports) @@ -724,6 +709,13 @@ namespace transport for (int i = 0; i < numExcluded; i++) transports |= it->second.priority[i]; i2p::data::netdb.ExcludeReachableTransports (ident, transports); + } + if (it->second.router) + { + auto transport = it->second.priority[it->second.numAttempts]; + if (transport == i2p::data::RouterInfo::eNTCP2V4 || + transport == i2p::data::RouterInfo::eNTCP2V6 || transport == i2p::data::RouterInfo::eNTCP2V6Mesh) + it->second.router->GetProfile ()->Connected (); // outgoing NTCP2 connection if always real } it->second.numAttempts = 0; it->second.router = nullptr; // we don't need RouterInfo after successive connect @@ -755,6 +747,7 @@ namespace transport if (!session->IsOutgoing ()) // incoming session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore auto r = i2p::data::netdb.FindRouter (ident); // router should be in netdb after SessionConfirmed + if (r) r->GetProfile ()->Connected (); auto ts = i2p::util::GetSecondsSinceEpoch (); std::unique_lock l(m_PeersMutex); auto it = m_Peers.insert (std::make_pair (ident, Peer{ r, ts })).first; From 623c3f4605b805fdc6b4c5e90d8735eae72107c1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 May 2023 18:07:21 -0400 Subject: [PATCH 0250/1160] check for max number of records in tunnel build and tunnel build reply messages --- libi2pd/I2NPProtocol.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 1a5b1cde..f100c6e5 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -424,6 +424,11 @@ namespace i2p { int num = buf[0]; LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); + if (num > i2p::tunnel::MAX_NUM_RECORDS) + { + LogPrint (eLogError, "I2NP: Too many records in VaribleTunnelBuild message ", num); + return; + } if (len < num*TUNNEL_BUILD_RECORD_SIZE + 1) { LogPrint (eLogError, "I2NP: VaribleTunnelBuild message of ", num, " records is too short ", len); @@ -477,6 +482,11 @@ namespace i2p { int num = buf[0]; LogPrint (eLogDebug, "I2NP: TunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); + if (num > i2p::tunnel::MAX_NUM_RECORDS) + { + LogPrint (eLogError, "I2NP: Too many records in TunnelBuildReply message ", num); + return; + } size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; if (len < num*recordSize + 1) { @@ -508,6 +518,11 @@ namespace i2p { int num = buf[0]; LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records"); + if (num > i2p::tunnel::MAX_NUM_RECORDS) + { + LogPrint (eLogError, "I2NP: Too many records in ShortTunnelBuild message ", num); + return; + } if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1) { LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len); From a15864715390e33f566b1133ed69edf05004e7dc Mon Sep 17 00:00:00 2001 From: weko Date: Mon, 8 May 2023 14:50:27 +0000 Subject: [PATCH 0251/1160] refactor TBM hadling --- libi2pd/I2NPProtocol.cpp | 74 ++++++++++++++++++---------------------- libi2pd/I2NPProtocol.h | 2 +- libi2pd/Tunnel.cpp | 8 ++--- 3 files changed, 38 insertions(+), 46 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index f100c6e5..623132ea 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -40,7 +40,7 @@ namespace i2p { return std::make_shared >(); } - + std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint); @@ -51,7 +51,7 @@ namespace i2p len += I2NP_HEADER_SIZE + 2; if (len <= I2NP_MAX_SHORT_MESSAGE_SIZE) return NewI2NPShortMessage (); if (len <= I2NP_MAX_MEDIUM_MESSAGE_SIZE) return NewI2NPMediumMessage (); - return NewI2NPMessage (); + return NewI2NPMessage (); } void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) @@ -748,46 +748,38 @@ namespace i2p return l; } - void HandleI2NPMessage (uint8_t * msg, size_t len) + void HandleTunnlBuildI2NPMessage (std::shared_ptr msg) { - if (len < I2NP_HEADER_SIZE) + if (msg) { - LogPrint (eLogError, "I2NP: Message length ", len, " is smaller than header"); - return; - } - uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET]; - uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET); - LogPrint (eLogDebug, "I2NP: Msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID); - uint8_t * buf = msg + I2NP_HEADER_SIZE; - auto size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET); - len -= I2NP_HEADER_SIZE; - if (size > len) - { - LogPrint (eLogError, "I2NP: Payload size ", size, " exceeds buffer length ", len); - size = len; - } - switch (typeID) - { - case eI2NPVariableTunnelBuild: - HandleVariableTunnelBuildMsg (msgID, buf, size); - break; - case eI2NPShortTunnelBuild: - HandleShortTunnelBuildMsg (msgID, buf, size); - break; - case eI2NPVariableTunnelBuildReply: - HandleTunnelBuildReplyMsg (msgID, buf, size, false); - break; - case eI2NPShortTunnelBuildReply: - HandleTunnelBuildReplyMsg (msgID, buf, size, true); - break; - case eI2NPTunnelBuild: - HandleTunnelBuildMsg (buf, size); - break; - case eI2NPTunnelBuildReply: - // TODO: - break; - default: - LogPrint (eLogWarning, "I2NP: Unexpected message ", (int)typeID); + uint8_t typeID = msg->GetTypeID(); + uint32_t msgID = msg->GetMsgID(); + LogPrint (eLogDebug, "I2NP: Handling tunnel build message with len=", msg->GetLength(),", type=", (int)typeID, ", msgID=", (unsigned int)msgID); + uint8_t * payload = msg->GetPayload(); + auto size = msg->GetPayloadLength(); + switch (typeID) + { + case eI2NPVariableTunnelBuild: + HandleVariableTunnelBuildMsg (msgID, payload, size); + break; + case eI2NPShortTunnelBuild: + HandleShortTunnelBuildMsg (msgID, payload, size); + break; + case eI2NPVariableTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, payload, size, false); + break; + case eI2NPShortTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, payload, size, true); + break; + case eI2NPTunnelBuild: + HandleTunnelBuildMsg (payload, size); + break; + case eI2NPTunnelBuildReply: + // TODO: + break; + default: + LogPrint (eLogError, "I2NP: Unexpected message with type", (int)typeID, " during handling TBM; skipping"); + } } } @@ -851,7 +843,7 @@ namespace i2p i2p::tunnel::tunnels.PostTunnelData (msg); break; default: - HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); + LogPrint(eLogError, "I2NP: Unexpected I2NP message with type ", int(typeID), " during handling; skipping"); } } } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index c0685190..5efd8f70 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -295,7 +295,7 @@ namespace tunnel std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr msg); size_t GetI2NPMessageLength (const uint8_t * msg, size_t len); - void HandleI2NPMessage (uint8_t * msg, size_t len); + void HandleTunnlBuildI2NPMessage (std::shared_ptr msg); void HandleI2NPMessage (std::shared_ptr msg); class I2NPMessagesHandler diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 249f0a31..99824ab7 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -516,7 +516,7 @@ namespace tunnel case eI2NPShortTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: - HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); + HandleTunnlBuildI2NPMessage (msg); break; default: LogPrint (eLogWarning, "Tunnel: Unexpected message type ", (int) typeID); @@ -590,13 +590,13 @@ namespace tunnel // DatabaseSearchReply with new routers i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg)); else if (IsRouterInfoMsg (msg)) - { + { // transit DatabaseStore might contain new/updated RI auto m = CopyI2NPMessage (msg); if (bufbe32toh (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET)) memset (m->GetPayload () + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0xFF, 4); // fake replyToken meaning no reply i2p::data::netdb.PostI2NPMsg (m); - } + } tunnel->SendTunnelDataMsg (msg); } @@ -986,6 +986,6 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: Max number of transit tunnels set to ", maxNumTransitTunnels); m_MaxNumTransitTunnels = maxNumTransitTunnels; } - } + } } } From d44be2fd73269d256295ede9b0637f33f27a7b85 Mon Sep 17 00:00:00 2001 From: weko Date: Mon, 8 May 2023 15:33:40 +0000 Subject: [PATCH 0252/1160] fix typo --- libi2pd/I2NPProtocol.cpp | 8 ++++---- libi2pd/I2NPProtocol.h | 2 +- libi2pd/Tunnel.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 623132ea..8a6f443c 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -428,7 +428,7 @@ namespace i2p { LogPrint (eLogError, "I2NP: Too many records in VaribleTunnelBuild message ", num); return; - } + } if (len < num*TUNNEL_BUILD_RECORD_SIZE + 1) { LogPrint (eLogError, "I2NP: VaribleTunnelBuild message of ", num, " records is too short ", len); @@ -486,7 +486,7 @@ namespace i2p { LogPrint (eLogError, "I2NP: Too many records in TunnelBuildReply message ", num); return; - } + } size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; if (len < num*recordSize + 1) { @@ -522,7 +522,7 @@ namespace i2p { LogPrint (eLogError, "I2NP: Too many records in ShortTunnelBuild message ", num); return; - } + } if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1) { LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len); @@ -748,7 +748,7 @@ namespace i2p return l; } - void HandleTunnlBuildI2NPMessage (std::shared_ptr msg) + void HandleTunnelBuildI2NPMessage (std::shared_ptr msg) { if (msg) { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 5efd8f70..6c64f2ab 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -295,7 +295,7 @@ namespace tunnel std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr msg); size_t GetI2NPMessageLength (const uint8_t * msg, size_t len); - void HandleTunnlBuildI2NPMessage (std::shared_ptr msg); + void HandleTunnelBuildI2NPMessage (std::shared_ptr msg); void HandleI2NPMessage (std::shared_ptr msg); class I2NPMessagesHandler diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 99824ab7..db6f74f9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -516,7 +516,7 @@ namespace tunnel case eI2NPShortTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: - HandleTunnlBuildI2NPMessage (msg); + HandleTunnelBuildI2NPMessage (msg); break; default: LogPrint (eLogWarning, "Tunnel: Unexpected message type ", (int) typeID); From c984f89dfb721a90dbb31f4c3bb169f6721fc82b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 21 May 2023 18:43:58 -0400 Subject: [PATCH 0253/1160] don't handle unecnrypted DatabaseSearchReply msg if came throug client tunnel --- libi2pd/I2NPProtocol.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 8a6f443c..b8147555 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -808,14 +808,12 @@ namespace i2p break; } case eI2NPDatabaseStore: + case eI2NPDatabaseSearchReply: // forward to netDb if came directly or through exploratory tunnel as response to our request if (!msg->from || !msg->from->GetTunnelPool () || msg->from->GetTunnelPool ()->IsExploratory ()) i2p::data::netdb.PostI2NPMsg (msg); break; - case eI2NPDatabaseSearchReply: - // forward to netDb - i2p::data::netdb.PostI2NPMsg (msg); - break; + case eI2NPDatabaseLookup: // forward to netDb if floodfill and came directly if (!msg->from && i2p::context.IsFloodfill ()) From e95fb3ab8941ae9e651bfc06b4e810b840c9460d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 22 May 2023 08:58:04 -0400 Subject: [PATCH 0254/1160] allow user/password authentication --- libi2pd_client/SOCKS.cpp | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index ca87e22a..c40cb479 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -66,6 +66,11 @@ namespace proxy GET5_IPV6, GET5_HOST_SIZE, GET5_HOST, + GET5_USERPASSWD, + GET5_USER_SIZE, + GET5_USER, + GET5_PASSWD_SIZE, + GET5_PASSWD, READY, UPSTREAM_RESOLVE, UPSTREAM_CONNECT, @@ -129,6 +134,7 @@ namespace proxy boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); boost::asio::const_buffers_1 GenerateUpstreamRequest(); bool Socks5ChooseAuth(); + void Socks5UserPasswdResponse (); void SocksRequestFailed(errTypes error); void SocksRequestSuccess(); void SentSocksFailed(const boost::system::error_code & ecode); @@ -324,6 +330,15 @@ namespace proxy } } + void SOCKSHandler::Socks5UserPasswdResponse () + { + m_response[0] = 5; // Version + m_response[1] = 0; // Response code + LogPrint(eLogDebug, "SOCKS: v5 user/password response"); + boost::asio::async_write(*m_sock, boost::asio::const_buffers_1(m_response, 2), + std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1)); + } + /* All hope is lost beyond this point */ void SOCKSHandler::SocksRequestFailed(SOCKSHandler::errTypes error) { @@ -438,10 +453,15 @@ namespace proxy m_parseleft --; if (*sock_buff == AUTH_NONE) m_authchosen = AUTH_NONE; + else if (*sock_buff == AUTH_USERPASSWD) + m_authchosen = AUTH_USERPASSWD; if ( m_parseleft == 0 ) { if (!Socks5ChooseAuth()) return false; - EnterState(GET5_REQUESTV); + if (m_authchosen == AUTH_USERPASSWD) + EnterState(GET5_USERPASSWD); + else + EnterState(GET5_REQUESTV); } break; case GET_COMMAND: @@ -557,6 +577,35 @@ namespace proxy m_parseleft--; if (m_parseleft == 0) EnterState(GET_PORT); break; + case GET5_USERPASSWD: + if (*sock_buff != 1) + { + LogPrint(eLogError,"SOCKS: v5 rejected invalid username/password subnegotiation: ", ((int)*sock_buff)); + SocksRequestFailed(SOCKS5_GEN_FAIL); + return false; + } + EnterState(GET5_USER_SIZE); + break; + case GET5_USER_SIZE: + EnterState(GET5_USER, *sock_buff); + break; + case GET5_USER: + // skip user for now + m_parseleft--; + if (m_parseleft == 0) EnterState(GET5_PASSWD_SIZE); + break; + case GET5_PASSWD_SIZE: + EnterState(GET5_PASSWD, *sock_buff); + break; + case GET5_PASSWD: + // skip passwd for now + m_parseleft--; + if (m_parseleft == 0) + { + Socks5UserPasswdResponse (); + EnterState(GET5_REQUESTV); + } + break; default: LogPrint(eLogError, "SOCKS: Parse state?? ", m_state); Terminate(); From e56d243c3f883c3ba7addf1c5bc769ed9ebeef8a Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 24 Apr 2023 14:04:56 +0300 Subject: [PATCH 0255/1160] [win32] suppress fallthrough warning Signed-off-by: r4sas --- Win32/Win32App.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 9eae7a95..fc61a8ac 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -348,6 +348,9 @@ namespace win32 } } } +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif } case WM_TRAYICON: { From a2726cf206a52360ab9798c1666059d5360a4cba Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 24 Apr 2023 14:07:12 +0300 Subject: [PATCH 0256/1160] [cmake] print commit-based version if option is used Signed-off-by: r4sas --- build/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 05401b1f..f5d01a0b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -329,7 +329,11 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " BINARY : ${WITH_BINARY}") message(STATUS " STATIC BUILD : ${WITH_STATIC}") message(STATUS " UPnP : ${WITH_UPNP}") +if(WITH_GIT_VERSION) +message(STATUS " GIT VERSION : ${WITH_GIT_VERSION} (${GIT_VERSION})") +else() message(STATUS " GIT VERSION : ${WITH_GIT_VERSION}") +endif() message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS "---------------------------------------") From fdf38f45d966454ee0d7eb9092de7809bce2677d Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 29 Apr 2023 22:00:13 +0300 Subject: [PATCH 0257/1160] more debug messages at destinations stop Signed-off-by: r4sas --- libi2pd/Destination.cpp | 11 +++++++++-- libi2pd_client/ClientContext.cpp | 14 +++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6bcedb4e..a755347d 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1036,11 +1036,15 @@ namespace client void ClientDestination::Stop () { + LogPrint(eLogDebug, "Destination: Stopping destination ", GetIdentHash().ToBase32(), ".b32.i2p"); LeaseSetDestination::Stop (); m_ReadyChecker.cancel(); + LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination"); m_StreamingDestination->Stop (); //m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; + + LogPrint(eLogDebug, "Destination: -> Stopping Streaming Destination by ports"); for (auto& it: m_StreamingDestinationsByPorts) { it.second->Stop (); @@ -1048,11 +1052,14 @@ namespace client } m_StreamingDestinationsByPorts.clear (); m_LastStreamingDestination = nullptr; + if (m_DatagramDestination) { + LogPrint(eLogDebug, "Destination: -> Stopping Datagram Destination"); delete m_DatagramDestination; m_DatagramDestination = nullptr; } + LogPrint(eLogDebug, "Destination: -> Stopping done"); } void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) @@ -1075,10 +1082,10 @@ namespace client if (toPort != m_LastPort || !m_LastStreamingDestination) { m_LastStreamingDestination = GetStreamingDestination (toPort); - if (!m_LastStreamingDestination) + if (!m_LastStreamingDestination) m_LastStreamingDestination = m_StreamingDestination; // if no destination on port use default m_LastPort = toPort; - } + } if (m_LastStreamingDestination) m_LastStreamingDestination->HandleDataMessagePayload (buf, length); else diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index dadb9ae5..afb34c2a 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -186,22 +186,30 @@ namespace client LogPrint(eLogInfo, "Clients: Stopping AddressBook"); m_AddressBook.Stop (); + LogPrint(eLogInfo, "Clients: Stopping UDP Tunnels"); { std::lock_guard lock(m_ForwardsMutex); m_ServerForwards.clear(); m_ClientForwards.clear(); } + LogPrint(eLogInfo, "Clients: Stopping UDP Tunnels timers"); if (m_CleanupUDPTimer) { m_CleanupUDPTimer->cancel (); m_CleanupUDPTimer = nullptr; } - for (auto& it: m_Destinations) - it.second->Stop (); - m_Destinations.clear (); + { + LogPrint(eLogInfo, "Clients: Stopping Destinations"); + std::lock_guard lock(m_DestinationsMutex); + for (auto& it: m_Destinations) + it.second->Stop (); + LogPrint(eLogInfo, "Clients: Stopping Destinations - Clear"); + m_Destinations.clear (); + } + LogPrint(eLogInfo, "Clients: Stopping SharedLocalDestination"); m_SharedLocalDestination->Release (); m_SharedLocalDestination = nullptr; } From dc6a42c26ff1572b97b59d64a2fd86bf5383053c Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 8 May 2023 22:49:12 +0300 Subject: [PATCH 0258/1160] [contrib] update example config file comments, remove ssu option Signed-off-by: r4sas --- contrib/i2pd.conf | 109 ++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 5d09c90a..5facbbd5 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -19,7 +19,7 @@ ## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates # certsdir = /var/lib/i2pd/certificates -## Where to write pidfile (default: i2pd.pid, not used in Windows) +## Where to write pidfile (default: /run/i2pd.pid, not used in Windows) # pidfile = /run/i2pd.pid ## Logging configuration section @@ -31,7 +31,7 @@ ## * file - log entries to a file ## * syslog - use syslog, see man 3 syslog # log = file -## Path to logfile (default - autodetect) +## Path to logfile (default: autodetect) # logfile = /var/log/i2pd/i2pd.log ## Log messages above this level (debug, info, *warn, error, critical, none) ## If you set it to none, logging will be disabled @@ -40,6 +40,7 @@ # logclftime = true ## Daemon mode. Router will go to background after start. Ignored on Windows +## (default: true) # daemon = true ## Specify a family, router belongs to (default - none) @@ -70,58 +71,60 @@ ## don't just uncomment this # port = 4567 -## Enable communication through ipv4 +## Enable communication through ipv4 (default: true) ipv4 = true -## Enable communication through ipv6 +## Enable communication through ipv6 (default: false) ipv6 = false -## Enable SSU transport -ssu = false - ## Bandwidth configuration -## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec, +## L limit bandwidth to 32 KB/sec, O - to 256 KB/sec, P - to 2048 KB/sec, ## X - unlimited -## Default is L (regular node) and X if floodfill mode enabled. If you want to -## share more bandwidth without floodfill mode, uncomment that line and adjust -## value to your possibilities +## Default is L (regular node) and X if floodfill mode enabled. +## If you want to share more bandwidth without floodfill mode, uncomment +## that line and adjust value to your possibilities. Value can be set to +## integer in kilobytes, it will apply that limit and flag will be used +## from next upper limit (example: if you set 4096 flag will be X, but real +## limit will be 4096 KB/s). Same can be done when floodfill mode is used, +## but keep in mind that low values may be negatively evaluated by Java +## router algorithms. # bandwidth = L -## Max % of bandwidth limit for transit. 0-100. 100 by default +## Max % of bandwidth limit for transit. 0-100 (default: 100) # share = 100 ## Router will not accept transit tunnels, disabling transit traffic completely -## (default = false) +## (default: false) # notransit = true -## Router will be floodfill +## Router will be floodfill (default: false) ## Note: that mode uses much more network connections and CPU! # floodfill = true [ntcp2] -## Enable NTCP2 transport (default = true) +## Enable NTCP2 transport (default: true) # enabled = true -## Publish address in RouterInfo (default = true) +## Publish address in RouterInfo (default: true) # published = true ## Port for incoming connections (default is global port option value) # port = 4567 [ssu2] -## Enable SSU2 transport +## Enable SSU2 transport (default: true) # enabled = true -## Publish address in RouterInfo +## Publish address in RouterInfo (default: true) # published = true -## Port for incoming connections (default is global port option value or port + 1 if SSU is enabled) +## Port for incoming connections (default is global port option value) # port = 4567 [http] ## Web Console settings -## Uncomment and set to 'false' to disable Web Console +## Enable the Web Console (default: true) # enabled = true -## Address and port service will listen on -address = 127.0.0.1 -port = 7070 -## Path to web console, default "/" +## Address and port service will listen on (default: 127.0.0.1:7070) +# address = 127.0.0.1 +# port = 7070 +## Path to web console (default: /) # webroot = / -## Uncomment following lines to enable Web Console authentication +## Enable Web Console authentication (default: false) ## You should not use Web Console via public networks without additional encryption. ## HTTP authentication is not encryption layer! # auth = true @@ -134,12 +137,12 @@ port = 7070 # lang = english [httpproxy] -## Uncomment and set to 'false' to disable HTTP Proxy +## Enable the HTTP proxy (default: true) # enabled = true -## Address and port service will listen on -address = 127.0.0.1 -port = 4444 -## Optional keys file for proxy local destination +## Address and port service will listen on (default: 127.0.0.1:4444) +# address = 127.0.0.1 +# port = 4444 +## Optional keys file for proxy local destination (default: http-proxy-keys.dat) # keys = http-proxy-keys.dat ## Enable address helper for adding .i2p domains with "jump URLs" (default: true) ## You should disable this feature if your i2pd HTTP Proxy is public, @@ -150,15 +153,15 @@ port = 4444 ## httpproxy section also accepts I2CP parameters, like "inbound.length" etc. [socksproxy] -## Uncomment and set to 'false' to disable SOCKS Proxy +## Enable the SOCKS proxy (default: true) # enabled = true -## Address and port service will listen on -address = 127.0.0.1 -port = 4447 -## Optional keys file for proxy local destination +## Address and port service will listen on (default: 127.0.0.1:4447) +# address = 127.0.0.1 +# port = 4447 +## Optional keys file for proxy local destination (default: socks-proxy-keys.dat) # keys = socks-proxy-keys.dat ## Socks outproxy. Example below is set to use Tor for all connections except i2p -## Uncomment and set to 'true' to enable using of SOCKS outproxy +## Enable using of SOCKS outproxy (works only with SOCKS4, default: false) # outproxy.enabled = false ## Address and port of outproxy # outproxy = 127.0.0.1 @@ -166,34 +169,34 @@ port = 4447 ## socksproxy section also accepts I2CP parameters, like "inbound.length" etc. [sam] -## Comment or set to 'false' to disable SAM Bridge -enabled = true -## Address and ports service will listen on +## Enable the SAM bridge (default: true) +# enabled = false +## Address and ports service will listen on (default: 127.0.0.1:7656, udp: 7655) # address = 127.0.0.1 # port = 7656 # portudp = 7655 [bob] -## Uncomment and set to 'true' to enable BOB command channel +## Enable the BOB command channel (default: false) # enabled = false -## Address and port service will listen on +## Address and port service will listen on (default: 127.0.0.1:2827) # address = 127.0.0.1 # port = 2827 [i2cp] -## Uncomment and set to 'true' to enable I2CP protocol +## Enable the I2CP protocol (default: false) # enabled = false -## Address and port service will listen on +## Address and port service will listen on (default: 127.0.0.1:7654) # address = 127.0.0.1 # port = 7654 [i2pcontrol] -## Uncomment and set to 'true' to enable I2PControl protocol +## Enable the I2PControl protocol (default: false) # enabled = false -## Address and port service will listen on +## Address and port service will listen on (default: 127.0.0.1:7650) # address = 127.0.0.1 # port = 7650 -## Authentication password. "itoopie" by default +## Authentication password (default: itoopie) # password = itoopie [precomputation] @@ -204,11 +207,11 @@ enabled = true [upnp] ## Enable or disable UPnP: automatic port forwarding (enabled by default in WINDOWS, ANDROID) # enabled = false -## Name i2pd appears in UPnP forwardings list (default = I2Pd) +## Name i2pd appears in UPnP forwardings list (default: I2Pd) # name = I2Pd [meshnets] -## Enable connectivity over the Yggdrasil network +## Enable connectivity over the Yggdrasil network (default: false) # yggdrasil = false ## You can bind address from your Yggdrasil subnet 300::/64 ## The address must first be added to the network interface @@ -216,7 +219,7 @@ enabled = true [reseed] ## Options for bootstrapping into I2P network, aka reseeding -## Enable or disable reseed data verification. +## Enable reseed data verification (default: true) verify = true ## URLs to request reseed data from, separated by comma ## Default: "mainline" I2P Network reseeds @@ -232,7 +235,7 @@ verify = true ## If you run i2pd behind a proxy server, set proxy server for reseeding here ## Should be http://address:port or socks://address:port # proxy = http://127.0.0.1:8118 -## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default +## Minimum number of known routers, below which i2pd triggers reseeding (default: 25) # threshold = 25 [addressbook] @@ -252,13 +255,13 @@ verify = true # coresize = 0 [trust] -## Enable explicit trust options. false by default +## Enable explicit trust options. (default: false) # enabled = true ## Make direct I2P connections only to routers in specified Family. # family = MyFamily ## Make direct I2P connections only to routers specified here. Comma separated list of base64 identities. # routers = -## Should we hide our router from other routers? false by default +## Should we hide our router from other routers? (default: false) # hidden = true [exploratory] @@ -279,6 +282,6 @@ verify = true # aesni = true ## Use CPU AVX instructions set when work with cryptography when available (default: true) # avx = true -## Force usage of CPU instructions set, even if they not found +## Force usage of CPU instructions set, even if they not found (default: false) ## DO NOT TOUCH that option if you really don't know what are you doing! # force = false From ae439b5385944215ce9cba75eba55a2789b9989e Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 27 May 2023 01:00:19 +0300 Subject: [PATCH 0259/1160] SSU2: check if socket is opened before sending data, handle network_reset error Signed-off-by: r4sas --- libi2pd/Profiling.cpp | 24 ++++++++++++------------ libi2pd/SSU2.cpp | 23 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 754a2ce3..4fbf0fa2 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -30,7 +30,7 @@ namespace data { return boost::posix_time::second_clock::local_time(); } - + RouterProfile::RouterProfile (): m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), @@ -175,8 +175,8 @@ namespace data { m_HasConnected = true; UpdateTime (); - } - + } + bool RouterProfile::IsLowPartcipationRate () const { return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate @@ -223,7 +223,7 @@ namespace data m_LastUnreachableTime = 0; return (bool)m_LastUnreachableTime; } - + bool RouterProfile::IsUseful() const { return m_NumTunnelsAgreed >= PEER_PROFILE_USEFUL_THRESHOLD || @@ -240,7 +240,7 @@ namespace data auto it = g_Profiles.find (identHash); if (it != g_Profiles.end ()) return it->second; - } + } auto profile = std::make_shared (); profile->Load (identHash); // if possible std::unique_lock l(g_ProfilesMutex); @@ -261,7 +261,7 @@ namespace data { std::unique_lock l(g_ProfilesMutex); for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) - { + { if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) { if (it->second->IsUpdated ()) @@ -270,11 +270,11 @@ namespace data } else it++; - } + } } for (auto& it: tmp) if (it.second) it.second->Save (it.first); - } + } void SaveProfiles () { @@ -288,22 +288,22 @@ namespace data for (auto& it: tmp) if (it.second->IsUseful() && it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it.second->Save (it.first); - } - + } + void DeleteObsoleteProfiles () { { auto ts = GetTime (); std::unique_lock l(g_ProfilesMutex); for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) - { + { if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it = g_Profiles.erase (it); else it++; } } - + struct stat st; std::time_t now = std::time(nullptr); diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 5df4d33a..a9e04790 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -78,6 +78,7 @@ namespace transport if (address->IsV4 ()) { found = true; + LogPrint (eLogDebug, "SSU2: Opening IPv4 socket at Start"); OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port)); m_ReceiveService.GetService ().post( [this]() @@ -89,6 +90,7 @@ namespace transport if (address->IsV6 ()) { found = true; + LogPrint (eLogDebug, "SSU2: Opening IPv6 socket at Start"); OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port)); m_ReceiveService.GetService ().post( [this]() @@ -243,10 +245,12 @@ namespace transport if (!ecode || ecode == boost::asio::error::connection_refused || ecode == boost::asio::error::connection_reset + || ecode == boost::asio::error::network_reset || ecode == boost::asio::error::network_unreachable || ecode == boost::asio::error::host_unreachable #ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO || ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_ + || ecode.value() == boost::winapi::WSAENETRESET_ // 10052 || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_ || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_ #endif @@ -303,7 +307,7 @@ namespace transport else { auto ep = socket.local_endpoint (); - socket.close (); + LogPrint (eLogCritical, "SSU2: Reopening socket in HandleReceivedFrom: code ", ecode.value(), ": ", ecode.message ()); OpenSocket (ep); Receive (socket); } @@ -558,16 +562,25 @@ namespace transport SendThroughProxy (header, headerLen, nullptr, 0, payload, payloadLen, to); return; } + std::vector bufs { boost::asio::buffer (header, headerLen), boost::asio::buffer (payload, payloadLen) }; + boost::system::error_code ec; if (to.address ().is_v6 ()) + { + if (!m_SocketV6.is_open ()) return; m_SocketV6.send_to (bufs, to, 0, ec); + } else + { + if (!m_SocketV4.is_open ()) return; m_SocketV4.send_to (bufs, to, 0, ec); + } + if (!ec) i2p::transport::transports.UpdateSentBytes (headerLen + payloadLen); else @@ -582,17 +595,25 @@ namespace transport SendThroughProxy (header, headerLen, headerX, headerXLen, payload, payloadLen, to); return; } + std::vector bufs { boost::asio::buffer (header, headerLen), boost::asio::buffer (headerX, headerXLen), boost::asio::buffer (payload, payloadLen) }; + boost::system::error_code ec; if (to.address ().is_v6 ()) + { + if (!m_SocketV6.is_open ()) return; m_SocketV6.send_to (bufs, to, 0, ec); + } else + { + if (!m_SocketV4.is_open ()) return; m_SocketV4.send_to (bufs, to, 0, ec); + } if (!ec) i2p::transport::transports.UpdateSentBytes (headerLen + headerXLen + payloadLen); From 86173400d5dda64da4a9c30bd4bd851d6bac7bcb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 May 2023 08:49:45 -0400 Subject: [PATCH 0260/1160] don't drop profile of real router too early --- libi2pd/NetDb.hpp | 2 +- libi2pd/Profiling.cpp | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 4aa69d59..adfdcde7 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -38,7 +38,7 @@ namespace data { const int NETDB_MIN_ROUTERS = 90; const int NETDB_MIN_FLOODFILLS = 5; - const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1000; + const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1500; const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 4fbf0fa2..47fc15e7 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -224,15 +224,11 @@ namespace data return (bool)m_LastUnreachableTime; } - bool RouterProfile::IsUseful() const { - return - m_NumTunnelsAgreed >= PEER_PROFILE_USEFUL_THRESHOLD || - m_NumTunnelsDeclined >= PEER_PROFILE_USEFUL_THRESHOLD || - m_NumTunnelsNonReplied >= PEER_PROFILE_USEFUL_THRESHOLD || - m_HasConnected; + bool RouterProfile::IsUseful() const + { + return IsReal () || m_NumTunnelsNonReplied >= PEER_PROFILE_USEFUL_THRESHOLD; } - std::shared_ptr GetRouterProfile (const IdentHash& identHash) { { @@ -286,7 +282,7 @@ namespace data } auto ts = GetTime (); for (auto& it: tmp) - if (it.second->IsUseful() && it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + if (it.second->IsUseful() && (it.second->IsUpdated () || (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600)) it.second->Save (it.first); } From d5ee1f602fdc7a47ccc9a4e239ea720dd63f123a Mon Sep 17 00:00:00 2001 From: AsciiMoth Date: Tue, 30 May 2023 18:27:40 +0400 Subject: [PATCH 0261/1160] Update dates in license (#1934) Update copyright timestamp in LICENSE file from 2020 to actual 2023 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9a1e4527..93280084 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2020, The PurpleI2P Project +Copyright (c) 2013-2023, The PurpleI2P Project All rights reserved. From dfe5df29e18afa7f93fa3c452ebe12398178ad6b Mon Sep 17 00:00:00 2001 From: r4sas Date: Tue, 30 May 2023 21:05:15 +0300 Subject: [PATCH 0262/1160] suppress build warnings on windows Signed-off-by: r4sas --- libi2pd/util.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 2426f13a..088a7af5 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -201,7 +201,7 @@ namespace net int GetMTUWindowsIpv4 (sockaddr_in inputAddress, int fallback) { typedef const char *(* IPN)(int af, const void *src, char *dst, socklen_t size); - IPN inetntop = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop"); + IPN inetntop = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop"); if (!inetntop) inetntop = inet_ntop_xp; // use own implementation if not found ULONG outBufLen = 0; @@ -262,7 +262,7 @@ namespace net int GetMTUWindowsIpv6 (sockaddr_in6 inputAddress, int fallback) { typedef const char *(* IPN)(int af, const void *src, char *dst, socklen_t size); - IPN inetntop = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop"); + IPN inetntop = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetNtop"); if (!inetntop) inetntop = inet_ntop_xp; // use own implementation if not found ULONG outBufLen = 0; @@ -341,7 +341,7 @@ namespace net #endif typedef int (* IPN)(int af, const char *src, void *dst); - IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); + IPN inetpton = (IPN)(void*)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if (localAddress.is_v4()) From 09f233dbfb07fb1c3edd38a47d65e56a99589d50 Mon Sep 17 00:00:00 2001 From: r4sas Date: Tue, 6 Jun 2023 01:00:07 +0300 Subject: [PATCH 0263/1160] NetDB: ignore LeaseSet store request if not floodfill Signed-off-by: r4sas --- libi2pd/NetDb.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 18b6694b..baf96f74 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -267,12 +267,12 @@ namespace data if (wasFloodfill) m_Floodfills.Remove (r->GetIdentHash ()); else if (r->IsEligibleFloodfill ()) - { - if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ()) + { + if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ()) m_Floodfills.Insert (r); else r->ResetFlooldFill (); - } + } } } else @@ -296,10 +296,10 @@ namespace data { LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); if (r->IsFloodfill () && r->IsEligibleFloodfill ()) - { + { if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || - r->GetProfile ()->IsReal ()) // don't insert floodfill until it's known real if we have enough - { + r->GetProfile ()->IsReal ()) // don't insert floodfill until it's known real if we have enough + { std::unique_lock l(m_FloodfillsMutex); m_Floodfills.Insert (r); } @@ -840,7 +840,12 @@ namespace data LogPrint (eLogError, "NetDb: Database store message is too long ", len); return; } - if (!m->from) // unsolicited LS must be received directly + if (!context.IsFloodfill ()) + { + LogPrint (eLogInfo, "NetDb: Not Floodfill, LeaseSet store request ignored for ", ident.ToBase32()); + return; + } + else if (!m->from) // unsolicited LS must be received directly { if (storeType == NETDB_STORE_TYPE_LEASESET) // 1 { From 4e426727e961eb944d2501cee733afe700fbb961 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 10 Jun 2023 04:08:56 +0300 Subject: [PATCH 0264/1160] Webconsole: fix output on i2p tunnels, add b32 on dest page Fixes: * adding of "Client Destinations" section header when there is no such tunnels * Print error when destination is not found instead of empty page Adds: * Print b32 on destination page Signed-off-by: r4sas --- daemon/HTTPServer.cpp | 62 ++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index f9b034ae..50666940 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -422,8 +422,12 @@ namespace http { static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest, uint32_t token) { + s << "Base32:
\r\n
\r\n
\r\n"; + s << "Base64:
\r\n
\r\n
\r\n"; + if (dest->IsEncryptedLeaseSet ()) { i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); @@ -605,6 +609,8 @@ namespace http { } s << "\r\n"; } + else + ShowError(s, tr("Such destination is not found")); } void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) @@ -972,34 +978,42 @@ namespace http { void ShowI2PTunnels (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "" << tr("Client Tunnels") << ":
\r\n

\r\n"; - for (auto& it: i2p::client::context.GetClientTunnels ()) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << "
"; - s << it.second->GetName () << " ⇐ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; - } + + auto& clientTunnels = i2p::client::context.GetClientTunnels (); auto httpProxy = i2p::client::context.GetHttpProxy (); - if (httpProxy) - { - auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); - s << "
"; - s << "HTTP " << tr("Proxy") << " ⇐ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; - } auto socksProxy = i2p::client::context.GetSocksProxy (); - if (socksProxy) + if (!clientTunnels.empty () || httpProxy || socksProxy) { - auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); - s << "
"; - s << "SOCKS " << tr("Proxy") << " ⇐ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "" << tr("Client Tunnels") << ":
\r\n
\r\n"; + if (!clientTunnels.empty ()) + { + for (auto& it: clientTunnels) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + s << "
"; + s << it.second->GetName () << " ⇐ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << "
\r\n"<< std::endl; + } + } + if (httpProxy) + { + auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); + s << "
"; + s << "HTTP " << tr("Proxy") << " ⇐ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << "
\r\n"<< std::endl; + } + if (socksProxy) + { + auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); + s << "
"; + s << "SOCKS " << tr("Proxy") << " ⇐ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << "
\r\n"<< std::endl; + } + s << "
\r\n"; } - s << "
\r\n"; auto& serverTunnels = i2p::client::context.GetServerTunnels (); if (!serverTunnels.empty ()) { From 75aa9f2c0c79c09d9ddc85465edad090dfee884d Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 10 Jun 2023 04:30:48 +0300 Subject: [PATCH 0265/1160] i18n: update translation file Signed-off-by: r4sas --- contrib/i18n/English.po | 402 +++++++++++++++++++++------------------- contrib/i18n/README.md | 2 +- 2 files changed, 211 insertions(+), 193 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 22010680..7782187f 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i2pd\n" "Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" -"POT-Creation-Date: 2023-01-19 04:18\n" +"POT-Creation-Date: 2023-06-10 01:25\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,28 +18,28 @@ msgstr "" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" -#: daemon/HTTPServer.cpp:106 +#: daemon/HTTPServer.cpp:107 #, c-format msgid "%d day" msgid_plural "%d days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:110 +#: daemon/HTTPServer.cpp:111 #, c-format msgid "%d hour" msgid_plural "%d hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:114 +#: daemon/HTTPServer.cpp:115 #, c-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:117 +#: daemon/HTTPServer.cpp:118 #, c-format msgid "%d second" msgid_plural "%d seconds" @@ -47,560 +47,578 @@ msgstr[0] "" msgstr[1] "" #. tr: Kibibyte -#: daemon/HTTPServer.cpp:125 daemon/HTTPServer.cpp:153 +#: daemon/HTTPServer.cpp:126 #, c-format msgid "%.2f KiB" msgstr "" #. tr: Mebibyte -#: daemon/HTTPServer.cpp:127 +#: daemon/HTTPServer.cpp:128 #, c-format msgid "%.2f MiB" msgstr "" #. tr: Gibibyte -#: daemon/HTTPServer.cpp:129 +#: daemon/HTTPServer.cpp:130 #, c-format msgid "%.2f GiB" msgstr "" -#: daemon/HTTPServer.cpp:146 +#: daemon/HTTPServer.cpp:147 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:147 +#: daemon/HTTPServer.cpp:148 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:148 +#: daemon/HTTPServer.cpp:149 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:149 +#: daemon/HTTPServer.cpp:150 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:150 +#: daemon/HTTPServer.cpp:151 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:152 +#: daemon/HTTPServer.cpp:153 msgid "exploratory" msgstr "" #. tr: Webconsole page title -#: daemon/HTTPServer.cpp:183 +#: daemon/HTTPServer.cpp:185 msgid "Purple I2P Webconsole" msgstr "" -#: daemon/HTTPServer.cpp:188 +#: daemon/HTTPServer.cpp:190 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:191 +#: daemon/HTTPServer.cpp:193 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:192 daemon/HTTPServer.cpp:712 +#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:742 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:193 daemon/HTTPServer.cpp:387 -#: daemon/HTTPServer.cpp:399 +#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:395 +#: daemon/HTTPServer.cpp:407 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:195 daemon/HTTPServer.cpp:357 -#: daemon/HTTPServer.cpp:443 daemon/HTTPServer.cpp:449 -#: daemon/HTTPServer.cpp:609 daemon/HTTPServer.cpp:652 -#: daemon/HTTPServer.cpp:656 +#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:365 +#: daemon/HTTPServer.cpp:454 daemon/HTTPServer.cpp:474 +#: daemon/HTTPServer.cpp:636 daemon/HTTPServer.cpp:682 +#: daemon/HTTPServer.cpp:686 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:197 daemon/HTTPServer.cpp:662 +#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:692 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:199 daemon/HTTPServer.cpp:364 -#: daemon/HTTPServer.cpp:781 daemon/HTTPServer.cpp:797 +#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:372 +#: daemon/HTTPServer.cpp:813 daemon/HTTPServer.cpp:830 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:201 daemon/HTTPServer.cpp:855 +#: daemon/HTTPServer.cpp:203 daemon/HTTPServer.cpp:898 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:202 +#: daemon/HTTPServer.cpp:204 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:204 daemon/HTTPServer.cpp:884 -#: daemon/HTTPServer.cpp:894 +#: daemon/HTTPServer.cpp:206 daemon/HTTPServer.cpp:927 +#: daemon/HTTPServer.cpp:937 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:220 daemon/HTTPServer.cpp:1278 -#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1284 -#: daemon/HTTPServer.cpp:1298 daemon/HTTPServer.cpp:1343 -#: daemon/HTTPServer.cpp:1346 daemon/HTTPServer.cpp:1349 +#: daemon/HTTPServer.cpp:222 daemon/HTTPServer.cpp:1329 +#: daemon/HTTPServer.cpp:1332 daemon/HTTPServer.cpp:1335 +#: daemon/HTTPServer.cpp:1362 daemon/HTTPServer.cpp:1365 +#: daemon/HTTPServer.cpp:1379 daemon/HTTPServer.cpp:1424 +#: daemon/HTTPServer.cpp:1427 daemon/HTTPServer.cpp:1430 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:227 +#: daemon/HTTPServer.cpp:229 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:228 +#: daemon/HTTPServer.cpp:230 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:229 +#: daemon/HTTPServer.cpp:231 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:233 -#: daemon/HTTPServer.cpp:329 +#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:235 +#: daemon/HTTPServer.cpp:336 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:231 daemon/HTTPServer.cpp:374 -#: daemon/HTTPServer.cpp:375 daemon/HTTPServer.cpp:952 -#: daemon/HTTPServer.cpp:961 +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:382 +#: daemon/HTTPServer.cpp:383 daemon/HTTPServer.cpp:1003 +#: daemon/HTTPServer.cpp:1011 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:232 +#: daemon/HTTPServer.cpp:234 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:240 +#: daemon/HTTPServer.cpp:242 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:243 +#: daemon/HTTPServer.cpp:245 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:246 +#: daemon/HTTPServer.cpp:248 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:249 +#: daemon/HTTPServer.cpp:251 msgid "Full cone NAT" msgstr "" -#: daemon/HTTPServer.cpp:252 +#: daemon/HTTPServer.cpp:254 msgid "No Descriptors" msgstr "" -#: daemon/HTTPServer.cpp:261 +#: daemon/HTTPServer.cpp:263 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:264 +#: daemon/HTTPServer.cpp:266 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:269 +#: daemon/HTTPServer.cpp:271 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:275 daemon/HTTPServer.cpp:282 +#: daemon/HTTPServer.cpp:277 daemon/HTTPServer.cpp:284 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:289 +#: daemon/HTTPServer.cpp:291 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:290 +#: daemon/HTTPServer.cpp:292 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:291 +#: daemon/HTTPServer.cpp:296 +msgid "Total tunnel creation success rate" +msgstr "" + +#: daemon/HTTPServer.cpp:298 msgid "Received" msgstr "" #. tr: Kibibyte/s -#: daemon/HTTPServer.cpp:293 daemon/HTTPServer.cpp:296 -#: daemon/HTTPServer.cpp:299 +#: daemon/HTTPServer.cpp:300 daemon/HTTPServer.cpp:303 +#: daemon/HTTPServer.cpp:306 #, c-format msgid "%.2f KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:294 +#: daemon/HTTPServer.cpp:301 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:297 +#: daemon/HTTPServer.cpp:304 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:300 +#: daemon/HTTPServer.cpp:307 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:303 +#: daemon/HTTPServer.cpp:310 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:307 +#: daemon/HTTPServer.cpp:314 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:309 +#: daemon/HTTPServer.cpp:316 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:310 +#: daemon/HTTPServer.cpp:317 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:311 +#: daemon/HTTPServer.cpp:318 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:312 +#: daemon/HTTPServer.cpp:319 msgid "Our external address" msgstr "" #. tr: Shown when router doesn't publish itself and have "Firewalled" state -#: daemon/HTTPServer.cpp:341 +#: daemon/HTTPServer.cpp:349 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:355 +#: daemon/HTTPServer.cpp:363 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:356 +#: daemon/HTTPServer.cpp:364 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:363 daemon/HTTPServer.cpp:938 +#: daemon/HTTPServer.cpp:371 daemon/HTTPServer.cpp:987 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:373 +#: daemon/HTTPServer.cpp:381 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:374 daemon/HTTPServer.cpp:375 -#: daemon/HTTPServer.cpp:376 daemon/HTTPServer.cpp:377 -#: daemon/HTTPServer.cpp:378 daemon/HTTPServer.cpp:379 +#: daemon/HTTPServer.cpp:382 daemon/HTTPServer.cpp:383 +#: daemon/HTTPServer.cpp:384 daemon/HTTPServer.cpp:385 +#: daemon/HTTPServer.cpp:386 daemon/HTTPServer.cpp:387 msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:374 daemon/HTTPServer.cpp:375 -#: daemon/HTTPServer.cpp:376 daemon/HTTPServer.cpp:377 -#: daemon/HTTPServer.cpp:378 daemon/HTTPServer.cpp:379 +#: daemon/HTTPServer.cpp:382 daemon/HTTPServer.cpp:383 +#: daemon/HTTPServer.cpp:384 daemon/HTTPServer.cpp:385 +#: daemon/HTTPServer.cpp:386 daemon/HTTPServer.cpp:387 msgid "Disabled" msgstr "" -#: daemon/HTTPServer.cpp:422 +#: daemon/HTTPServer.cpp:434 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:431 +#: daemon/HTTPServer.cpp:442 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:436 +#: daemon/HTTPServer.cpp:447 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:437 +#: daemon/HTTPServer.cpp:448 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:438 +#: daemon/HTTPServer.cpp:449 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:444 +#: daemon/HTTPServer.cpp:457 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:444 +#: daemon/HTTPServer.cpp:459 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:444 +#: daemon/HTTPServer.cpp:460 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:454 daemon/HTTPServer.cpp:667 +#: daemon/HTTPServer.cpp:467 +msgid "Expire LeaseSet" +msgstr "" + +#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:697 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:489 -#: daemon/HTTPServer.cpp:681 daemon/HTTPServer.cpp:701 +#: daemon/HTTPServer.cpp:494 daemon/HTTPServer.cpp:514 +#: daemon/HTTPServer.cpp:711 daemon/HTTPServer.cpp:731 #, c-format msgid "%dms" msgstr "" -#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:686 +#: daemon/HTTPServer.cpp:499 daemon/HTTPServer.cpp:716 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:521 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:497 +#: daemon/HTTPServer.cpp:522 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:510 +#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:535 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:507 daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:532 daemon/HTTPServer.cpp:551 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:507 +#: daemon/HTTPServer.cpp:532 daemon/HTTPServer.cpp:814 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:515 +#: daemon/HTTPServer.cpp:540 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:529 +#: daemon/HTTPServer.cpp:548 daemon/HTTPServer.cpp:554 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:551 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:536 daemon/HTTPServer.cpp:594 +#: daemon/HTTPServer.cpp:561 daemon/HTTPServer.cpp:621 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:547 daemon/HTTPServer.cpp:917 +#: daemon/HTTPServer.cpp:572 daemon/HTTPServer.cpp:960 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:570 +#: daemon/HTTPServer.cpp:595 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:599 +#: daemon/HTTPServer.cpp:613 daemon/HTTPServer.cpp:1430 +msgid "Such destination is not found" +msgstr "" + +#: daemon/HTTPServer.cpp:626 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:602 +#: daemon/HTTPServer.cpp:629 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:658 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:631 +#: daemon/HTTPServer.cpp:661 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:632 +#: daemon/HTTPServer.cpp:662 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:637 +#: daemon/HTTPServer.cpp:667 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:640 +#: daemon/HTTPServer.cpp:670 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:641 +#: daemon/HTTPServer.cpp:671 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:642 +#: daemon/HTTPServer.cpp:672 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:682 msgid "floodfill mode is disabled" msgstr "" -#: daemon/HTTPServer.cpp:663 +#: daemon/HTTPServer.cpp:693 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:713 +#: daemon/HTTPServer.cpp:743 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:714 +#: daemon/HTTPServer.cpp:744 msgid "Reload tunnels configuration" msgstr "" -#: daemon/HTTPServer.cpp:717 +#: daemon/HTTPServer.cpp:747 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:749 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:723 daemon/HTTPServer.cpp:728 +#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:758 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:730 +#: daemon/HTTPServer.cpp:755 daemon/HTTPServer.cpp:760 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:733 +#: daemon/HTTPServer.cpp:763 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:734 +#: daemon/HTTPServer.cpp:764 msgid "Reload external CSS styles" msgstr "" -#: daemon/HTTPServer.cpp:737 +#: daemon/HTTPServer.cpp:767 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:739 +#: daemon/HTTPServer.cpp:770 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:747 +#: daemon/HTTPServer.cpp:779 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:752 daemon/HTTPServer.cpp:771 +#: daemon/HTTPServer.cpp:784 daemon/HTTPServer.cpp:803 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:759 +#: daemon/HTTPServer.cpp:791 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:797 +#: daemon/HTTPServer.cpp:830 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:878 daemon/HTTPServer.cpp:901 +#: daemon/HTTPServer.cpp:921 daemon/HTTPServer.cpp:944 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:894 +#: daemon/HTTPServer.cpp:937 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:907 +#: daemon/HTTPServer.cpp:950 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:912 +#: daemon/HTTPServer.cpp:955 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:969 +#: daemon/HTTPServer.cpp:1020 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:985 +#: daemon/HTTPServer.cpp:1036 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:999 +#: daemon/HTTPServer.cpp:1050 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1199 +#: daemon/HTTPServer.cpp:1250 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1218 +#: daemon/HTTPServer.cpp:1269 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1333 -#: daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:1327 daemon/HTTPServer.cpp:1359 +#: daemon/HTTPServer.cpp:1414 daemon/HTTPServer.cpp:1454 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1276 +#: daemon/HTTPServer.cpp:1327 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1278 +#: daemon/HTTPServer.cpp:1329 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1281 +#: daemon/HTTPServer.cpp:1332 daemon/HTTPServer.cpp:1365 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1284 +#: daemon/HTTPServer.cpp:1335 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1286 daemon/HTTPServer.cpp:1351 +#: daemon/HTTPServer.cpp:1337 daemon/HTTPServer.cpp:1367 +#: daemon/HTTPServer.cpp:1432 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1287 daemon/HTTPServer.cpp:1300 -#: daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:1338 daemon/HTTPServer.cpp:1368 +#: daemon/HTTPServer.cpp:1381 daemon/HTTPServer.cpp:1456 #, c-format msgid "You will be redirected in %d seconds" msgstr "" -#: daemon/HTTPServer.cpp:1298 +#: daemon/HTTPServer.cpp:1359 +msgid "LeaseSet expiration time updated" +msgstr "" + +#: daemon/HTTPServer.cpp:1362 +msgid "LeaseSet is not found or already expired" +msgstr "" + +#: daemon/HTTPServer.cpp:1379 #, c-format msgid "Transit tunnels count must not exceed %d" msgstr "" -#: daemon/HTTPServer.cpp:1299 daemon/HTTPServer.cpp:1374 +#: daemon/HTTPServer.cpp:1380 daemon/HTTPServer.cpp:1455 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1335 +#: daemon/HTTPServer.cpp:1416 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1336 +#: daemon/HTTPServer.cpp:1417 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1336 +#: daemon/HTTPServer.cpp:1417 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1418 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1343 +#: daemon/HTTPServer.cpp:1424 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1346 +#: daemon/HTTPServer.cpp:1427 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1349 -msgid "Such destination is not found" -msgstr "" - -#: daemon/HTTPServer.cpp:1369 +#: daemon/HTTPServer.cpp:1450 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:1454 msgid "Command accepted" msgstr "" @@ -624,20 +642,20 @@ msgstr "" msgid "You may try to find this host on jump services below" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:309 libi2pd_client/HTTPProxy.cpp:324 -#: libi2pd_client/HTTPProxy.cpp:392 libi2pd_client/HTTPProxy.cpp:435 +#: libi2pd_client/HTTPProxy.cpp:333 libi2pd_client/HTTPProxy.cpp:348 +#: libi2pd_client/HTTPProxy.cpp:417 libi2pd_client/HTTPProxy.cpp:460 msgid "Invalid request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:309 +#: libi2pd_client/HTTPProxy.cpp:333 msgid "Proxy unable to parse your request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:324 +#: libi2pd_client/HTTPProxy.cpp:348 msgid "Addresshelper is not supported" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:349 +#: libi2pd_client/HTTPProxy.cpp:373 #, c-format msgid "" "Host %s is already in router's addressbook. Be " @@ -645,121 +663,121 @@ msgid "" "Continue." msgstr "" -#: libi2pd_client/HTTPProxy.cpp:351 +#: libi2pd_client/HTTPProxy.cpp:375 msgid "Addresshelper forced update rejected" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:358 +#: libi2pd_client/HTTPProxy.cpp:382 #, c-format msgid "" -"To add host %s in router's addressbook, click here: Continue." +"To add host %s in router's addressbook, click here: Continue." msgstr "" -#: libi2pd_client/HTTPProxy.cpp:360 +#: libi2pd_client/HTTPProxy.cpp:384 msgid "Addresshelper request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:369 +#: libi2pd_client/HTTPProxy.cpp:393 #, c-format msgid "" "Host %s added to router's addressbook from helper. Click here to proceed: Continue." msgstr "" -#: libi2pd_client/HTTPProxy.cpp:370 +#: libi2pd_client/HTTPProxy.cpp:395 msgid "Addresshelper adding" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:377 +#: libi2pd_client/HTTPProxy.cpp:402 #, c-format msgid "" "Host %s is already in router's addressbook. Click " "here to update record: Continue." msgstr "" -#: libi2pd_client/HTTPProxy.cpp:379 +#: libi2pd_client/HTTPProxy.cpp:404 msgid "Addresshelper update" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:392 +#: libi2pd_client/HTTPProxy.cpp:417 msgid "Invalid request URI" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:435 +#: libi2pd_client/HTTPProxy.cpp:460 msgid "Can't detect destination host from request" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:452 libi2pd_client/HTTPProxy.cpp:456 +#: libi2pd_client/HTTPProxy.cpp:477 libi2pd_client/HTTPProxy.cpp:481 msgid "Outproxy failure" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:452 +#: libi2pd_client/HTTPProxy.cpp:477 msgid "Bad outproxy settings" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:455 +#: libi2pd_client/HTTPProxy.cpp:480 #, c-format msgid "Host %s is not inside I2P network, but outproxy is not enabled" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:544 +#: libi2pd_client/HTTPProxy.cpp:569 msgid "Unknown outproxy URL" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:550 +#: libi2pd_client/HTTPProxy.cpp:575 msgid "Cannot resolve upstream proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:558 +#: libi2pd_client/HTTPProxy.cpp:583 msgid "Hostname is too long" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:585 +#: libi2pd_client/HTTPProxy.cpp:610 msgid "Cannot connect to upstream SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:591 +#: libi2pd_client/HTTPProxy.cpp:616 msgid "Cannot negotiate with SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:633 +#: libi2pd_client/HTTPProxy.cpp:658 msgid "CONNECT error" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:633 +#: libi2pd_client/HTTPProxy.cpp:658 msgid "Failed to connect" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:644 libi2pd_client/HTTPProxy.cpp:670 +#: libi2pd_client/HTTPProxy.cpp:669 libi2pd_client/HTTPProxy.cpp:695 msgid "SOCKS proxy error" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:652 +#: libi2pd_client/HTTPProxy.cpp:677 msgid "Failed to send request to upstream" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:673 +#: libi2pd_client/HTTPProxy.cpp:698 msgid "No reply from SOCKS proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:680 +#: libi2pd_client/HTTPProxy.cpp:705 msgid "Cannot connect" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:680 +#: libi2pd_client/HTTPProxy.cpp:705 msgid "HTTP out proxy not implemented" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:681 +#: libi2pd_client/HTTPProxy.cpp:706 msgid "Cannot connect to upstream HTTP proxy" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:714 +#: libi2pd_client/HTTPProxy.cpp:739 msgid "Host is down" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:714 +#: libi2pd_client/HTTPProxy.cpp:739 msgid "" "Can't create connection to requested host, it may be down. Please try again " "later." diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md index 56d76c5a..1a9bd289 100644 --- a/contrib/i18n/README.md +++ b/contrib/i18n/README.md @@ -2,7 +2,7 @@ --- ``` -xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp +xgettext --omit-header -ctr: -ktr -kntr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp ``` Regex for transforming gettext translations to our format: From bb52056aec59a296df6bec7ee44184b7a4b75136 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Jun 2023 06:48:47 -0400 Subject: [PATCH 0266/1160] correct index for connected transport --- libi2pd/Transports.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index f66a8f96..8daf56ef 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -710,9 +710,9 @@ namespace transport transports |= it->second.priority[i]; i2p::data::netdb.ExcludeReachableTransports (ident, transports); } - if (it->second.router) + if (it->second.router && it->second.numAttempts) { - auto transport = it->second.priority[it->second.numAttempts]; + auto transport = it->second.priority[it->second.numAttempts-1]; if (transport == i2p::data::RouterInfo::eNTCP2V4 || transport == i2p::data::RouterInfo::eNTCP2V6 || transport == i2p::data::RouterInfo::eNTCP2V6Mesh) it->second.router->GetProfile ()->Connected (); // outgoing NTCP2 connection if always real From 52b2d6c39397f27fbeb9cab52cdf69c3fba5e0cb Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Jun 2023 15:44:16 -0400 Subject: [PATCH 0267/1160] 2.48.0 --- ChangeLog | 27 +++++++++++++++++++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b6005d4f..424aaee5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,33 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.48.0] - 2023-06-12 +### Added +- Allow user/password authentication method for SOCK5 proxy +- Publish reject all congestion cap 'G' if transit is not accepted +- 'critical' log level +- Print b32 on webconsole destination page +- Webconsole button to drop a remote LeaseSet +- limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup +- Recognize real routers if successfully connected or responded to tunnel build request +### Changed +- Bypass slow transport sessions for first hop selection +- Limit AESNI inline asm to x86/x64 +- Create smaller I2NP packets if possible +- Make router unreachable if AEAD tag verification fails in SessionCreated +- Don't include a router to floodfills list until it's confirmed as real +- Drop LeaseSet store request if not floodfill +- Bypass medium congestion('D') routers for client tunnels +- Publish encrypted RouterInfo through tunnels +- Check if s is valid x25519 public key +- Check if socket is open before sending data in SSU2 +### Fixed +- Webconsole empty page if destination is not found +- i2p.streaming.answerPings param +- Reload tunnels +- Address caps for unspecified ipv6 address +- Incomplete HTTP headers in I2P tunnels + ## [2.47.0] - 2023-03-11 ### Added - Congestion caps diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 4ee7a8df..62a28631 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.47.0 +Version: 2.48.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -158,6 +158,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Jun 12 2023 orignal - 2.48.0 +- update to 2.48.0 + * Sat Mar 11 2023 orignal - 2.47.0 - update to 2.47.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 407e2d43..19825237 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.47.0 +Version: 2.48.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Jun 12 2023 orignal - 2.48.0 +- update to 2.48.0 + * Sat Mar 11 2023 orignal - 2.47.0 - update to 2.47.0 diff --git a/debian/changelog b/debian/changelog index 44b0b8b5..91b0abdf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.48.0-1) unstable; urgency=high + + * updated to version 2.48.0/0.9.59 + + -- orignal Mon, 12 Jun 2023 16:00:00 +0000 + i2pd (2.47.0-1) unstable; urgency=high * updated to version 2.47.0/0.9.58 diff --git a/libi2pd/version.h b/libi2pd/version.h index 7d5e79fb..903ceebc 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -18,7 +18,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 47 +#define I2PD_VERSION_MINOR 48 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #ifdef GITVER @@ -33,7 +33,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 58 +#define I2P_VERSION_MICRO 59 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 3af1f4bc763d6a47d982944b6f8bcbb8eb8541a0 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 12 Jun 2023 00:32:44 +0300 Subject: [PATCH 0268/1160] Use of 'server' type tunnel port as inport (#1936) Signed-off-by: r4sas --- ChangeLog | 8 +++++--- libi2pd_client/I2PTunnel.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 424aaee5..881e05d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,9 +5,9 @@ ### Added - Allow user/password authentication method for SOCK5 proxy - Publish reject all congestion cap 'G' if transit is not accepted -- 'critical' log level +- 'critical' log level - Print b32 on webconsole destination page -- Webconsole button to drop a remote LeaseSet +- Webconsole button to drop a remote LeaseSet - limits.zombies param - minimum percentage of successfully created tunnels for routers cleanup - Recognize real routers if successfully connected or responded to tunnel build request ### Changed @@ -26,7 +26,9 @@ - i2p.streaming.answerPings param - Reload tunnels - Address caps for unspecified ipv6 address -- Incomplete HTTP headers in I2P tunnels +- Incomplete HTTP headers in I2P tunnels +- SSU2 socket network exceptions on Windows +- Use of 'server' type tunnel port as inport (#1936) ## [2.47.0] - 2023-03-11 ### Added diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index d1006f26..1118da24 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -351,7 +351,7 @@ namespace client m_InHeader.clear (); m_InHeader << line; break; - } + } } if (endOfHeader) @@ -434,12 +434,12 @@ namespace client } } else - { + { // insert incomplete line back m_InHeader.clear (); m_InHeader << line; break; - } + } } if (endOfHeader) @@ -508,12 +508,12 @@ namespace client } } else - { + { // insert incomplete line back m_InHeader.clear (); m_InHeader << line; break; - } + } } if (endOfHeader) @@ -708,10 +708,10 @@ namespace client int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { - if (!inport) inport = port; - m_PortDestination = localDestination->GetStreamingDestination (inport); - if (!m_PortDestination) // default destination - m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip); + int inPort = (inport ? inport : port); + m_PortDestination = localDestination->GetStreamingDestination (inPort); + if (!m_PortDestination) // default destination + m_PortDestination = localDestination->CreateStreamingDestination (inPort, gzip); } void I2PServerTunnel::Start () From 03cc6e05249be47be31ed1ad2c4455c6c537de75 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 12 Jun 2023 05:10:32 +0300 Subject: [PATCH 0269/1160] use uint16_t for ports Signed-off-by: r4sas --- libi2pd/Destination.cpp | 18 +++++++++--------- libi2pd/Destination.h | 18 +++++++++--------- libi2pd_client/BOB.cpp | 26 ++++++++++++++++---------- libi2pd_client/BOB.h | 20 ++++++++++---------- libi2pd_client/ClientContext.cpp | 26 +++++++++++++------------- libi2pd_client/HTTPProxy.cpp | 2 +- libi2pd_client/HTTPProxy.h | 6 +++--- libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 4 ++-- libi2pd_client/I2PService.cpp | 6 +++--- libi2pd_client/I2PService.h | 10 +++++----- libi2pd_client/I2PTunnel.cpp | 20 ++++++++++---------- libi2pd_client/I2PTunnel.h | 24 ++++++++++++------------ libi2pd_client/SAM.cpp | 4 ++-- libi2pd_client/SAM.h | 6 +++--- libi2pd_client/SOCKS.cpp | 2 +- libi2pd_client/SOCKS.h | 4 ++-- 17 files changed, 102 insertions(+), 96 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a755347d..b9555abe 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1111,7 +1111,7 @@ namespace client } } - void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, uint16_t port) { if (!streamRequestComplete) { @@ -1141,7 +1141,7 @@ namespace client } } - void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port) + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, uint16_t port) { if (!streamRequestComplete) { @@ -1160,7 +1160,7 @@ namespace client } template - std::shared_ptr ClientDestination::CreateStreamSync (const Dest& dest, int port) + std::shared_ptr ClientDestination::CreateStreamSync (const Dest& dest, uint16_t port) { volatile bool done = false; std::shared_ptr stream; @@ -1184,17 +1184,17 @@ namespace client return stream; } - std::shared_ptr ClientDestination::CreateStream (const i2p::data::IdentHash& dest, int port) + std::shared_ptr ClientDestination::CreateStream (const i2p::data::IdentHash& dest, uint16_t port) { return CreateStreamSync (dest, port); } - std::shared_ptr ClientDestination::CreateStream (std::shared_ptr dest, int port) + std::shared_ptr ClientDestination::CreateStream (std::shared_ptr dest, uint16_t port) { return CreateStreamSync (dest, port); } - std::shared_ptr ClientDestination::CreateStream (std::shared_ptr remote, int port) + std::shared_ptr ClientDestination::CreateStream (std::shared_ptr remote, uint16_t port) { if (m_StreamingDestination) return m_StreamingDestination->CreateNewOutgoingStream (remote, port); @@ -1231,7 +1231,7 @@ namespace client }); } - std::shared_ptr ClientDestination::GetStreamingDestination (int port) const + std::shared_ptr ClientDestination::GetStreamingDestination (uint16_t port) const { if (port) { @@ -1269,7 +1269,7 @@ namespace client m_StreamingDestination->AcceptOnce (acceptor); } - std::shared_ptr ClientDestination::CreateStreamingDestination (int port, bool gzip) + std::shared_ptr ClientDestination::CreateStreamingDestination (uint16_t port, bool gzip) { auto dest = std::make_shared (GetSharedFromThis (), port, gzip); if (port) @@ -1279,7 +1279,7 @@ namespace client return dest; } - std::shared_ptr ClientDestination::RemoveStreamingDestination (int port) + std::shared_ptr ClientDestination::RemoveStreamingDestination (uint16_t port) { if (port) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 76508e49..3b395f4d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -242,15 +242,15 @@ namespace client int GetRefCounter () const { return m_RefCounter; }; // streaming - std::shared_ptr CreateStreamingDestination (int port, bool gzip = true); // additional - std::shared_ptr GetStreamingDestination (int port = 0) const; - std::shared_ptr RemoveStreamingDestination (int port); + std::shared_ptr CreateStreamingDestination (uint16_t port, bool gzip = true); // additional + std::shared_ptr GetStreamingDestination (uint16_t port = 0) const; + std::shared_ptr RemoveStreamingDestination (uint16_t port); // following methods operate with default streaming destination - void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0); - void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port = 0); - std::shared_ptr CreateStream (const i2p::data::IdentHash& dest, int port = 0); // sync - std::shared_ptr CreateStream (std::shared_ptr dest, int port = 0); // sync - std::shared_ptr CreateStream (std::shared_ptr remote, int port = 0); + void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, uint16_t port = 0); + void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, uint16_t port = 0); + std::shared_ptr CreateStream (const i2p::data::IdentHash& dest, uint16_t port = 0); // sync + std::shared_ptr CreateStream (std::shared_ptr dest, uint16_t port = 0); // sync + std::shared_ptr CreateStream (std::shared_ptr remote, uint16_t port = 0); void SendPing (const i2p::data::IdentHash& to); void SendPing (std::shared_ptr to); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); @@ -286,7 +286,7 @@ namespace client void ReadAuthKey (const std::string& group, const std::map * params); template - std::shared_ptr CreateStreamSync (const Dest& dest, int port); + std::shared_ptr CreateStreamSync (const Dest& dest, uint16_t port); private: diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 5f738380..3e6590f2 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -127,7 +127,7 @@ namespace client connection->I2PConnect (receiver->data, receiver->dataLen); } - BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, int port, + BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, uint16_t port, std::shared_ptr localDestination, bool quiet): BOBI2PTunnel (localDestination), m_Endpoint (boost::asio::ip::address::from_string (outhost), port), m_IsQuiet (quiet) { @@ -164,7 +164,7 @@ namespace client BOBDestination::BOBDestination (std::shared_ptr localDestination, const std::string &nickname, const std::string &inhost, const std::string &outhost, - const int inport, const int outport, const bool quiet): + const uint16_t inport, const uint16_t outport, const bool quiet): m_LocalDestination (localDestination), m_OutboundTunnel (nullptr), m_InboundTunnel (nullptr), m_Nickname(nickname), m_InHost(inhost), m_OutHost(outhost), @@ -209,7 +209,7 @@ namespace client } } - void BOBDestination::CreateInboundTunnel (int port, const std::string& inhost) + void BOBDestination::CreateInboundTunnel (uint16_t port, const std::string& inhost) { if (!m_InboundTunnel) { @@ -230,7 +230,7 @@ namespace client } } - void BOBDestination::CreateOutboundTunnel (const std::string& outhost, int port, bool quiet) + void BOBDestination::CreateOutboundTunnel (const std::string& outhost, uint16_t port, bool quiet) { if (!m_OutboundTunnel) { @@ -595,9 +595,12 @@ namespace client LogPrint (eLogDebug, "BOB: outport ", operand); if (*operand) { - m_OutPort = std::stoi(operand); - if (m_OutPort >= 0) + int port = std::stoi(operand); + if (port >= 0 && port < 65536) + { + m_OutPort = port; SendReplyOK ("outbound port set"); + } else SendReplyError ("port out of range"); } @@ -622,9 +625,12 @@ namespace client LogPrint (eLogDebug, "BOB: inport ", operand); if (*operand) { - m_InPort = std::stoi(operand); - if (m_InPort >= 0) + int port = std::stoi(operand); + if (port >= 0 && port < 65536) + { + m_InPort = port; SendReplyOK ("inbound port set"); + } else SendReplyError ("port out of range"); } @@ -814,7 +820,7 @@ namespace client } } - BOBCommandChannel::BOBCommandChannel (const std::string& address, int port): + BOBCommandChannel::BOBCommandChannel (const std::string& address, uint16_t port): RunnableService ("BOB"), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) { diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 2e6314e2..8b0b31d2 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -124,7 +124,7 @@ namespace client { public: - BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); + BOBI2POutboundTunnel (const std::string& outhost, uint16_t port, std::shared_ptr localDestination, bool quiet); void Start (); void Stop (); @@ -149,19 +149,19 @@ namespace client BOBDestination (std::shared_ptr localDestination, const std::string &nickname, const std::string &inhost, const std::string &outhost, - const int inport, const int outport, const bool quiet); + const uint16_t inport, const uint16_t outport, const bool quiet); ~BOBDestination (); void Start (); void Stop (); void StopTunnels (); - void CreateInboundTunnel (int port, const std::string& inhost); - void CreateOutboundTunnel (const std::string& outhost, int port, bool quiet); + void CreateInboundTunnel (uint16_t port, const std::string& inhost); + void CreateOutboundTunnel (const std::string& outhost, uint16_t port, bool quiet); const std::string& GetNickname() const { return m_Nickname; } const std::string& GetInHost() const { return m_InHost; } const std::string& GetOutHost() const { return m_OutHost; } - int GetInPort() const { return m_InPort; } - int GetOutPort() const { return m_OutPort; } + uint16_t GetInPort() const { return m_InPort; } + uint16_t GetOutPort() const { return m_OutPort; } bool GetQuiet() const { return m_Quiet; } bool IsRunning() const { return m_IsRunning; } const i2p::data::PrivateKeys& GetKeys () const { return m_LocalDestination->GetPrivateKeys (); }; @@ -175,7 +175,7 @@ namespace client std::string m_Nickname; std::string m_InHost, m_OutHost; - int m_InPort, m_OutPort; + uint16_t m_InPort, m_OutPort; bool m_Quiet; bool m_IsRunning; }; @@ -237,7 +237,7 @@ namespace client boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; bool m_IsOpen, m_IsQuiet, m_IsActive; std::string m_Nickname, m_InHost, m_OutHost; - int m_InPort, m_OutPort; + uint16_t m_InPort, m_OutPort; i2p::data::PrivateKeys m_Keys; std::map m_Options; BOBDestination * m_CurrentDestination; @@ -248,7 +248,7 @@ namespace client { public: - BOBCommandChannel (const std::string& address, int port); + BOBCommandChannel (const std::string& address, uint16_t port); ~BOBCommandChannel (); void Start (); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index afb34c2a..829756a1 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -577,12 +577,12 @@ namespace client std::string dest; if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); - int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); + uint16_t port = section.second.get (I2P_CLIENT_TUNNEL_PORT); // optional params - bool matchTunnels = section.second.get(I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false); - std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "transient"); - std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); - int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + bool matchTunnels = section.second.get (I2P_CLIENT_TUNNEL_MATCH_TUNNELS, false); + std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "transient"); + std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); + uint16_t destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); // I2CP @@ -720,22 +720,22 @@ namespace client { // mandatory params std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); - int port = section.second.get (I2P_SERVER_TUNNEL_PORT); + uint16_t port = section.second.get (I2P_SERVER_TUNNEL_PORT); std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); // optional params - int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); - std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); + uint16_t inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); + std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); if(accessList == "") - accessList=section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, ""); - std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); + accessList = section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, ""); + std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, false); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, ""); - bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); - bool ssl = section.second.get(I2P_SERVER_TUNNEL_SSL, false); + bool isUniqueLocal = section.second.get (I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); + bool ssl = section.second.get (I2P_SERVER_TUNNEL_SSL, false); // I2CP std::map options; diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 61930876..26b47d8b 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -748,7 +748,7 @@ namespace proxy { Done (shared_from_this()); } - HTTPProxy::HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination): + HTTPProxy::HTTPProxy(const std::string& name, const std::string& address, uint16_t port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination): TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name), m_OutproxyUrl (outproxy), m_Addresshelper (addresshelper) { diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 69ed4cef..d819a53c 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,8 +15,8 @@ namespace proxy { { public: - HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination); - HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr localDestination = nullptr) : + HTTPProxy(const std::string& name, const std::string& address, uint16_t port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination); + HTTPProxy(const std::string& name, const std::string& address, uint16_t port, std::shared_ptr localDestination = nullptr) : HTTPProxy(name, address, port, "", true, localDestination) {} ; ~HTTPProxy() {}; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 87f37e5e..2c53e766 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -936,7 +936,7 @@ namespace client } } - I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): + I2CPServer::I2CPServer (const std::string& interface, uint16_t port, bool isSingleThread): RunnableService ("I2CP"), m_IsSingleThread (isSingleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index e38da0ac..f0081ef6 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -210,7 +210,7 @@ namespace client { public: - I2CPServer (const std::string& interface, int port, bool isSingleThread); + I2CPServer (const std::string& interface, uint16_t port, bool isSingleThread); ~I2CPServer (); void Start (); diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 2a6fe44e..c30b7c9f 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -107,7 +107,7 @@ namespace client m_ReadyTimerTriggered = false; } - void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) { + void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, uint16_t port) { assert(streamRequestComplete); auto address = i2p::client::context.GetAddressBook ().GetAddress (dest); if (address) @@ -119,7 +119,7 @@ namespace client } } - void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr address, int port) + void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr address, uint16_t port) { if(m_ConnectTimeout && !m_LocalDestination->IsReady()) { diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index e14f85c1..4f67e19c 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -59,8 +59,8 @@ namespace client if (dest) dest->Acquire (); m_LocalDestination = dest; } - void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0); - void CreateStream(StreamRequestComplete complete, std::shared_ptr address, int port); + void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, uint16_t port = 0); + void CreateStream(StreamRequestComplete complete, std::shared_ptr address, uint16_t port); inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } virtual void Start () = 0; @@ -155,11 +155,11 @@ namespace client { public: - TCPIPAcceptor (const std::string& address, int port, std::shared_ptr localDestination = nullptr) : + TCPIPAcceptor (const std::string& address, uint16_t port, std::shared_ptr localDestination = nullptr) : I2PService(localDestination), m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), m_Timer (GetService ()) {} - TCPIPAcceptor (const std::string& address, int port, i2p::data::SigningKeyType kt) : + TCPIPAcceptor (const std::string& address, uint16_t port, i2p::data::SigningKeyType kt) : I2PService(kt), m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), m_Timer (GetService ()) {} diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 1118da24..9a9a4988 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -31,7 +31,7 @@ namespace client } I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, - std::shared_ptr leaseSet, int port): + std::shared_ptr leaseSet, uint16_t port): I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) { @@ -581,7 +581,7 @@ namespace client { public: I2PClientTunnelHandler (I2PClientTunnel * parent, std::shared_ptr address, - int destinationPort, std::shared_ptr socket): + uint16_t destinationPort, std::shared_ptr socket): I2PServiceHandler(parent), m_Address(address), m_DestinationPort (destinationPort), m_Socket(socket) {}; void Handle(); @@ -589,7 +589,7 @@ namespace client private: void HandleStreamRequestComplete (std::shared_ptr stream); std::shared_ptr m_Address; - int m_DestinationPort; + uint16_t m_DestinationPort; std::shared_ptr m_Socket; }; @@ -630,7 +630,7 @@ namespace client } I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, - const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): + const std::string& address, uint16_t port, std::shared_ptr localDestination, uint16_t destinationPort): TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), m_DestinationPort (destinationPort), m_KeepAliveInterval (0) { @@ -705,10 +705,10 @@ namespace client } I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, int inport, bool gzip): + uint16_t port, std::shared_ptr localDestination, uint16_t inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { - int inPort = (inport ? inport : port); + uint16_t inPort = (inport ? inport : port); m_PortDestination = localDestination->GetStreamingDestination (inPort); if (!m_PortDestination) // default destination m_PortDestination = localDestination->CreateStreamingDestination (inPort, gzip); @@ -870,8 +870,8 @@ namespace client } I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, - const std::string& host, int inport, bool gzip): + uint16_t port, std::shared_ptr localDestination, + const std::string& host, uint16_t inport, bool gzip): I2PServerTunnel (name, address, port, localDestination, inport, gzip), m_Host (host) { @@ -883,8 +883,8 @@ namespace client } I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, - const std::string& webircpass, int inport, bool gzip): + uint16_t port, std::shared_ptr localDestination, + const std::string& webircpass, uint16_t inport, bool gzip): I2PServerTunnel (name, address, port, localDestination, inport, gzip), m_WebircPass (webircpass) { diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 4c7b2002..b94eb9e4 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -41,7 +41,7 @@ namespace client public: I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, - std::shared_ptr leaseSet, int port = 0); // to I2P + std::shared_ptr leaseSet, uint16_t port = 0); // to I2P I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream); // to I2P using simplified API I2PTunnelConnection (I2PService * owner, std::shared_ptr stream, @@ -154,7 +154,7 @@ namespace client public: I2PClientTunnel (const std::string& name, const std::string& destination, - const std::string& address, int port, std::shared_ptr localDestination, int destinationPort = 0); + const std::string& address, uint16_t port, std::shared_ptr localDestination, uint16_t destinationPort = 0); ~I2PClientTunnel () {} void Start (); @@ -174,7 +174,7 @@ namespace client std::string m_Name, m_Destination; std::shared_ptr m_Address; - int m_DestinationPort; + uint16_t m_DestinationPort; uint32_t m_KeepAliveInterval; std::unique_ptr m_KeepAliveTimer; }; @@ -183,8 +183,8 @@ namespace client { public: - I2PServerTunnel (const std::string& name, const std::string& address, int port, - std::shared_ptr localDestination, int inport = 0, bool gzip = true); + I2PServerTunnel (const std::string& name, const std::string& address, uint16_t port, + std::shared_ptr localDestination, uint16_t inport = 0, bool gzip = true); void Start (); void Stop (); @@ -200,7 +200,7 @@ namespace client void SetLocalAddress (const std::string& localAddress); const std::string& GetAddress() const { return m_Address; } - int GetPort () const { return m_Port; }; + uint16_t GetPort () const { return m_Port; }; uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); }; const boost::asio::ip::tcp::endpoint& GetEndpoint () const { return m_Endpoint; } @@ -219,7 +219,7 @@ namespace client bool m_IsUniqueLocal; std::string m_Name, m_Address; - int m_Port; + uint16_t m_Port; boost::asio::ip::tcp::endpoint m_Endpoint; std::shared_ptr m_PortDestination; std::set m_AccessList; @@ -232,9 +232,9 @@ namespace client { public: - I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port, + I2PServerTunnelHTTP (const std::string& name, const std::string& address, uint16_t port, std::shared_ptr localDestination, const std::string& host, - int inport = 0, bool gzip = true); + uint16_t inport = 0, bool gzip = true); private: @@ -249,9 +249,9 @@ namespace client { public: - I2PServerTunnelIRC (const std::string& name, const std::string& address, int port, + I2PServerTunnelIRC (const std::string& name, const std::string& address, uint16_t port, std::shared_ptr localDestination, const std::string& webircpass, - int inport = 0, bool gzip = true); + uint16_t inport = 0, bool gzip = true); private: diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 4e19990a..bb9d6a6b 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1217,7 +1217,7 @@ namespace client subsessions.clear (); } - SAMSubSession::SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, int port): + SAMSubSession::SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, uint16_t port): SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port) { if (Type == eSAMSessionTypeStream) @@ -1244,7 +1244,7 @@ namespace client // TODO: implement datagrams } - SAMBridge::SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread): + SAMBridge::SAMBridge (const std::string& address, uint16_t portTCP, uint16_t portUDP, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), portTCP)), m_DatagramEndpoint (boost::asio::ip::address::from_string(address), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 97ac0b8e..b4c72754 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -221,9 +221,9 @@ namespace client struct SAMSubSession: public SAMSession { std::shared_ptr masterSession; - int inPort; + uint16_t inPort; - SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, int port); + SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, uint16_t port); // implements SAMSession std::shared_ptr GetLocalDestination (); void StopLocalDestination (); @@ -233,7 +233,7 @@ namespace client { public: - SAMBridge (const std::string& address, int portTCP, int portUDP, bool singleThread); + SAMBridge (const std::string& address, uint16_t portTCP, uint16_t portUDP, bool singleThread); ~SAMBridge (); void Start (); diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index c40cb479..693c5185 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -837,7 +837,7 @@ namespace proxy shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, int port, + SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, uint16_t port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination) : TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name) diff --git a/libi2pd_client/SOCKS.h b/libi2pd_client/SOCKS.h index f41cfd72..bd88d6e6 100644 --- a/libi2pd_client/SOCKS.h +++ b/libi2pd_client/SOCKS.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -23,7 +23,7 @@ namespace proxy { public: - SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort, + SOCKSServer(const std::string& name, const std::string& address, uint16_t port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination = nullptr); ~SOCKSServer() {}; From a0795d85341b86f56893bb5e49cf1938467cd280 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 12 Jun 2023 05:12:07 +0300 Subject: [PATCH 0270/1160] set server tunnel inport in ClientContext from port (#1936) Signed-off-by: r4sas --- libi2pd_client/ClientContext.cpp | 2 +- libi2pd_client/I2PTunnel.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 829756a1..d8c0bd2d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -723,7 +723,7 @@ namespace client uint16_t port = section.second.get (I2P_SERVER_TUNNEL_PORT); std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); // optional params - uint16_t inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); + uint16_t inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, port); std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); if(accessList == "") accessList = section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, ""); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 9a9a4988..ad4e14b8 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -708,10 +708,9 @@ namespace client uint16_t port, std::shared_ptr localDestination, uint16_t inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { - uint16_t inPort = (inport ? inport : port); - m_PortDestination = localDestination->GetStreamingDestination (inPort); + m_PortDestination = localDestination->GetStreamingDestination (inport); if (!m_PortDestination) // default destination - m_PortDestination = localDestination->CreateStreamingDestination (inPort, gzip); + m_PortDestination = localDestination->CreateStreamingDestination (inport, gzip); } void I2PServerTunnel::Start () From fba23a45286f844710fa5c561ba60430ebc70d5e Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 12 Jun 2023 16:33:21 +0300 Subject: [PATCH 0271/1160] i18n: update translations Signed-off-by: r4sas --- contrib/i18n/README.md | 9 +++++---- i18n/Chinese.cpp | 2 +- i18n/French.cpp | 18 +++++++++++------- i18n/Russian.cpp | 6 +++++- i18n/Swedish.cpp | 14 +++++++++++++- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md index 1a9bd289..ce775ecb 100644 --- a/contrib/i18n/README.md +++ b/contrib/i18n/README.md @@ -8,6 +8,11 @@ xgettext --omit-header -ctr: -ktr -kntr:1,2 daemon/HTTPServer.cpp libi2pd_client Regex for transforming gettext translations to our format: --- +``` +in: ^(\"|#[:.,]|msgctxt)(.*)$\n +out: +``` + ``` in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\n(msgstr\[1\]\ \"(.*)\"\n)?(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? out: #{"$2", {"$3", "$5", "$7", "$9", "$11"}},\n @@ -18,10 +23,6 @@ in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n out: {"$1", "$2"},\n ``` -``` -in: ^#[:.,](.*)$\n -out: -``` ``` in: \n\n diff --git a/i18n/Chinese.cpp b/i18n/Chinese.cpp index cd38fa0f..5ecfe067 100644 --- a/i18n/Chinese.cpp +++ b/i18n/Chinese.cpp @@ -109,6 +109,7 @@ namespace chinese // language namespace {"Local Destination", "本地目标"}, {"Streams", "流"}, {"Close stream", "断开流"}, + {"Such destination is not found", "找不到此目标"}, {"I2CP session not found", "未找到 I2CP 会话"}, {"I2CP is not enabled", "I2CP 未启用"}, {"Invalid", "无效"}, @@ -158,7 +159,6 @@ namespace chinese // language namespace {"Submit", "提交"}, {"Domain can't end with .b32.i2p", "域名不能以 .b32.i2p 结尾"}, {"Domain must end with .i2p", "域名必须以 .i2p 结尾"}, - {"Such destination is not found", "找不到此目标"}, {"Unknown command", "未知指令"}, {"Command accepted", "已接受指令"}, {"Proxy error", "代理错误"}, diff --git a/i18n/French.cpp b/i18n/French.cpp index 0ce044e1..8bec887c 100644 --- a/i18n/French.cpp +++ b/i18n/French.cpp @@ -69,6 +69,7 @@ namespace french // language namespace {"Stopping in", "Arrêt dans"}, {"Family", "Famille"}, {"Tunnel creation success rate", "Taux de succès de création de tunnels"}, + {"Total tunnel creation success rate", "Taux de réussite de création de tunnel"}, {"Received", "Reçu"}, {"%.2f KiB/s", "%.2f Kio/s"}, {"Sent", "Envoyé"}, @@ -91,10 +92,11 @@ namespace french // language namespace {"Address registration line", "Ligne d'inscription de l'adresse"}, {"Domain", "Domaine"}, {"Generate", "Générer"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Note: La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Note : La chaîne résultante peut seulement être utilisée pour enregistrer les domaines 2LD (exemple.i2p). Pour enregistrer des sous-domaines, veuillez utiliser i2pd-tools."}, {"Address", "Adresse"}, {"Type", "Type"}, {"EncType", "EncType"}, + {"Expire LeaseSet", "Expiration du LeaseSet"}, {"Inbound tunnels", "Tunnels entrants"}, {"%dms", "%dms"}, {"Outbound tunnels", "Tunnels sortants"}, @@ -109,6 +111,7 @@ namespace french // language namespace {"Local Destination", "Destination locale"}, {"Streams", "Flux"}, {"Close stream", "Fermer le flux"}, + {"Such destination is not found", "Cette destination est introuvable"}, {"I2CP session not found", "Session I2CP introuvable"}, {"I2CP is not enabled", "I2CP est désactivé"}, {"Invalid", "Invalide"}, @@ -128,7 +131,7 @@ namespace french // language namespace {"Start graceful shutdown", "Démarrer l'arrêt gracieux"}, {"Force shutdown", "Forcer l'arrêt"}, {"Reload external CSS styles", "Rafraîchir les styles CSS externes"}, - {"Note: any action done here are not persistent and not changes your config files.", "Note: Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."}, + {"Note: any action done here are not persistent and not changes your config files.", "Note : Toute action effectuée ici n'est pas permanente et ne modifie pas vos fichiers de configuration."}, {"Logging level", "Niveau de journalisation"}, {"Transit tunnels limit", "Limite sur les tunnels transitoires"}, {"Change", "Changer"}, @@ -150,6 +153,8 @@ namespace french // language namespace {"StreamID can't be null", "StreamID ne peut pas être vide"}, {"Return to destination page", "Retourner à la page de destination"}, {"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"}, + {"LeaseSet expiration time updated", "Temps d'expiration du LeaseSet mis à jour"}, + {"LeaseSet is not found or already expired", "Le LeaseSet est introuvable ou a déjà expirée"}, {"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"}, {"Back to commands list", "Retour à la liste des commandes"}, {"Register at reg.i2p", "Inscription à reg.i2p"}, @@ -158,24 +163,23 @@ namespace french // language namespace {"Submit", "Soumettre"}, {"Domain can't end with .b32.i2p", "Le domaine ne peut pas terminer par .b32.i2p"}, {"Domain must end with .i2p", "Le domaine doit terminer par .i2p"}, - {"Such destination is not found", "Cette destination est introuvable"}, {"Unknown command", "Commande inconnue"}, {"Command accepted", "Commande acceptée"}, {"Proxy error", "Erreur de proxy"}, {"Proxy info", "Information sur le proxy"}, - {"Proxy error: Host not found", "Erreur de proxy: Hôte introuvable"}, + {"Proxy error: Host not found", "Erreur de proxy : Hôte introuvable"}, {"Remote host not found in router's addressbook", "Hôte distant introuvable dans le carnet d'adresse du routeur"}, {"You may try to find this host on jump services below", "Vous pouvez essayer de trouver cet hôte sur des services de redirection ci-dessous"}, {"Invalid request", "Requête invalide"}, {"Proxy unable to parse your request", "Proxy incapable de comprendre votre requête"}, {"Addresshelper is not supported", "Assistant d'adresse non supporté"}, - {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Attention : la source de cette URL peut être nuisible ! Cliquez ici pour mettre à jour l'enregistrement : Continuer."}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Attention : la source de cette URL peut être nuisible ! Cliquez ici pour mettre à jour l'enregistrement : Continuer."}, {"Addresshelper forced update rejected", "Mise à jour forcée des assistants d'adresses rejetée"}, - {"To add host %s in router's addressbook, click here: Continue.", "Pour ajouter l'hôte %s au carnet d'adresses du routeur, cliquez ici : Continuer."}, + {"To add host %s in router's addressbook, click here: Continue.", "Pour ajouter l'hôte %s au carnet d'adresses du routeur, cliquez ici : Continuer."}, {"Addresshelper request", "Demande à l'assistant d'adresse"}, {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "L'hôte %s a été ajouté au carnet d'adresses du routeur depuis l'assistant. Cliquez ici pour continuer : Continuer."}, {"Addresshelper adding", "Ajout de l'assistant d'adresse"}, - {"Host %s is already in router's addressbook. Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Cliquez ici pour mettre à jour le dossier : Continuer."}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "L'hôte %s est déjà dans le carnet d'adresses du routeur. Cliquez ici pour mettre à jour le dossier : Continuer."}, {"Addresshelper update", "Mise à jour de l'assistant d'adresse"}, {"Invalid request URI", "URI de la requête invalide"}, {"Can't detect destination host from request", "Impossible de détecter l'hôte de destination à partir de la requête"}, diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index dbfb13f2..15952710 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -69,6 +69,7 @@ namespace russian // language namespace {"Stopping in", "Остановка через"}, {"Family", "Семейство"}, {"Tunnel creation success rate", "Успешно построенных туннелей"}, + {"Total tunnel creation success rate", "Общий процент успешно построенных туннелей"}, {"Received", "Получено"}, {"%.2f KiB/s", "%.2f КиБ/с"}, {"Sent", "Отправлено"}, @@ -95,6 +96,7 @@ namespace russian // language namespace {"Address", "Адрес"}, {"Type", "Тип"}, {"EncType", "ТипШифр"}, + {"Expire LeaseSet", "Просрочить Лизсет"}, {"Inbound tunnels", "Входящие туннели"}, {"%dms", "%dмс"}, {"Outbound tunnels", "Исходящие туннели"}, @@ -109,6 +111,7 @@ namespace russian // language namespace {"Local Destination", "Локальное назначение"}, {"Streams", "Стримы"}, {"Close stream", "Закрыть стрим"}, + {"Such destination is not found", "Такая точка назначения не найдена"}, {"I2CP session not found", "I2CP сессия не найдена"}, {"I2CP is not enabled", "I2CP не включен"}, {"Invalid", "Некорректный"}, @@ -150,6 +153,8 @@ namespace russian // language namespace {"StreamID can't be null", "StreamID не может быть пустым"}, {"Return to destination page", "Вернуться на страницу точки назначения"}, {"You will be redirected in %d seconds", "Вы будете переадресованы через %d секунд"}, + {"LeaseSet expiration time updated", "Время действия LeaseSet обновлено"}, + {"LeaseSet is not found or already expired", "Лизсет не найден или время действия уже истекло"}, {"Transit tunnels count must not exceed %d", "Число транзитных туннелей не должно превышать %d"}, {"Back to commands list", "Вернуться к списку команд"}, {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, @@ -158,7 +163,6 @@ namespace russian // language namespace {"Submit", "Отправить"}, {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, - {"Such destination is not found", "Такая точка назначения не найдена"}, {"Unknown command", "Неизвестная команда"}, {"Command accepted", "Команда принята"}, {"Proxy error", "Ошибка прокси"}, diff --git a/i18n/Swedish.cpp b/i18n/Swedish.cpp index e7f84e69..05ed1e18 100644 --- a/i18n/Swedish.cpp +++ b/i18n/Swedish.cpp @@ -61,6 +61,8 @@ namespace swedish // language namespace {"Clock skew", "Tidsförskjutning"}, {"Offline", "Nedkopplad"}, {"Symmetric NAT", "Symmetrisk NAT"}, + {"Full cone NAT", "Full kon NAT"}, + {"No Descriptors", "Inga Beskrivningar"}, {"Uptime", "Upptid"}, {"Network status", "Nätverkstillstånd"}, {"Network status v6", "Nätverkstillstånd v6"}, @@ -107,6 +109,7 @@ namespace swedish // language namespace {"Local Destination", "Lokal Plats"}, {"Streams", "Strömmar"}, {"Close stream", "Stäng strömmen"}, + {"Such destination is not found", "En sådan plats hittas ej"}, {"I2CP session not found", "I2CP-period hittades inte"}, {"I2CP is not enabled", "I2CP är inte påslaget"}, {"Invalid", "Ogiltig"}, @@ -116,8 +119,10 @@ namespace swedish // language namespace {"Gateway", "Gateway"}, {"TunnelID", "TunnelID"}, {"EndDate", "EndDate"}, + {"floodfill mode is disabled", "Floodfill läget är inaktiverat"}, {"Queue size", "Köstorlek"}, {"Run peer test", "Utför utsiktstest"}, + {"Reload tunnels configuration", "Ladda om tunnelkonfiguration"}, {"Decline transit tunnels", "Avvisa förmedlande tunnlar"}, {"Accept transit tunnels", "Tillåt förmedlande tunnlar"}, {"Cancel graceful shutdown", "Avbryt välvillig avstängning"}, @@ -154,7 +159,6 @@ namespace swedish // language namespace {"Submit", "Skicka"}, {"Domain can't end with .b32.i2p", "Domänen får inte sluta med .b32.i2p"}, {"Domain must end with .i2p", "Domänen måste sluta med .i2p"}, - {"Such destination is not found", "En sådan plats hittas ej"}, {"Unknown command", "Okänt kommando"}, {"Command accepted", "Kommando accepterades"}, {"Proxy error", "Proxyfel"}, @@ -165,6 +169,14 @@ namespace swedish // language namespace {"Invalid request", "Ogiltig förfrågan"}, {"Proxy unable to parse your request", "Proxyt kan inte behandla din förfrågan"}, {"Addresshelper is not supported", "Adresshjälparen stöds ej"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Värd %s är redan i routerns adressbok. Var försiktig: källan till denna URL kan vara skadlig! Klicka här för att uppdatera registreringen: Fortsätt."}, + {"Addresshelper forced update rejected", "Tvingad uppdatering av adresshjälparen nekad"}, + {"To add host %s in router's addressbook, click here: Continue.", "För att lägga till värd %s i routerns adressbok, klicka här: Fortsätt."}, + {"Addresshelper request", "Adresshjälpare förfrågan"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Värd %s tillagd i routerns adressbok från hjälparen. Klicka här för att fortsätta: Fortsätt."}, + {"Addresshelper adding", "Adresshjälpare tilläggning"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Värd %s är redan i routerns adressbok. Klicka här för att uppdatera registreringen: Fortsätt."}, + {"Addresshelper update", "Adresshjälpare uppdatering"}, {"Invalid request URI", "Ogiltig förfrågnings-URI"}, {"Can't detect destination host from request", "Kan inte upptäcka platsvärden från förfrågan"}, {"Outproxy failure", "Utproxyfel"}, From ca02b5d860d7989c44355f9cbc35bc0e2449638d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Jun 2023 14:45:34 +0000 Subject: [PATCH 0272/1160] debian: add compat patches for previous releases Signed-off-by: R4SAS --- contrib/debian/README | 7 +++++-- contrib/debian/bionic/compat | 1 + contrib/debian/bionic/control | 18 ++++++++++++++++++ contrib/debian/trusty/compat | 1 + contrib/debian/trusty/control | 18 ++++++++++++++++++ contrib/debian/trusty/patches/01-upnp.patch | 17 +++++++++++++++++ .../debian/trusty/patches/02-service.patch | 19 +++++++++++++++++++ contrib/debian/trusty/patches/series | 2 ++ contrib/debian/trusty/rules | 18 ++++++++++++++++++ contrib/debian/xenial/compat | 1 + contrib/debian/xenial/control | 18 ++++++++++++++++++ contrib/debian/xenial/patches/01-upnp.patch | 17 +++++++++++++++++ .../debian/xenial/patches/02-service.patch | 19 +++++++++++++++++++ contrib/debian/xenial/patches/series | 2 ++ contrib/debian/xenial/rules | 13 +++++++++++++ 15 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 contrib/debian/bionic/compat create mode 100644 contrib/debian/bionic/control create mode 100644 contrib/debian/trusty/compat create mode 100644 contrib/debian/trusty/control create mode 100644 contrib/debian/trusty/patches/01-upnp.patch create mode 100644 contrib/debian/trusty/patches/02-service.patch create mode 100644 contrib/debian/trusty/patches/series create mode 100755 contrib/debian/trusty/rules create mode 100644 contrib/debian/xenial/compat create mode 100644 contrib/debian/xenial/control create mode 100644 contrib/debian/xenial/patches/01-upnp.patch create mode 100644 contrib/debian/xenial/patches/02-service.patch create mode 100644 contrib/debian/xenial/patches/series create mode 100755 contrib/debian/xenial/rules diff --git a/contrib/debian/README b/contrib/debian/README index cccbc4de..7dc3a61f 100644 --- a/contrib/debian/README +++ b/contrib/debian/README @@ -1,2 +1,5 @@ -This forder contain systemd unit files. -To use systemd daemon control, place files from this directory to debian folder before building package. +This forder contain files required for building debian packages. + +The trunk repository is contains the packaging files for the latest stable version of Debian (if we not forgot to update them). + +Files in subdirectories contains fixes to make possible to build package on specific versions of Debian/Ubuntu. They are used when building the release package. diff --git a/contrib/debian/bionic/compat b/contrib/debian/bionic/compat new file mode 100644 index 00000000..b4de3947 --- /dev/null +++ b/contrib/debian/bionic/compat @@ -0,0 +1 @@ +11 diff --git a/contrib/debian/bionic/control b/contrib/debian/bionic/control new file mode 100644 index 00000000..d872881c --- /dev/null +++ b/contrib/debian/bionic/control @@ -0,0 +1,18 @@ +Source: i2pd +Section: net +Priority: optional +Maintainer: r4sas +Build-Depends: debhelper (>= 11~), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev +Standards-Version: 4.2.0 +Homepage: http://i2pd.website/ +Vcs-Git: git://github.com/PurpleI2P/i2pd.git +Vcs-Browser: https://github.com/PurpleI2P/i2pd + +Package: i2pd +Architecture: any +Pre-Depends: ${misc:Pre-Depends}, adduser +Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, +Description: Full-featured C++ implementation of I2P client. + I2P (Invisible Internet Protocol) is a universal anonymous network layer. All + communications over I2P are anonymous and end-to-end encrypted, participants + don't reveal their real IP addresses. diff --git a/contrib/debian/trusty/compat b/contrib/debian/trusty/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/contrib/debian/trusty/compat @@ -0,0 +1 @@ +9 diff --git a/contrib/debian/trusty/control b/contrib/debian/trusty/control new file mode 100644 index 00000000..fc618ddc --- /dev/null +++ b/contrib/debian/trusty/control @@ -0,0 +1,18 @@ +Source: i2pd +Section: net +Priority: optional +Maintainer: r4sas +Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev +Standards-Version: 3.9.8 +Homepage: http://i2pd.website/ +Vcs-Git: git://github.com/PurpleI2P/i2pd.git +Vcs-Browser: https://github.com/PurpleI2P/i2pd + +Package: i2pd +Architecture: any +Pre-Depends: ${misc:Pre-Depends}, adduser +Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, +Description: Full-featured C++ implementation of I2P client. + I2P (Invisible Internet Protocol) is a universal anonymous network layer. All + communications over I2P are anonymous and end-to-end encrypted, participants + don't reveal their real IP addresses. diff --git a/contrib/debian/trusty/patches/01-upnp.patch b/contrib/debian/trusty/patches/01-upnp.patch new file mode 100644 index 00000000..bec8f2b0 --- /dev/null +++ b/contrib/debian/trusty/patches/01-upnp.patch @@ -0,0 +1,17 @@ +Description: Enable UPnP usage in package +Author: r4sas + +Reviewed-By: r4sas +Last-Update: 2022-03-23 + +--- i2pd.orig/Makefile ++++ i2pd/Makefile +@@ -31,7 +31,7 @@ include filelist.mk + + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) + + # for debugging purposes only, when commit hash needed in trunk builds in i2pd version string diff --git a/contrib/debian/trusty/patches/02-service.patch b/contrib/debian/trusty/patches/02-service.patch new file mode 100644 index 00000000..12b35525 --- /dev/null +++ b/contrib/debian/trusty/patches/02-service.patch @@ -0,0 +1,19 @@ +Description: Disable LogsDirectory and LogsDirectoryMode options in service +Author: r4sas + +Reviewed-By: r4sas +Last-Update: 2023-05-17 + +--- a/contrib/i2pd.service ++++ b/contrib/i2pd.service +@@ -8,8 +8,8 @@ User=i2pd + Group=i2pd + RuntimeDirectory=i2pd + RuntimeDirectoryMode=0700 +-LogsDirectory=i2pd +-LogsDirectoryMode=0700 ++#LogsDirectory=i2pd ++#LogsDirectoryMode=0700 + Type=forking + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/sh -c "kill -HUP $MAINPID" diff --git a/contrib/debian/trusty/patches/series b/contrib/debian/trusty/patches/series new file mode 100644 index 00000000..d8caec41 --- /dev/null +++ b/contrib/debian/trusty/patches/series @@ -0,0 +1,2 @@ +01-upnp.patch +02-service.patch diff --git a/contrib/debian/trusty/rules b/contrib/debian/trusty/rules new file mode 100755 index 00000000..97a4e008 --- /dev/null +++ b/contrib/debian/trusty/rules @@ -0,0 +1,18 @@ +#!/usr/bin/make -f +#export DH_VERBOSE=1 + +export DEB_BUILD_MAINT_OPTIONS=hardening=+all + +include /usr/share/dpkg/architecture.mk + +ifeq ($(DEB_HOST_ARCH),i386) + export DEB_BUILD_OPTIONS=parallel=1 +endif + +export DEB_CXXFLAGS_MAINT_APPEND=-Wall -pedantic +export DEB_LDFLAGS_MAINT_APPEND= + +%: + dh $@ --parallel + +override_dh_auto_install: diff --git a/contrib/debian/xenial/compat b/contrib/debian/xenial/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/contrib/debian/xenial/compat @@ -0,0 +1 @@ +9 diff --git a/contrib/debian/xenial/control b/contrib/debian/xenial/control new file mode 100644 index 00000000..fc618ddc --- /dev/null +++ b/contrib/debian/xenial/control @@ -0,0 +1,18 @@ +Source: i2pd +Section: net +Priority: optional +Maintainer: r4sas +Build-Depends: debhelper (>= 9), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev +Standards-Version: 3.9.8 +Homepage: http://i2pd.website/ +Vcs-Git: git://github.com/PurpleI2P/i2pd.git +Vcs-Browser: https://github.com/PurpleI2P/i2pd + +Package: i2pd +Architecture: any +Pre-Depends: ${misc:Pre-Depends}, adduser +Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, +Description: Full-featured C++ implementation of I2P client. + I2P (Invisible Internet Protocol) is a universal anonymous network layer. All + communications over I2P are anonymous and end-to-end encrypted, participants + don't reveal their real IP addresses. diff --git a/contrib/debian/xenial/patches/01-upnp.patch b/contrib/debian/xenial/patches/01-upnp.patch new file mode 100644 index 00000000..bec8f2b0 --- /dev/null +++ b/contrib/debian/xenial/patches/01-upnp.patch @@ -0,0 +1,17 @@ +Description: Enable UPnP usage in package +Author: r4sas + +Reviewed-By: r4sas +Last-Update: 2022-03-23 + +--- i2pd.orig/Makefile ++++ i2pd/Makefile +@@ -31,7 +31,7 @@ include filelist.mk + + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) + + # for debugging purposes only, when commit hash needed in trunk builds in i2pd version string diff --git a/contrib/debian/xenial/patches/02-service.patch b/contrib/debian/xenial/patches/02-service.patch new file mode 100644 index 00000000..12b35525 --- /dev/null +++ b/contrib/debian/xenial/patches/02-service.patch @@ -0,0 +1,19 @@ +Description: Disable LogsDirectory and LogsDirectoryMode options in service +Author: r4sas + +Reviewed-By: r4sas +Last-Update: 2023-05-17 + +--- a/contrib/i2pd.service ++++ b/contrib/i2pd.service +@@ -8,8 +8,8 @@ User=i2pd + Group=i2pd + RuntimeDirectory=i2pd + RuntimeDirectoryMode=0700 +-LogsDirectory=i2pd +-LogsDirectoryMode=0700 ++#LogsDirectory=i2pd ++#LogsDirectoryMode=0700 + Type=forking + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/sh -c "kill -HUP $MAINPID" diff --git a/contrib/debian/xenial/patches/series b/contrib/debian/xenial/patches/series new file mode 100644 index 00000000..d8caec41 --- /dev/null +++ b/contrib/debian/xenial/patches/series @@ -0,0 +1,2 @@ +01-upnp.patch +02-service.patch diff --git a/contrib/debian/xenial/rules b/contrib/debian/xenial/rules new file mode 100755 index 00000000..11791d9b --- /dev/null +++ b/contrib/debian/xenial/rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +#export DH_VERBOSE=1 +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +include /usr/share/dpkg/architecture.mk + +export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic +export DEB_LDFLAGS_MAINT_APPEND = + +%: + dh $@ --parallel + +override_dh_auto_install: From fee940238a4b8cba86eecb2204aadc445f824c24 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 17 Jun 2023 07:52:06 -0400 Subject: [PATCH 0273/1160] handle SOCK5 authrosation with empty user/password --- libi2pd_client/SOCKS.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 693c5185..649ad814 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -587,7 +587,10 @@ namespace proxy EnterState(GET5_USER_SIZE); break; case GET5_USER_SIZE: - EnterState(GET5_USER, *sock_buff); + if (*sock_buff) + EnterState(GET5_USER, *sock_buff); + else // empty user + EnterState(GET5_PASSWD_SIZE); break; case GET5_USER: // skip user for now @@ -595,7 +598,13 @@ namespace proxy if (m_parseleft == 0) EnterState(GET5_PASSWD_SIZE); break; case GET5_PASSWD_SIZE: - EnterState(GET5_PASSWD, *sock_buff); + if (*sock_buff) + EnterState(GET5_PASSWD, *sock_buff); + else // empty password + { + Socks5UserPasswdResponse (); + EnterState(GET5_REQUESTV); + } break; case GET5_PASSWD: // skip passwd for now From 07c529173e9833220eb89353c758cae03faf73f4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 17 Jun 2023 10:08:04 -0400 Subject: [PATCH 0274/1160] send current version of the subnegotiation in user/password response --- libi2pd_client/SOCKS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 649ad814..547a2da2 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -332,7 +332,7 @@ namespace proxy void SOCKSHandler::Socks5UserPasswdResponse () { - m_response[0] = 5; // Version + m_response[0] = 1; // Version of the subnegotiation m_response[1] = 0; // Response code LogPrint(eLogDebug, "SOCKS: v5 user/password response"); boost::asio::async_write(*m_sock, boost::asio::const_buffers_1(m_response, 2), From 13f263b7910a30d59c4090a07d8773d0a1c99260 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 30 Jun 2023 11:54:55 -0400 Subject: [PATCH 0275/1160] correct transport comptibility for OBEP in second attempt --- libi2pd/TunnelPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 3dc0256e..a2168f64 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -522,7 +522,7 @@ namespace tunnel } if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && !hop->IsPublished (true)))) // IBGW is not published ipv4 { - auto hop1 = nextHop (prevHop, true); + auto hop1 = nextHop (prevHop, inbound); if (hop1) hop = hop1; } prevHop = hop; From 5f430269862c710ddaa7d97b8823b68a7fe5f24a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Jul 2023 12:30:33 -0400 Subject: [PATCH 0276/1160] check if local destination is not null --- libi2pd_client/BOB.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 3e6590f2..498a5460 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -667,6 +667,11 @@ namespace client return; } auto localDestination = m_CurrentDestination ? m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination (); + if (!localDestination) + { + SendReplyError ("No local destination"); + return; + } if (addr->IsIdentHash ()) { // we might have leaseset already From b8f998f76a4acb0f0764e151308f6150a19f076c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Jul 2023 13:08:39 -0400 Subject: [PATCH 0277/1160] don't delete BOBDestination if used by another BOBSession --- libi2pd_client/BOB.cpp | 24 +++++++++++------------- libi2pd_client/BOB.h | 10 +++++----- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 498a5460..23c3b72f 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -357,13 +357,13 @@ namespace client os << data << std::endl; } - void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) + void BOBCommandSession::BuildStatusLine(bool currentTunnel, std::shared_ptr dest, std::string &out) { // helper lambdas const auto issetStr = [](const std::string &str) { return str.empty() ? "not_set" : str; }; // for inhost, outhost const auto issetNum = [&issetStr](const int p) { return issetStr(p == 0 ? "" : std::to_string(p)); }; // for inport, outport const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; }; - const auto destReady = [](const BOBDestination * const dest) { return dest->IsRunning(); }; + const auto destReady = [](const BOBDestination * const dest) { return dest && dest->IsRunning(); }; const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str // tunnel info @@ -373,9 +373,9 @@ namespace client const std::string outhost = issetStr(currentTunnel ? m_OutHost : dest->GetOutHost()); const std::string inport = issetNum(currentTunnel ? m_InPort : dest->GetInPort()); const std::string outport = issetNum(currentTunnel ? m_OutPort : dest->GetOutPort()); - const bool keys = destExists(dest); // key must exist when destination is created - const bool starting = destExists(dest) && !destReady(dest); - const bool running = destExists(dest) && destReady(dest); + const bool keys = destExists(dest.get ()); // key must exist when destination is created + const bool starting = destExists(dest.get ()) && !destReady(dest.get ()); + const bool running = destExists(dest.get ()) && destReady(dest.get ()); const bool stopping = false; // build line @@ -446,7 +446,7 @@ namespace client if (!m_CurrentDestination) { - m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command + m_CurrentDestination = std::make_shared (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); m_Owner.AddDestination (m_Nickname, m_CurrentDestination); } @@ -666,7 +666,8 @@ namespace client SendReplyError ("Address Not found"); return; } - auto localDestination = m_CurrentDestination ? m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination (); + auto localDestination = (m_CurrentDestination && m_CurrentDestination->IsRunning ()) ? + m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination (); if (!localDestination) { SendReplyError ("No local destination"); @@ -880,8 +881,6 @@ namespace client { if (IsRunning ()) Stop (); - for (const auto& it: m_Destinations) - delete it.second; } void BOBCommandChannel::Start () @@ -898,9 +897,9 @@ namespace client StopIOService (); } - void BOBCommandChannel::AddDestination (const std::string& name, BOBDestination * dest) + void BOBCommandChannel::AddDestination (const std::string& name, std::shared_ptr dest) { - m_Destinations[name] = dest; + m_Destinations.emplace (name, dest); } void BOBCommandChannel::DeleteDestination (const std::string& name) @@ -909,12 +908,11 @@ namespace client if (it != m_Destinations.end ()) { it->second->Stop (); - delete it->second; m_Destinations.erase (it); } } - BOBDestination * BOBCommandChannel::FindDestination (const std::string& name) + std::shared_ptr BOBCommandChannel::FindDestination (const std::string& name) { auto it = m_Destinations.find (name); if (it != m_Destinations.end ()) diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 8b0b31d2..1f5fda5f 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -228,7 +228,7 @@ namespace client void SendReplyError (const char * msg); void SendRaw (const char * data); - void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out); + void BuildStatusLine(bool currentTunnel, std::shared_ptr destination, std::string &out); private: @@ -240,7 +240,7 @@ namespace client uint16_t m_InPort, m_OutPort; i2p::data::PrivateKeys m_Keys; std::map m_Options; - BOBDestination * m_CurrentDestination; + std::shared_ptr m_CurrentDestination; }; typedef void (BOBCommandSession::*BOBCommandHandler)(const char * operand, size_t len); @@ -255,9 +255,9 @@ namespace client void Stop (); boost::asio::io_service& GetService () { return GetIOService (); }; - void AddDestination (const std::string& name, BOBDestination * dest); + void AddDestination (const std::string& name, std::shared_ptr dest); void DeleteDestination (const std::string& name); - BOBDestination * FindDestination (const std::string& name); + std::shared_ptr FindDestination (const std::string& name); private: @@ -267,7 +267,7 @@ namespace client private: boost::asio::ip::tcp::acceptor m_Acceptor; - std::map m_Destinations; + std::map > m_Destinations; std::map m_CommandHandlers; std::map m_HelpStrings; From 638e9b4d7ff7366c8e902d45ae1a0d3ae13189d8 Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Sat, 8 Jul 2023 17:07:04 -0700 Subject: [PATCH 0278/1160] Fixed division by zero due to thread race condition. --- libi2pd/NetDb.cpp | 4 +++- libi2pd/Transports.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index baf96f74..5134dbe0 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1253,7 +1253,9 @@ namespace data uint16_t inds[3]; RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::unique_lock l(m_RouterInfosMutex); - inds[0] %= m_RouterInfos.size (); + auto count = m_RouterInfos.size (); + if(count == 0) return nullptr; + inds[0] %= count; auto it = m_RouterInfos.begin (); std::advance (it, inds[0]); // try random router diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8daf56ef..38d6e270 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -861,7 +861,9 @@ namespace transport uint16_t inds[3]; RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::unique_lock l(m_PeersMutex); - inds[0] %= m_Peers.size (); + auto count = m_Peers.size (); + if(count == 0) return nullptr; + inds[0] %= count; auto it = m_Peers.begin (); std::advance (it, inds[0]); // try random peer From 2bb48b4546a0d174af55b32afac293cbeb8e4302 Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Sun, 9 Jul 2023 13:12:22 -0700 Subject: [PATCH 0279/1160] Fixed crash when Base64ToByteStream() is only given '=' characters. --- libi2pd/Base.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 94446e86..8f84728c 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -187,6 +187,9 @@ namespace data else return 0; + if(*InBuffer == P64) + return 0; + ps = (unsigned char *)(InBuffer + InCount - 1); while ( *ps-- == P64 ) outCount--; From 47dc5591b92b5fbf2385f5e25b0726dd5768ec12 Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Sun, 9 Jul 2023 15:09:17 -0700 Subject: [PATCH 0280/1160] Eliminate undefined behavior of bit shifting signed int. --- libi2pd/Base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 94446e86..5f8b7e58 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -298,7 +298,7 @@ namespace data size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen) { size_t ret = 0, pos = 1; - int bits = 8, tmp = inBuf[0]; + unsigned int bits = 8, tmp = inBuf[0]; while (ret < outLen && (bits > 0 || pos < len)) { if (bits < 5) From c4be5f7fdb4ff4113b62f5b8f049887a9fcacdf4 Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Sun, 9 Jul 2023 18:45:30 -0700 Subject: [PATCH 0281/1160] Use offset from Identity::signingKey instead of Identity::certificate for key. --- libi2pd/Identity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index ca47e797..a4a9f716 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -581,7 +581,7 @@ namespace data if (keyType == SIGNING_KEY_TYPE_DSA_SHA1) m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); else if (keyType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 && !IsOfflineSignature ()) - m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH)); // TODO: remove public key check + m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey + (sizeof(Identity::signingKey) - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH))); // TODO: remove public key check else { // public key is not required From 17c4038c6048a1567eba76b89a8a9e19d7e81d38 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 11 Jul 2023 13:16:35 -0400 Subject: [PATCH 0282/1160] select router with ipv4 for endpoint --- libi2pd/NetDb.cpp | 19 ++++++++++++------- libi2pd/NetDb.hpp | 4 ++-- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/TunnelPool.cpp | 19 ++++++++----------- libi2pd/TunnelPool.h | 4 ++-- libi2pd_client/MatchedDestination.cpp | 3 ++- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5134dbe0..7bccb2a0 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -59,7 +59,7 @@ namespace data { Reseed (); } - else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false)) + else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false, false)) Reseed (); // we don't have a router we can connect to. Trying to reseed auto it = m_RouterInfos.find (i2p::context.GetIdentHash ()); @@ -1199,15 +1199,17 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const + std::shared_ptr NetDb::GetRandomRouter (std::shared_ptr compatibleWith, + bool reverse, bool endpoint) const { return GetRandomRouter ( - [compatibleWith, reverse](std::shared_ptr router)->bool + [compatibleWith, reverse, endpoint](std::shared_ptr router)->bool { return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : router->IsReachableFrom (*compatibleWith)) && - router->IsECIES () && !router->IsHighCongestion (false); + router->IsECIES () && !router->IsHighCongestion (false) && + (!endpoint || (router->IsV4 () && (!reverse || router->IsPublished (true)))); // endpoint must be ipv4 and published if inbound(reverse) }); } @@ -1231,17 +1233,20 @@ namespace data }); } - std::shared_ptr NetDb::GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const + std::shared_ptr NetDb::GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, + bool reverse, bool endpoint) const { return GetRandomRouter ( - [compatibleWith, reverse](std::shared_ptr router)->bool + [compatibleWith, reverse, endpoint](std::shared_ptr router)->bool { return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : router->IsReachableFrom (*compatibleWith)) && (router->GetCaps () & RouterInfo::eHighBandwidth) && router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && - router->IsECIES () && !router->IsHighCongestion (true); + router->IsECIES () && !router->IsHighCongestion (true) && + (!endpoint || (router->IsV4 () && (!reverse || router->IsPublished (true)))); // endpoint must be ipv4 and published if inbound(reverse) + }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index adfdcde7..b7d9a5b3 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -84,8 +84,8 @@ namespace data void HandleNTCP2RouterInfoMsg (std::shared_ptr m); std::shared_ptr GetRandomRouter () const; - std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; - std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; + std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse, bool endpoint) const; + std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse, bool endpoint) const; std::shared_ptr GetRandomSSU2PeerTestRouter (bool v4, const std::set& excluded) const; std::shared_ptr GetRandomSSU2Introducer (bool v4, const std::set& excluded) const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index db6f74f9..6234ceb4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -709,7 +709,7 @@ namespace tunnel auto inboundTunnel = GetNextInboundTunnel (); auto router = i2p::transport::transports.RoutesRestricted() ? i2p::transport::transports.GetRestrictedPeer() : - i2p::data::netdb.GetRandomRouter (i2p::context.GetSharedRouterInfo (), false); // reachable by us + i2p::data::netdb.GetRandomRouter (i2p::context.GetSharedRouterInfo (), false, true); // reachable by us if (!inboundTunnel || !router) return; LogPrint (eLogDebug, "Tunnel: Creating one hop outbound tunnel"); CreateTunnel ( @@ -781,7 +781,7 @@ namespace tunnel auto router = i2p::transport::transports.RoutesRestricted() ? i2p::transport::transports.GetRestrictedPeer() : // should be reachable by us because we send build request directly - i2p::data::netdb.GetRandomRouter (i2p::context.GetSharedRouterInfo (), false); + i2p::data::netdb.GetRandomRouter (i2p::context.GetSharedRouterInfo (), false, true); if (!router) { LogPrint (eLogWarning, "Tunnel: Can't find any router, skip creating tunnel"); return; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a2168f64..5b305de1 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -470,13 +470,14 @@ namespace tunnel return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this (); } - std::shared_ptr TunnelPool::SelectNextHop (std::shared_ptr prevHop, bool reverse) const + std::shared_ptr TunnelPool::SelectNextHop (std::shared_ptr prevHop, + bool reverse, bool endpoint) const { - auto hop = IsExploratory () ? i2p::data::netdb.GetRandomRouter (prevHop, reverse): - i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse); + auto hop = IsExploratory () ? i2p::data::netdb.GetRandomRouter (prevHop, reverse, endpoint): + i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse, endpoint); if (!hop || hop->GetProfile ()->IsBad ()) - hop = i2p::data::netdb.GetRandomRouter (prevHop, reverse); + hop = i2p::data::netdb.GetRandomRouter (prevHop, reverse, endpoint); return hop; } @@ -508,7 +509,7 @@ namespace tunnel for(int i = start; i < numHops; i++ ) { - auto hop = nextHop (prevHop, inbound); + auto hop = nextHop (prevHop, inbound, i == numHops - 1); if (!hop && !i) // if no suitable peer found for first hop, try already connected { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); @@ -520,11 +521,6 @@ namespace tunnel LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); return false; } - if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && !hop->IsPublished (true)))) // IBGW is not published ipv4 - { - auto hop1 = nextHop (prevHop, inbound); - if (hop1) hop = hop1; - } prevHop = hop; path.Add (hop); } @@ -566,7 +562,8 @@ namespace tunnel if (m_CustomPeerSelector) return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } - return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); + return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index e9dd142e..c1fd19cd 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -56,7 +56,7 @@ namespace tunnel class TunnelPool: public std::enable_shared_from_this // per local destination { - typedef std::function(std::shared_ptr, bool)> SelectHopFunc; + typedef std::function(std::shared_ptr, bool, bool)> SelectHopFunc; public: TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, @@ -112,7 +112,7 @@ namespace tunnel std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude = nullptr) const; // for overriding tunnel peer selection - std::shared_ptr SelectNextHop (std::shared_ptr prevHop, bool reverse) const; + std::shared_ptr SelectNextHop (std::shared_ptr prevHop, bool reverse, bool endpoint) const; bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); private: diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 1e2e8275..40752f5b 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -73,7 +73,8 @@ namespace client { auto pool = GetTunnelPool(); if(!pool || !pool->StandardSelectPeers(path, hops, inbound, - std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2))) + std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3))) return false; // more here for outbound tunnels if(!inbound && m_RemoteLeaseSet) From ea7cf1cf6905257cd668848283ad86dfb5c6eb00 Mon Sep 17 00:00:00 2001 From: Vort Date: Sat, 15 Jul 2023 18:44:37 +0300 Subject: [PATCH 0283/1160] fix termination block processing and size check --- libi2pd/NTCP2.cpp | 2 +- libi2pd/SSU2Session.cpp | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 5e1cbaf6..364ebe8e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -884,7 +884,7 @@ namespace transport auto size = bufbe16toh (frame + offset); offset += 2; LogPrint (eLogDebug, "NTCP2: Block type ", (int)blk, " of size ", size); - if (size > len) + if (offset + size > len) { LogPrint (eLogError, "NTCP2: Unexpected block length ", size); break; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 49004437..23afd4c3 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1486,7 +1486,7 @@ namespace transport auto size = bufbe16toh (buf + offset); offset += 2; LogPrint (eLogDebug, "SSU2: Block type ", (int)blk, " of size ", size); - if (size > len) + if (offset + size > len) { LogPrint (eLogError, "SSU2: Unexpected block length ", size); break; @@ -1532,16 +1532,21 @@ namespace transport break; case eSSU2BlkTermination: { - uint8_t rsn = buf[11]; // reason - LogPrint (eLogDebug, "SSU2: Termination reason=", (int)rsn); - if (IsEstablished () && rsn != eSSU2TerminationReasonTerminationReceived) - RequestTermination (eSSU2TerminationReasonTerminationReceived); - else if (m_State != eSSU2SessionStateTerminated) + if (size >= 9) { - if (m_State == eSSU2SessionStateClosing && rsn == eSSU2TerminationReasonTerminationReceived) - m_State = eSSU2SessionStateClosingConfirmed; - Done (); + uint8_t rsn = buf[offset + 8]; // reason + LogPrint (eLogDebug, "SSU2: Termination reason=", (int)rsn); + if (IsEstablished () && rsn != eSSU2TerminationReasonTerminationReceived) + RequestTermination (eSSU2TerminationReasonTerminationReceived); + else if (m_State != eSSU2SessionStateTerminated) + { + if (m_State == eSSU2SessionStateClosing && rsn == eSSU2TerminationReasonTerminationReceived) + m_State = eSSU2SessionStateClosingConfirmed; + Done (); + } } + else + LogPrint(eLogWarning, "SSU2: Unexpected termination block size ", size); break; } case eSSU2BlkRelayRequest: From 8e63f8f333d21724bb5143f99f8ee0c471ddd473 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 15 Jul 2023 17:11:56 -0400 Subject: [PATCH 0284/1160] consider all addresses non published for U and H routers --- libi2pd/RouterInfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 5ba8a5b1..646711c1 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -995,6 +995,7 @@ namespace data bool RouterInfo::IsPublished (bool v4) const { + if (m_Caps & (eUnreachable | eHidden)) return false; // if router sets U or H we assume that all addreses are not published auto addr = GetAddresses (); if (v4) return ((*addr)[eNTCP2V4Idx] && ((*addr)[eNTCP2V4Idx])->published) || From 940a97db11d2e092273090319b4cf2f148bb0971 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 16 Jul 2023 14:02:30 +0300 Subject: [PATCH 0285/1160] [gha] fix msvc build Signed-off-by: r4sas --- .github/workflows/build-windows-msvc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index 356bb466..172e0596 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -29,7 +29,7 @@ jobs: - name: Install Boost uses: crazy-max/ghaction-chocolatey@v2 with: - args: install boost-msvc-14.3 + args: install boost-msvc-14.3 --version=1.81.0 - name: Install OpenSSL uses: crazy-max/ghaction-chocolatey@v2 From e7157cf15efddbe50a057c72afee5eb0a3276199 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Jul 2023 17:57:30 -0400 Subject: [PATCH 0286/1160] don't create paired inbound tunnel if length is different --- libi2pd/TunnelPool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5b305de1..fd31cb09 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -296,10 +296,12 @@ namespace tunnel for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } - if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) + if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0 && + m_NumInboundHops == m_NumOutboundHops) { for (auto it: m_OutboundTunnels) { + // try to create inbound tunnel through the same path as succesive outbound CreatePairedInboundTunnel (it); num++; if (num >= m_NumInboundTunnels) break; From c620fc1232e4a7823b2ac1558ffeb454c3a9f8b4 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Jul 2023 18:44:51 -0400 Subject: [PATCH 0287/1160] clear unreachable flag upon succesive connect --- libi2pd/NetDb.cpp | 9 +++------ libi2pd/Profiling.cpp | 6 +++--- libi2pd/Profiling.h | 2 +- libi2pd/Transports.cpp | 1 + 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 7bccb2a0..112d3cb3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -424,12 +424,9 @@ namespace data if (r) { r->SetUnreachable (unreachable); - if (unreachable) - { - auto profile = r->GetProfile (); - if (profile) - profile->Unreachable (); - } + auto profile = r->GetProfile (); + if (profile) + profile->Unreachable (unreachable); } } diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 47fc15e7..879aea29 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -165,12 +165,12 @@ namespace data } } - void RouterProfile::Unreachable () + void RouterProfile::Unreachable (bool unreachable) { - m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch (); + m_LastUnreachableTime = unreachable ? i2p::util::GetSecondsSinceEpoch () : 0; UpdateTime (); } - + void RouterProfile::Connected () { m_HasConnected = true; diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 6b814893..c351b41d 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -55,7 +55,7 @@ namespace data void TunnelBuildResponse (uint8_t ret); void TunnelNonReplied (); - void Unreachable (); + void Unreachable (bool unreachable); void Connected (); boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 38d6e270..01e484f4 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -716,6 +716,7 @@ namespace transport if (transport == i2p::data::RouterInfo::eNTCP2V4 || transport == i2p::data::RouterInfo::eNTCP2V6 || transport == i2p::data::RouterInfo::eNTCP2V6Mesh) it->second.router->GetProfile ()->Connected (); // outgoing NTCP2 connection if always real + i2p::data::netdb.SetUnreachable (ident, false); // clear unreachable } it->second.numAttempts = 0; it->second.router = nullptr; // we don't need RouterInfo after successive connect From 902899ae2422d82147a5e73dac13d7a7f2297a30 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Jul 2023 19:49:42 -0400 Subject: [PATCH 0288/1160] don't pick completely unreachable peers --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 112d3cb3..061ccc23 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1203,7 +1203,7 @@ namespace data [compatibleWith, reverse, endpoint](std::shared_ptr router)->bool { return !router->IsHidden () && router != compatibleWith && - (reverse ? compatibleWith->IsReachableFrom (*router) : + (reverse ? (compatibleWith->IsReachableFrom (*router) && router->GetCompatibleTransports (true)): router->IsReachableFrom (*compatibleWith)) && router->IsECIES () && !router->IsHighCongestion (false) && (!endpoint || (router->IsV4 () && (!reverse || router->IsPublished (true)))); // endpoint must be ipv4 and published if inbound(reverse) @@ -1237,7 +1237,7 @@ namespace data [compatibleWith, reverse, endpoint](std::shared_ptr router)->bool { return !router->IsHidden () && router != compatibleWith && - (reverse ? compatibleWith->IsReachableFrom (*router) : + (reverse ? (compatibleWith->IsReachableFrom (*router) && router->GetCompatibleTransports (true)) : router->IsReachableFrom (*compatibleWith)) && (router->GetCaps () & RouterInfo::eHighBandwidth) && router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && From 0754255c1f597beba3f9dae5c21f7c99e927918b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Jul 2023 21:08:26 -0400 Subject: [PATCH 0289/1160] drop incoming session from too old or from future routers --- libi2pd/NTCP2.cpp | 11 +++++++++-- libi2pd/SSU2Session.cpp | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 364ebe8e..fa852f92 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -695,12 +695,19 @@ namespace transport SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); return; } - if (i2p::util::GetMillisecondsSinceEpoch () > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes + auto ts = i2p::util::GetMillisecondsSinceEpoch (); + if (ts > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes { - LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed"); + LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed for ", (ts - ri.GetTimestamp ())/1000LL, " seconds"); SendTerminationAndTerminate (eNTCP2Message3Error); return; } + if (ts + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri.GetTimestamp ()) // 2 minutes + { + LogPrint (eLogError, "NTCP2: RouterInfo is from future for ", (ri.GetTimestamp () - ts)/1000LL, " seconds"); + SendTerminationAndTerminate (eNTCP2Message3Error); + return; + } auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri.GetNTCP2V4Address () : (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri.GetYggdrasilAddress () : ri.GetNTCP2V6Address ()); if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 23afd4c3..51c167ea 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1053,6 +1053,17 @@ namespace transport LogPrint (eLogError, "SSU2: SessionConfirmed malformed RouterInfo block"); return false; } + auto ts = i2p::util::GetMillisecondsSinceEpoch(); + if (ts > ri->GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes + { + LogPrint (eLogError, "SSU2: RouterInfo in SessionConfirmed is too old for ", (ts - ri->GetTimestamp ())/1000LL, " seconds"); + return false; + } + if (ts + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri->GetTimestamp ()) // 2 minutes + { + LogPrint (eLogError, "SSU2: RouterInfo in SessionConfirmed is from future for ", (ri->GetTimestamp () - ts)/1000LL, " seconds"); + return false; + } m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address (); if (!m_Address || memcmp (S, m_Address->s, 32)) { From f13cc0b862646c0d13514d429d1472df1b948883 Mon Sep 17 00:00:00 2001 From: Vort Date: Wed, 19 Jul 2023 16:38:04 +0300 Subject: [PATCH 0290/1160] allow 0 hops with explicitPeers --- libi2pd/TunnelPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index fd31cb09..23cc53e3 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -570,9 +570,9 @@ namespace tunnel bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { + if (!m_ExplicitPeers->size ()) return false; int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); - if (!numHops) return false; for (int i = 0; i < numHops; i++) { auto& ident = (*m_ExplicitPeers)[i]; From 6e9a3422e9e723197c3ad56fbc9357f2656fe1f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Jul 2023 07:59:09 -0400 Subject: [PATCH 0291/1160] correct min size for keepalive --- libi2pd/SSU2Session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 51c167ea..dcc5ad52 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -243,7 +243,7 @@ namespace transport if (IsEstablished ()) { uint8_t payload[20]; - size_t payloadSize = CreatePaddingBlock (payload, 20, 5); + size_t payloadSize = CreatePaddingBlock (payload, 20, 8); SendData (payload, payloadSize); } } From c7efd465fa5bd06d4fccfde0e771a1920c624049 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Jul 2023 18:25:28 -0400 Subject: [PATCH 0292/1160] padding for path response --- libi2pd/SSU2Session.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index dcc5ad52..4a1395b3 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2857,7 +2857,7 @@ namespace transport void SSU2Session::SendPathResponse (const uint8_t * data, size_t len) { - if (len < 8 || len > m_MaxPayloadSize - 3) + if (len > m_MaxPayloadSize - 3) { LogPrint (eLogWarning, "SSU2: Incorrect data size for path response ", len); return; @@ -2866,7 +2866,10 @@ namespace transport payload[0] = eSSU2BlkPathResponse; htobe16buf (payload + 1, len); memcpy (payload + 3, data, len); - SendData (payload, len + 3); + size_t payloadSize = len + 3; + if (payloadSize < m_MaxPayloadSize) + payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, payloadSize < 8 ? 8 : 0); + SendData (payload, payloadSize); } void SSU2Session::SendPathChallenge () @@ -2884,7 +2887,7 @@ namespace transport } len += 3; if (len < m_MaxPayloadSize) - len += CreatePaddingBlock (payload + len, m_MaxPayloadSize - len); + len += CreatePaddingBlock (payload + len, m_MaxPayloadSize - len, len < 8 ? 8 : 0); SendData (payload, len); } From b8e19bf5f1e3fbcf0f45ccfb85b1923142d96e46 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Jul 2023 08:50:49 -0400 Subject: [PATCH 0293/1160] reduced peer test interval and added peer test interval variance --- libi2pd/SSU2.cpp | 12 ++++++++---- libi2pd/SSU2.h | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index a9e04790..6594f6d9 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1078,7 +1078,8 @@ namespace transport { if (m_IsPublished) { - m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL)); + m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds( + SSU2_KEEP_ALIVE_INTERVAL + rand () % SSU2_KEEP_ALIVE_INTERVAL_VARIANCE)); m_IntroducersUpdateTimer.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer, this, std::placeholders::_1, true)); } @@ -1091,7 +1092,8 @@ namespace transport m_IntroducersUpdateTimer.cancel (); i2p::context.ClearSSU2Introducers (true); m_Introducers.clear (); - m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL/2)); + m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds( + (SSU2_KEEP_ALIVE_INTERVAL + rand () % SSU2_KEEP_ALIVE_INTERVAL_VARIANCE)/2)); m_IntroducersUpdateTimer.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer, this, std::placeholders::_1, true)); } @@ -1101,7 +1103,8 @@ namespace transport { if (m_IsPublished) { - m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL)); + m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds( + SSU2_KEEP_ALIVE_INTERVAL + rand () % SSU2_KEEP_ALIVE_INTERVAL_VARIANCE)); m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer, this, std::placeholders::_1, false)); } @@ -1114,7 +1117,8 @@ namespace transport m_IntroducersUpdateTimerV6.cancel (); i2p::context.ClearSSU2Introducers (false); m_IntroducersV6.clear (); - m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL/2)); + m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds( + (SSU2_KEEP_ALIVE_INTERVAL + rand () % SSU2_KEEP_ALIVE_INTERVAL_VARIANCE)/2)); m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer, this, std::placeholders::_1, false)); } diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 2e652786..a1fafc63 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -29,7 +29,8 @@ namespace transport const size_t SSU2_MAX_NUM_INTRODUCERS = 3; const int SSU2_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour const int SSU2_TO_INTRODUCER_SESSION_EXPIRATION = 4800; // 80 minutes - const int SSU2_KEEP_ALIVE_INTERVAL = 30; // in seconds + const int SSU2_KEEP_ALIVE_INTERVAL = 15; // in seconds + const int SSU2_KEEP_ALIVE_INTERVAL_VARIANCE = 4; // in seconds const int SSU2_PROXY_CONNECT_RETRY_TIMEOUT = 30; // in seconds class SSU2Server: private i2p::util::RunnableServiceWithWork From 413e25f20e16a0a0e1b01ed9cdf1d76e20ba3a5b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Jul 2023 10:13:05 -0400 Subject: [PATCH 0294/1160] don't pick too old session for introducer --- libi2pd/SSU2.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 6594f6d9..f3f0542d 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1035,10 +1035,13 @@ namespace transport for (const auto& it : sessions) { + uint32_t exp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION; + if (ts + SSU2_TO_INTRODUCER_SESSION_DURATION/2 > exp) + continue; // don't pick too old session for introducer i2p::data::RouterInfo::Introducer introducer; introducer.iTag = it->GetRelayTag (); introducer.iH = it->GetRemoteIdentity ()->GetIdentHash (); - introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION; + introducer.iExp = exp; excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ()); if (i2p::context.AddSSU2Introducer (introducer, v4)) { From d6834d6a9a205756f77a1ec02488db947a1c4d4d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Jul 2023 15:03:03 -0400 Subject: [PATCH 0295/1160] keep non-published, but not-expired introducers in the introducers list --- libi2pd/SSU2.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index f3f0542d..959bef54 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -983,7 +983,7 @@ namespace transport void SSU2Server::UpdateIntroducers (bool v4) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - std::list newList; + std::list newList, impliedList; auto& introducers = v4 ? m_Introducers : m_IntroducersV6; std::set excluded; for (const auto& it : introducers) @@ -997,12 +997,17 @@ namespace transport } if (session && session->IsEstablished ()) { - if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) - session->SendKeepAlive (); if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) newList.push_back (it); else + { + if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) + { + impliedList.push_back (it); // keep in introducers list, but not publish + session->SendKeepAlive (); + } session = nullptr; + } } if (!session) i2p::context.RemoveSSU2Introducer (it, v4); @@ -1024,10 +1029,7 @@ namespace transport { session->SetCreationTime (session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION); if (std::find (newList.begin (), newList.end (), it) == newList.end ()) - { - newList.push_back (it); sessions.push_back (session); - } } } } @@ -1075,6 +1077,7 @@ namespace transport } } } + introducers.splice (introducers.end (), impliedList); // insert non-published, but non-expired introducers back } void SSU2Server::ScheduleIntroducersUpdateTimer () From 4aa631c33f7db3e75979a3e21da3597ebd83bc6b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Jul 2023 16:51:19 -0400 Subject: [PATCH 0296/1160] clear implied list if no more introducers found --- libi2pd/SSU2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 959bef54..c371928c 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1019,6 +1019,7 @@ namespace transport { // bump creation time for previous introducers if no new sessions found LogPrint (eLogDebug, "SSU2: No new introducers found. Trying to reuse existing"); + impliedList.clear (); for (auto& it : introducers) { auto it1 = m_SessionsByRouterHash.find (it); From 2064504ccedc84d16007db4b22f8385c949dec28 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 Jul 2023 07:17:10 -0400 Subject: [PATCH 0297/1160] fixed send keepalive for existing session --- libi2pd/SSU2.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index c371928c..0832b78c 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -997,17 +997,16 @@ namespace transport } if (session && session->IsEstablished ()) { - if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) + if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) newList.push_back (it); else { if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) - { impliedList.push_back (it); // keep in introducers list, but not publish - session->SendKeepAlive (); - } - session = nullptr; - } + else + session = nullptr; + } + if (session) session->SendKeepAlive (); } if (!session) i2p::context.RemoveSSU2Introducer (it, v4); From ae5239de435e1dcdff342961af9b506f60a494d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 Jul 2023 07:42:36 -0400 Subject: [PATCH 0298/1160] remove introducer from RouterInfo after 60 minutes --- libi2pd/SSU2.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 0832b78c..ac42ca7a 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -997,16 +997,19 @@ namespace transport } if (session && session->IsEstablished ()) { - if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) - newList.push_back (it); - else + if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) { - if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) + session->SendKeepAlive (); + if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION) + newList.push_back (it); + else + { impliedList.push_back (it); // keep in introducers list, but not publish - else - session = nullptr; + session = nullptr; + } } - if (session) session->SendKeepAlive (); + else + session = nullptr; } if (!session) i2p::context.RemoveSSU2Introducer (it, v4); From 68f4961f1aff340f5e0269af7653cf029918d97a Mon Sep 17 00:00:00 2001 From: Vort Date: Sun, 30 Jul 2023 15:29:10 +0300 Subject: [PATCH 0299/1160] separate test status from network status --- Win32/Win32App.cpp | 9 ++++--- daemon/HTTPServer.cpp | 9 ++++--- libi2pd/RouterContext.cpp | 31 ++++++++++++++++++------ libi2pd/RouterContext.h | 14 +++++++---- libi2pd/SSU2.cpp | 4 +-- libi2pd/SSU2Session.cpp | 51 ++++++++++++++++++++++++++++++--------- libi2pd/SSU2Session.h | 2 ++ libi2pd/Transports.cpp | 12 ++++----- 8 files changed, 92 insertions(+), 40 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index fc61a8ac..9f750c4c 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -145,18 +145,19 @@ namespace win32 s << bytes << " Bytes\n"; } - static void ShowNetworkStatus (std::stringstream& s, RouterStatus status) + static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing) { switch (status) { case eRouterStatusOK: s << "OK"; break; - case eRouterStatusTesting: s << "Test"; break; case eRouterStatusFirewalled: s << "FW"; break; case eRouterStatusUnknown: s << "Unk"; break; case eRouterStatusProxy: s << "Proxy"; break; case eRouterStatusMesh: s << "Mesh"; break; default: s << "Unk"; }; + if (testing) + s << " (Test)"; if (i2p::context.GetError () != eRouterErrorNone) { switch (i2p::context.GetError ()) @@ -179,11 +180,11 @@ namespace win32 { s << "\n"; s << "Status: "; - ShowNetworkStatus (s, i2p::context.GetStatus ()); + ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting ()); if (i2p::context.SupportsV6 ()) { s << " / "; - ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); + ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6 ()); } s << "; "; s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 50666940..2d6800b4 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -222,18 +222,19 @@ namespace http { s << "" << tr("ERROR") << ": " << string << "
\r\n"; } - static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, RouterError error) + static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, bool testing, RouterError error) { switch (status) { case eRouterStatusOK: s << tr("OK"); break; - case eRouterStatusTesting: s << tr("Testing"); break; case eRouterStatusFirewalled: s << tr("Firewalled"); break; case eRouterStatusUnknown: s << tr("Unknown"); break; case eRouterStatusProxy: s << tr("Proxy"); break; case eRouterStatusMesh: s << tr("Mesh"); break; default: s << tr("Unknown"); } + if (testing) + s << " (" << tr("Testing") << ")"; if (error != eRouterErrorNone) { switch (error) @@ -264,12 +265,12 @@ namespace http { ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; s << "" << tr("Network status") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetError ()); + ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetTesting(), i2p::context.GetError ()); s << "
\r\n"; if (i2p::context.SupportsV6 ()) { s << "" << tr("Network status v6") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetErrorV6 ()); + ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetTestingV6(), i2p::context.GetErrorV6 ()); s << "
\r\n"; } #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 3e7d7a2c..fa3ba7bd 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -31,7 +31,8 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), - m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID), + m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), + m_Testing (false), m_TestingV6 (false), m_NetID (I2PD_NET_ID), m_PublishReplyToken (0), m_IsHiddenMode (false) { } @@ -277,8 +278,29 @@ namespace i2p fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); } + void RouterContext::SetTesting (bool testing) + { + if (testing != m_Testing) + { + m_Testing = testing; + if (m_Testing) + m_Error = eRouterErrorNone; + } + } + + void RouterContext::SetTestingV6 (bool testing) + { + if (testing != m_TestingV6) + { + m_TestingV6 = testing; + if (m_TestingV6) + m_ErrorV6 = eRouterErrorNone; + } + } + void RouterContext::SetStatus (RouterStatus status) { + SetTesting (false); if (status != m_Status) { m_Status = status; @@ -290,9 +312,6 @@ namespace i2p case eRouterStatusFirewalled: SetUnreachable (true, false); // ipv4 break; - case eRouterStatusTesting: - m_Error = eRouterErrorNone; - break; default: ; } @@ -301,6 +320,7 @@ namespace i2p void RouterContext::SetStatusV6 (RouterStatus status) { + SetTestingV6 (false); if (status != m_StatusV6) { m_StatusV6 = status; @@ -312,9 +332,6 @@ namespace i2p case eRouterStatusFirewalled: SetUnreachable (false, true); // ipv6 break; - case eRouterStatusTesting: - m_ErrorV6 = eRouterErrorNone; - break; default: ; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index b8183339..d49b5523 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -42,11 +42,10 @@ namespace garlic enum RouterStatus { eRouterStatusOK = 0, - eRouterStatusTesting = 1, - eRouterStatusFirewalled = 2, - eRouterStatusUnknown = 3, - eRouterStatusProxy = 4, - eRouterStatusMesh = 5 + eRouterStatusFirewalled = 1, + eRouterStatusUnknown = 2, + eRouterStatusProxy = 3, + eRouterStatusMesh = 4 }; enum RouterError @@ -121,10 +120,14 @@ namespace garlic uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; uint64_t GetTransitBandwidthLimit () const { return (m_BandwidthLimit*m_ShareRatio)/100LL; }; + bool GetTesting () const { return m_Testing; }; + void SetTesting (bool testing); RouterStatus GetStatus () const { return m_Status; }; void SetStatus (RouterStatus status); RouterError GetError () const { return m_Error; }; void SetError (RouterError error) { m_Error = error; }; + bool GetTestingV6 () const { return m_TestingV6; }; + void SetTestingV6 (bool testing); RouterStatus GetStatusV6 () const { return m_StatusV6; }; void SetStatusV6 (RouterStatus status); RouterError GetErrorV6 () const { return m_ErrorV6; }; @@ -231,6 +234,7 @@ namespace garlic int m_ShareRatio; RouterStatus m_Status, m_StatusV6; RouterError m_Error, m_ErrorV6; + bool m_Testing, m_TestingV6; int m_NetID; std::unique_ptr m_NTCP2Keys; std::unique_ptr m_SSU2Keys; diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index ac42ca7a..53ef8db7 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1140,7 +1140,7 @@ namespace transport // timeout expired if (v4) { - if (i2p::context.GetStatus () == eRouterStatusTesting) + if (i2p::context.GetTesting ()) { // we still don't know if we need introducers ScheduleIntroducersUpdateTimer (); @@ -1163,7 +1163,7 @@ namespace transport } else { - if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + if (i2p::context.GetTestingV6 ()) { // we still don't know if we need introducers ScheduleIntroducersUpdateTimerV6 (); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 4a1395b3..54add930 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1651,8 +1651,8 @@ namespace transport break; case eSSU2SessionStateSessionCreatedReceived: case eSSU2SessionStateTokenReceived: - if ((m_RemoteEndpoint.address ().is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting) || - (m_RemoteEndpoint.address ().is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusTesting)) + if ((m_RemoteEndpoint.address ().is_v4 () && i2p::context.GetTesting ()) || + (m_RemoteEndpoint.address ().is_v6 () && i2p::context.GetTestingV6 ())) { if (m_Server.IsSyncClockFromPeers ()) { @@ -1750,14 +1750,14 @@ namespace transport LogPrint (eLogInfo, "SSU2: Our port ", ep.port (), " received from ", m_RemoteEndpoint, " is different from ", m_Server.GetPort (isV4)); if (isV4) { - if (i2p::context.GetStatus () == eRouterStatusTesting) + if (i2p::context.GetTesting ()) i2p::context.SetError (eRouterErrorSymmetricNAT); else if (m_State == eSSU2SessionStatePeerTest) i2p::context.SetError (eRouterErrorFullConeNAT); } else { - if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + if (i2p::context.GetTestingV6 ()) i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT); else if (m_State == eSSU2SessionStatePeerTest) i2p::context.SetErrorV6 (eRouterErrorFullConeNAT); @@ -2230,7 +2230,7 @@ namespace transport if (buf[1] == eSSU2PeerTestCodeAccept) { if (GetRouterStatus () == eRouterStatusUnknown) - SetRouterStatus (eRouterStatusTesting); + SetTestingState (true); auto r = i2p::data::netdb.FindRouter (buf + 3); // find Charlie if (r && it->second.first) { @@ -2256,13 +2256,17 @@ namespace transport } else { - if (GetRouterStatus () == eRouterStatusTesting) + if (GetTestingState ()) { - SetRouterStatus (eRouterStatusFirewalled); - if (m_Address->IsV4 ()) - m_Server.RescheduleIntroducersUpdateTimer (); - else - m_Server.RescheduleIntroducersUpdateTimerV6 (); + SetTestingState (false); + if (GetRouterStatus () != eRouterStatusFirewalled) + { + SetRouterStatus (eRouterStatusFirewalled); + if (m_Address->IsV4 ()) + m_Server.RescheduleIntroducersUpdateTimer (); + else + m_Server.RescheduleIntroducersUpdateTimerV6 (); + } } } LogPrint (eLogDebug, "SSU2: Peer test 4 received from ", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), @@ -2291,7 +2295,7 @@ namespace transport { LogPrint (eLogInfo, "SSU2: Peer test 4 error code ", (int)buf[1], " from ", i2p::data::GetIdentHashAbbreviation (buf[1] < 64 ? GetRemoteIdentity ()->GetIdentHash () : i2p::data::IdentHash (buf + 3))); - if (GetRouterStatus () == eRouterStatusTesting) + if (GetTestingState ()) SetRouterStatus (eRouterStatusUnknown); it->second.first->Done (); } @@ -2445,6 +2449,29 @@ namespace transport } } + bool SSU2Session::GetTestingState () const + { + if (m_Address) + { + if (m_Address->IsV4 ()) + return i2p::context.GetTesting (); + if (m_Address->IsV6 ()) + return i2p::context.GetTestingV6 (); + } + return false; + } + + void SSU2Session::SetTestingState (bool testing) const + { + if (m_Address) + { + if (m_Address->IsV4 ()) + i2p::context.SetTesting (testing); + else if (m_Address->IsV6 ()) + i2p::context.SetTestingV6 (testing); + } + } + size_t SSU2Session::CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep) { if (len < 9) return 0; diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 304efdab..14d76971 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -308,6 +308,8 @@ namespace transport void AdjustMaxPayloadSize (); RouterStatus GetRouterStatus () const; void SetRouterStatus (RouterStatus status) const; + bool GetTestingState () const; + void SetTestingState(bool testing) const; std::shared_ptr ExtractRouterInfo (const uint8_t * buf, size_t size); void CreateNonce (uint64_t seqn, uint8_t * nonce); bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 01e484f4..b452c05e 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -650,8 +650,8 @@ namespace transport auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (true, excluded); // v4 if (router) { - if (i2p::context.GetStatus () != eRouterStatusTesting) - i2p::context.SetStatus (eRouterStatusTesting); + if (!i2p::context.GetTesting ()) + i2p::context.SetTesting (true); m_SSU2Server->StartPeerTest (router, true); excluded.insert (router->GetIdentHash ()); } @@ -669,8 +669,8 @@ namespace transport auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (false, excluded); // v6 if (router) { - if (i2p::context.GetStatusV6 () != eRouterStatusTesting) - i2p::context.SetStatusV6 (eRouterStatusTesting); + if (!i2p::context.GetTestingV6 ()) + i2p::context.SetTestingV6 (true); m_SSU2Server->StartPeerTest (router, false); excluded.insert (router->GetIdentHash ()); } @@ -832,8 +832,8 @@ namespace transport ++it; } } - bool ipv4Testing = i2p::context.GetStatus () == eRouterStatusTesting; - bool ipv6Testing = i2p::context.GetStatusV6 () == eRouterStatusTesting; + bool ipv4Testing = i2p::context.GetTesting (); + bool ipv6Testing = i2p::context.GetTestingV6 (); // if still testing, repeat peer test if (ipv4Testing || ipv6Testing) PeerTest (ipv4Testing, ipv6Testing); From 38795a41cbbb21a756ecb4fd13f045e6f5f5811f Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 5 Aug 2023 08:55:06 -0400 Subject: [PATCH 0300/1160] don't publish introducers with zero iTag --- libi2pd/SSU2.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 53ef8db7..5d0e7d22 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1028,7 +1028,7 @@ namespace transport if (it1 != m_SessionsByRouterHash.end ()) { auto session = it1->second; - if (session->IsEstablished ()) + if (session->IsEstablished () && session->GetRelayTag () && session->IsOutgoing ()) { session->SetCreationTime (session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_DURATION); if (std::find (newList.begin (), newList.end (), it) == newList.end ()) @@ -1040,11 +1040,12 @@ namespace transport for (const auto& it : sessions) { + uint32_t tag = it->GetRelayTag (); uint32_t exp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION; - if (ts + SSU2_TO_INTRODUCER_SESSION_DURATION/2 > exp) + if (!tag || ts + SSU2_TO_INTRODUCER_SESSION_DURATION/2 > exp) continue; // don't pick too old session for introducer i2p::data::RouterInfo::Introducer introducer; - introducer.iTag = it->GetRelayTag (); + introducer.iTag = tag; introducer.iH = it->GetRemoteIdentity ()->GetIdentHash (); introducer.iExp = exp; excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ()); From 9bac680f2a3181bb861beb2dbf739d92a5ab6597 Mon Sep 17 00:00:00 2001 From: Vort Date: Sat, 5 Aug 2023 17:49:22 +0300 Subject: [PATCH 0301/1160] improve transport session logging --- libi2pd/NTCP2.cpp | 23 ++++++++++++++++++----- libi2pd/SSU2Session.cpp | 15 ++++++++++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index fa852f92..bbd93435 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -375,7 +375,16 @@ namespace transport m_Server.RemoveNTCP2Session (shared_from_this ()); m_SendQueue.clear (); m_SendQueueSize = 0; - LogPrint (eLogDebug, "NTCP2: Session terminated"); + auto remoteIdentity = GetRemoteIdentity (); + if (remoteIdentity) + { + LogPrint (eLogDebug, "NTCP2: Session with ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ") terminated"); + } + else + { + LogPrint (eLogDebug, "NTCP2: Session with ", GetRemoteEndpoint (), " terminated"); + } } } @@ -691,11 +700,13 @@ namespace transport i2p::data::RouterInfo ri (buf.data () + 4, size - 1); // 1 byte block type + 2 bytes size + 1 byte flag if (ri.IsUnreachable ()) { - LogPrint (eLogError, "NTCP2: Signature verification failed in SessionConfirmed"); + LogPrint (eLogError, "NTCP2: RouterInfo verification failed in SessionConfirmed from ", GetRemoteEndpoint ()); SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); return; } - auto ts = i2p::util::GetMillisecondsSinceEpoch (); + LogPrint(eLogDebug, "NTCP2: SessionConfirmed from ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (ri.GetIdentHash ()), ")"); + auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (ts > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes { LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed for ", (ts - ri.GetTimestamp ())/1000LL, " seconds"); @@ -1409,7 +1420,8 @@ namespace transport LogPrint (eLogError, "NTCP2: Can't connect to unspecified address"); return; } - LogPrint (eLogDebug, "NTCP2: Connecting to ", conn->GetRemoteEndpoint ()); + LogPrint (eLogDebug, "NTCP2: Connecting to ", conn->GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (conn->GetRemoteIdentity ()->GetIdentHash ()), ")"); GetService ().post([this, conn]() { if (this->AddNTCP2Session (conn)) @@ -1465,7 +1477,8 @@ namespace transport } else { - LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetRemoteEndpoint ()); + LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (conn->GetRemoteIdentity ()->GetIdentHash ()), ")"); conn->ClientLogin (); } } diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 54add930..f0e539c7 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -114,6 +114,8 @@ namespace transport { if (m_State == eSSU2SessionStateUnknown || m_State == eSSU2SessionStateTokenReceived) { + LogPrint(eLogDebug, "SSU2: Connecting to ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ")"); ScheduleConnectTimer (); auto token = m_Server.FindOutgoingToken (m_RemoteEndpoint); if (token) @@ -269,7 +271,16 @@ namespace transport m_ReceivedI2NPMsgIDs.clear (); m_Server.RemoveSession (m_SourceConnID); transports.PeerDisconnected (shared_from_this ()); - LogPrint (eLogDebug, "SSU2: Session terminated"); + auto remoteIdentity = GetRemoteIdentity (); + if (remoteIdentity) + { + LogPrint (eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ") terminated"); + } + else + { + LogPrint (eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (), " terminated"); + } } } @@ -298,6 +309,8 @@ namespace transport m_OnEstablished (); m_OnEstablished = nullptr; } + LogPrint(eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ") established"); } void SSU2Session::Done () From 8447822c3596cadadfa6c7bd7ab0643ddd814b34 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 5 Aug 2023 15:25:16 -0400 Subject: [PATCH 0302/1160] don't publish intrducers with zero tag --- libi2pd/RouterInfo.cpp | 3 +++ libi2pd/SSU2.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 646711c1..399e26a1 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1321,6 +1321,7 @@ namespace data int i = 0; for (const auto& introducer: address.ssu->introducers) { + if (!introducer.iTag) continue; if (introducer.iExp) // expiration is specified { WriteString ("iexp" + boost::lexical_cast(i), properties); @@ -1333,6 +1334,7 @@ namespace data i = 0; for (const auto& introducer: address.ssu->introducers) { + if (!introducer.iTag) continue; WriteString ("ih" + boost::lexical_cast(i), properties); properties << '='; char value[64]; @@ -1345,6 +1347,7 @@ namespace data i = 0; for (const auto& introducer: address.ssu->introducers) { + if (!introducer.iTag) continue; WriteString ("itag" + boost::lexical_cast(i), properties); properties << '='; WriteString (boost::lexical_cast(introducer.iTag), properties); diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 5d0e7d22..7099ba0c 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -995,7 +995,7 @@ namespace transport session = it1->second; excluded.insert (it); } - if (session && session->IsEstablished ()) + if (session && session->IsEstablished () && session->GetRelayTag () && session->IsOutgoing ()) // still session with introducer? { if (ts < session->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION) { From 7bcc905f05b1356bb2f02cdc2abfe5a6a516207c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Aug 2023 21:28:13 -0400 Subject: [PATCH 0303/1160] exclude SSU1 introducers --- libi2pd/RouterInfo.cpp | 2 +- libi2pd/RouterInfo.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 399e26a1..63cb79ef 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -579,7 +579,7 @@ namespace data int numValid = 0; for (auto& it: address->ssu->introducers) { - if (it.iTag && ts < it.iExp) + if (it.iTag && ts < it.iExp && !it.iH.IsZero ()) numValid++; else it.iTag = 0; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 47ee1dae..9aff2240 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -125,7 +125,7 @@ namespace data struct Introducer { - Introducer (): iTag (0), iExp (0) {}; + Introducer (): iTag (0), iExp (0) { iH.Fill(0); }; IdentHash iH; uint32_t iTag; uint32_t iExp; From 627b8dca8334ad036f948013bc564abcee8c291b Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Sun, 13 Aug 2023 17:08:14 -0700 Subject: [PATCH 0304/1160] Fixed buf offset EVP_EncryptFinal_ex() to include outlen. --- libi2pd/Crypto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 4a78f2b1..12087443 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -991,7 +991,7 @@ namespace crypto EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adLen); EVP_EncryptUpdate(ctx, buf, &outlen, msg, msgLen); - EVP_EncryptFinal_ex(ctx, buf, &outlen); + EVP_EncryptFinal_ex(ctx, buf + outlen, &outlen); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, buf + msgLen); } else From 662a59d0fda3f763a2f67654dd50cc2cf38a8178 Mon Sep 17 00:00:00 2001 From: Chad Fraleigh Date: Mon, 14 Aug 2023 19:21:30 -0700 Subject: [PATCH 0305/1160] Eliminate additional undefined behavior of bit shifting signed int. --- libi2pd/Base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 0e69b663..e979c5b4 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -272,7 +272,7 @@ namespace data size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen) { - int tmp = 0, bits = 0; + unsigned int tmp = 0, bits = 0; size_t ret = 0; for (size_t i = 0; i < len; i++) { From c112276eea649c3b406953e3400573d78a049f20 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Aug 2023 10:57:05 -0400 Subject: [PATCH 0306/1160] memory poll for RouterProfile --- libi2pd/NetDb.cpp | 1 + libi2pd/NetDb.hpp | 2 ++ libi2pd/Profiling.cpp | 3 ++- libi2pd/Profiling.h | 3 +-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 061ccc23..02d4dfd8 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -175,6 +175,7 @@ namespace data if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) || ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup) { + m_RouterProfilesPool.CleanUpMt (); if (m_PersistProfiles) PersistProfiles (); DeleteObsoleteProfiles (); lastProfilesCleanup = ts; diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index b7d9a5b3..44dff3b8 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -128,6 +128,7 @@ namespace data }; std::shared_ptr NewLease (const Lease& lease) { return m_LeasesPool.AcquireSharedMt (lease); }; std::shared_ptr NewIdentity (const uint8_t * buf, size_t len) { return m_IdentitiesPool.AcquireSharedMt (buf, len); }; + std::shared_ptr NewRouterProfile () { return m_RouterProfilesPool.AcquireSharedMt (); }; uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; @@ -185,6 +186,7 @@ namespace data i2p::util::MemoryPoolMt m_RouterInfoAddressVectorsPool; i2p::util::MemoryPoolMt m_LeasesPool; i2p::util::MemoryPoolMt m_IdentitiesPool; + i2p::util::MemoryPoolMt m_RouterProfilesPool; }; extern NetDb netdb; diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 879aea29..2031fa39 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -16,6 +16,7 @@ #include "FS.h" #include "Log.h" #include "Timestamp.h" +#include "NetDb.hpp" #include "Profiling.h" namespace i2p @@ -237,7 +238,7 @@ namespace data if (it != g_Profiles.end ()) return it->second; } - auto profile = std::make_shared (); + auto profile = netdb.NewRouterProfile (); profile->Load (identHash); // if possible std::unique_lock l(g_ProfilesMutex); g_Profiles.emplace (identHash, profile); diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index c351b41d..6531e060 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -31,7 +31,7 @@ namespace data const char PEER_PROFILE_USAGE_CONNECTED[] = "connected"; const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days) - const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours) + const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 3 * 3600; // in seconds (3 hours) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes) @@ -43,7 +43,6 @@ namespace data public: RouterProfile (); - RouterProfile& operator= (const RouterProfile& ) = default; void Save (const IdentHash& identHash); void Load (const IdentHash& identHash); From 32c5ff23a62b8b8f200b4717244524bb3ab68638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B0=9C=E0=B0=BF=E0=B0=82=E0=B0=A6=E0=B0=82=20=E0=B0=B5?= =?UTF-8?q?=E0=B0=BE=E0=B0=90=E0=B0=BF?= <109575325+jindam-vani@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:51:21 +0000 Subject: [PATCH 0307/1160] Differentiate cryptocurrency & its associated address (#1951) --- README.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d0481ed9..e7fb7318 100644 --- a/README.md +++ b/README.md @@ -99,13 +99,23 @@ Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](http Donations --------- -BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f -LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59 -ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d -DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF -ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ -GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG -XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH +**E-Mail**: ```i2porignal at yandex.ru``` + +**BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f``` + +**LTC**: ```LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59``` + +**ETH**: ```0x9e5bac70d20d1079ceaa111127f4fb3bccce379d``` + +**GST**: ```GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG``` + +**DASH**: ```Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF``` + +**ZEC**: ```t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ``` + +**ANC**: ```AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z``` + +**XMR**: ```497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH``` License ------- From 7b6aa41ca8dc3ca2a0c9d01ff9870794ad98e403 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 31 Aug 2023 16:52:51 +0000 Subject: [PATCH 0308/1160] CPU: remove AVX code, switch to __builtin for AES detection (#1959) * [cpu] remove avx detect and code blocks, try to switch to __builtin * [cpu] use __builtin_* only on x86 systems * [cpu] perform check in separate function * [cpu] set AES definition on MSVC * update x86 and aes support checks at compile time * [cmake] update comment about AES on MSVC --- .editorconfig | 3 + build/CMakeLists.txt | 11 +- contrib/i2pd.conf | 2 - daemon/Daemon.cpp | 3 +- libi2pd/CPU.cpp | 60 ++++---- libi2pd/CPU.h | 5 +- libi2pd/Config.cpp | 4 +- libi2pd/Crypto.cpp | 332 ++++++++++++++++++++++--------------------- libi2pd/Crypto.h | 2 +- libi2pd/Identity.cpp | 29 +--- libi2pd/api.cpp | 3 +- 11 files changed, 222 insertions(+), 232 deletions(-) diff --git a/.editorconfig b/.editorconfig index e1f1243a..0f57a84a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -34,3 +34,6 @@ trim_trailing_whitespace = false [*.yml] indent_style = space indent_size = 2 + +[*.patch] +trim_trailing_whitespace = false diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index f5d01a0b..3185ffab 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -197,14 +197,11 @@ endif() # Note: AES-NI and AVX is available on x86-based CPU's. # Here also ARM64 implementation, but currently we don't support it. -# MSVC is not supported. -if(MSVC) - message(STATUS "AES-NI is not supported on MSVC, option was disabled") - set(WITH_AESNI OFF) -endif() - +# MSVC is not supported due to different ASM processing, so we hope OpenSSL has its own checks to run optimized code. if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386")) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") + if(NOT MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") + endif() add_definitions(-D__AES__) endif() diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 5facbbd5..545973a3 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -280,8 +280,6 @@ verify = true [cpuext] ## Use CPU AES-NI instructions set when work with cryptography when available (default: true) # aesni = true -## Use CPU AVX instructions set when work with cryptography when available (default: true) -# avx = true ## Force usage of CPU instructions set, even if they not found (default: false) ## DO NOT TOUCH that option if you really don't know what are you doing! # force = false diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 8e9721db..f04236fe 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -150,12 +150,11 @@ namespace util bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); - bool avx; i2p::config::GetOption("cpuext.avx", avx); bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); bool ssu; i2p::config::GetOption("ssu", ssu); if (!ssu && i2p::config::IsDefault ("precomputation.elgamal")) precomputation = false; // we don't elgamal table if no ssu, unless it's specified explicitly - i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); + i2p::crypto::InitCrypto (precomputation, aesni, forceCpuExt); i2p::transport::InitAddressFromIface (); // get address4/6 from interfaces diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 0804e2ac..d42f1ddd 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -7,52 +7,52 @@ */ #include "CPU.h" -#if defined(__x86_64__) || defined(__i386__) -#include -#endif #include "Log.h" -#ifndef bit_AES -#define bit_AES (1 << 25) -#endif -#ifndef bit_AVX -#define bit_AVX (1 << 28) -#endif +#if defined(_MSC_VER) +#include +#ifndef bit_AES + #define bit_AES (1 << 25) +#endif +#endif namespace i2p { namespace cpu { bool aesni = false; - bool avx = false; - void Detect(bool AesSwitch, bool AvxSwitch, bool force) + inline bool cpu_support_aes() { -#if defined(__x86_64__) || defined(__i386__) - int info[4]; - __cpuid(0, info[0], info[1], info[2], info[3]); - if (info[0] >= 0x00000001) { - __cpuid(0x00000001, info[0], info[1], info[2], info[3]); -#if defined (_WIN32) && (WINVER == 0x0501) // WinXP - if (AesSwitch && force) { // only if forced -#else - if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) { +#if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) +#if defined(_MSC_VER) + int cpu_info[4]; + __cpuid(cpu_info, 1); + return ((cpu_info[2] & bit_AES) != 0); +#elif defined(__clang__) +#if __clang_major__ >= 6 + __builtin_cpu_init(); #endif - aesni = true; - } -#if defined (_WIN32) && (WINVER == 0x0501) // WinXP - if (AvxSwitch && force) { // only if forced + return __builtin_cpu_supports("aes"); +#elif defined(__GNUC__) + __builtin_cpu_init(); + return __builtin_cpu_supports("aes"); #else - if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) { + return false; #endif - avx = true; - } +#else + return false; +#endif + } + + void Detect(bool AesSwitch, bool force) + { + if ((cpu_support_aes() && AesSwitch) || (AesSwitch && force)) { + aesni = true; } -#endif // defined(__x86_64__) || defined(__i386__) LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled")); - LogPrint(eLogInfo, "AVX ", (avx ? "enabled" : "disabled")); } } } diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index f021bccb..a0695884 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -14,9 +14,8 @@ namespace i2p namespace cpu { extern bool aesni; - extern bool avx; - void Detect(bool AesSwitch, bool AvxSwitch, bool force); + void Detect(bool AesSwitch, bool force); } } diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 6b515ef9..5551b010 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -193,7 +193,7 @@ namespace config { options_description precomputation("Precomputation options"); precomputation.add_options() ("precomputation.elgamal", -#if defined(__x86_64__) +#if (defined(_M_AMD64) || defined(__x86_64__)) value()->default_value(false), #else value()->default_value(true), @@ -308,7 +308,7 @@ namespace config { options_description cpuext("CPU encryption extensions options"); cpuext.add_options() ("cpuext.aesni", bool_switch()->default_value(true), "Use auto detection for AESNI CPU extensions. If false, AESNI will be not used") - ("cpuext.avx", bool_switch()->default_value(true), "Use auto detection for AVX CPU extensions. If false, AVX will be not used") + ("cpuext.avx", bool_switch()->default_value(false), "Deprecated option") ("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines") ; diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 12087443..b5bc33d1 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -28,6 +28,12 @@ #include "I2PEndian.h" #include "Log.h" +#if defined(__AES__) && !defined(_MSC_VER) && ((defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__))) + #define SUPPORTS_AES 1 +#else + #define SUPPORTS_AES 0 +#endif + namespace i2p { namespace crypto @@ -361,7 +367,7 @@ namespace crypto BIGNUM * b1 = BN_CTX_get (ctx); BIGNUM * b = BN_CTX_get (ctx); // select random k -#if defined(__x86_64__) +#if (defined(_M_AMD64) || defined(__x86_64__)) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits @@ -428,7 +434,7 @@ namespace crypto void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub) { -#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) +#if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) || defined(_MSC_VER) RAND_bytes (priv, 256); #else // lower 226 bits (28 bytes and 2 bits) only. short exponent @@ -555,7 +561,7 @@ namespace crypto } // AES -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES #define KeyExpansion256(round0,round1) \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \ "movaps %%xmm1, %%xmm4 \n" \ @@ -580,7 +586,7 @@ namespace crypto "movaps %%xmm3, "#round1"(%[sched]) \n" #endif -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES void ECBCryptoAESNI::ExpandKey (const AESKey& key) { __asm__ @@ -621,7 +627,7 @@ namespace crypto #endif -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES #define EncryptAES256(sched) \ "pxor (%["#sched"]), %%xmm0 \n" \ "aesenc 16(%["#sched"]), %%xmm0 \n" \ @@ -642,16 +648,18 @@ namespace crypto void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[in]), %%xmm0 \n" - EncryptAES256(sched) - "movups %%xmm0, (%[out]) \n" - : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" - ); + ( + "movups (%[in]), %%xmm0 \n" + EncryptAES256(sched) + "movups %%xmm0, (%[out]) \n" + : + : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) + : "%xmm0", "memory" + ); } else #endif @@ -660,7 +668,7 @@ namespace crypto } } -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES #define DecryptAES256(sched) \ "pxor 224(%["#sched"]), %%xmm0 \n" \ "aesdec 208(%["#sched"]), %%xmm0 \n" \ @@ -681,16 +689,18 @@ namespace crypto void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[in]), %%xmm0 \n" - DecryptAES256(sched) - "movups %%xmm0, (%[out]) \n" - : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" - ); + ( + "movups (%[in]), %%xmm0 \n" + DecryptAES256(sched) + "movups %%xmm0, (%[out]) \n" + : + : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) + : "%xmm0", "memory" + ); } else #endif @@ -699,7 +709,7 @@ namespace crypto } } -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES #define CallAESIMC(offset) \ "movaps "#offset"(%[shed]), %%xmm0 \n" \ "aesimc %%xmm0, %%xmm0 \n" \ @@ -708,7 +718,7 @@ namespace crypto void ECBEncryption::SetKey (const AESKey& key) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { ExpandKey (key); @@ -722,28 +732,30 @@ namespace crypto void ECBDecryption::SetKey (const AESKey& key) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { ExpandKey (key); // expand encryption key first // then invert it using aesimc __asm__ - ( - CallAESIMC(16) - CallAESIMC(32) - CallAESIMC(48) - CallAESIMC(64) - CallAESIMC(80) - CallAESIMC(96) - CallAESIMC(112) - CallAESIMC(128) - CallAESIMC(144) - CallAESIMC(160) - CallAESIMC(176) - CallAESIMC(192) - CallAESIMC(208) - : : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory" - ); + ( + CallAESIMC(16) + CallAESIMC(32) + CallAESIMC(48) + CallAESIMC(64) + CallAESIMC(80) + CallAESIMC(96) + CallAESIMC(112) + CallAESIMC(128) + CallAESIMC(144) + CallAESIMC(160) + CallAESIMC(176) + CallAESIMC(192) + CallAESIMC(208) + : + : [shed]"r"(GetKeySchedule ()) + : "%xmm0", "memory" + ); } else #endif @@ -754,28 +766,28 @@ namespace crypto void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[iv]), %%xmm1 \n" - "1: \n" - "movups (%[in]), %%xmm0 \n" - "pxor %%xmm1, %%xmm0 \n" - EncryptAES256(sched) - "movaps %%xmm0, %%xmm1 \n" - "movups %%xmm0, (%[out]) \n" - "add $16, %[in] \n" - "add $16, %[out] \n" - "dec %[num] \n" - "jnz 1b \n" - "movups %%xmm1, (%[iv]) \n" - : - : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), - [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) - : "%xmm0", "%xmm1", "cc", "memory" - ); + ( + "movups (%[iv]), %%xmm1 \n" + "1: \n" + "movups (%[in]), %%xmm0 \n" + "pxor %%xmm1, %%xmm0 \n" + EncryptAES256(sched) + "movaps %%xmm0, %%xmm1 \n" + "movups %%xmm0, (%[out]) \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "dec %[num] \n" + "jnz 1b \n" + "movups %%xmm1, (%[iv]) \n" + : + : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), + [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) + : "%xmm0", "%xmm1", "cc", "memory" + ); } else #endif @@ -799,22 +811,22 @@ namespace crypto void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[iv]), %%xmm1 \n" - "movups (%[in]), %%xmm0 \n" - "pxor %%xmm1, %%xmm0 \n" - EncryptAES256(sched) - "movups %%xmm0, (%[out]) \n" - "movups %%xmm0, (%[iv]) \n" - : - : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), - [in]"r"(in), [out]"r"(out) - : "%xmm0", "%xmm1", "memory" - ); + ( + "movups (%[iv]), %%xmm1 \n" + "movups (%[in]), %%xmm0 \n" + "pxor %%xmm1, %%xmm0 \n" + EncryptAES256(sched) + "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[iv]) \n" + : + : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), + [in]"r"(in), [out]"r"(out) + : "%xmm0", "%xmm1", "memory" + ); } else #endif @@ -823,29 +835,29 @@ namespace crypto void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[iv]), %%xmm1 \n" - "1: \n" - "movups (%[in]), %%xmm0 \n" - "movaps %%xmm0, %%xmm2 \n" - DecryptAES256(sched) - "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" - "movaps %%xmm2, %%xmm1 \n" - "add $16, %[in] \n" - "add $16, %[out] \n" - "dec %[num] \n" - "jnz 1b \n" - "movups %%xmm1, (%[iv]) \n" - : - : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), - [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) - : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" - ); + ( + "movups (%[iv]), %%xmm1 \n" + "1: \n" + "movups (%[in]), %%xmm0 \n" + "movaps %%xmm0, %%xmm2 \n" + DecryptAES256(sched) + "pxor %%xmm1, %%xmm0 \n" + "movups %%xmm0, (%[out]) \n" + "movaps %%xmm2, %%xmm1 \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "dec %[num] \n" + "jnz 1b \n" + "movups %%xmm1, (%[iv]) \n" + : + : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), + [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) + : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" + ); } else #endif @@ -869,22 +881,22 @@ namespace crypto void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - "movups (%[iv]), %%xmm1 \n" - "movups (%[in]), %%xmm0 \n" - "movups %%xmm0, (%[iv]) \n" - DecryptAES256(sched) - "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" - : - : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), - [in]"r"(in), [out]"r"(out) - : "%xmm0", "%xmm1", "memory" - ); + ( + "movups (%[iv]), %%xmm1 \n" + "movups (%[in]), %%xmm0 \n" + "movups %%xmm0, (%[iv]) \n" + DecryptAES256(sched) + "pxor %%xmm1, %%xmm0 \n" + "movups %%xmm0, (%[out]) \n" + : + : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), + [in]"r"(in), [out]"r"(out) + : "%xmm0", "%xmm1", "memory" + ); } else #endif @@ -893,34 +905,34 @@ namespace crypto void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - // encrypt IV - "movups (%[in]), %%xmm0 \n" - EncryptAES256(sched_iv) - "movaps %%xmm0, %%xmm1 \n" - // double IV encryption - EncryptAES256(sched_iv) - "movups %%xmm0, (%[out]) \n" - // encrypt data, IV is xmm1 - "1: \n" - "add $16, %[in] \n" - "add $16, %[out] \n" - "movups (%[in]), %%xmm0 \n" - "pxor %%xmm1, %%xmm0 \n" - EncryptAES256(sched_l) - "movaps %%xmm0, %%xmm1 \n" - "movups %%xmm0, (%[out]) \n" - "dec %[num] \n" - "jnz 1b \n" - : - : [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()), - [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes - : "%xmm0", "%xmm1", "cc", "memory" - ); + ( + // encrypt IV + "movups (%[in]), %%xmm0 \n" + EncryptAES256(sched_iv) + "movaps %%xmm0, %%xmm1 \n" + // double IV encryption + EncryptAES256(sched_iv) + "movups %%xmm0, (%[out]) \n" + // encrypt data, IV is xmm1 + "1: \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "movups (%[in]), %%xmm0 \n" + "pxor %%xmm1, %%xmm0 \n" + EncryptAES256(sched_l) + "movaps %%xmm0, %%xmm1 \n" + "movups %%xmm0, (%[out]) \n" + "dec %[num] \n" + "jnz 1b \n" + : + : [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()), + [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes + : "%xmm0", "%xmm1", "cc", "memory" + ); } else #endif @@ -934,35 +946,35 @@ namespace crypto void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out) { -#if defined(__AES__) && (defined(__x86_64__) || defined(__i386__)) +#if SUPPORTS_AES if(i2p::cpu::aesni) { __asm__ - ( - // decrypt IV - "movups (%[in]), %%xmm0 \n" - DecryptAES256(sched_iv) - "movaps %%xmm0, %%xmm1 \n" - // double IV encryption - DecryptAES256(sched_iv) - "movups %%xmm0, (%[out]) \n" - // decrypt data, IV is xmm1 - "1: \n" - "add $16, %[in] \n" - "add $16, %[out] \n" - "movups (%[in]), %%xmm0 \n" - "movaps %%xmm0, %%xmm2 \n" - DecryptAES256(sched_l) - "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" - "movaps %%xmm2, %%xmm1 \n" - "dec %[num] \n" - "jnz 1b \n" - : - : [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()), - [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes - : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" - ); + ( + // decrypt IV + "movups (%[in]), %%xmm0 \n" + DecryptAES256(sched_iv) + "movaps %%xmm0, %%xmm1 \n" + // double IV encryption + DecryptAES256(sched_iv) + "movups %%xmm0, (%[out]) \n" + // decrypt data, IV is xmm1 + "1: \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "movups (%[in]), %%xmm0 \n" + "movaps %%xmm0, %%xmm2 \n" + DecryptAES256(sched_l) + "pxor %%xmm1, %%xmm0 \n" + "movups %%xmm0, (%[out]) \n" + "movaps %%xmm2, %%xmm1 \n" + "dec %[num] \n" + "jnz 1b \n" + : + : [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()), + [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes + : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" + ); } else #endif @@ -1285,9 +1297,9 @@ namespace crypto } }*/ - void InitCrypto (bool precomputation, bool aesni, bool avx, bool force) + void InitCrypto (bool precomputation, bool aesni, bool force) { - i2p::cpu::Detect (aesni, avx, force); + i2p::cpu::Detect (aesni, force); #if LEGACY_OPENSSL SSL_library_init (); #endif @@ -1297,7 +1309,7 @@ namespace crypto CRYPTO_set_locking_callback (OpensslLockingCallback);*/ if (precomputation) { -#if defined(__x86_64__) +#if (defined(_M_AMD64) || defined(__x86_64__)) g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); #else @@ -1312,7 +1324,7 @@ namespace crypto if (g_ElggTable) { DestroyElggTable (g_ElggTable, -#if defined(__x86_64__) +#if (defined(_M_AMD64) || defined(__x86_64__)) ELGAMAL_FULL_EXPONENT_NUM_BYTES #else ELGAMAL_SHORT_EXPONENT_NUM_BYTES diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index d4cbda97..1419293b 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -307,7 +307,7 @@ namespace crypto void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) // init and terminate - void InitCrypto (bool precomputation, bool aesni, bool avx, bool force); + void InitCrypto (bool precomputation, bool aesni, bool force); void TerminateCrypto (); } } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index a4a9f716..3a659c11 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -803,29 +803,12 @@ namespace data XORMetric operator^(const IdentHash& key1, const IdentHash& key2) { XORMetric m; -#if (defined(__x86_64__) || defined(__i386__)) && defined(__AVX__) // not all X86 targets supports AVX (like old Pentium, see #1600) - if(i2p::cpu::avx) - { - __asm__ - ( - "vmovups %1, %%ymm0 \n" - "vmovups %2, %%ymm1 \n" - "vxorps %%ymm0, %%ymm1, %%ymm1 \n" - "vmovups %%ymm1, %0 \n" - : "=m"(*m.metric) - : "m"(*key1), "m"(*key2) - : "memory", "%xmm0", "%xmm1" // should be replaced by %ymm0/1 once supported by compiler - ); - } - else -#endif - { - const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL (); - m.metric_ll[0] = hash1[0] ^ hash2[0]; - m.metric_ll[1] = hash1[1] ^ hash2[1]; - m.metric_ll[2] = hash1[2] ^ hash2[2]; - m.metric_ll[3] = hash1[3] ^ hash2[3]; - } + + const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL (); + m.metric_ll[0] = hash1[0] ^ hash2[0]; + m.metric_ll[1] = hash1[1] ^ hash2[1]; + m.metric_ll[2] = hash1[2] ^ hash2[2]; + m.metric_ll[3] = hash1[3] ^ hash2[3]; return m; } diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 3bfb801c..ad24519f 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -38,9 +38,8 @@ namespace api bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); - bool avx; i2p::config::GetOption("cpuext.avx", avx); bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); - i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); + i2p::crypto::InitCrypto (precomputation, aesni, forceCpuExt); int netID; i2p::config::GetOption("netid", netID); i2p::context.SetNetID (netID); From c53ad2012ceb9c7489c97378e86500332d8edbac Mon Sep 17 00:00:00 2001 From: r4sas Date: Wed, 6 Sep 2023 20:26:46 +0000 Subject: [PATCH 0309/1160] [cpu] use cpuid on gcc < 5 Signed-off-by: r4sas --- libi2pd/CPU.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index d42f1ddd..14ce3788 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -9,12 +9,16 @@ #include "CPU.h" #include "Log.h" -#if defined(_MSC_VER) -#include - #ifndef bit_AES #define bit_AES (1 << 25) #endif + +#if (defined(__GNUC__) && __GNUC__ < 5) + #include +#endif + +#ifdef _MSC_VER + #include #endif namespace i2p @@ -26,18 +30,18 @@ namespace cpu inline bool cpu_support_aes() { #if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) -#if defined(_MSC_VER) - int cpu_info[4]; - __cpuid(cpu_info, 1); - return ((cpu_info[2] & bit_AES) != 0); +#if (defined(__GNUC__) && __GNUC__ > 4) + __builtin_cpu_init(); + return __builtin_cpu_supports("aes"); #elif defined(__clang__) #if __clang_major__ >= 6 __builtin_cpu_init(); #endif return __builtin_cpu_supports("aes"); -#elif defined(__GNUC__) - __builtin_cpu_init(); - return __builtin_cpu_supports("aes"); +#elif (defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 5)) + int cpu_info[4]; + __cpuid(cpu_info, 1); + return ((cpu_info[2] & bit_AES) != 0); #else return false; #endif From 4a5e16b99405182c6daa5862088a9b9247e1c6b4 Mon Sep 17 00:00:00 2001 From: r4sas Date: Thu, 7 Sep 2023 16:56:53 +0000 Subject: [PATCH 0310/1160] [cpu] tests with preprocessor Signed-off-by: r4sas --- libi2pd/CPU.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 14ce3788..53771ff0 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -30,21 +30,26 @@ namespace cpu inline bool cpu_support_aes() { #if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) -#if (defined(__GNUC__) && __GNUC__ > 4) +# if (defined(__GNUC__) && __GNUC__ > 4) +# warning("CPU: IN GCC!!!") __builtin_cpu_init(); return __builtin_cpu_supports("aes"); -#elif defined(__clang__) -#if __clang_major__ >= 6 +# elif (defined(__clang__) && !defined(__GNUC__)) +# warning("CPU: IN CLANG!!!") +# warning(__clang__) +# if (__clang_major__ >= 6) __builtin_cpu_init(); -#endif +# endif return __builtin_cpu_supports("aes"); -#elif (defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 5)) +# elif (defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 5)) +# warning("CPU: IN MSVC!!!") int cpu_info[4]; __cpuid(cpu_info, 1); return ((cpu_info[2] & bit_AES) != 0); -#else +# else +# warning("CPU: FALSE") return false; -#endif +# endif #else return false; #endif From 4ed19c05f68e58a15c57f2791b1b0e1d863dda55 Mon Sep 17 00:00:00 2001 From: r4sas Date: Thu, 7 Sep 2023 21:20:52 +0000 Subject: [PATCH 0311/1160] [cpu] split AES detect for GNU C < 5 Signed-off-by: r4sas --- libi2pd/CPU.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 53771ff0..106882eb 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -30,29 +30,30 @@ namespace cpu inline bool cpu_support_aes() { #if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) -# if (defined(__GNUC__) && __GNUC__ > 4) -# warning("CPU: IN GCC!!!") +#if defined(__clang__) +# if (__clang_major__ >= 6) + __builtin_cpu_init(); +# endif + return __builtin_cpu_supports("aes"); +#elif (defined(__GNUC__) && __GNUC__ >= 5) __builtin_cpu_init(); return __builtin_cpu_supports("aes"); -# elif (defined(__clang__) && !defined(__GNUC__)) -# warning("CPU: IN CLANG!!!") -# warning(__clang__) -# if (__clang_major__ >= 6) - __builtin_cpu_init(); -# endif - return __builtin_cpu_supports("aes"); -# elif (defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 5)) -# warning("CPU: IN MSVC!!!") +#elif (defined(__GNUC__) && __GNUC__ < 5) + int cpu_info[4]; + bool flag = false; + __cpuid(0, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]); + if (cpu_info[0] >= 0x00000001) { + __cpuid(0x00000001, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]); + flag = ((cpu_info[2] & bit_AES) != 0); + } + return flag; +#elif defined(_MSC_VER) int cpu_info[4]; __cpuid(cpu_info, 1); return ((cpu_info[2] & bit_AES) != 0); -# else -# warning("CPU: FALSE") - return false; -# endif -#else - return false; #endif +#endif + return false; } void Detect(bool AesSwitch, bool force) From 70829ee79e971f325ea4f3b753d0f8b02bce9fce Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 10 Sep 2023 13:02:52 +0300 Subject: [PATCH 0312/1160] [rpm] add Fedora ELN support Signed-off-by: r4sas --- contrib/rpm/i2pd-git.spec | 68 +++++++++++++++----------------------- contrib/rpm/i2pd.spec | 69 ++++++++++++++++----------------------- 2 files changed, 55 insertions(+), 82 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 62a28631..ff46bc0f 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -28,9 +28,11 @@ Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd + %description C++ implementation of I2P. + %prep %setup -q -n i2pd-openssl @@ -38,72 +40,56 @@ C++ implementation of I2P. %build cd build %if 0%{?rhel} == 7 -%cmake3 \ + %cmake3 \ -DWITH_LIBRARY=OFF \ -DWITH_UPNP=ON \ -DWITH_HARDENING=ON \ -DBUILD_SHARED_LIBS:BOOL=OFF %else -%cmake \ + %cmake \ -DWITH_LIBRARY=OFF \ -DWITH_UPNP=ON \ -DWITH_HARDENING=ON \ -%if 0%{?fedora} > 29 + %if 0%{?fedora} > 29 -DBUILD_SHARED_LIBS:BOOL=OFF \ . -%else + %else -DBUILD_SHARED_LIBS:BOOL=OFF -%endif + %endif %endif - -%if 0%{?rhel} == 9 -pushd redhat-linux-build -%endif - -%if 0%{?fedora} >= 35 -pushd redhat-linux-build +%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} + pushd redhat-linux-build %else -%if 0%{?fedora} >= 33 -pushd %{_target_platform} -%endif -%endif + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif -%if 0%{?mageia} > 7 -pushd build + %if 0%{?mageia} > 7 + pushd build + %endif %endif make %{?_smp_mflags} -%if 0%{?rhel} == 9 -popd +%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7 + popd %endif -%if 0%{?fedora} >= 33 -popd -%endif - -%if 0%{?mageia} > 7 -popd -%endif %install pushd build -%if 0%{?rhel} == 9 -pushd redhat-linux-build -%endif - -%if 0%{?fedora} >= 35 -pushd redhat-linux-build +%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} + pushd redhat-linux-build %else -%if 0%{?fedora} >= 33 -pushd %{_target_platform} -%endif -%endif + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif -%if 0%{?mageia} -pushd build + %if 0%{?mageia} + pushd build + %endif %endif chrpath -d i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 19825237..5d1adfb7 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.48.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -26,9 +26,11 @@ Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd + %description C++ implementation of I2P. + %prep %setup -q @@ -36,71 +38,56 @@ C++ implementation of I2P. %build cd build %if 0%{?rhel} == 7 -%cmake3 \ + %cmake3 \ -DWITH_LIBRARY=OFF \ -DWITH_UPNP=ON \ -DWITH_HARDENING=ON \ -DBUILD_SHARED_LIBS:BOOL=OFF %else -%cmake \ + %cmake \ -DWITH_LIBRARY=OFF \ -DWITH_UPNP=ON \ -DWITH_HARDENING=ON \ -%if 0%{?fedora} > 29 + %if 0%{?fedora} > 29 -DBUILD_SHARED_LIBS:BOOL=OFF \ . -%else + %else -DBUILD_SHARED_LIBS:BOOL=OFF -%endif + %endif %endif -%if 0%{?rhel} == 9 -pushd redhat-linux-build -%endif - -%if 0%{?fedora} >= 35 -pushd redhat-linux-build +%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} + pushd redhat-linux-build %else -%if 0%{?fedora} >= 33 -pushd %{_target_platform} -%endif -%endif + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif -%if 0%{?mageia} > 7 -pushd build + %if 0%{?mageia} > 7 + pushd build + %endif %endif make %{?_smp_mflags} -%if 0%{?rhel} == 9 -popd +%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7 + popd %endif -%if 0%{?fedora} >= 33 -popd -%endif - -%if 0%{?mageia} > 7 -popd -%endif %install pushd build -%if 0%{?rhel} == 9 -pushd redhat-linux-build -%endif - -%if 0%{?fedora} >= 35 -pushd redhat-linux-build +%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln} + pushd redhat-linux-build %else -%if 0%{?fedora} >= 33 -pushd %{_target_platform} -%endif -%endif + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif -%if 0%{?mageia} -pushd build + %if 0%{?mageia} + pushd build + %endif %endif chrpath -d i2pd From 1e7feae0df17eb26cd4d843fcbf1afb26bae95f7 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 10 Sep 2023 13:08:00 +0300 Subject: [PATCH 0313/1160] [rpm] remove BuildRequires tabulation Signed-off-by: r4sas --- contrib/rpm/i2pd-git.spec | 4 ++-- contrib/rpm/i2pd.spec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index ff46bc0f..cebc15a4 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5d1adfb7..cc826928 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath From 918aa556ef93272464ca396ae485b30b24b42b36 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 15 Sep 2023 11:37:45 -0400 Subject: [PATCH 0314/1160] fixed non-x86 build --- libi2pd/CPU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 106882eb..5d5fc6b3 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -13,7 +13,7 @@ #define bit_AES (1 << 25) #endif -#if (defined(__GNUC__) && __GNUC__ < 5) +#if (defined(__GNUC__) && __GNUC__ < 5 && (defined(__x86_64__) || defined(__i386__))) #include #endif From df6bb6d9b8b33d9a7db81386fd8771c5b7b8bc57 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Sep 2023 10:19:57 -0400 Subject: [PATCH 0315/1160] 2.49.0 --- ChangeLog | 27 +++++++++++++++++++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 881e05d7..17ec98d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,33 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.49.0] - 2023-09-18 +### Added +- Handle SOCK5 authrozation with empty user/password +- Drop incoming transport sessions from too old or from future routers +- Memory pool for router profiles +- Allow 0 hops in explicitPeers +### Changed +- Separate network and testing status +- Remove AVX code +- Improve NTCP2 transport session logging +- Select router with ipv4 for tunnel endpoint +- Consider all addresses non-published for U and H routers even if they have host/port +- Don't pick completely unreachable routers for tunnels +- Exclude SSU1 introducers from SSU2 addresses +- Don't create paired inbound tunnel if length is different +- Remove introducer from RouterInfo after 60 minutes +- Reduce SSU2 keep alive interval and add peer test interval variance +- Don't pick too old sessions for introducer +### Fixed +- Version of the subnegotiation in user/password SOCKS5 response +- Send keepalive for existing session with introducer +- Buffer offset for EVP_EncryptFinal_ex() to include outlen +- Termination block size processing for transport sessions +- Crash if deleted BOB destination was shared between few BOB sessions +- Introducers with zero tag +- Padding for SSU2 path response + ## [2.48.0] - 2023-06-12 ### Added - Allow user/password authentication method for SOCK5 proxy diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index cebc15a4..c745e05f 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.48.0 +Version: 2.49.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -144,6 +144,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Sep 18 2023 orignal - 2.49.0 +- update to 2.49.0 + * Mon Jun 12 2023 orignal - 2.48.0 - update to 2.48.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index cc826928..b88f21b2 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.48.0 +Version: 2.49.0 Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -142,6 +142,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Sep 18 2023 orignal - 2.49.0 +- update to 2.49.0 + * Mon Jun 12 2023 orignal - 2.48.0 - update to 2.48.0 diff --git a/debian/changelog b/debian/changelog index 91b0abdf..613bc7c9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.49.0-1) unstable; urgency=high + + * updated to version 2.49.0/0.9.60 + + -- orignal Mon, 18 Sep 2023 16:00:00 +0000 + i2pd (2.48.0-1) unstable; urgency=high * updated to version 2.48.0/0.9.59 diff --git a/libi2pd/version.h b/libi2pd/version.h index 903ceebc..9854995e 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -18,7 +18,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 48 +#define I2PD_VERSION_MINOR 49 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #ifdef GITVER @@ -33,7 +33,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 59 +#define I2P_VERSION_MICRO 60 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 3a4238729a103baef76ab677d555ae55a4833a9b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Sep 2023 10:41:31 -0400 Subject: [PATCH 0316/1160] 2.49.0 --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17ec98d7..69d5c4c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ ## [2.49.0] - 2023-09-18 ### Added -- Handle SOCK5 authrozation with empty user/password +- Handle SOCK5 authorization with empty user/password - Drop incoming transport sessions from too old or from future routers - Memory pool for router profiles - Allow 0 hops in explicitPeers @@ -17,7 +17,7 @@ - Exclude SSU1 introducers from SSU2 addresses - Don't create paired inbound tunnel if length is different - Remove introducer from RouterInfo after 60 minutes -- Reduce SSU2 keep alive interval and add peer test interval variance +- Reduce SSU2 keep alive interval and add keep alive interval variance - Don't pick too old sessions for introducer ### Fixed - Version of the subnegotiation in user/password SOCKS5 response From 4d573f6655c37cc13022157c1e2d043debca7512 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 17 Sep 2023 15:36:15 +0000 Subject: [PATCH 0317/1160] 2.49.0 Signed-off-by: r4sas --- ChangeLog | 16 ++++++++-------- Win32/mask.bmp | Bin 25818 -> 0 bytes contrib/rpm/i2pd.spec | 2 +- debian/changelog | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 Win32/mask.bmp diff --git a/ChangeLog b/ChangeLog index 69d5c4c9..4dd49a24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,20 +4,20 @@ ## [2.49.0] - 2023-09-18 ### Added - Handle SOCK5 authorization with empty user/password -- Drop incoming transport sessions from too old or from future routers -- Memory pool for router profiles +- Drop incoming transport sessions from too old or from future routers +- Memory pool for router profiles - Allow 0 hops in explicitPeers ### Changed - Separate network and testing status - Remove AVX code -- Improve NTCP2 transport session logging -- Select router with ipv4 for tunnel endpoint +- Improve NTCP2 transport session logging +- Select router with ipv4 for tunnel endpoint - Consider all addresses non-published for U and H routers even if they have host/port - Don't pick completely unreachable routers for tunnels -- Exclude SSU1 introducers from SSU2 addresses +- Exclude SSU1 introducers from SSU2 addresses - Don't create paired inbound tunnel if length is different -- Remove introducer from RouterInfo after 60 minutes -- Reduce SSU2 keep alive interval and add keep alive interval variance +- Remove introducer from RouterInfo after 60 minutes +- Reduce SSU2 keep alive interval and add keep alive interval variance - Don't pick too old sessions for introducer ### Fixed - Version of the subnegotiation in user/password SOCKS5 response @@ -26,7 +26,7 @@ - Termination block size processing for transport sessions - Crash if deleted BOB destination was shared between few BOB sessions - Introducers with zero tag -- Padding for SSU2 path response +- Padding for SSU2 path response ## [2.48.0] - 2023-06-12 ### Added diff --git a/Win32/mask.bmp b/Win32/mask.bmp deleted file mode 100644 index cc2aeda75c6139ef81b479bb01f726996e756050..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25818 zcmeHPcUV(d7I**Holl+FZ)cRENUT(c0qHF?=@v#o1*5{yl8}(lLJd7gCv+kfK#^WV zDHae0>{1kz8O8283JR!L#x}brJm;AS9S1~t?|aF2bKkk`_shBWoO5rYx8|z-jQ&d* z-X-Cc3NJNy{bPnOyd&4rA7;$pzW%)aH_fhh@80!2d-lg4e@wG+e@VmT)YN`kce1qM zI_r;84v;%>;)K*jf{FyVOEr7{QMFf1!37%^K znHJ&gZNH4NrHaC0X8{S4ki@mC9iuFQiA^v9zumj*1jlteHw(FwsbXMl;*RO|yVpnWD5D2&by3OD&@`+u)eMhAHNIn+G;lpK; zK7uw9)!n^u@eI+JC~5*YAA>f`qPV#9b4XLt8OY(Kj*f3QnGwg14_X$>oOlFUFSOc= zdLcAM(~<^K1UYspI*1>>3yWJ@Tc13A3RLq_1WjFP zyJS1x(+kHoUqV(}9bo3ZBP=1K=g){vN>mI&AiRThdgkm|zTRag=LeX?@MU5j$B4j% z%k2$~Ef<N;ItzdJh4%WTso!6gu4K}kRp+_;Odl(Vd6EXk#+csuy+H zIK3BWG)nD+gz=6Z6R$jWR5VFIjHi@DWquKF2alE4zzm%1y^}W+OaHA1ba!{>W$v|6 z(jxLufpUT*OqVJGb-?Rn)(_GF^!4&ZZ2ynOkxG{1l#qf8axy6U{QrHC}%=O~b-6LQ*Qg{l4`71g!DKqlm@jJu{x z-t*&9WnTHBoqN!cr?Peefpm$Go>2sQ&{9}pya>Re2j+iLcqBno3Y}evLXs+*!+|dC z&~viO71x-W{bXTjB(Owfy&s~AD$Y50n>eb_d)lGkfxY{o3t$+P=9W1v2mos~${`sl zA8)^~a$`jRz`k|s7GsNzy?_`HqOG{bi1Sc`Su4C^l@h%`!C{BGYoY2UZ=BFV4WGkY zRgC#nopE6OA~{4AA@W^)kn6f^D+#j&816hF_d7zuGYM0i=~kd-Tk_5Dvk&$jRRCZ0Z+$Q1d8T8FNL2ma9t7 zha4?dle8swnuY09hgnM$mI4}onzM``;_QWsLkOfVW?gQ*{OJZX&X)Ou6yvOBl8g2B z_7lq&54$*_dt78gV4DfWo{9_B za614j^=n|KZp204P~D?Ug_;dHa2q7vQFh9LdxbR{&#Yb5o!}BtRAMIDNyU{~~ntzxN;rs!xpwW@p#KorfyHvl&qm6Zk6vuFuQVRQSSZT%|{cOK1VHu8evx>ul=OJ`)A7U1++|G5sCTotCs58DA=cgCjlOYpcEcRo&C+f7weNC*7kwP9o^>QRH)h4C>&<#q51&% zFbfN-qS)8i2!1Q)`V38`=CP|r4>+I-Tv!;LC$20c0xJrL3?|k+bJ4w+feYNJq?9pi$GnaVvghQ9&Vux`7|$g0Ij0 z`}gzrWd~V1*e(76>>iqi;V*5Mc$>!3LnDx1f8wjss&#RklAN-p#wIx9G?XkL?Xhw- zD51?fDNsNC_#0eK{AyHPi|_&UsxE~Z-c{gRz$3VUG~MtPRksrG7*PU2UUxME+zW@f zVw;4;?Bq2mT1HN4dbZ;7)^nF4r{0M3q|yReuqQoKH?aHx2t0rOqVQM^y5TVcnV9Uz6l*Tgh~e9 zupQ!QYTkC?BA@bq=mD1cCS5;LUL|+M#D*Jp_IrJOlG5EQ8u+UO!4`YC3=t z?o=Y~f~PR4A_Rh>LPCYQ-yrF(vHYrm?7`&eu5Eg}yb=u2kLo2>csK;AD=M7?#1Z(n z%$L>)YlI0CHY6a(tWqW1rw=h3WlA<|Awu|6)Ay*R zUo~MqR}8(0!V*CiTN{qmjOb?!*SSye>~lM-4gk}&O;F&Sg(S62UGyT_v;ymOSxx#1 zYia!iA_Dqq8$cDo)`2LSR`4lJW(}g2kg2`a6DCsF(|4FJDNGU&5B2au*0H;H@6vHdOqI=v*bO{n$0hMOe%mA! zAQ%H$*LHhee8QH;Bz{#@9b0^0 zVn#C!YlT=FQ2~!A71%UPA_d~52o8{NlK1J?F81y??qN~j%5Uu^UR8u5IT;_$kpj;U zP-{7Ru{`&1USe@pcwPo8XJ1r)UTX1?lIqr$ww|7zwksXgO)alpVP4|j@^u5qcf}?k z@h>L<35K;Du!PnOPg5Bg$P5Xa#7KVUg9mWto0mp=8P%coC!hx8LhHm5e>VbGuUxSf z;riob0dapv3M`C#Ez}=9f$ZkSxFw^HAW%(O_LrYlggLtbSEvA%m@EWf7NzQQy*@ZW z8toSV#>c>xpY=VXNe6){23ke(K5c7mAuV}-loV=k5D+WbpUW$Nr6(Q%U@VwSg9!B2 z#WH321;c0&+nEE_i90@+&tY%B*h-fAa5&#ibUF6dLKDv$(gM)+=GB|z&~SpV7>nu( zCdlwDpF7dWSQz6Z!36u0Px9`q+cXtDbZxYgRt5*3Pv*1!I3>^10D);Wb&HSGI{f6& zarNpj>W5+vR*tJ?5M@Eo_3PKsOf&(T^?{Z)h*bn+I_s{&eyWXvGcgGuZF^DackHyI zr}=-RJ4}NmnFkrTn9}^gJvtycEqFV*|JO1=W}rQpZ`K{AX6(_p5P+4iv#V<~8i-a8 z=WJ-QfvI6b{`?batF5SVT($yK5uyY+>ATUgSYm1*02J+t%!(u>4&R-dH*QeW^&yaB zi(7vC_U++?v8R)cK-;BD#&%vKp5_2&-;ZDmTlPLyHe*utNgvQOY_PDd{+}n$JC{|A z$P6rx2>~IS1(w2}Ym6v74UznGL+zVg6&8WZD=w)&fzdb`#HOT7 jeqH_7=~>Zb Date: Sun, 17 Sep 2023 15:59:11 +0000 Subject: [PATCH 0318/1160] [i18n] update translations Signed-off-by: r4sas --- i18n/French.cpp | 6 +++--- i18n/Italian.cpp | 6 +++++- i18n/Portuguese.cpp | 6 +++++- i18n/Ukrainian.cpp | 6 +++++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/i18n/French.cpp b/i18n/French.cpp index 8bec887c..0a5b147e 100644 --- a/i18n/French.cpp +++ b/i18n/French.cpp @@ -96,7 +96,7 @@ namespace french // language namespace {"Address", "Adresse"}, {"Type", "Type"}, {"EncType", "EncType"}, - {"Expire LeaseSet", "Expiration du LeaseSet"}, + {"Expire LeaseSet", "Expirer le jeu de baux"}, {"Inbound tunnels", "Tunnels entrants"}, {"%dms", "%dms"}, {"Outbound tunnels", "Tunnels sortants"}, @@ -153,8 +153,8 @@ namespace french // language namespace {"StreamID can't be null", "StreamID ne peut pas être vide"}, {"Return to destination page", "Retourner à la page de destination"}, {"You will be redirected in %d seconds", "Vous serez redirigé dans %d secondes"}, - {"LeaseSet expiration time updated", "Temps d'expiration du LeaseSet mis à jour"}, - {"LeaseSet is not found or already expired", "Le LeaseSet est introuvable ou a déjà expirée"}, + {"LeaseSet expiration time updated", "Temps d'expiration du jeu de baux mis à jour"}, + {"LeaseSet is not found or already expired", "Le jeu de baux est introuvable ou a déjà expiré"}, {"Transit tunnels count must not exceed %d", "Le nombre de tunnels de transit ne doit pas excéder %d"}, {"Back to commands list", "Retour à la liste des commandes"}, {"Register at reg.i2p", "Inscription à reg.i2p"}, diff --git a/i18n/Italian.cpp b/i18n/Italian.cpp index 386372d5..2dcaab5e 100644 --- a/i18n/Italian.cpp +++ b/i18n/Italian.cpp @@ -69,6 +69,7 @@ namespace italian // language namespace {"Stopping in", "Arresto in"}, {"Family", "Famiglia"}, {"Tunnel creation success rate", "Percentuale di tunnel creati con successo"}, + {"Total tunnel creation success rate", "Percentuale di successo totale nella creazione del tunnel"}, {"Received", "Ricevuti"}, {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Inviati"}, @@ -95,6 +96,7 @@ namespace italian // language namespace {"Address", "Indirizzo"}, {"Type", "Tipologia"}, {"EncType", "Tipo di crittografia"}, + {"Expire LeaseSet", "Scadenza LeaseSet"}, {"Inbound tunnels", "Tunnel in entrata"}, {"%dms", "%dms"}, {"Outbound tunnels", "Tunnel in uscita"}, @@ -109,6 +111,7 @@ namespace italian // language namespace {"Local Destination", "Destinazione locale"}, {"Streams", "Flussi"}, {"Close stream", "Interrompi il flusso"}, + {"Such destination is not found", "Questa destinazione non è stata trovata"}, {"I2CP session not found", "Sessione I2CP non trovata"}, {"I2CP is not enabled", "I2CP non è abilitato"}, {"Invalid", "Invalido"}, @@ -150,6 +153,8 @@ namespace italian // language namespace {"StreamID can't be null", "Lo StreamID non può essere null"}, {"Return to destination page", "Ritorna alla pagina di destinazione"}, {"You will be redirected in %d seconds", "Sarai reindirizzato tra %d secondi"}, + {"LeaseSet expiration time updated", "Tempo di scadenza LeaseSet aggiornato"}, + {"LeaseSet is not found or already expired", "LeaseSet non trovato o già scaduto"}, {"Transit tunnels count must not exceed %d", "Il conteggio dei tunnel di transito non deve superare %d"}, {"Back to commands list", "Ritorna alla lista dei comandi"}, {"Register at reg.i2p", "Registra a reg.i2p"}, @@ -158,7 +163,6 @@ namespace italian // language namespace {"Submit", "Invia"}, {"Domain can't end with .b32.i2p", "I domini non possono terminare con .b32.i2p"}, {"Domain must end with .i2p", "I domini devono terminare con .i2p"}, - {"Such destination is not found", "Questa destinazione non è stata trovata"}, {"Unknown command", "Comando sconosciuto"}, {"Command accepted", "Comando accettato"}, {"Proxy error", "Errore del proxy"}, diff --git a/i18n/Portuguese.cpp b/i18n/Portuguese.cpp index 8ba7f0cd..4c6d749f 100644 --- a/i18n/Portuguese.cpp +++ b/i18n/Portuguese.cpp @@ -69,6 +69,7 @@ namespace portuguese // language namespace {"Stopping in", "Parando em"}, {"Family", "Família"}, {"Tunnel creation success rate", "Taxa de sucesso na criação de túneis"}, + {"Total tunnel creation success rate", "Taxa total de sucesso na criação de túneis"}, {"Received", "Recebido"}, {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Enviado"}, @@ -95,6 +96,7 @@ namespace portuguese // language namespace {"Address", "Endereço"}, {"Type", "Tipo"}, {"EncType", "Tipo de Criptografia"}, + {"Expire LeaseSet", "Expirar LeaseSet"}, {"Inbound tunnels", "Túneis de Entrada"}, {"%dms", "%dms"}, {"Outbound tunnels", "Túneis de Saída"}, @@ -109,6 +111,7 @@ namespace portuguese // language namespace {"Local Destination", "Destinos Locais"}, {"Streams", "Fluxos"}, {"Close stream", "Fechar fluxo"}, + {"Such destination is not found", "Tal destino não foi encontrado"}, {"I2CP session not found", "Sessão do I2CP não encontrada"}, {"I2CP is not enabled", "I2CP não está ativado"}, {"Invalid", "Inválido"}, @@ -150,6 +153,8 @@ namespace portuguese // language namespace {"StreamID can't be null", "StreamID não pode ser nulo"}, {"Return to destination page", "Retornar para à página de destino"}, {"You will be redirected in %d seconds", "Você será redirecionado em %d segundos"}, + {"LeaseSet expiration time updated", "Tempo de validade do LeaseSet atualizado"}, + {"LeaseSet is not found or already expired", "LeaseSet não foi encontrado ou já expirou"}, {"Transit tunnels count must not exceed %d", "A contagem de túneis de trânsito não deve exceder %d"}, {"Back to commands list", "Voltar para a lista de comandos"}, {"Register at reg.i2p", "Registrar na reg.i2p"}, @@ -158,7 +163,6 @@ namespace portuguese // language namespace {"Submit", "Enviar"}, {"Domain can't end with .b32.i2p", "O domínio não pode terminar com .b32.i2p"}, {"Domain must end with .i2p", "O domínio não pode terminar com .i2p"}, - {"Such destination is not found", "Tal destino não foi encontrado"}, {"Unknown command", "Comando desconhecido"}, {"Command accepted", "Comando aceito"}, {"Proxy error", "Erro no proxy"}, diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index c1e222ea..d089c142 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -69,6 +69,7 @@ namespace ukrainian // language namespace {"Stopping in", "Зупинка через"}, {"Family", "Сімейство"}, {"Tunnel creation success rate", "Успішно побудованих тунелів"}, + {"Total tunnel creation success rate", "Загальна кількість створених тунелів"}, {"Received", "Отримано"}, {"%.2f KiB/s", "%.2f КіБ/с"}, {"Sent", "Відправлено"}, @@ -95,6 +96,7 @@ namespace ukrainian // language namespace {"Address", "Адреса"}, {"Type", "Тип"}, {"EncType", "ТипШифр"}, + {"Expire LeaseSet", "Завершити LeaseSet"}, {"Inbound tunnels", "Вхідні тунелі"}, {"%dms", "%dмс"}, {"Outbound tunnels", "Вихідні тунелі"}, @@ -109,6 +111,7 @@ namespace ukrainian // language namespace {"Local Destination", "Локальні Призначення"}, {"Streams", "Потоки"}, {"Close stream", "Закрити потік"}, + {"Such destination is not found", "Така точка призначення не знайдена"}, {"I2CP session not found", "I2CP сесія не знайдена"}, {"I2CP is not enabled", "I2CP не увікнуто"}, {"Invalid", "Некоректний"}, @@ -150,6 +153,8 @@ namespace ukrainian // language namespace {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, {"Return to destination page", "Повернутися на сторінку точки призначення"}, {"You will be redirected in %d seconds", "Ви будете переадресовані через %d секунд"}, + {"LeaseSet expiration time updated", "Час закінчення LeaseSet оновлено"}, + {"LeaseSet is not found or already expired", "LeaseSet не знайдено або вже закінчився"}, {"Transit tunnels count must not exceed %d", "Кількість транзитних тунелів не повинна перевищувати %d"}, {"Back to commands list", "Повернутися до списку команд"}, {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, @@ -158,7 +163,6 @@ namespace ukrainian // language namespace {"Submit", "Надіслати"}, {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, - {"Such destination is not found", "Така точка призначення не знайдена"}, {"Unknown command", "Невідома команда"}, {"Command accepted", "Команда прийнята"}, {"Proxy error", "Помилка проксі"}, From 9c25a88707294f93843c2fead9cd4768776d6078 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 17 Sep 2023 16:21:36 +0000 Subject: [PATCH 0319/1160] [i18n] update translations Signed-off-by: r4sas --- i18n/Uzbek.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/i18n/Uzbek.cpp b/i18n/Uzbek.cpp index 9d798be4..cf94a489 100644 --- a/i18n/Uzbek.cpp +++ b/i18n/Uzbek.cpp @@ -69,6 +69,7 @@ namespace uzbek // language namespace {"Stopping in", "Ichida to'xtatish"}, {"Family", "Oila"}, {"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"}, + {"Total tunnel creation success rate", "Tunnel yaratishning umumiy muvaffaqiyat darajasi"}, {"Received", "Qabul qilindi"}, {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Yuborilgan"}, @@ -95,6 +96,7 @@ namespace uzbek // language namespace {"Address", "Manzil"}, {"Type", "Turi"}, {"EncType", "ShifrlashTuri"}, + {"Expire LeaseSet", "LeaseSet muddati tugaydi"}, {"Inbound tunnels", "Kirish tunnellari"}, {"%dms", "%dms"}, {"Outbound tunnels", "Chiquvchi tunnellar"}, @@ -109,6 +111,7 @@ namespace uzbek // language namespace {"Local Destination", "Mahalliy joylanish"}, {"Streams", "Strim"}, {"Close stream", "Strimni o'chirish"}, + {"Such destination is not found", "Bunday yo'nalish topilmadi"}, {"I2CP session not found", "I2CP sessiyasi topilmadi"}, {"I2CP is not enabled", "I2CP yoqilmagan"}, {"Invalid", "Noto'g'ri"}, @@ -150,6 +153,8 @@ namespace uzbek // language namespace {"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"}, {"Return to destination page", "Manzilgoh sahifasiga qaytish"}, {"You will be redirected in %d seconds", "Siz %d soniyadan so‘ng boshqa yo‘nalishga yo‘naltirilasiz"}, + {"LeaseSet expiration time updated", "LeaseSet amal qilish muddati yangilandi"}, + {"LeaseSet is not found or already expired", "LeaseSet topilmadi yoki muddati tugagan"}, {"Transit tunnels count must not exceed %d", "Tranzit tunnellar soni %d dan oshmasligi kerak"}, {"Back to commands list", "Buyruqlar ro'yxatiga qaytish"}, {"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"}, @@ -158,7 +163,6 @@ namespace uzbek // language namespace {"Submit", "Yuborish"}, {"Domain can't end with .b32.i2p", "Domen .b32.i2p bilan tugashi mumkin emas"}, {"Domain must end with .i2p", "Domen .i2p bilan tugashi kerak"}, - {"Such destination is not found", "Bunday yo'nalish topilmadi"}, {"Unknown command", "Noma'lum buyruq"}, {"Command accepted", "Buyruq qabul qilindi"}, {"Proxy error", "Proksi xatosi"}, From 1857f14be86aa360c90f7baab0d7013f10f22632 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 17 Sep 2023 18:33:42 +0000 Subject: [PATCH 0320/1160] [cpu] use short defines instead of long checks Signed-off-by: r4sas --- libi2pd/CPU.cpp | 4 ++-- libi2pd/CPU.h | 18 ++++++++++++++++++ libi2pd/Crypto.cpp | 15 +++++---------- libi2pd/Crypto.h | 8 ++++---- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 5d5fc6b3..4c522987 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -13,7 +13,7 @@ #define bit_AES (1 << 25) #endif -#if (defined(__GNUC__) && __GNUC__ < 5 && (defined(__x86_64__) || defined(__i386__))) +#if defined(__GNUC__) && __GNUC__ < 5 && IS_X86 #include #endif @@ -29,7 +29,7 @@ namespace cpu inline bool cpu_support_aes() { -#if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) +#if IS_X86 #if defined(__clang__) # if (__clang_major__ >= 6) __builtin_cpu_init(); diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index a0695884..1c30db48 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -9,6 +9,24 @@ #ifndef LIBI2PD_CPU_H #define LIBI2PD_CPU_H +#if defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IX86) || defined(__i386__) +# define IS_X86 1 +# if defined(_M_AMD64) || defined(__x86_64__) +# define IS_X86_64 1 +# else +# define IS_X86_64 0 +# endif +#else +# define IS_X86 0 +# define IS_X86_64 0 +#endif + +#if defined(__AES__) && !defined(_MSC_VER) && IS_X86 +# define SUPPORTS_AES 1 +#else +# define SUPPORTS_AES 0 +#endif + namespace i2p { namespace cpu diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index b5bc33d1..3e5bdd35 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -28,11 +28,6 @@ #include "I2PEndian.h" #include "Log.h" -#if defined(__AES__) && !defined(_MSC_VER) && ((defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__))) - #define SUPPORTS_AES 1 -#else - #define SUPPORTS_AES 0 -#endif namespace i2p { @@ -165,7 +160,7 @@ namespace crypto // DH/ElGamal -#if !defined(__x86_64__) +#if !IS_X86_64 const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; #endif @@ -367,7 +362,7 @@ namespace crypto BIGNUM * b1 = BN_CTX_get (ctx); BIGNUM * b = BN_CTX_get (ctx); // select random k -#if (defined(_M_AMD64) || defined(__x86_64__)) +#if IS_X86_64 BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits @@ -434,7 +429,7 @@ namespace crypto void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub) { -#if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)) || defined(_MSC_VER) +#if IS_X86 || defined(_MSC_VER) RAND_bytes (priv, 256); #else // lower 226 bits (28 bytes and 2 bits) only. short exponent @@ -1309,7 +1304,7 @@ namespace crypto CRYPTO_set_locking_callback (OpensslLockingCallback);*/ if (precomputation) { -#if (defined(_M_AMD64) || defined(__x86_64__)) +#if IS_X86_64 g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); #else @@ -1324,7 +1319,7 @@ namespace crypto if (g_ElggTable) { DestroyElggTable (g_ElggTable, -#if (defined(_M_AMD64) || defined(__x86_64__)) +#if IS_X86_64 ELGAMAL_FULL_EXPONENT_NUM_BYTES #else ELGAMAL_SHORT_EXPONENT_NUM_BYTES diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 1419293b..816d79fd 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -150,7 +150,7 @@ namespace crypto }; -#ifdef __AES__ +#if SUPPORTS_AES class ECBCryptoAESNI { public: @@ -167,7 +167,7 @@ namespace crypto }; #endif -#ifdef __AES__ +#if SUPPORTS_AES class ECBEncryption: public ECBCryptoAESNI #else class ECBEncryption @@ -183,7 +183,7 @@ namespace crypto AES_KEY m_Key; }; -#ifdef __AES__ +#if SUPPORTS_AES class ECBDecryption: public ECBCryptoAESNI #else class ECBDecryption From 3da50614264f2bb93bc7bad9425772d92b01a973 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 18 Sep 2023 17:11:45 +0000 Subject: [PATCH 0321/1160] [cpu] Increase GCC version for use of builtin CPU extensions checker Signed-off-by: r4sas --- libi2pd/CPU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 4c522987..e434dd57 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -13,7 +13,7 @@ #define bit_AES (1 << 25) #endif -#if defined(__GNUC__) && __GNUC__ < 5 && IS_X86 +#if defined(__GNUC__) && __GNUC__ < 6 && IS_X86 #include #endif From fb420bb563a3ebf8803faaa390ba6b2bb840d872 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 18 Sep 2023 18:12:26 +0000 Subject: [PATCH 0322/1160] [cpu] more builtin version check changes Signed-off-by: r4sas --- libi2pd/CPU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index e434dd57..77820c88 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -35,10 +35,10 @@ namespace cpu __builtin_cpu_init(); # endif return __builtin_cpu_supports("aes"); -#elif (defined(__GNUC__) && __GNUC__ >= 5) +#elif (defined(__GNUC__) && __GNUC__ >= 6) __builtin_cpu_init(); return __builtin_cpu_supports("aes"); -#elif (defined(__GNUC__) && __GNUC__ < 5) +#elif (defined(__GNUC__) && __GNUC__ < 6) int cpu_info[4]; bool flag = false; __cpuid(0, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]); From 0cf656cd7687fce461f644820066afc36be312b3 Mon Sep 17 00:00:00 2001 From: hfsfox Date: Thu, 28 Sep 2023 22:30:38 +0300 Subject: [PATCH 0323/1160] Add Haiku OS support (#1970) --- Makefile | 3 +++ Makefile.haiku | 10 ++++++++++ build/CMakeLists.txt | 4 ++++ libi2pd/FS.cpp | 8 ++++++++ libi2pd/I2PEndian.h | 2 +- libi2pd/util.cpp | 11 +++++++++++ 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 Makefile.haiku diff --git a/Makefile b/Makefile index 0861ec0b..86ea0aa8 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,9 @@ else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS))) else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp include Makefile.bsd +else ifneq (, $(findstring haiku, $(SYS))) + DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp + include Makefile.haiku else # not supported $(error Not supported platform) endif diff --git a/Makefile.haiku b/Makefile.haiku new file mode 100644 index 00000000..85c2835d --- /dev/null +++ b/Makefile.haiku @@ -0,0 +1,10 @@ +CXX = g++ +CXXFLAGS := -Wall -std=c++11 +INCFLAGS = -I/system/develop/headers +DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE +LDLIBS = -lbe -lbsd -lnetwork -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread + +ifeq ($(USE_UPNP),yes) + DEFINES += -DUSE_UPNP + LDLIBS += -lminiupnpc +endif diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 3185ffab..abfadfca 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -139,6 +139,10 @@ if(APPLE) add_definitions(-DMAC_OSX) endif() +if(HAIKU) + add_definitions(-D_DEFAULT_SOURCE -D_GNU_SOURCE) +endif() + if(MSVC) add_definitions(-DWINVER=0x0600) add_definitions(-D_WIN32_WINNT=0x0600) diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 7334550f..d38bcc2f 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -136,6 +136,14 @@ namespace fs { dataDir = (home != NULL && strlen(home) > 0) ? home : ""; dataDir += "/Library/Application Support/" + appName; return; +#elif defined(__HAIKU__) + char *home = getenv("HOME"); + if (home != NULL && strlen(home) > 0) { + dataDir = std::string(home) + "/config/settings/" + appName; + } else { + dataDir = "/tmp/" + appName; + } + return; #else /* other unix */ #if defined(ANDROID) const char * ext = getenv("EXTERNAL_STORAGE"); diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index 06abf29a..681a4999 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -14,7 +14,7 @@ #if defined(__FreeBSD__) || defined(__NetBSD__) #include -#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__GLIBC__) +#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__HAIKU__) #include #elif defined(__APPLE__) && defined(__MACH__) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 088a7af5..a7afdce8 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -27,6 +27,17 @@ # include #endif +#if defined(__HAIKU__) +#include +#include +#include +#include +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#include +#endif +#endif + #ifdef _WIN32 #include #include From 1e6edf06a29a0af8ac09f12c227f6b9ed76d75df Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Sep 2023 16:05:13 -0400 Subject: [PATCH 0324/1160] send already accepting error response --- libi2pd_client/SAM.cpp | 49 ++++++++++++++++++++++++++++-------------- libi2pd_client/SAM.h | 5 +++-- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index bb9d6a6b..1a281c57 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -360,7 +360,7 @@ namespace client if (type == eSAMSessionTypeUnknown) { // unknown style - SendI2PError("Unknown STYLE"); + SendSessionI2PError("Unknown STYLE"); return; } @@ -375,14 +375,14 @@ namespace client if (e) { // not an ip address - SendI2PError("Invalid IP Address in HOST"); + SendSessionI2PError("Invalid IP Address in HOST"); return; } auto port = std::stoi(params[SAM_PARAM_PORT]); if (port == -1) { - SendI2PError("Invalid port"); + SendSessionI2PError("Invalid port"); return; } forward = std::make_shared(addr, port); @@ -484,7 +484,7 @@ namespace client LogPrint (eLogDebug, "SAM: Stream connect: ", buf); if ( m_SocketType != eSAMSocketTypeUnknown) { - SendI2PError ("Socket already in use"); + SendSessionI2PError ("Socket already in use"); return; } std::map params; @@ -582,7 +582,7 @@ namespace client LogPrint (eLogDebug, "SAM: Stream accept: ", buf); if ( m_SocketType != eSAMSocketTypeUnknown) { - SendI2PError ("Socket already in use"); + SendSessionI2PError ("Socket already in use"); return; } std::map params; @@ -598,9 +598,15 @@ namespace client if (!session->GetLocalDestination ()->IsAcceptingStreams ()) { m_IsAccepting = true; + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + else // already accepting + { + // TODO: implement queue + LogPrint (eLogInfo, "SAM: Session ", m_ID, " is already accepting"); + SendStreamI2PError ("Already accepting"); + } } else SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); @@ -620,26 +626,26 @@ namespace client } if (session->GetLocalDestination ()->IsAcceptingStreams ()) { - SendI2PError ("Already accepting"); + SendSessionI2PError ("Already accepting"); return; } auto it = params.find (SAM_PARAM_PORT); if (it == params.end ()) { - SendI2PError ("PORT is missing"); + SendSessionI2PError ("PORT is missing"); return; } auto port = std::stoi (it->second); if (port <= 0 || port >= 0xFFFF) { - SendI2PError ("Invalid PORT"); + SendSessionI2PError ("Invalid PORT"); return; } boost::system::error_code ec; auto ep = m_Socket.remote_endpoint (ec); if (ec) { - SendI2PError ("Socket error"); + SendSessionI2PError ("Socket error"); return; } ep.port (port); @@ -791,13 +797,13 @@ namespace client if (type == eSAMSessionTypeUnknown) { // unknown style - SendI2PError("Unsupported STYLE"); + SendSessionI2PError("Unsupported STYLE"); return; } auto fromPort = std::stoi(params[SAM_PARAM_FROM_PORT]); if (fromPort == -1) { - SendI2PError("Invalid from port"); + SendSessionI2PError("Invalid from port"); return; } auto subsession = std::make_shared(masterSession, id, type, fromPort); @@ -810,7 +816,7 @@ namespace client SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false); } else - SendI2PError ("Wrong session type"); + SendSessionI2PError ("Wrong session type"); } void SAMSocket::ProcessSessionRemove (char * buf, size_t len) @@ -832,12 +838,12 @@ namespace client SendSessionCreateReplyOk (); } else - SendI2PError ("Wrong session type"); + SendSessionI2PError ("Wrong session type"); } - void SAMSocket::SendI2PError(const std::string & msg) + void SAMSocket::SendSessionI2PError(const std::string & msg) { - LogPrint (eLogError, "SAM: I2P error: ", msg); + LogPrint (eLogError, "SAM: Session I2P error: ", msg); #ifdef _MSC_VER size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str()); #else @@ -846,6 +852,17 @@ namespace client SendMessageReply (m_Buffer, len, true); } + void SAMSocket::SendStreamI2PError(const std::string & msg) + { + LogPrint (eLogError, "SAM: Stream I2P error: ", msg); +#ifdef _MSC_VER + size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_STREAM_STATUS_I2P_ERROR, msg.c_str()); +#else + size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_STREAM_STATUS_I2P_ERROR, msg.c_str()); +#endif + SendMessageReply (m_Buffer, len, true); + } + void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name) { if (leaseSet) diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index b4c72754..736c0945 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -49,7 +49,7 @@ namespace client const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n"; const char SAM_STREAM_STATUS_INVALID_KEY[] = "STREAM STATUS RESULT=INVALID_KEY\n"; const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER\n"; - const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR\n"; + const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"%s\"\n"; const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT"; const char SAM_STREAM_FORWARD[] = "STREAM FORWARD"; const char SAM_DATAGRAM_SEND[] = "DATAGRAM SEND"; @@ -141,7 +141,8 @@ namespace client void ProcessNamingLookup (char * buf, size_t len); void ProcessSessionAdd (char * buf, size_t len); void ProcessSessionRemove (char * buf, size_t len); - void SendI2PError(const std::string & msg); + void SendSessionI2PError(const std::string & msg); + void SendStreamI2PError(const std::string & msg); size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 void ExtractParams (char * buf, std::map& params); From efdbe267554bfa03bcb51097f8e19e9d335e3a9f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Sep 2023 18:40:51 -0400 Subject: [PATCH 0325/1160] try peer test again if Unknown --- libi2pd/Transports.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b452c05e..45284e24 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -833,8 +833,12 @@ namespace transport } } bool ipv4Testing = i2p::context.GetTesting (); + if (!ipv4Testing) + ipv4Testing = i2p::context.GetRouterInfo ().IsSSU2V4 () && (i2p::context.GetStatus() == eRouterStatusUnknown); bool ipv6Testing = i2p::context.GetTestingV6 (); - // if still testing, repeat peer test + if (!ipv6Testing) + ipv6Testing = i2p::context.GetRouterInfo ().IsSSU2V6 () && (i2p::context.GetStatusV6() == eRouterStatusUnknown); + // if still testing or unknown, repeat peer test if (ipv4Testing || ipv6Testing) PeerTest (ipv4Testing, ipv6Testing); m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(3 * SESSION_CREATION_TIMEOUT)); From 9980bfa0e7f03a3849eca4e2e771593cc64419a5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Sep 2023 14:10:45 -0400 Subject: [PATCH 0326/1160] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7fb7318..ce25c8f2 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](http Donations --------- -**E-Mail**: ```i2porignal at yandex.ru``` +**E-Mail**: ```i2porignal at yandex.com``` **BTC**: ```3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f``` From e926b0392f3458a1c8af15a4baba0185a56eea09 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Oct 2023 14:22:53 -0400 Subject: [PATCH 0327/1160] reseed.is.prestium.org reseed added --- .../reheatedburger_at_protonmail.com.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 3 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt diff --git a/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt b/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt new file mode 100644 index 00000000..d14c5fe1 --- /dev/null +++ b/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIRANVB/+wEuXS0Ttoh5teJt90wDQYJKoZIhvcNAQELBQAw +fTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE +ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxJjAkBgNVBAMM +HXJlaGVhdGVkYnVyZ2VyQHByb3Rvbm1haWwuY29tMB4XDTIzMDkyMTE4MDAyOVoX +DTMzMDkyMTE4MDAyOVowfTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYD +VQQJEwJYWDEeMBwGA1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQL +EwNJMlAxJjAkBgNVBAMMHXJlaGVhdGVkYnVyZ2VyQHByb3Rvbm1haWwuY29tMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuNwmiIY3MLSBS5sL5PXRDVK6 +MoSNw4qx0o8nDHvVBxNtzgc0/qjYvsuUggY0tZbPpxhML6GHd4qo7Z3Ip1x0MxhI +Ao5MJaflaEdm4+HeMy0IE3aU73KRUwp+nF3cUHZdlps+9mtYs4oncVEWkFQwGsgt +4yrLtXf6PmPWfFH28ffeaev90e+hdhQpTvr54Ewx6NTaMQr8mkhXL2utvPpjnPM5 +UAhOeJCMgfhLzgS4rahG0O8CQMtH5gKZ+6zjoSRatnjj0j1mBO7+e1TL5O7dVS9k +P83tmkIDDl4tXBzXr9aXQMJstbM2CEvinVcCsR74GjPcg4iB0Ift71Dx7oGKI06t +3bSvll0GZm2mFhIba/4q6f4oAJ2aeq6ejt1Kcm8g5cxtwrRZnXv5JXHZqba3y8J5 +zWaRHzhc9tyEqRBRkc6c7xMdZQ31iJ6TlxUT8vAJ1N7OnX87oHrCjwyikpyOen4r +Uvv1Ge054XPTeoHz+Jyt34t71ty1W13uPHpuvtPVR9MfgGrxd4Z9+LWvAjmMbFsZ +lC3Ll+94nUk+O0puU6KisuCGP4hCtdEtebkIqT8zo8LicLAYUMjX7KwnS7681Cu1 +sY2mB2oZAytN9Zy42oOoNeY5x39kxfwuut/2E1kxKX75O0bwfIXr611abCKc3bbz +euMrIsaB/2VFp9nAah8CAwEAAaNqMGgwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQW +MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCYGA1UdDgQf +BB1yZWhlYXRlZGJ1cmdlckBwcm90b25tYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOC +AgEATuHi2Yz52OK7e+sKVdHu2KrSLCGm98BG1UIMHFi3WRBTOFyp+lZ519bJ1rFj +tmP9E1a+k/vlbc7FbV4PcV6HJYfGEv/ImtJsEnrzbhrQphC1zMFv7q6JCTUbAzl6 +ySlJ++mVxQ6AzPNH3TQgL1wPKuLh76/Y4053fg+NI3PmzzhkTUheVDkg0/a9ENSf +xMnCa3fIm869735qHk67QlikFvAfWwc4zT1Ncwodh8G4+oX0GFzIl+OZaM1GTMuD +UCcFKoqwtjyLCr22xNk8CfyiExPJXQG1HzEvDcxyoxQtnh9occR9PgqXySz26/NM +XDyM+l4utLMGBcVY4x9fksRiaWEfxiygYOxY9zDl6clh6S10b3CLut4UMiS1RTtE +Mjx2BZN3p0nxpT2leJdGxtBPGrvxuiCOEmTbOMLc3DQtppXO97B3dVMtJ5Ee8Y6p +Tq/8eiHI6eQXat6dgFT5X16vzF7w7XO7fAxuqk4Kx1D1aTVyikdo+Fcdg44dWOjq +NZu8VcCzZij/Dfjlce6t6h8D+wvDD8AkiivaDljpvbNDx/QQlQXFgH98TZA8Rnvr +QcyNNATfz+1yQUiyO6Lrjaw64OJwXYX/llgnDC+qQpP6kqZabi2TsG0EVPukVvr9 +0HyAUu4lnXtTIDq2yPNenegCloqDL1ZQdaYd2XIItnfZdTY= +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 5551b010..0f101e64 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -221,7 +221,8 @@ namespace config { "https://reseed-pl.i2pd.xyz/," "https://www2.mk16.de/," "https://i2p.ghativega.in/," - "https://i2p.novg.net/" + "https://i2p.novg.net/," + "https://reseed.is.prestium.org/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From 606e35eec1efd02480f85bac9b8d47706aca8dbe Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Oct 2023 12:59:40 -0400 Subject: [PATCH 0328/1160] reseed.us.prestium.org reseed added --- .../reseed/null_at_i2pmail.org.crt | 33 +++++++++++++++++++ libi2pd/Config.cpp | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 contrib/certificates/reseed/null_at_i2pmail.org.crt diff --git a/contrib/certificates/reseed/null_at_i2pmail.org.crt b/contrib/certificates/reseed/null_at_i2pmail.org.crt new file mode 100644 index 00000000..d736a95e --- /dev/null +++ b/contrib/certificates/reseed/null_at_i2pmail.org.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFyDCCA7CgAwIBAgIRAO8lBnTo+hlvglQwug2jHZkwDQYJKoZIhvcNAQELBQAw +cDELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE +ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGTAXBgNVBAMM +EG51bGxAaTJwbWFpbC5vcmcwHhcNMjMwOTIxMjIzMTM2WhcNMzMwOTIxMjIzMTM2 +WjBwMQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYD +VQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UE +AwwQbnVsbEBpMnBtYWlsLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAMMpAvaHwzuZZ6qelRU4jcgpuAIZFH++F1Te4b1t02pRfnQ0Eeh04VC1JxO0 +XjUr1/iszEyvrI4+AdxaobDyRFPylkOLtfec4d2ciDc1cupj6y2vyYhMVN31rrvE +ve7sKoTHJ5Dx+UPGOVZZsSsmK9TXIU23W2bo7k2VnjVBXdWZyNE4twfTYCosDnYA +1HIEaIUFVv+COqw2pktxkMmfUAlnDLeVSfsAzEr37K+x0Xk5hO8m6GWQx0NRjjYp +gyEcFhWAJjAYaF3gUVR9rVVky1OeFhZgxE/KzVrW7uc84ZCMKITEPwT0qqIpsTJp +486YXzuPSc+ef78cKSQf5992l7imySJ24I/5H73HkovGAFGZdwvl6V6Ta5YqO7RR +gVDOL1EIVUnMCqFBCE6RmyZqXBVrv4Cacdc6lZ4fj42SRtWZfe6rNCpJzTRtbOyW +DBmYpK6q/jddfqI1sX0PXIn9U+Rod5Z4uz82PAjhamqyr5fpAnoQxKppBvQ3tNfn +KQhmP73Hdpvl24pRyQLBIRUL86i7TPBBn7n3XZlQfXP7lp8+KJYLkL2/zCVDrwLX +kC9hRIxCU9bZbXlkRE2R/PrK53LZecjk2KcgINA4ZlguNgze/Qj8BXelUF4izbpV +bTSvniTM46AECvjDcICAOky9Ku4RnmUJxQVf3ahDEuso7/N7AgMBAAGjXTBbMA4G +A1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYD +VR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQbnVsbEBpMnBtYWlsLm9yZzANBgkqhkiG +9w0BAQsFAAOCAgEAEUfYJTdDH7uCojnpF0Gs2tXxPJ22UhdqEsXfqR7KhhmmApss +q5kiiPIYoy5T/4IM7NVyeeJAMYwQsdJjwZ4QyxLBb9EqMS2krREcPZNRfFzBr2Wj +EBhJEYTnbIn4docwJWyXsJVG0CqFXPF1qGd0Sc2u87yj2xZNTnloWKAEQAO7DE39 +gWfDH6slM/3h3WD3Mjuk7JoYSYmBfvvm2hkBbC6lzD7XY7rdSmIUwJ050e9UrJaV +La51dd5r4q8d1cHrVUwLiACAaXJ15AEqUDLHQcvKvyfhkabwRy+v0wsodSMgSMEH +xA+kGhkIW7yV7o2exYOYypHCca3IA+pimMpEseNNrHSwbHOMfauiN7jiZLEPg6D6 +a8XwK7qmMYUq7j6QWuIqI81o29WZRf4LZ0GFoVce+e5VxkVKSItKcJoedIAp1ML8 +NhFwd9s/nqWidu/StscEEbGzz6ZuDXwshERXC0QR8HjHEPi4U8220juf4cxUahxK +heEU91l7VksSZYRUN98h28vovGcukLcnVoLj5H/+Z4r/BgxMrOUJKetxf8fU7FjO +j1U6XV36tGi+IOwYQb9D5fTVafC3hHkuUIjlOdUGYadse98ILhn9kaNtqkBtk/EU +vK+McnrEv7tcKrbvYEop/KaUayhjFiL+wGWnpxt7gLhIiavnIeUyD7acltw= +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 0f101e64..cd78727f 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -222,7 +222,8 @@ namespace config { "https://www2.mk16.de/," "https://i2p.ghativega.in/," "https://i2p.novg.net/," - "https://reseed.is.prestium.org/" + "https://reseed.is.prestium.org/," + "https://reseed.us.prestium.org/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From 0cc91dd2d2225b7e4690fc4fb7a39106d018ebf8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Oct 2023 08:31:55 -0400 Subject: [PATCH 0329/1160] don't pick too active peer --- libi2pd/NTCP2.cpp | 20 +++++++------- libi2pd/RouterContext.cpp | 14 +++++----- libi2pd/RouterInfo.h | 8 ++++-- libi2pd/SSU2Session.cpp | 18 ++++++------- libi2pd/TransportSession.h | 55 +++++++++++++++++++++++++++++++++----- libi2pd/Transports.cpp | 2 +- 6 files changed, 80 insertions(+), 37 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index bbd93435..0a23f07e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -374,7 +374,7 @@ namespace transport transports.PeerDisconnected (shared_from_this ()); m_Server.RemoveNTCP2Session (shared_from_this ()); m_SendQueue.clear (); - m_SendQueueSize = 0; + SetSendQueueSize (0); auto remoteIdentity = GetRemoteIdentity (); if (remoteIdentity) { @@ -433,7 +433,7 @@ namespace transport void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts) { if (m_NextReceivedBuffer && !m_IsReceiving && - ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT) + ts > GetLastActivityTimestamp () + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT) { delete[] m_NextReceivedBuffer; m_NextReceivedBuffer = nullptr; @@ -789,7 +789,7 @@ namespace transport void NTCP2Session::ServerLogin () { SetTerminationTimeout (NTCP2_ESTABLISH_TIMEOUT); - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); + SetLastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()); m_Establisher->CreateEphemeralKey (); boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestReceived, shared_from_this (), @@ -872,9 +872,8 @@ namespace transport } else { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumReceivedBytes += bytes_transferred + 2; // + length - i2p::transport::transports.UpdateReceivedBytes (bytes_transferred); + UpdateNumReceivedBytes (bytes_transferred + 2); + i2p::transport::transports.UpdateReceivedBytes (bytes_transferred + 2); uint8_t nonce[12]; CreateNonce (m_ReceiveSequenceNumber, nonce); m_ReceiveSequenceNumber++; if (i2p::crypto::AEADChaCha20Poly1305 (m_NextReceivedBuffer, m_NextReceivedLen-16, nullptr, 0, m_ReceiveKey, nonce, m_NextReceivedBuffer, m_NextReceivedLen, false)) @@ -1095,11 +1094,10 @@ namespace transport } else { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumSentBytes += bytes_transferred; + UpdateNumSentBytes (bytes_transferred); i2p::transport::transports.UpdateSentBytes (bytes_transferred); LogPrint (eLogDebug, "NTCP2: Next frame sent ", bytes_transferred); - if (m_LastActivityTimestamp > m_NextRouterInfoResendTime) + if (GetLastActivityTimestamp () > m_NextRouterInfoResendTime) { m_NextRouterInfoResendTime += NTCP2_ROUTERINFO_RESEND_INTERVAL + rand ()%NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD; @@ -1108,7 +1106,7 @@ namespace transport else { SendQueue (); - m_SendQueueSize = m_SendQueue.size (); + SetSendQueueSize (m_SendQueue.size ()); } } } @@ -1231,7 +1229,7 @@ namespace transport GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); Terminate (); } - m_SendQueueSize = m_SendQueue.size (); + SetSendQueueSize (m_SendQueue.size ()); } void NTCP2Session::SendLocalRouterInfo (bool update) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index fa3ba7bd..f21c0592 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -594,15 +594,15 @@ namespace i2p /* detect parameters */ switch (L) { - case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; - case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = 48; type = low; break; - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 64; type = high; break; - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break; - case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; + case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; + case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = i2p::data::LOW_BANDWIDTH_LIMIT; type = low; break; // 48 + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 64; type = high; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = i2p::data::HIGH_BANDWIDTH_LIMIT; type = high; break; // 256 + case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = i2p::data::EXTRA_BANDWIDTH_LIMIT; type = extra; break; // 2048 case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s default: - limit = 48; type = low; + limit = i2p::data::LOW_BANDWIDTH_LIMIT; type = low; // 48 } /* update caps & flags in RI */ auto caps = m_RouterInfo.GetCaps (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 9aff2240..a95119ed 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -42,8 +42,12 @@ namespace data const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M'; /* 48-64 KBps */ const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N'; /* 64-128 KBps */ const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */ - const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */ - const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2000 KBps */ + const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2048 KBps */ + const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2048 KBps */ + // bandwidth limits in kBps + const uint32_t LOW_BANDWIDTH_LIMIT = 48; + const uint32_t HIGH_BANDWIDTH_LIMIT = 256; + const uint32_t EXTRA_BANDWIDTH_LIMIT = 2048; // congesion flags const char CAPS_FLAG_MEDIUM_CONGESTION = 'D'; const char CAPS_FLAG_HIGH_CONGESTION = 'E'; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index f0e539c7..487d5549 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -263,7 +263,7 @@ namespace transport m_SessionConfirmedFragment.reset (nullptr); m_PathChallenge.reset (nullptr); m_SendQueue.clear (); - m_SendQueueSize = 0; + SetSendQueueSize (0); m_SentPackets.clear (); m_IncompleteMessages.clear (); m_RelaySessions.clear (); @@ -364,7 +364,7 @@ namespace transport RequestTermination (eSSU2TerminationReasonTimeout); } } - m_SendQueueSize = m_SendQueue.size (); + SetSendQueueSize (m_SendQueue.size ()); } bool SSU2Session::SendQueue () @@ -524,7 +524,7 @@ namespace transport LogPrint (eLogInfo, "SSU2: Packet was not Acked after ", it->second->numResends, " attempts. Terminate session"); m_SentPackets.clear (); m_SendQueue.clear (); - m_SendQueueSize = 0; + SetSendQueueSize (0); RequestTermination (eSSU2TerminationReasonTimeout); return resentPackets.size (); } @@ -1452,8 +1452,7 @@ namespace transport header.ll[1] ^= CreateHeaderMask (m_KeyDataSend + 32, payload + (len + 4)); m_Server.Send (header.buf, 16, payload, len + 16, m_RemoteEndpoint); m_SendPacketNum++; - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumSentBytes += len + 32; + UpdateNumSentBytes (len + 32); return m_SendPacketNum - 1; } @@ -1494,8 +1493,7 @@ namespace transport LogPrint (eLogWarning, "SSU2: Data AEAD verification failed "); return; } - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumReceivedBytes += len; + UpdateNumReceivedBytes (len); if (!packetNum || UpdateReceivePacketNum (packetNum)) HandlePayload (payload, payloadSize); } @@ -2357,7 +2355,7 @@ namespace transport if (!msg->IsExpired ()) { // m_LastActivityTimestamp is updated in ProcessData before - if (m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp).second) + if (m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)GetLastActivityTimestamp ()).second) m_Handler.PutNextMessage (std::move (msg)); else LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); @@ -2943,7 +2941,7 @@ namespace transport else ++it; } - if (m_ReceivedI2NPMsgIDs.size () > SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS || ts > m_LastActivityTimestamp + SSU2_DECAY_INTERVAL) + if (m_ReceivedI2NPMsgIDs.size () > SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS || ts > GetLastActivityTimestamp () + SSU2_DECAY_INTERVAL) // decay m_ReceivedI2NPMsgIDs.clear (); else @@ -3015,7 +3013,7 @@ namespace transport { bool sent = SendQueue (); // if we have something to send if (sent) - m_SendQueueSize = m_SendQueue.size (); + SetSendQueueSize (m_SendQueue.size ()); if (m_IsDataReceived) { if (!sent) SendQuickAck (); diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 7d2f2653..e298fdb2 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -71,15 +71,17 @@ namespace transport const int64_t TRANSPORT_SESSION_SLOWNESS_THRESHOLD = 500; // in milliseconds const int64_t TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL = 10000; // in milliseconds + const uint64_t TRANSPORT_SESSION_BANDWIDTH_UPDATE_MIN_INTERVAL = 5; // in seconds class TransportSession { public: TransportSession (std::shared_ptr router, int terminationTimeout): - m_NumSentBytes (0), m_NumReceivedBytes (0), m_SendQueueSize (0), - m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), - m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()), - m_HandshakeInterval (0) + m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), m_HandshakeInterval (0), + m_SendQueueSize (0), m_NumSentBytes (0), m_NumReceivedBytes (0), + m_LastBandWidthUpdateNumSentBytes (0), m_LastBandWidthUpdateNumReceivedBytes (0), + m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()), + m_LastBandwidthUpdateTimestamp (m_LastActivityTimestamp), m_InBandwidth (0), m_OutBandwidth (0) { if (router) m_RemoteIdentity = router->GetRouterIdentity (); @@ -103,11 +105,29 @@ namespace transport } size_t GetNumSentBytes () const { return m_NumSentBytes; }; + void UpdateNumSentBytes (size_t len) + { + m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); + m_NumSentBytes += len; + UpdateBandwidth (); + } size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; + void UpdateNumReceivedBytes (size_t len) + { + m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); + m_NumReceivedBytes += len; + UpdateBandwidth (); + } size_t GetSendQueueSize () const { return m_SendQueueSize; }; + void SetSendQueueSize (size_t s) { m_SendQueueSize = s; }; bool IsOutgoing () const { return m_IsOutgoing; }; bool IsSlow () const { return m_HandshakeInterval > TRANSPORT_SESSION_SLOWNESS_THRESHOLD && m_HandshakeInterval < TRANSPORT_SESSION_MAX_HANDSHAKE_INTERVAL; }; + bool IsBandwidthExceeded (bool isHighBandwidth) const + { + auto limit = isHighBandwidth ? i2p::data::HIGH_BANDWIDTH_LIMIT*1024 : i2p::data::LOW_BANDWIDTH_LIMIT*1024; // convert to bytes + return std::max (m_InBandwidth, m_OutBandwidth) > limit; + } int GetTerminationTimeout () const { return m_TerminationTimeout; }; void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; }; @@ -120,21 +140,44 @@ namespace transport uint32_t GetCreationTime () const { return m_CreationTime; }; void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers + uint64_t GetLastActivityTimestamp () const { return m_LastActivityTimestamp; }; + void SetLastActivityTimestamp (uint64_t ts) { m_LastActivityTimestamp = ts; }; + virtual uint32_t GetRelayTag () const { return 0; }; virtual void SendLocalRouterInfo (bool update = false) { SendI2NPMessages ({ CreateDatabaseStoreMsg () }); }; virtual void SendI2NPMessages (const std::vector >& msgs) = 0; virtual bool IsEstablished () const = 0; + private: + + void UpdateBandwidth () + { + uint64_t interval = m_LastActivityTimestamp - m_LastBandwidthUpdateTimestamp; + if (interval > TRANSPORT_SESSION_BANDWIDTH_UPDATE_MIN_INTERVAL) + { + m_OutBandwidth = (m_NumSentBytes - m_LastBandWidthUpdateNumSentBytes)/interval; + m_LastBandWidthUpdateNumSentBytes = m_NumSentBytes; + m_InBandwidth = (m_NumReceivedBytes - m_LastBandWidthUpdateNumReceivedBytes)/interval; + m_LastBandWidthUpdateNumReceivedBytes = m_NumReceivedBytes; + m_LastBandwidthUpdateTimestamp = m_LastActivityTimestamp; + } + } + protected: std::shared_ptr m_RemoteIdentity; mutable std::mutex m_RemoteIdentityMutex; - size_t m_NumSentBytes, m_NumReceivedBytes, m_SendQueueSize; bool m_IsOutgoing; int m_TerminationTimeout; - uint64_t m_LastActivityTimestamp; uint32_t m_CreationTime; // seconds since epoch int64_t m_HandshakeInterval; // in milliseconds between SessionRequest->SessionCreated or SessionCreated->SessionConfirmed + + private: + + size_t m_SendQueueSize, m_NumSentBytes, m_NumReceivedBytes, + m_LastBandWidthUpdateNumSentBytes, m_LastBandWidthUpdateNumReceivedBytes; + uint64_t m_LastActivityTimestamp, m_LastBandwidthUpdateTimestamp; + uint32_t m_InBandwidth, m_OutBandwidth; }; // SOCKS5 proxy diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 45284e24..53a13410 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -951,7 +951,7 @@ namespace transport // connected, not overloaded and not slow return !peer.router && !peer.sessions.empty () && peer.isReachable && peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE && - !peer.sessions.front ()->IsSlow () && + !peer.sessions.front ()->IsSlow () && !peer.sessions.front ()->IsBandwidthExceeded (peer.isHighBandwidth) && (!isHighBandwidth || peer.isHighBandwidth); }); } From 0a519d8072423c978a6ea1a788c20976580a5d2c Mon Sep 17 00:00:00 2001 From: Vort Date: Sun, 15 Oct 2023 18:08:15 +0300 Subject: [PATCH 0330/1160] Fix MSVC compilation for std::max --- build/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index abfadfca..6a2aa99b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -121,7 +121,7 @@ if(WIN32) ) file(GLOB WIN32_RC ${WIN32_SRC_DIR}/*.rc) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_APP -DWIN32_LEAN_AND_MEAN -DNOMINMAX") endif() From 04adc14b769da541b07dfddb6a6a0c7b269f15e3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Oct 2023 18:46:59 -0400 Subject: [PATCH 0331/1160] ls@mail.i2p yggdrasil reseed added --- .../certificates/reseed/ls_at_mail.i2p.crt | 32 +++++++++++++++++++ libi2pd/Config.cpp | 3 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 contrib/certificates/reseed/ls_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/ls_at_mail.i2p.crt b/contrib/certificates/reseed/ls_at_mail.i2p.crt new file mode 100644 index 00000000..8e0902d7 --- /dev/null +++ b/contrib/certificates/reseed/ls_at_mail.i2p.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdTCCA12gAwIBAgIEQ5vCxzANBgkqhkiG9w0BAQ0FADBrMQswCQYDVQQGEwJY +WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt +b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEUMBIGA1UEAwwLbHNAbWFpbC5pMnAw +HhcNMjMxMDE2MjAwNTA5WhcNMzMxMDEzMjAwNTA5WjBrMQswCQYDVQQGEwJYWDEL +MAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnltb3Vz +IE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEUMBIGA1UEAwwLbHNAbWFpbC5pMnAwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDPcbKRtf4PzrDa0iRit0XrwnmA +2c1fJhkBipdPor7gMOAlkR82H1lkZSizR7kTZnr7vYqjDrOQr7bl5Dy3qo8/YCbZ +jsnUCTIIgIJQUxUlR40RjaSXphqzUEiXKHR6b0RahhFisQ3hlbbgzSch5YgSLKws +hOLi+eDSXw+HlwHlWFlT1XOKxSTJ/F3Bv40gxqZVC2pbxiPOeRZHQ6Ojw75lxTSF +gww2WzgztiWt4X9BO1yepnVqhAVRPmTfGUMfKzq9jkMzZKeQFV4uZSP9nCqzEpYd +WNDUfpTWiAQ9F+BwFXGusXXA3tGVwS7s6IEoiJFM5fsoJYfRoWGh3/1eirhBXW7U +M6oubMSTADyrvfjLfJBMmMnc2hNblRlKr0ZKUjMfv8cnyT4kQxlXLAHHXY2P89TM +TEVODkU48gnv6tC4t1JCb1/Da+3yVMjNX6rCzQfUwnLFrWthrwiI0NivAKFtiZjq +w1/ZQcYke2YyeqcfXMn+NTUA22Sm2mJoMo7jUf+rbM9Pi27/DncJgRGj5qwY0D3S +gc7829EjuZNPttGBmae1EmO7WQMB32cqdmItnV2FXpMhnn9h0u5H52kYqwn+mdtc +dTJRcbfKG1RTr3UjFISaTwL8qigMIkVXIzcpnr/R/sSeEs8xCqfsJ6rb4dCyFx+M +hqQcOCL5tumyd4W/LQIDAQABoyEwHzAdBgNVHQ4EFgQUgfaOG5HCnlW82wZ5BahL +GRO06igwDQYJKoZIhvcNAQENBQADggIBAKdVpqS9qF7gGotgXaVA1iP5YNsWlTvG +daGqeA/87//U21W6gpq82FhzsmsvUtXZfIeVIlDPI7WNDzS+A3K/KKrwM7dLgSie +r9eMl3D8WYPU95QF4mAlRyl7PCCsYoVjyvfro0iq3/iudIA5476rjfLdTXRi5hAT +qemPj0S+6sRjKEldRtGXrQATFlvLIWVYpgHijdDDx5M2hAz2y0mFxlDZTlA4BhL4 +DwtGlVKmbc2x5MvIQM4UhbQqkxYS4gXnzf5Qx9QIytHfTr/hmbrkhKR1GCO31BSk +x9LhZxdI8LlwKSo6YgwXEB9E0M/tplaK9iZJFv4HPYLZrVJpb4IklMumyLMrgW5P +fR0dgKn+R9lk0emJ1Cu+qyyzf1vsLycYBwaEztINn4VK+/HfDFpnVCvJOyNuDmj5 +KBLIoGdGoVfylmnc+e8zAXe+DY41fgniHMISOO78P8Bx9vTB+rhqnOUr9MzlUxPB +sKGjbXy2YynEqiGb+9g344v/+ukTSDenqTPHVzJ5uOi0iedy+3ASzUNN6GJocovP +167VOhwaETM0FwiKe0VdZRLLbbZ79CtJC0tmgcgPQPRa9Ldr6KN7u1J3D6lUp6zl +byPom10ueKONRb36t7ai79l2SEUZRSMkx6AXIU0JJ1SMtQtav7b5LkpYJfdL7+vO +dDx2/Za0VmdD +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index cd78727f..3d3c5c2a 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -230,7 +230,8 @@ namespace config { "http://[301:65b9:c7cd:9a36::1]:18801/," "http://[320:8936:ec1a:31f1::216]/," "http://[306:3834:97b9:a00a::1]/," - "http://[316:f9e0:f22e:a74f::216]/" + "http://[316:f9e0:f22e:a74f::216]/," + "http://[300:e097:2621:79e3::add1]:7170" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From d04b19d77ce03a973f4e83668fa3e79be574bcdb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Oct 2023 18:09:41 -0400 Subject: [PATCH 0332/1160] don't recalculate badwidth if clock was adjusted too much --- libi2pd/TransportSession.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index e298fdb2..f4668116 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -152,8 +152,16 @@ namespace transport void UpdateBandwidth () { - uint64_t interval = m_LastActivityTimestamp - m_LastBandwidthUpdateTimestamp; - if (interval > TRANSPORT_SESSION_BANDWIDTH_UPDATE_MIN_INTERVAL) + int64_t interval = m_LastActivityTimestamp - m_LastBandwidthUpdateTimestamp; + if (interval < 0 || interval > 60*10) // 10 minutes + { + // clock was adjusted, copy new values + m_LastBandWidthUpdateNumSentBytes = m_NumSentBytes; + m_LastBandWidthUpdateNumReceivedBytes = m_NumReceivedBytes; + m_LastBandwidthUpdateTimestamp = m_LastActivityTimestamp; + return; + } + if ((uint64_t)interval > TRANSPORT_SESSION_BANDWIDTH_UPDATE_MIN_INTERVAL) { m_OutBandwidth = (m_NumSentBytes - m_LastBandWidthUpdateNumSentBytes)/interval; m_LastBandWidthUpdateNumSentBytes = m_NumSentBytes; From 0ef9c083264ba00227383b921a2f4459a8afa290 Mon Sep 17 00:00:00 2001 From: Dex Date: Fri, 27 Oct 2023 15:06:24 +1100 Subject: [PATCH 0333/1160] fix manpage typo for ipv4 flag --- debian/i2pd.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/i2pd.1 b/debian/i2pd.1 index 5145321f..42c282d9 100644 --- a/debian/i2pd.1 +++ b/debian/i2pd.1 @@ -64,7 +64,7 @@ The network interface to bind to for IPv4 connections The network interface to bind to for IPv6 connections .TP \fB\-\-ipv4=\fR -Enable communication through ipv6 (\fIenabled\fR by default) +Enable communication through ipv4 (\fIenabled\fR by default) .TP \fB\-\-ipv6\fR Enable communication through ipv6 (\fIdisabled\fR by default) From e090b9052a15c57ab6bf2aebfbdd43a845bb97f8 Mon Sep 17 00:00:00 2001 From: acetone <63557806+freeacetone@users.noreply.github.com> Date: Sun, 29 Oct 2023 11:57:14 +0300 Subject: [PATCH 0334/1160] Yggdrasil reseed address replaced by address for 4.X+ version --- contrib/i2pd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 545973a3..be4a6719 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -225,7 +225,7 @@ verify = true ## Default: "mainline" I2P Network reseeds # urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/ ## Reseed URLs through the Yggdrasil, separated by comma -# yggurls = http://[324:9de3:fea4:f6ac::ace]:7070/ +# yggurls = http://[324:71e:281a:9ed3::ace]:7070/ ## Path to local reseed data file (.su3) for manual reseeding # file = /path/to/i2pseeds.su3 ## or HTTPS URL to reseed from From 3286bdb4a771fb1cb8bd33bb03a4d4ff695ac39a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 Oct 2023 22:11:38 -0400 Subject: [PATCH 0335/1160] verify jump link for valid characters --- libi2pd/Base.cpp | 12 ++++++++++- libi2pd/Base.h | 4 +++- libi2pd_client/AddressBook.cpp | 20 +++++++++++++----- libi2pd_client/HTTPProxy.cpp | 37 ++++++++++++++++++++++++++++------ 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index e979c5b4..02ad5f9f 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -28,6 +28,11 @@ namespace data return T32; } + bool IsBase32 (char ch) + { + return (ch >= 'a' && ch <= 'z') || (ch >= '2' && ch <= '7'); + } + static void iT64Build(void); /* @@ -55,6 +60,11 @@ namespace data return T64; } + bool IsBase64 (char ch) + { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '~'; + } + /* * Reverse Substitution Table (built in run time) */ diff --git a/libi2pd/Base.h b/libi2pd/Base.h index 79152e02..a163435c 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,9 +19,11 @@ namespace data { size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); const char * GetBase32SubstitutionTable (); const char * GetBase64SubstitutionTable (); + bool IsBase64 (char ch); size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen); size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen); + bool IsBase32 (char ch); /** * Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 055311a9..8f2117a7 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -403,10 +403,20 @@ namespace client if (!addr) return false; - i2p::data::IdentityEx ident; - if (ident.FromBase64 (jump) && ident.GetIdentHash () == addr->identHash) - return true; - + auto pos = jump.find(".b32.i2p"); + if (pos != std::string::npos) + { + i2p::data::IdentHash identHash; + if (identHash.FromBase32(jump.substr (0, pos)) && identHash == addr->identHash) + return true; + } + else + { + i2p::data::IdentityEx ident; + if (ident.FromBase64 (jump) && ident.GetIdentHash () == addr->identHash) + return true; + } + return false; } diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 26b47d8b..76d37a1e 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -75,8 +75,9 @@ namespace proxy { void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void Terminate(); void AsyncSockRead(); - bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm); - void SanitizeHTTPRequest(i2p::http::HTTPReq & req); + static bool ExtractAddressHelper(i2p::http::URL& url, std::string& jump, bool& confirm); + static bool VerifyAddressHelper (const std::string& jump); + static void SanitizeHTTPRequest(i2p::http::HTTPReq& req); void SentHTTPFailed(const boost::system::error_code & ecode); void HandleStreamRequestComplete (std::shared_ptr stream); /* error helpers */ @@ -221,7 +222,7 @@ namespace proxy { std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } - bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm) + bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL& url, std::string& jump, bool& confirm) { confirm = false; const char *param = "i2paddresshelper="; @@ -237,8 +238,13 @@ namespace proxy { std::string value = params["i2paddresshelper"]; len += value.length(); - b64 = i2p::http::UrlDecode(value); - + jump = i2p::http::UrlDecode(value); + if (!VerifyAddressHelper (jump)) + { + LogPrint (eLogError, "HTTPProxy: Malformed jump link ", jump); + return false; + } + // if we need update exists, request formed with update param if (params["update"] == "true") { @@ -269,7 +275,26 @@ namespace proxy { return true; } - void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq & req) + bool HTTPReqHandler::VerifyAddressHelper (const std::string& jump) + { + auto pos = jump.find(".b32.i2p"); + if (pos != std::string::npos) + { + auto b32 = jump.substr (0, pos); + for (auto& ch: b32) + if (!i2p::data::IsBase32(ch)) return false; + return true; + } + else + { + for (auto& ch: jump) + if (!i2p::data::IsBase64(ch)) return false; + return true; + } + return false; + } + + void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq& req) { /* drop common headers */ req.RemoveHeader("Via"); From e1b4feb618ecd7ab9fc81c462646182224384e8c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Oct 2023 08:10:17 -0400 Subject: [PATCH 0336/1160] correct base64 check --- libi2pd/Base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 02ad5f9f..b8de571b 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -62,7 +62,7 @@ namespace data bool IsBase64 (char ch) { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '~'; + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '-' || ch == '~'; } /* From 69b0bef206c23046e3ace953db5ecf8af35ebff6 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Oct 2023 10:09:47 -0400 Subject: [PATCH 0337/1160] fixed possible invalid pointer when send error response --- libi2pd_client/HTTPProxy.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 76d37a1e..88de602b 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -109,7 +109,7 @@ namespace proxy { std::shared_ptr m_sock; std::shared_ptr m_proxysock; boost::asio::ip::tcp::resolver m_proxy_resolver; - std::string m_OutproxyUrl; + std::string m_OutproxyUrl, m_Response; bool m_Addresshelper; i2p::http::URL m_ProxyURL; i2p::http::URL m_RequestURL; @@ -206,8 +206,8 @@ namespace proxy { << "" << content << "\r\n" << "\r\n"; res.body = ss.str(); - std::string response = res.to_string(); - boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(), + m_Response = res.to_string(); + boost::asio::async_write(*m_sock, boost::asio::buffer(m_Response), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } @@ -217,8 +217,8 @@ namespace proxy { res.code = 302; res.add_header("Location", address); res.add_header("Connection", "close"); - std::string response = res.to_string(); - boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(), + m_Response = res.to_string(); + boost::asio::async_write(*m_sock, boost::asio::buffer(m_Response), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } From 575268d36093928d48491cf85e007504732bbf2d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Oct 2023 20:02:48 -0400 Subject: [PATCH 0338/1160] reduce expiration time for low bandwidth and far routers --- libi2pd/NetDb.cpp | 11 +++++++++-- libi2pd/NetDb.hpp | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 02d4dfd8..12817ad1 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -654,13 +654,20 @@ namespace data // find & mark expired routers if (!it.second->GetCompatibleTransports (true)) // non reachable by any transport it.second->SetUnreachable (true); - else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) - it.second->SetUnreachable (true); else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ()) { LogPrint (eLogWarning, "NetDb: RouterInfo is from future for ", (it.second->GetTimestamp () - ts)/1000LL, " seconds"); it.second->SetUnreachable (true); } + else if (checkForExpiration) + { + uint64_t t = expirationTimeout; + if (total > NETDB_NUM_ROUTERS_THRESHOLD && !it.second->IsHighBandwidth () && // low bandwidth router + ((it.second->GetIdentHash()[0] & 0xFE) != (i2p::context.GetIdentHash ()[0] & 0xFE))) // different first 7 bits + t >>= 1; // reduce expiration time by 2 times + if (ts > it.second->GetTimestamp () + t) + it.second->SetUnreachable (true); + } if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ())) it.second->SetUnreachable (false); // don't expire connected router } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 44dff3b8..8edc94d6 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -39,6 +39,7 @@ namespace data const int NETDB_MIN_ROUTERS = 90; const int NETDB_MIN_FLOODFILLS = 5; const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1500; + const int NETDB_NUM_ROUTERS_THRESHOLD = 4*NETDB_NUM_FLOODFILLS_THRESHOLD; const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours From a6ee1e648e0724d7798986d1f490c22b80105dd9 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Oct 2023 09:10:56 -0400 Subject: [PATCH 0339/1160] recognize trailing padding as part of base64 address --- libi2pd_client/HTTPProxy.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 88de602b..a0fc8f07 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -287,8 +287,17 @@ namespace proxy { } else { + bool padding = false; for (auto& ch: jump) - if (!i2p::data::IsBase64(ch)) return false; + { + if (ch == '=') + padding = true; + else + { + if (padding) return false; // other chars after padding + if (!i2p::data::IsBase64(ch)) return false; + } + } return true; } return false; From a3f62e1d7150cd6d1b5195019a8f3a0caf201548 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Oct 2023 13:20:04 -0400 Subject: [PATCH 0340/1160] check actual distance with router to reduce expiration time --- libi2pd/NetDb.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 12817ad1..54b7b7c1 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -661,12 +661,13 @@ namespace data } else if (checkForExpiration) { - uint64_t t = expirationTimeout; - if (total > NETDB_NUM_ROUTERS_THRESHOLD && !it.second->IsHighBandwidth () && // low bandwidth router - ((it.second->GetIdentHash()[0] & 0xFE) != (i2p::context.GetIdentHash ()[0] & 0xFE))) // different first 7 bits - t >>= 1; // reduce expiration time by 2 times - if (ts > it.second->GetTimestamp () + t) + if (ts > it.second->GetTimestamp () + expirationTimeout) it.second->SetUnreachable (true); + else if ((ts > it.second->GetTimestamp () + expirationTimeout/2) && // more than half of expiration + total > NETDB_NUM_ROUTERS_THRESHOLD && !it.second->IsHighBandwidth() && // low bandwidth + !it.second->IsFloodfill() && (!i2p::context.IsFloodfill () || // non floodfill + (CreateRoutingKey (it.second->GetIdentHash ()) ^ i2p::context.GetIdentHash ()).metric[0] >= 0x02)) // different first 7 bits + it.second->SetUnreachable (true); } if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ())) it.second->SetUnreachable (false); // don't expire connected router From 379be2a29e3d9298cb46e0adba1abc27f36732c1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 31 Oct 2023 22:33:12 +0300 Subject: [PATCH 0341/1160] [gha] Update FreeBSD build action --- .github/workflows/build-freebsd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml index 76b496ad..b4decc49 100644 --- a/.github/workflows/build-freebsd.yml +++ b/.github/workflows/build-freebsd.yml @@ -13,7 +13,7 @@ jobs: - name: Test in FreeBSD id: test - uses: vmactions/freebsd-vm@v0.3.0 + uses: vmactions/freebsd-vm@v0.3.1 with: usesh: true mem: 2048 From 0021501d750250ad0da604cc4593b5a28b442b05 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 31 Oct 2023 22:39:51 +0300 Subject: [PATCH 0342/1160] [gha] disable FreeBSD build Additional info: https://github.com/vmactions/freebsd-vm/issues/74 --- .../workflows/{build-freebsd.yml => build-freebsd.yml-disabled} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{build-freebsd.yml => build-freebsd.yml-disabled} (100%) diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml-disabled similarity index 100% rename from .github/workflows/build-freebsd.yml rename to .github/workflows/build-freebsd.yml-disabled From 083034fa35bfdc4924294e57c08313a739cc02f4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Nov 2023 21:56:32 -0500 Subject: [PATCH 0343/1160] send peer tests with random delays --- libi2pd/Transports.cpp | 44 +++++++++++++++++++++++++++++++++++++++--- libi2pd/Transports.h | 2 ++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 53a13410..b6e2e261 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -645,14 +645,33 @@ namespace transport LogPrint (eLogInfo, "Transports: Started peer test IPv4"); std::set excluded; excluded.insert (i2p::context.GetIdentHash ()); // don't pick own router + int testDelay = 0; for (int i = 0; i < 5; i++) { auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (true, excluded); // v4 if (router) { if (!i2p::context.GetTesting ()) + { i2p::context.SetTesting (true); - m_SSU2Server->StartPeerTest (router, true); + // send first peer test immediately + m_SSU2Server->StartPeerTest (router, true); + } + else + { + testDelay += PEER_TEST_DELAY_INTERVAL + rand() % PEER_TEST_DELAY_INTERVAL_VARIANCE; + if (m_Service) + { + auto delayTimer = std::make_shared(*m_Service); + delayTimer->expires_from_now (boost::posix_time::milliseconds (testDelay)); + delayTimer->async_wait ( + [this, router, delayTimer](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + m_SSU2Server->StartPeerTest (router, true); + }); + } + } excluded.insert (router->GetIdentHash ()); } } @@ -664,14 +683,33 @@ namespace transport LogPrint (eLogInfo, "Transports: Started peer test IPv6"); std::set excluded; excluded.insert (i2p::context.GetIdentHash ()); // don't pick own router + int testDelay = 0; for (int i = 0; i < 5; i++) { auto router = i2p::data::netdb.GetRandomSSU2PeerTestRouter (false, excluded); // v6 if (router) { if (!i2p::context.GetTestingV6 ()) - i2p::context.SetTestingV6 (true); - m_SSU2Server->StartPeerTest (router, false); + { + i2p::context.SetTestingV6 (true); + // send first peer test immediately + m_SSU2Server->StartPeerTest (router, false); + } + else + { + testDelay += PEER_TEST_DELAY_INTERVAL + rand() % PEER_TEST_DELAY_INTERVAL_VARIANCE; + if (m_Service) + { + auto delayTimer = std::make_shared(*m_Service); + delayTimer->expires_from_now (boost::posix_time::milliseconds (testDelay)); + delayTimer->async_wait ( + [this, router, delayTimer](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + m_SSU2Server->StartPeerTest (router, false); + }); + } + } excluded.insert (router->GetIdentHash ()); } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index a8f2a16a..cb63ca91 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -105,6 +105,8 @@ namespace transport const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds const int PEER_TEST_INTERVAL = 71; // in minutes + const int PEER_TEST_DELAY_INTERVAL = 20; // in milliseconds + const int PEER_TEST_DELAY_INTERVAL_VARIANCE = 30; // in milliseconds const int MAX_NUM_DELAYED_MESSAGES = 150; const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after class Transports From 6b33250c599f138d8834fb00bfe9f936bc9d8894 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Sat, 4 Nov 2023 12:24:33 +0100 Subject: [PATCH 0344/1160] build/CMakeLists.txt: enable C language MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detection of libatomic is broken since version 2.47.0 and https://github.com/PurpleI2P/i2pd/commit/b7f0d87dafa8957131b496c38fbe65d8cb378a9d because C language is not enabled anymore: -- Looking for __atomic_fetch_add_4 in atomic -- Looking for __atomic_fetch_add_4 in atomic - not found CMake Error at cmake_modules/CheckAtomic.cmake:59 (message): Host compiler appears to require libatomic, but cannot find it. Call Stack (most recent call first): CMakeLists.txt:54 (include) Indeed if C language is not enabled, the test will be run with the C++ compiler resulting in the following error: Building CXX object CMakeFiles/cmTC_03d01.dir/CheckFunctionExists.cxx.o /home/fabrice/buildroot/output/host/bin/x86_64-linux-g++ --sysroot=/home/fabrice/buildroot/output/host/x86_64-buildroot-linux-gnu/sysroot -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O1 -g0 -D_FORTIFY_SOURCE=2 -DCHECK_FUNCTION_EXISTS=__atomic_fetch_add_4 -DNDEBUG -o CMakeFiles/cmTC_03d01.dir/CheckFunctionExists.cxx.o -c /home/fabrice/buildroot/output/build/i2pd-2.49.0/build/CMakeFiles/CMakeScratch/TryCompile-NApnv9/CheckFunctionExists.cxx : error: new declaration ‘char __atomic_fetch_add_4()’ ambiguates built-in declaration ‘unsigned int __atomic_fetch_add_4(volatile void*, unsigned int, int)’ [-fpermissive] whereas with a C compiler, we'll get: Building C object CMakeFiles/cmTC_7e47b.dir/CheckFunctionExists.c.o /home/fabrice/buildroot/output/host/bin/x86_64-linux-gcc --sysroot=/home/fabrice/buildroot/output/host/x86_64-buildroot-linux-gnu/sysroot -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O1 -g0 -D_FORTIFY_SOURCE=2 -DCHECK_FUNCTION_EXISTS=__atomic_fetch_add_4 -DNDEBUG -o CMakeFiles/cmTC_7e47b.dir/CheckFunctionExists.c.o -c /home/fabrice/buildroot/output/build/i2pd-2.49.0/build/CMakeFiles/CMakeScratch/TryCompile-e0zFMG/CheckFunctionExists.c : warning: conflicting types for built-in function ‘__atomic_fetch_add_4’; expected ‘unsigned int(volatile void *, unsigned int, int)’ [-Wbuiltin-declaration-mismatch] Fix #1908 Signed-off-by: Fabrice Fontaine --- build/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 6a2aa99b..232e427f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -25,7 +25,7 @@ project( i2pd VERSION ${PROJECT_VERSION} HOMEPAGE_URL "https://i2pd.website/" - LANGUAGES CXX + LANGUAGES C CXX ) # configurable options From 1a02819187ea306d64e6090d7a3536bacfc76982 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Fri, 21 Jul 2023 21:43:40 +0300 Subject: [PATCH 0345/1160] Remove deprecated bind_at_load from macOS --- Makefile.osx | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.osx b/Makefile.osx index e069aaff..467c9fdd 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -5,7 +5,6 @@ DEFINES := -DMAC_OSX LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib LDFLAGS += -Wl,-dead_strip LDFLAGS += -Wl,-dead_strip_dylibs -LDFLAGS += -Wl,-bind_at_load ifeq ($(USE_STATIC),yes) LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread From 9632e7ba03533533ff056ad89546bdc3441269b4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Nov 2023 18:32:57 -0500 Subject: [PATCH 0346/1160] exclude NAT64 ipv6 addresses --- libi2pd/util.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index a7afdce8..d1ed9992 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -665,6 +665,7 @@ namespace net if (host.is_v6()) { static const std::vector< std::pair > reservedIPv6Ranges { + address_pair_v6("64:ff9b::", "64:ff9b:ffff:ffff:ffff:ffff:ffff:ffff"), // NAT64 address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), From 8d6eb5b6b2c8f69627cefaa5b6eb4f1010c11631 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Nov 2023 19:12:07 -0500 Subject: [PATCH 0347/1160] don't lock mutex in AsyncSend --- libi2pd/Streaming.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index c2cf3a0a..a7f932f5 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -532,14 +532,18 @@ namespace stream void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler) { + std::shared_ptr buffer; if (len > 0 && buf) - { - std::unique_lock l(m_SendBufferMutex); - m_SendBuffer.Add (buf, len, handler); - } + buffer = std::make_shared(buf, len, handler); else if (handler) handler(boost::system::error_code ()); - m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ())); + auto s = shared_from_this (); + m_Service.post ([s, buffer]() + { + if (buffer) + s->m_SendBuffer.Add (buffer); + s->SendBuffer (); + }); } void Stream::SendBuffer () From 21259204b1f55e1014d088d5d7a2b1cf11048ea6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Nov 2023 09:39:36 -0500 Subject: [PATCH 0348/1160] eliminate send buffer mutex completely --- libi2pd/Streaming.cpp | 171 ++++++++++++++++++++---------------------- libi2pd/Streaming.h | 2 - 2 files changed, 80 insertions(+), 93 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index a7f932f5..629039ab 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -19,11 +19,6 @@ namespace i2p { namespace stream { - void SendBufferQueue::Add (const uint8_t * buf, size_t len, SendHandler handler) - { - Add (std::make_shared(buf, len, handler)); - } - void SendBufferQueue::Add (std::shared_ptr buf) { if (buf) @@ -115,10 +110,7 @@ namespace stream void Stream::CleanUp () { - { - std::unique_lock l(m_SendBufferMutex); - m_SendBuffer.CleanUp (); - } + m_SendBuffer.CleanUp (); while (!m_ReceiveQueue.empty ()) { auto packet = m_ReceiveQueue.front (); @@ -553,91 +545,88 @@ namespace stream bool isNoAck = m_LastReceivedSequenceNumber < 0; // first packet std::vector packets; + while ((m_Status == eStreamStatusNew) || (IsEstablished () && !m_SendBuffer.IsEmpty () && numMsgs > 0)) { - std::unique_lock l(m_SendBufferMutex); - while ((m_Status == eStreamStatusNew) || (IsEstablished () && !m_SendBuffer.IsEmpty () && numMsgs > 0)) + Packet * p = m_LocalDestination.NewPacket (); + uint8_t * packet = p->GetBuffer (); + // TODO: implement setters + size_t size = 0; + htobe32buf (packet + size, m_SendStreamID); + size += 4; // sendStreamID + htobe32buf (packet + size, m_RecvStreamID); + size += 4; // receiveStreamID + htobe32buf (packet + size, m_SequenceNumber++); + size += 4; // sequenceNum + if (isNoAck) + htobuf32 (packet + size, 0); + else + htobe32buf (packet + size, m_LastReceivedSequenceNumber); + size += 4; // ack Through + if (m_Status == eStreamStatusNew && !m_SendStreamID && m_RemoteIdentity) { - Packet * p = m_LocalDestination.NewPacket (); - uint8_t * packet = p->GetBuffer (); - // TODO: implement setters - size_t size = 0; - htobe32buf (packet + size, m_SendStreamID); - size += 4; // sendStreamID - htobe32buf (packet + size, m_RecvStreamID); - size += 4; // receiveStreamID - htobe32buf (packet + size, m_SequenceNumber++); - size += 4; // sequenceNum - if (isNoAck) - htobuf32 (packet + size, 0); - else - htobe32buf (packet + size, m_LastReceivedSequenceNumber); - size += 4; // ack Through - if (m_Status == eStreamStatusNew && !m_SendStreamID && m_RemoteIdentity) - { - // first SYN packet - packet[size] = 8; - size++; // NACK count - memcpy (packet + size, m_RemoteIdentity->GetIdentHash (), 32); - size += 32; - } - else - { - packet[size] = 0; - size++; // NACK count - } - packet[size] = m_RTO/1000; - size++; // resend delay - if (m_Status == eStreamStatusNew) - { - // initial packet - m_Status = eStreamStatusOpen; - if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; - if (m_RemoteLeaseSet) - { - m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); - m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; - } - uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | - PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; - if (isNoAck) flags |= PACKET_FLAG_NO_ACK; - bool isOfflineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().IsOfflineSignature (); - if (isOfflineSignature) flags |= PACKET_FLAG_OFFLINE_SIGNATURE; - htobe16buf (packet + size, flags); - size += 2; // flags - size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen (); - size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); - uint8_t * optionsSize = packet + size; // set options size later - size += 2; // options size - m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); - size += identityLen; // from - htobe16buf (packet + size, m_MTU); - size += 2; // max packet size - if (isOfflineSignature) - { - const auto& offlineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetOfflineSignature (); - memcpy (packet + size, offlineSignature.data (), offlineSignature.size ()); - size += offlineSignature.size (); // offline signature - } - uint8_t * signature = packet + size; // set it later - memset (signature, 0, signatureLen); // zeroes for now - size += signatureLen; // signature - htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size - size += m_SendBuffer.Get (packet + size, m_MTU); // payload - m_LocalDestination.GetOwner ()->Sign (packet, size, signature); - } - else - { - // follow on packet - htobuf16 (packet + size, 0); - size += 2; // flags - htobuf16 (packet + size, 0); // no options - size += 2; // options size - size += m_SendBuffer.Get(packet + size, m_MTU); // payload - } - p->len = size; - packets.push_back (p); - numMsgs--; + // first SYN packet + packet[size] = 8; + size++; // NACK count + memcpy (packet + size, m_RemoteIdentity->GetIdentHash (), 32); + size += 32; } + else + { + packet[size] = 0; + size++; // NACK count + } + packet[size] = m_RTO/1000; + size++; // resend delay + if (m_Status == eStreamStatusNew) + { + // initial packet + m_Status = eStreamStatusOpen; + if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; + if (m_RemoteLeaseSet) + { + m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); + m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; + } + uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | + PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; + if (isNoAck) flags |= PACKET_FLAG_NO_ACK; + bool isOfflineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().IsOfflineSignature (); + if (isOfflineSignature) flags |= PACKET_FLAG_OFFLINE_SIGNATURE; + htobe16buf (packet + size, flags); + size += 2; // flags + size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen (); + size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); + uint8_t * optionsSize = packet + size; // set options size later + size += 2; // options size + m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); + size += identityLen; // from + htobe16buf (packet + size, m_MTU); + size += 2; // max packet size + if (isOfflineSignature) + { + const auto& offlineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetOfflineSignature (); + memcpy (packet + size, offlineSignature.data (), offlineSignature.size ()); + size += offlineSignature.size (); // offline signature + } + uint8_t * signature = packet + size; // set it later + memset (signature, 0, signatureLen); // zeroes for now + size += signatureLen; // signature + htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size + size += m_SendBuffer.Get (packet + size, m_MTU); // payload + m_LocalDestination.GetOwner ()->Sign (packet, size, signature); + } + else + { + // follow on packet + htobuf16 (packet + size, 0); + size += 2; // flags + htobuf16 (packet + size, 0); // no options + size += 2; // options size + size += m_SendBuffer.Get(packet + size, m_MTU); // payload + } + p->len = size; + packets.push_back (p); + numMsgs--; } if (packets.size () > 0) { diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 3609df92..1db59118 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -135,7 +135,6 @@ namespace stream SendBufferQueue (): m_Size (0) {}; ~SendBufferQueue () { CleanUp (); }; - void Add (const uint8_t * buf, size_t len, SendHandler handler); void Add (std::shared_ptr buf); size_t Get (uint8_t * buf, size_t len); size_t GetSize () const { return m_Size; }; @@ -251,7 +250,6 @@ namespace stream size_t m_NumSentBytes, m_NumReceivedBytes; uint16_t m_Port; - std::mutex m_SendBufferMutex; SendBufferQueue m_SendBuffer; int m_WindowSize, m_RTT, m_RTO, m_AckDelay; uint64_t m_LastWindowSizeIncreaseTime; From 94255ebaf40236f224bcd45be89c18d0747ce591 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Nov 2023 13:44:30 -0500 Subject: [PATCH 0349/1160] STREAM ACCEPT queue --- libi2pd_client/SAM.cpp | 29 +++++++++++++++++------------ libi2pd_client/SAM.h | 5 ++++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 1a281c57..54da4654 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -601,10 +601,15 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } - else // already accepting + else if (session->acceptQueue.size () < SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE) + { + // already accepting, queue up + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + session->acceptQueue.push_back (shared_from_this()); + } + else { - // TODO: implement queue - LogPrint (eLogInfo, "SAM: Session ", m_ID, " is already accepting"); + LogPrint (eLogInfo, "SAM: Session ", m_ID, " accept queue is full ", session->acceptQueue.size ()); SendStreamI2PError ("Already accepting"); } } @@ -1057,16 +1062,16 @@ namespace client m_Stream = stream; context.GetAddressBook ().InsertFullAddress (stream->GetRemoteIdentity ()); auto session = m_Owner.FindSession (m_ID); - if (session) + if (session && !session->acceptQueue.empty ()) { - // find more pending acceptors - for (auto & it: m_Owner.ListSockets (m_ID)) - if (it->m_SocketType == eSAMSocketTypeAcceptor) - { - it->m_IsAccepting = true; - session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1)); - break; - } + // pending acceptors + auto socket = session->acceptQueue.front (); + session->acceptQueue.pop_front (); + if (socket && socket->GetSocketType () == eSAMSocketTypeAcceptor) + { + socket->m_IsAccepting = true; + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, socket, std::placeholders::_1)); + } } if (!m_IsSilent) { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 736c0945..2841afb9 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -31,6 +31,8 @@ namespace client const size_t SAM_SOCKET_BUFFER_SIZE = 8192; const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds const int SAM_SESSION_READINESS_CHECK_INTERVAL = 3; // in seconds + const size_t SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE = 64; + const char SAM_HANDSHAKE[] = "HELLO VERSION"; const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n"; const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n"; @@ -189,7 +191,8 @@ namespace client std::string Name; SAMSessionType Type; std::shared_ptr UDPEndpoint; // TODO: move - + std::list > acceptQueue; + SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type); virtual ~SAMSession () {}; From d327533b56d5a7f88d9d5004670fa5274d333dfc Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Nov 2023 18:50:52 -0500 Subject: [PATCH 0350/1160] close unclaimed acceptors after 3 seconds --- libi2pd_client/SAM.cpp | 52 ++++++++++++++++++++++++++++++------------ libi2pd_client/SAM.h | 5 ++-- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 54da4654..ffdeb5ac 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -601,16 +601,27 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } - else if (session->acceptQueue.size () < SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE) - { - // already accepting, queue up - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); - session->acceptQueue.push_back (shared_from_this()); - } - else + else { - LogPrint (eLogInfo, "SAM: Session ", m_ID, " accept queue is full ", session->acceptQueue.size ()); - SendStreamI2PError ("Already accepting"); + auto ts = i2p::util::GetSecondsSinceEpoch (); + while (!session->acceptQueue.empty () && session->acceptQueue.front ().second + SAM_SESSION_MAX_ACCEPT_INTERVAL > ts) + { + auto socket = session->acceptQueue.front ().first; + session->acceptQueue.pop_front (); + if (socket) + m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); + } + if (session->acceptQueue.size () < SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE) + { + // already accepting, queue up + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + session->acceptQueue.push_back (std::make_pair(shared_from_this(), ts)); + } + else + { + LogPrint (eLogInfo, "SAM: Session ", m_ID, " accept queue is full ", session->acceptQueue.size ()); + SendStreamI2PError ("Already accepting"); + } } } else @@ -1065,12 +1076,23 @@ namespace client if (session && !session->acceptQueue.empty ()) { // pending acceptors - auto socket = session->acceptQueue.front (); - session->acceptQueue.pop_front (); - if (socket && socket->GetSocketType () == eSAMSocketTypeAcceptor) - { - socket->m_IsAccepting = true; - session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, socket, std::placeholders::_1)); + auto ts = i2p::util::GetSecondsSinceEpoch (); + while (!session->acceptQueue.empty () && session->acceptQueue.front ().second + SAM_SESSION_MAX_ACCEPT_INTERVAL > ts) + { + auto socket = session->acceptQueue.front ().first; + session->acceptQueue.pop_front (); + if (socket) + m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); + } + if (!session->acceptQueue.empty ()) + { + auto socket = session->acceptQueue.front ().first; + session->acceptQueue.pop_front (); + if (socket && socket->GetSocketType () == eSAMSocketTypeAcceptor) + { + socket->m_IsAccepting = true; + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, socket, std::placeholders::_1)); + } } } if (!m_IsSilent) diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 2841afb9..34af5a62 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -31,7 +31,8 @@ namespace client const size_t SAM_SOCKET_BUFFER_SIZE = 8192; const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds const int SAM_SESSION_READINESS_CHECK_INTERVAL = 3; // in seconds - const size_t SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE = 64; + const size_t SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE = 50; + const size_t SAM_SESSION_MAX_ACCEPT_INTERVAL = 3; // in seconds const char SAM_HANDSHAKE[] = "HELLO VERSION"; const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n"; @@ -191,7 +192,7 @@ namespace client std::string Name; SAMSessionType Type; std::shared_ptr UDPEndpoint; // TODO: move - std::list > acceptQueue; + std::list, uint64_t> > acceptQueue; // socket, receive time in seconds SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type); virtual ~SAMSession () {}; From c215f2e8d19f07b95163fdfecd974fa5eec2dce1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Nov 2023 13:06:50 -0500 Subject: [PATCH 0351/1160] check router for null pointer --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 54b7b7c1..07f0f341 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -628,7 +628,7 @@ namespace data auto own = i2p::context.GetSharedRouterInfo (); for (auto& it: m_RouterInfos) { - if (it.second == own) continue; // skip own + if (!it.second || it.second == own) continue; // skip own std::string ident = it.second->GetIdentHashBase64(); if (it.second->IsUpdated ()) { @@ -698,7 +698,7 @@ namespace data std::unique_lock l(m_RouterInfosMutex); for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();) { - if (it->second->IsUnreachable ()) + if (!it->second || it->second->IsUnreachable ()) it = m_RouterInfos.erase (it); else { From c802c2deb0eac4e8b012939f0da6128d40bf6b8c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Dec 2023 15:48:26 -0500 Subject: [PATCH 0352/1160] update yggdrasil ressed address --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 3d3c5c2a..4deb59ac 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -231,7 +231,7 @@ namespace config { "http://[320:8936:ec1a:31f1::216]/," "http://[306:3834:97b9:a00a::1]/," "http://[316:f9e0:f22e:a74f::216]/," - "http://[300:e097:2621:79e3::add1]:7170" + "http://[300:eaff:7fab:181b::e621]:7170" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From 9b82265cd87e8bd4b329733713b50c6c7f85b6ba Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Dec 2023 11:07:10 -0500 Subject: [PATCH 0353/1160] 2.50.0 --- ChangeLog | 15 +++++++++++++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4dd49a24..1e5156f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,21 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.50.0] - 2023-12-18 +### Added +- Support of concurrent ACCEPTs on SAM 3.1 +- Haiku OS support +- Low bandwidth and far routers can expire before 1 hour +### Changed +- Don't pick too active peer for first hop +- Try peer test again if status is Unknown +- Send peer tests with random delay +- Reseeds list +### Fixed +- XSS vulnerability in addresshelper +- Publishing NAT64 ipv6 addresses +- Deadlock in AsyncSend callback + ## [2.49.0] - 2023-09-18 ### Added - Handle SOCK5 authorization with empty user/password diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index c745e05f..f0344a34 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.49.0 +Version: 2.50.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -144,6 +144,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Dec 18 2023 orignal - 2.50.0 +- update to 2.50.0 + * Mon Sep 18 2023 orignal - 2.49.0 - update to 2.49.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 56a7f6e1..9b662f6e 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.49.0 +Version: 2.50.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -142,6 +142,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Dec 18 2023 orignal - 2.50.0 +- update to 2.50.0 + * Mon Sep 18 2023 orignal - 2.49.0 - update to 2.49.0 diff --git a/debian/changelog b/debian/changelog index 4c8ed6bb..55566573 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.50.0-1) unstable; urgency=medium + + * updated to version 2.50.0/0.9.61 + + -- orignal Mon, 18 Dec 2023 16:00:00 +0000 + i2pd (2.49.0-1) unstable; urgency=medium * updated to version 2.49.0/0.9.60 diff --git a/libi2pd/version.h b/libi2pd/version.h index 9854995e..03d6b963 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -18,7 +18,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 49 +#define I2PD_VERSION_MINOR 50 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #ifdef GITVER @@ -33,7 +33,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 60 +#define I2P_VERSION_MICRO 61 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From c2d71331749ac3500d20d19038c29d7d8d4d2eed Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 17 Dec 2023 19:30:55 +0000 Subject: [PATCH 0354/1160] [make] fix windows msys2 build Signed-off-by: r4sas --- Makefile | 2 +- Makefile.mingw | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 86ea0aa8..3998beb0 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ obj/%.o: %.cpp | mk_obj_dir -include $(DEPS) $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) - $(CXX) -o $@ $(DEFINES) $(LDFLAGS) $^ $(LDLIBS) + $(CXX) $(DEFINES) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) diff --git a/Makefile.mingw b/Makefile.mingw index 6cd19080..157f49c1 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -5,14 +5,11 @@ WINDRES = windres CXXFLAGS := $(CXX_DEBUG) -fPIC -msse INCFLAGS := -I$(DAEMON_SRC_DIR) -IWin32 -LDFLAGS := ${LD_DEBUG} -static +LDFLAGS := ${LD_DEBUG} -static -fPIC -msse NEEDED_CXXFLAGS += -std=c++17 DEFINES += -DWIN32_LEAN_AND_MEAN -# Boost libraries suffix -BOOST_SUFFIX = -mt - # UPNP Support ifeq ($(USE_UPNP),yes) DEFINES += -DUSE_UPNP -DMINIUPNP_STATICLIB @@ -20,20 +17,20 @@ ifeq ($(USE_UPNP),yes) endif LDLIBS += \ - -lboost_system$(BOOST_SUFFIX) \ - -lboost_date_time$(BOOST_SUFFIX) \ - -lboost_filesystem$(BOOST_SUFFIX) \ - -lboost_program_options$(BOOST_SUFFIX) \ - -lssl \ - -lcrypto \ - -lz \ + $(MINGW_PREFIX)/lib/libboost_system-mt.a \ + $(MINGW_PREFIX)/lib/libboost_date_time-mt.a \ + $(MINGW_PREFIX)/lib/libboost_filesystem-mt.a \ + $(MINGW_PREFIX)/lib/libboost_program_options-mt.a \ + $(MINGW_PREFIX)/lib/libssl.a \ + $(MINGW_PREFIX)/lib/libcrypto.a \ + $(MINGW_PREFIX)/lib/libz.a \ -lwsock32 \ -lws2_32 \ - -lgdi32 \ -liphlpapi \ + -lcrypt32 \ + -lgdi32 \ -lole32 \ - -luuid \ - -lpthread + -luuid ifeq ($(USE_WIN32_APP), yes) DEFINES += -DWIN32_APP @@ -48,6 +45,7 @@ endif ifeq ($(USE_AESNI),yes) NEEDED_CXXFLAGS += -maes + LDFLAGS += -maes DEFINES += -D__AES__ endif From 53c6b10177b85f510dd0e67a9d6dbb5ccaa0bbcf Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 17 Dec 2023 19:41:28 +0000 Subject: [PATCH 0355/1160] [make] get the mistakenly deleted pthread back Signed-off-by: r4sas --- Makefile.mingw | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.mingw b/Makefile.mingw index 157f49c1..38da225a 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -30,7 +30,8 @@ LDLIBS += \ -lcrypt32 \ -lgdi32 \ -lole32 \ - -luuid + -luuid \ + -lpthread ifeq ($(USE_WIN32_APP), yes) DEFINES += -DWIN32_APP From c3429bb1a935f8c637cae422a2b85d0f3508d1aa Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 18 Dec 2023 09:38:08 +0000 Subject: [PATCH 0356/1160] [gha] return freebsd build back Signed-off-by: r4sas --- .github/workflows/build-freebsd.yml | 32 +++++++++++++++++++++++++++++ ChangeLog | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-freebsd.yml diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml new file mode 100644 index 00000000..6dc46a39 --- /dev/null +++ b/.github/workflows/build-freebsd.yml @@ -0,0 +1,32 @@ +name: Build on FreeBSD + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + name: with UPnP + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Test in FreeBSD + id: test + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + mem: 2048 + sync: rsync + copyback: true + prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc + run: | + cd build + cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . + gmake -j2 + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: i2pd-freebsd + path: build/i2pd diff --git a/ChangeLog b/ChangeLog index 1e5156f9..31e8718b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,7 +9,7 @@ ### Changed - Don't pick too active peer for first hop - Try peer test again if status is Unknown -- Send peer tests with random delay +- Send peer tests with random delay - Reseeds list ### Fixed - XSS vulnerability in addresshelper From 05eda2bc9eed9a816f6668c9b06a62d7a42d98d5 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 18 Dec 2023 09:55:10 +0000 Subject: [PATCH 0357/1160] [gha] build docker containers only on specific paths changes Signed-off-by: r4sas --- .github/workflows/build-freebsd.yml-disabled | 32 -------------------- .github/workflows/docker.yml | 10 ++++++ 2 files changed, 10 insertions(+), 32 deletions(-) delete mode 100644 .github/workflows/build-freebsd.yml-disabled diff --git a/.github/workflows/build-freebsd.yml-disabled b/.github/workflows/build-freebsd.yml-disabled deleted file mode 100644 index b4decc49..00000000 --- a/.github/workflows/build-freebsd.yml-disabled +++ /dev/null @@ -1,32 +0,0 @@ -name: Build on FreeBSD - -on: [push, pull_request] - -jobs: - build: - runs-on: macos-12 - name: with UPnP - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Test in FreeBSD - id: test - uses: vmactions/freebsd-vm@v0.3.1 - with: - usesh: true - mem: 2048 - sync: rsync - copyback: true - prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc - run: | - cd build - cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . - gmake -j2 - - - name: Upload artifacts - uses: actions/upload-artifact@v3 - with: - name: i2pd-freebsd - path: build/i2pd diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 28e4e8b0..41fe859e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -5,6 +5,16 @@ on: branches: - openssl - docker + paths: + - .github/workflows/docker.yml + - contrib/docker/** + - contrib/certificates/** + - daemon/** + - i18n/** + - libi2pd/** + - libi2pd_client/** + - Makefile + - Makefile.linux tags: - '*' From beffdb9fe175a93164bd88ee0fafe1a22595ed15 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 18 Dec 2023 10:06:49 +0000 Subject: [PATCH 0358/1160] [apparmor] add profile for docker container Author: corona@mail.i2p Signed-off-by: r4sas --- contrib/apparmor/docker-i2pd | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 contrib/apparmor/docker-i2pd diff --git a/contrib/apparmor/docker-i2pd b/contrib/apparmor/docker-i2pd new file mode 100644 index 00000000..8e34298a --- /dev/null +++ b/contrib/apparmor/docker-i2pd @@ -0,0 +1,42 @@ +# _________________________________________ +# / Copy this file to the right location \ +# | then load with: | +# | | +# | apparmor_parser -r -W | +# | /etc/apparmor.d/docker-i2pd | +# | | +# | docker run --security-opt | +# | "apparmor=docker-i2pd" ... | +# | purplei2p/i2pd | +# | | +# \ And "aa-status" to verify it's loaded. / +# ----------------------------------------- +# \ ^__^ +# \ (oo)\_______ +# (__)\ )\/\ +# ||----w | +# || || + +#include + +profile docker-i2pd flags=(attach_disconnected,mediate_deleted) { + #include + #include + #include + + /bin/busybox ix, + /usr/local/bin/i2pd ix, + /entrypoint.sh ixr, + + /i2pd_certificates/** r, + + /home/i2pd/data/** rw, + + /home/i2pd/data/i2pd.pid k, + + deny /home/i2pd/data/i2pd.conf w, + deny /home/i2pd/data/tunnels.conf w, + deny /home/i2pd/data/tunnels.d/** w, + deny /home/i2pd/data/certificates/** w, + deny /home/i2pd/data/i2pd.log r, +} From 0e98dd5c7049d79bdcdba341357c504e562eb61f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Dec 2023 07:40:40 -0500 Subject: [PATCH 0359/1160] use fallback EdDSA implementation with openssl 3.2.0 due to regression in EVP_DigestSign (#23075) --- libi2pd/Crypto.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 816d79fd..5b31cdd4 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -39,7 +39,9 @@ # define LEGACY_OPENSSL 0 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 # define OPENSSL_HKDF 1 -# define OPENSSL_EDDSA 1 +# if (OPENSSL_VERSION_NUMBER < 0x030200000) // 3.2.0, regression in EVP_DigestSign +# define OPENSSL_EDDSA 1 +# endif # define OPENSSL_X25519 1 # if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash # define OPENSSL_SIPHASH 1 From 8ffc1486a4cbacb774fd5b8834f9a6022ed2044b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Dec 2023 09:32:12 -0500 Subject: [PATCH 0360/1160] test-eddsa added --- tests/CMakeLists.txt | 7 +++++ tests/Makefile | 6 +++- tests/test-eddsa.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/test-eddsa.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 21daadd9..de319f5d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -65,6 +65,10 @@ SET(test-elligator_SRCS test-elligator.cpp ) +set(test-eddsa_SRCS + test-eddsa.cpp +) + add_executable(test-http-merge_chunked ${test-http-merge_chunked_SRCS}) add_executable(test-http-req ${test-http-req_SRCS}) add_executable(test-http-res ${test-http-res_SRCS}) @@ -77,6 +81,7 @@ add_executable(test-x25519 ${test-x25519_SRCS}) add_executable(test-aeadchacha20poly1305 ${test-aeadchacha20poly1305_SRCS}) add_executable(test-blinding ${test-blinding_SRCS}) add_executable(test-elligator ${test-elligator_SRCS}) +add_executable(test-eddsa ${test-eddsa_SRCS}) set(LIBS libi2pd @@ -101,6 +106,7 @@ target_link_libraries(test-x25519 ${LIBS}) target_link_libraries(test-aeadchacha20poly1305 ${LIBS}) target_link_libraries(test-blinding ${LIBS}) target_link_libraries(test-elligator ${LIBS}) +target_link_libraries(test-eddsa ${LIBS}) add_test(test-http-merge_chunked ${TEST_PATH}/test-http-merge_chunked) add_test(test-http-req ${TEST_PATH}/test-http-req) @@ -114,3 +120,4 @@ add_test(test-x25519 ${TEST_PATH}/test-x25519) add_test(test-aeadchacha20poly1305 ${TEST_PATH}/test-aeadchacha20poly1305) add_test(test-blinding ${TEST_PATH}/test-blinding) add_test(test-elligator ${TEST_PATH}/test-elligator) +add_test(test-eddsa ${TEST_PATH}/test-eddsa) diff --git a/tests/Makefile b/tests/Makefile index 9c5711e2..7c44e467 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -7,7 +7,8 @@ LIBI2PD = ../libi2pd.a TESTS = \ test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \ - test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator + test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding \ + test-elligator test-eddsa ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS))) CXXFLAGS += -DWIN32_LEAN_AND_MEAN @@ -55,6 +56,9 @@ test-blinding: test-blinding.cpp $(LIBI2PD) test-elligator: test-elligator.cpp $(LIBI2PD) $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) +test-eddsa: test-eddsa.cpp $(LIBI2PD) + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) + run: $(TESTS) @for TEST in $(TESTS); do echo Running $$TEST; ./$$TEST ; done diff --git a/tests/test-eddsa.cpp b/tests/test-eddsa.cpp new file mode 100644 index 00000000..b3895e2b --- /dev/null +++ b/tests/test-eddsa.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "Signature.h" + +// TEST 1024 from RFC-8032 + +int main () +{ + uint8_t key[32], pub[32], msg[1024], sig[64]; + BIGNUM * input = BN_new(); + BN_hex2bn(&input, "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5"); + BN_bn2bin(input, key); + BN_hex2bn(&input, + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98" + "fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d8" + "79de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d" + "658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc" + "1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4fe" + "ba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e" + "06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbef" + "efd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7" + "aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed1" + "85ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2" + "d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24" + "554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f270" + "88d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc" + "2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b07" + "07e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128ba" + "b27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51a" + "ddd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429e" + "c96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb7" + "51fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c" + "42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8" + "ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34df" + "f7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08" + "d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649" + "de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e4" + "88acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a3" + "2ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e" + "6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5f" + "b93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b5" + "0d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1" + "369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380d" + "b2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c" + "0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0" + ); + BN_bn2bin(input, msg); + BN_hex2bn(&input, + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350" + "aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"); + BN_bn2bin(input, sig); + BN_hex2bn(&input, + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e"); + BN_bn2bin(input, pub); + + uint8_t s[64]; + i2p::crypto::EDDSA25519Signer signer (key); + signer.Sign (msg, 1023, s); +#if OPENSSL_EDDSA + assert(memcmp (s, sig, 64) == 0); +#endif + + i2p::crypto::EDDSA25519Verifier verifier; + verifier.SetPublicKey (pub); + assert(verifier.Verify (msg, 1023, s)); +} From 43e130ee347c9aea7a840ebfa242ec897f906886 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 Dec 2023 19:29:08 -0500 Subject: [PATCH 0361/1160] reinitialize context before each Sign/Verify call to make it working with openssl 3.2 --- libi2pd/Crypto.h | 4 +--- libi2pd/Signature.cpp | 27 ++++++++++++++------------- libi2pd/Signature.h | 4 +++- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 5b31cdd4..816d79fd 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -39,9 +39,7 @@ # define LEGACY_OPENSSL 0 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 # define OPENSSL_HKDF 1 -# if (OPENSSL_VERSION_NUMBER < 0x030200000) // 3.2.0, regression in EVP_DigestSign -# define OPENSSL_EDDSA 1 -# endif +# define OPENSSL_EDDSA 1 # define OPENSSL_X25519 1 # if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash # define OPENSSL_SIPHASH 1 diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index ebc188a9..60cdbec2 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,7 +15,8 @@ namespace i2p namespace crypto { #if OPENSSL_EDDSA - EDDSA25519Verifier::EDDSA25519Verifier () + EDDSA25519Verifier::EDDSA25519Verifier (): + m_Pkey (nullptr) { m_MDCtx = EVP_MD_CTX_create (); } @@ -23,17 +24,18 @@ namespace crypto EDDSA25519Verifier::~EDDSA25519Verifier () { EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); } void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) { - 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); + if (m_Pkey) EVP_PKEY_free (m_Pkey); + m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); } bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { + EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); } @@ -99,29 +101,26 @@ namespace crypto #if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): - m_MDCtx (nullptr), m_Fallback (nullptr) + m_MDCtx (nullptr), m_Pkey (nullptr), m_Fallback (nullptr) { - EVP_PKEY * pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + m_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 (pkey, publicKey, &len); + EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) { LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); } else - { m_MDCtx = EVP_MD_CTX_create (); - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, pkey); - } - EVP_PKEY_free (pkey); } EDDSA25519Signer::~EDDSA25519Signer () { if (m_Fallback) delete m_Fallback; EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const @@ -131,7 +130,9 @@ namespace crypto { size_t l = 64; uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 - EVP_DigestSign (m_MDCtx, sig, &l, buf, len); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + if (!EVP_DigestSign (m_MDCtx, sig, &l, buf, len)) + LogPrint (eLogError, "EdDSA signing failed"); memcpy (signature, sig, 64); } } diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index e153e66d..671ebfb7 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -305,6 +305,7 @@ namespace crypto #if OPENSSL_EDDSA EVP_MD_CTX * m_MDCtx; + EVP_PKEY * m_Pkey; #else EDDSAPoint m_PublicKey; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; @@ -342,6 +343,7 @@ namespace crypto private: EVP_MD_CTX * m_MDCtx; + EVP_PKEY * m_Pkey; EDDSA25519SignerCompat * m_Fallback; }; #else From 816a58f292228fb72ca9383023cba817acfad56d Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 23 Dec 2023 18:13:31 +0000 Subject: [PATCH 0362/1160] 2.50.1 Signed-off-by: r4sas --- ChangeLog | 4 ++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31e8718b..87329bf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.50.0] - 2023-12-23 +###Fixed +- Support for new EdDSA usage behavior in OpenSSL 3.2.0 + ## [2.50.0] - 2023-12-18 ### Added - Support of concurrent ACCEPTs on SAM 3.1 diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index f0344a34..ab5b4190 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.50.0 +Version: 2.50.1 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -144,6 +144,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Dec 23 2023 r4sas - 2.50.1 +- update to 2.50.1 + * Mon Dec 18 2023 orignal - 2.50.0 - update to 2.50.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 9b662f6e..74cc826d 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.50.0 +Version: 2.50.1 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -142,6 +142,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Dec 23 2023 r4sas - 2.50.1 +- update to 2.50.1 + * Mon Dec 18 2023 orignal - 2.50.0 - update to 2.50.0 diff --git a/debian/changelog b/debian/changelog index 55566573..5484fd92 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.50.1-1) unstable; urgency=medium + + * updated to version 2.50.1/0.9.61 + + -- r4sas Sat, 23 Dec 2023 18:30:00 +0000 + i2pd (2.50.0-1) unstable; urgency=medium * updated to version 2.50.0/0.9.61 diff --git a/libi2pd/version.h b/libi2pd/version.h index 03d6b963..c79e3a2b 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -19,7 +19,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 50 -#define I2PD_VERSION_MICRO 0 +#define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION XSTRINGIZE(GITVER) From 69ee6112b3b134c40e4446999ede613d985a9122 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 23 Dec 2023 19:53:39 +0000 Subject: [PATCH 0363/1160] [changelog] fix version Signed-off-by: r4sas --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 87329bf8..0778cd70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog -## [2.50.0] - 2023-12-23 +## [2.50.1] - 2023-12-23 ###Fixed - Support for new EdDSA usage behavior in OpenSSL 3.2.0 From 302af823a3509e5faa0e5cfcacdef2e480250d88 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Dec 2023 15:55:53 -0500 Subject: [PATCH 0364/1160] fixed race condition with openssl 3.2.0 --- libi2pd/Signature.cpp | 38 +++++++++++++++++++++++++------------- libi2pd/Signature.h | 2 -- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 60cdbec2..342b6d03 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -18,12 +18,10 @@ namespace crypto EDDSA25519Verifier::EDDSA25519Verifier (): m_Pkey (nullptr) { - m_MDCtx = EVP_MD_CTX_create (); } EDDSA25519Verifier::~EDDSA25519Verifier () { - EVP_MD_CTX_destroy (m_MDCtx); EVP_PKEY_free (m_Pkey); } @@ -35,8 +33,17 @@ namespace crypto bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { - EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); + if (m_Pkey) + { + EVP_MD_CTX * ctx = EVP_MD_CTX_create (); + EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, m_Pkey); + auto ret = EVP_DigestVerify (ctx, signature, 64, buf, len); + EVP_MD_CTX_destroy (ctx); + return ret; + } + else + LogPrint (eLogError, "EdDSA verification key is not set"); + return false; } #else @@ -101,7 +108,7 @@ namespace crypto #if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): - m_MDCtx (nullptr), m_Pkey (nullptr), m_Fallback (nullptr) + m_Pkey (nullptr), m_Fallback (nullptr) { m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; @@ -111,30 +118,35 @@ namespace crypto { LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); + EVP_PKEY_free (m_Pkey); + m_Pkey = nullptr; } - else - m_MDCtx = EVP_MD_CTX_create (); } EDDSA25519Signer::~EDDSA25519Signer () { if (m_Fallback) delete m_Fallback; - EVP_MD_CTX_destroy (m_MDCtx); - EVP_PKEY_free (m_Pkey); + if (m_Pkey) EVP_PKEY_free (m_Pkey); } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const { - if (m_Fallback) return m_Fallback->Sign (buf, len, signature); - else + if (m_Fallback) + return m_Fallback->Sign (buf, len, signature); + else if (m_Pkey) { + + EVP_MD_CTX * ctx = EVP_MD_CTX_create (); size_t l = 64; uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - if (!EVP_DigestSign (m_MDCtx, sig, &l, buf, len)) + EVP_DigestSignInit (ctx, NULL, NULL, NULL, m_Pkey); + if (!EVP_DigestSign (ctx, sig, &l, buf, len)) LogPrint (eLogError, "EdDSA signing failed"); memcpy (signature, sig, 64); + EVP_MD_CTX_destroy (ctx); } + else + LogPrint (eLogError, "EdDSA signing key is not set"); } #endif } diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 671ebfb7..8bd94357 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -304,7 +304,6 @@ namespace crypto private: #if OPENSSL_EDDSA - EVP_MD_CTX * m_MDCtx; EVP_PKEY * m_Pkey; #else EDDSAPoint m_PublicKey; @@ -342,7 +341,6 @@ namespace crypto private: - EVP_MD_CTX * m_MDCtx; EVP_PKEY * m_Pkey; EDDSA25519SignerCompat * m_Fallback; }; From d4c47d90cb308c9845888fcc746b30dcb1c96fdd Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Dec 2023 17:16:28 -0500 Subject: [PATCH 0365/1160] adjust time offset after second time discrepancy --- libi2pd/SSU2.cpp | 21 ++++++++++++++++++++- libi2pd/SSU2.h | 2 ++ libi2pd/SSU2Session.cpp | 7 +++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 7099ba0c..4448c1df 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -24,7 +24,8 @@ namespace transport m_AddressV4 (boost::asio::ip::address_v4()), m_AddressV6 (boost::asio::ip::address_v6()), m_TerminationTimer (GetService ()), m_CleanupTimer (GetService ()), m_ResendTimer (GetService ()), m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()), - m_IsPublished (true), m_IsSyncClockFromPeers (true), m_IsThroughProxy (false) + m_IsPublished (true), m_IsSyncClockFromPeers (true), m_PendingTimeOffset (0), + m_IsThroughProxy (false) { } @@ -209,6 +210,24 @@ namespace transport return ep.port (); } + void SSU2Server::AdjustTimeOffset (int64_t offset) + { + if (offset) + { + if (m_PendingTimeOffset) // one more + { + offset = (m_PendingTimeOffset + offset)/2; // average + LogPrint (eLogWarning, "SSU2: Clock adjusted by ", -offset, " seconds"); + i2p::util::AdjustTimeOffset (-offset); + m_PendingTimeOffset = 0; + } + else + m_PendingTimeOffset = offset; // first + } + else + m_PendingTimeOffset = 0; // reset + } + boost::asio::ip::udp::socket& SSU2Server::OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint) { boost::asio::ip::udp::socket& socket = localEndpoint.address ().is_v6 () ? m_SocketV6 : m_SocketV4; diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index a1fafc63..03e22245 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -66,6 +66,7 @@ namespace transport bool IsSupported (const boost::asio::ip::address& addr) const; uint16_t GetPort (bool v4) const; bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; }; + void AdjustTimeOffset (int64_t offset); void AddSession (std::shared_ptr session); void RemoveSession (uint64_t connID); @@ -161,6 +162,7 @@ namespace transport std::shared_ptr m_LastSession; bool m_IsPublished; // if we maintain introducers bool m_IsSyncClockFromPeers; + int64_t m_PendingTimeOffset; // during peer test // proxy bool m_IsThroughProxy; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 487d5549..bab9f2bb 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1668,10 +1668,7 @@ namespace transport if (m_Server.IsSyncClockFromPeers ()) { if (std::abs (offset) > SSU2_CLOCK_THRESHOLD) - { - LogPrint (eLogWarning, "SSU2: Clock adjusted by ", -offset, " seconds"); - i2p::util::AdjustTimeOffset (-offset); - } + m_Server.AdjustTimeOffset (-offset); } else if (std::abs (offset) > SSU2_CLOCK_SKEW) { @@ -2481,6 +2478,8 @@ namespace transport else if (m_Address->IsV6 ()) i2p::context.SetTestingV6 (testing); } + if (!testing) + m_Server.AdjustTimeOffset (0); // reset time offset when testing is over } size_t SSU2Session::CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep) From 8319dd6b25b62b085d3f9b2867e438cd204ed7fb Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Dec 2023 19:49:16 -0500 Subject: [PATCH 0366/1160] drop exploratory and leaseset lookups for non-floodfill router --- libi2pd/NetDb.cpp | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 07f0f341..9f186659 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1019,6 +1019,11 @@ namespace data std::shared_ptr replyMsg; if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP) { + if (!context.IsFloodfill ()) + { + LogPrint (eLogWarning, "NetDb: Exploratory lookup to non-floodfill dropped"); + return; + } LogPrint (eLogInfo, "NetDb: Exploratory close to ", key, " ", numExcluded, " excluded"); std::set excludedRouters; const uint8_t * excluded_ident = excluded; @@ -1044,6 +1049,7 @@ namespace data if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP) { + // try to find router auto router = FindRouter (ident); if (router && !router->IsUnreachable ()) { @@ -1056,17 +1062,26 @@ namespace data if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)) { - auto leaseSet = FindLeaseSet (ident); - if (!leaseSet) + // try to find leaseset + if (context.IsFloodfill ()) + { + auto leaseSet = FindLeaseSet (ident); + if (!leaseSet) + { + // no leaseset found + LogPrint(eLogDebug, "NetDb: Requested LeaseSet not found for ", ident.ToBase32()); + } + else if (!leaseSet->IsExpired ()) // we don't send back expired leasesets + { + LogPrint (eLogDebug, "NetDb: Requested LeaseSet ", key, " found"); + replyMsg = CreateDatabaseStoreMsg (ident, leaseSet); + } + } + else if (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP) { - // no lease set found - LogPrint(eLogDebug, "NetDb: Requested LeaseSet not found for ", ident.ToBase32()); - } - else if (!leaseSet->IsExpired ()) // we don't send back our LeaseSets - { - LogPrint (eLogDebug, "NetDb: Requested LeaseSet ", key, " found"); - replyMsg = CreateDatabaseStoreMsg (ident, leaseSet); - } + LogPrint (eLogWarning, "NetDb: Explicit LeaseSet lookup to non-floodfill dropped"); + return; + } } if (!replyMsg) From 21f41a2b2a39461a480b8539beb2f1c141bb8fe7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Dec 2023 10:14:24 -0500 Subject: [PATCH 0367/1160] correct time offset direction --- libi2pd/SSU2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 4448c1df..55eb0567 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -217,8 +217,8 @@ namespace transport if (m_PendingTimeOffset) // one more { offset = (m_PendingTimeOffset + offset)/2; // average - LogPrint (eLogWarning, "SSU2: Clock adjusted by ", -offset, " seconds"); - i2p::util::AdjustTimeOffset (-offset); + LogPrint (eLogWarning, "SSU2: Clock adjusted by ", offset, " seconds"); + i2p::util::AdjustTimeOffset (offset); m_PendingTimeOffset = 0; } else From b855c7189111a30ed5acdffe8d2d584c35b2fc61 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Dec 2023 14:39:59 -0500 Subject: [PATCH 0368/1160] don't adjust clock if time offsets are too different --- libi2pd/SSU2.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 55eb0567..6a8615d5 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -216,9 +216,14 @@ namespace transport { if (m_PendingTimeOffset) // one more { - offset = (m_PendingTimeOffset + offset)/2; // average - LogPrint (eLogWarning, "SSU2: Clock adjusted by ", offset, " seconds"); - i2p::util::AdjustTimeOffset (offset); + if (std::abs (m_PendingTimeOffset - offset) < SSU2_CLOCK_SKEW) + { + offset = (m_PendingTimeOffset + offset)/2; // average + LogPrint (eLogWarning, "SSU2: Clock adjusted by ", offset, " seconds"); + i2p::util::AdjustTimeOffset (offset); + } + else + LogPrint (eLogWarning, "SSU2: Time offsets are too different. Clock not adjusted"); m_PendingTimeOffset = 0; } else From c5cab05a6b8690f3fd2442054c1475e06dc43640 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Jan 2024 19:42:49 -0500 Subject: [PATCH 0369/1160] reset peding time offset if correct time was received --- libi2pd/SSU2Session.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index bab9f2bb..e5261622 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, The PurpleI2P Project +* Copyright (c) 2022-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1668,7 +1668,12 @@ namespace transport if (m_Server.IsSyncClockFromPeers ()) { if (std::abs (offset) > SSU2_CLOCK_THRESHOLD) + { + LogPrint (eLogWarning, "SSU2: Time offset ", offset, " from ", m_RemoteEndpoint); m_Server.AdjustTimeOffset (-offset); + } + else + m_Server.AdjustTimeOffset (0); } else if (std::abs (offset) > SSU2_CLOCK_SKEW) { From 577c71b930dddcc0ca74dcb4368aa2aea07486da Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Thu, 4 Jan 2024 21:35:25 +0200 Subject: [PATCH 0370/1160] Fix typos --- libi2pd/Datagram.h | 2 +- libi2pd/NTCP2.cpp | 2 +- libi2pd/RouterInfo.cpp | 2 +- libi2pd/TunnelPool.cpp | 2 +- libi2pd_client/UDPTunnel.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 8f3d5ceb..e6d1f7b6 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -150,7 +150,7 @@ namespace datagram void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); - /** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */ + /** find a receiver by port, if none by port is found try default receiver, otherwise returns nullptr */ Receiver FindReceiver(uint16_t port); private: diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 0a23f07e..f1a5e241 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1234,7 +1234,7 @@ namespace transport void NTCP2Session::SendLocalRouterInfo (bool update) { - if (update || !IsOutgoing ()) // we send it in SessionConfirmed for ougoing session + if (update || !IsOutgoing ()) // we send it in SessionConfirmed for outgoing session m_Server.GetService ().post (std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ())); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 63cb79ef..60f9a518 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -995,7 +995,7 @@ namespace data bool RouterInfo::IsPublished (bool v4) const { - if (m_Caps & (eUnreachable | eHidden)) return false; // if router sets U or H we assume that all addreses are not published + if (m_Caps & (eUnreachable | eHidden)) return false; // if router sets U or H we assume that all addresses are not published auto addr = GetAddresses (); if (v4) return ((*addr)[eNTCP2V4Idx] && ((*addr)[eNTCP2V4Idx])->published) || diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 23cc53e3..5339c9be 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -301,7 +301,7 @@ namespace tunnel { for (auto it: m_OutboundTunnels) { - // try to create inbound tunnel through the same path as succesive outbound + // try to create inbound tunnel through the same path as successive outbound CreatePairedInboundTunnel (it); num++; if (num >= m_NumInboundTunnels) break; diff --git a/libi2pd_client/UDPTunnel.h b/libi2pd_client/UDPTunnel.h index 862ce216..3233c3f0 100644 --- a/libi2pd_client/UDPTunnel.h +++ b/libi2pd_client/UDPTunnel.h @@ -72,7 +72,7 @@ namespace client boost::asio::ip::udp::endpoint LocalEndpoint; /** client's udp endpoint */ boost::asio::ip::udp::endpoint RemoteEndpoint; - /** how long has this converstation been idle in ms */ + /** how long has this conversation been idle in ms */ uint64_t idle; }; From 5cf1961fa4910ad7b5bd1298bfe723af50b5ccb5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Jan 2024 11:31:01 -0500 Subject: [PATCH 0371/1160] drop updated routers from future --- libi2pd/NetDb.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9f186659..6e023c45 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -247,9 +247,10 @@ namespace data m_Requests.RequestComplete (ident, r); return r; } - if (r->IsUnreachable ()) + if (r->IsUnreachable () || + i2p::util::GetMillisecondsSinceEpoch () + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < r->GetTimestamp ()) { - // delete router as invalid after update + // delete router as invalid or from future after update m_RouterInfos.erase (ident); if (wasFloodfill) { From a8135b8d1820281d18d96cf2fa87e65c55350356 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Jan 2024 14:51:42 -0500 Subject: [PATCH 0372/1160] 2.50.2 --- libi2pd/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/version.h b/libi2pd/version.h index c79e3a2b..7b9e20c8 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,7 +19,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 50 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MICRO 2 #define I2PD_VERSION_PATCH 0 #ifdef GITVER #define I2PD_VERSION XSTRINGIZE(GITVER) From 3b97feb89fdc310ab43cc9336e1817f5b17f4b82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Jan 2024 15:07:51 -0500 Subject: [PATCH 0373/1160] 2.50.2 --- ChangeLog | 5 +++++ contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0778cd70..6534a9b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.50.2] - 2024-01-06 +###Fixed +- Crash with OpenSSL 3.2.0 +- False positive clock skew detection + ## [2.50.1] - 2023-12-23 ###Fixed - Support for new EdDSA usage behavior in OpenSSL 3.2.0 diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index ab5b4190..0bc46eab 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.50.1 +Version: 2.50.2 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -144,6 +144,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Jan 06 2024 orignal - 2.50.2 +- update to 2.50.2 + * Sat Dec 23 2023 r4sas - 2.50.1 - update to 2.50.1 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 74cc826d..1de4076e 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.50.1 +Version: 2.50.2 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -142,6 +142,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Sat Jan 06 2024 orignal - 2.50.2 +- update to 2.50.2 + * Sat Dec 23 2023 r4sas - 2.50.1 - update to 2.50.1 diff --git a/debian/changelog b/debian/changelog index 5484fd92..56ab7c16 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.50.2) unstable; urgency=medium + + * updated to version 2.50.2/0.9.61 + +-- orignal Sat, 06 Jan 2024 16:00:00 +0000 + i2pd (2.50.1-1) unstable; urgency=medium * updated to version 2.50.1/0.9.61 From 8bc58daa5a63a12f88b3fb454ee297e37e1ec48a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Jan 2024 18:42:34 -0500 Subject: [PATCH 0374/1160] fixed #2004. Check supported crypto --- libi2pd_client/SAM.cpp | 56 +++++++++++++++++++++++++----------------- libi2pd_client/SAM.h | 6 +++-- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index ffdeb5ac..775b9411 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -550,17 +550,22 @@ namespace client if (!session) session = m_Owner.FindSession(m_ID); if (session) { - m_SocketType = eSAMSocketTypeStream; - m_Stream = session->GetLocalDestination ()->CreateStream (remote); - if (m_Stream) - { - m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send - m_BufferOffset = 0; - I2PReceive (); - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + if (session->GetLocalDestination ()->SupportsEncryptionType (remote->GetEncryptionType ())) + { + m_SocketType = eSAMSocketTypeStream; + m_Stream = session->GetLocalDestination ()->CreateStream (remote); + if (m_Stream) + { + m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send + m_BufferOffset = 0; + I2PReceive (); + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } else - SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); + SendStreamCantReachPeer ("Incompatible crypto"); } else SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); @@ -573,7 +578,7 @@ namespace client else { LogPrint (eLogError, "SAM: Destination to connect not found"); - SendMessageReply (SAM_STREAM_STATUS_CANT_REACH_PEER, strlen(SAM_STREAM_STATUS_CANT_REACH_PEER), true); + SendStreamCantReachPeer ("LeaseSet not found"); } } @@ -857,27 +862,32 @@ namespace client SendSessionI2PError ("Wrong session type"); } + void SAMSocket::SendReplyWithMessage (const char * reply, const std::string & msg) + { +#ifdef _MSC_VER + size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, reply, msg.c_str()); +#else + size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, reply, msg.c_str()); +#endif + SendMessageReply (m_Buffer, len, true); + } + void SAMSocket::SendSessionI2PError(const std::string & msg) { LogPrint (eLogError, "SAM: Session I2P error: ", msg); -#ifdef _MSC_VER - size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str()); -#else - size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str()); -#endif - SendMessageReply (m_Buffer, len, true); + SendReplyWithMessage (SAM_SESSION_STATUS_I2P_ERROR, msg); } void SAMSocket::SendStreamI2PError(const std::string & msg) { LogPrint (eLogError, "SAM: Stream I2P error: ", msg); -#ifdef _MSC_VER - size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_STREAM_STATUS_I2P_ERROR, msg.c_str()); -#else - size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_STREAM_STATUS_I2P_ERROR, msg.c_str()); -#endif - SendMessageReply (m_Buffer, len, true); + SendReplyWithMessage (SAM_STREAM_STATUS_I2P_ERROR, msg); } + + void SAMSocket::SendStreamCantReachPeer(const std::string & msg) + { + SendReplyWithMessage (SAM_STREAM_STATUS_CANT_REACH_PEER, msg); + } void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name) { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 34af5a62..3ed8f00c 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -51,7 +51,7 @@ namespace client const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n"; const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n"; const char SAM_STREAM_STATUS_INVALID_KEY[] = "STREAM STATUS RESULT=INVALID_KEY\n"; - const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER\n"; + const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER MESSAGE=\"%s\"\n"; const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"%s\"\n"; const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT"; const char SAM_STREAM_FORWARD[] = "STREAM FORWARD"; @@ -144,8 +144,10 @@ namespace client void ProcessNamingLookup (char * buf, size_t len); void ProcessSessionAdd (char * buf, size_t len); void ProcessSessionRemove (char * buf, size_t len); + void SendReplyWithMessage (const char * reply, const std::string & msg); void SendSessionI2PError(const std::string & msg); void SendStreamI2PError(const std::string & msg); + void SendStreamCantReachPeer(const std::string & msg); size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 void ExtractParams (char * buf, std::map& params); From 1e9bcd6b8b228aeed713f1d1714809409e97633a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Jan 2024 16:36:14 +0300 Subject: [PATCH 0375/1160] [gha] MSVC: Switch to direct Boost and OpenSSL installation --- .github/workflows/build-windows-msvc.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index 172e0596..a077d626 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -26,15 +26,27 @@ jobs: ./install_zlib.bat del install_zlib.bat + #- name: Install Boost + # uses: crazy-max/ghaction-chocolatey@v2 + # with: + # args: install boost-msvc-14.3 --version=1.81.0 + + #- name: Install OpenSSL + # uses: crazy-max/ghaction-chocolatey@v2 + # with: + # args: install openssl + - name: Install Boost - uses: crazy-max/ghaction-chocolatey@v2 - with: - args: install boost-msvc-14.3 --version=1.81.0 + run: | + powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.84.0/boost_1_84_0-msvc-14.3-64.exe/download -OutFile boost_1_84_0-msvc-14.3-64.exe)" + ./boost_1_84_0-msvc-14.3-64.exe /VERYSILENT + del boost_1_84_0-msvc-14.3-64.exe - name: Install OpenSSL - uses: crazy-max/ghaction-chocolatey@v2 - with: - args: install openssl + run: | + powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://slproweb.com/download/Win64OpenSSL-3_2_0.exe -OutFile Win64OpenSSL-3_2_0.exe)" + ./Win64OpenSSL-3_2_0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- + del Win64OpenSSL-3_2_0.exe - name: Configure working-directory: build From dfe8b25e5ec2d0533584bf03cf0d1289bc1ca71d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Jan 2024 17:05:36 +0300 Subject: [PATCH 0376/1160] [gha] MSVC: remove deletion of installation files --- .github/workflows/build-windows-msvc.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index a077d626..5af526e2 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -40,13 +40,11 @@ jobs: run: | powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.84.0/boost_1_84_0-msvc-14.3-64.exe/download -OutFile boost_1_84_0-msvc-14.3-64.exe)" ./boost_1_84_0-msvc-14.3-64.exe /VERYSILENT - del boost_1_84_0-msvc-14.3-64.exe - name: Install OpenSSL run: | powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://slproweb.com/download/Win64OpenSSL-3_2_0.exe -OutFile Win64OpenSSL-3_2_0.exe)" ./Win64OpenSSL-3_2_0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- - del Win64OpenSSL-3_2_0.exe - name: Configure working-directory: build From cd087568b55161767c6094f86054d4976e137209 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jan 2024 21:02:11 -0500 Subject: [PATCH 0377/1160] reply with CANT_REACH_PEER if connect to outselves --- libi2pd_client/SAM.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 775b9411..1a3afb58 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -523,15 +523,20 @@ namespace client { if (addr->IsIdentHash ()) { - auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash); - if (leaseSet) - Connect(leaseSet, session); - else - { - session->GetLocalDestination ()->RequestDestination(addr->identHash, - std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, - shared_from_this(), std::placeholders::_1)); + if (session->GetLocalDestination ()->GetIdentHash () != addr->identHash) + { + auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash); + if (leaseSet) + Connect(leaseSet, session); + else + { + session->GetLocalDestination ()->RequestDestination(addr->identHash, + std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, + shared_from_this(), std::placeholders::_1)); + } } + else + SendStreamCantReachPeer ("Can't connect to myself"); } else // B33 session->GetLocalDestination ()->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, From 2ad26dd4c9def4cf05e144f65793323187a2b830 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Jan 2024 14:09:08 -0500 Subject: [PATCH 0378/1160] fixed race condition in ECIESx25519 tags table --- libi2pd/RouterContext.cpp | 22 +++++++++++++++++++++- libi2pd/RouterContext.h | 1 + libi2pd/Tunnel.cpp | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index f21c0592..10d33bf5 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1199,7 +1199,27 @@ namespace i2p else i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); } - + + void RouterContext::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag) + { + if (m_Service) + { + struct + { + uint8_t k[32]; + uint64_t t; + } data; + memcpy (data.k, key, 32); + data.t = tag; + m_Service->GetService ().post ([this,data](void) + { + AddECIESx25519Key (data.k, data.t); + }); + } + else + LogPrint (eLogError, "Router: service is NULL"); + } + void RouterContext::CleanupDestination () { if (m_Service) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index d49b5523..91a553ba 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -136,6 +136,7 @@ namespace garlic void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data); bool DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data); + void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag); void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU2 or Daemon diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 6234ceb4..b8e17920 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -116,7 +116,7 @@ namespace tunnel if (m_Pool && m_Pool->GetLocalDestination ()) m_Pool->GetLocalDestination ()->SubmitECIESx25519Key (key, tag); else - i2p::context.AddECIESx25519Key (key, tag); + i2p::context.SubmitECIESx25519Key (key, tag); } i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); } From ca9782dd0d4ad8116035352f22524b4f3ee77633 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Jan 2024 15:39:42 -0500 Subject: [PATCH 0379/1160] handle 'reservedrange' param properly --- daemon/Daemon.cpp | 4 +--- libi2pd/NTCP2.cpp | 4 ++-- libi2pd/Reseed.cpp | 24 +++++++++++------------- libi2pd/RouterInfo.cpp | 5 +++-- libi2pd/SSU2.cpp | 8 ++++---- libi2pd/SSU2Session.cpp | 4 ++-- libi2pd/Transports.cpp | 13 ++++++++++--- libi2pd/Transports.h | 5 +++-- 8 files changed, 36 insertions(+), 31 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index f04236fe..308daa4c 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -298,12 +298,10 @@ namespace util bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); - bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved); LogPrint(eLogInfo, "Daemon: Starting Transports"); if(!ssu2) LogPrint(eLogInfo, "Daemon: SSU2 disabled"); if(!ntcp2) LogPrint(eLogInfo, "Daemon: NTCP2 disabled"); - i2p::transport::transports.SetCheckReserved(checkInReserved); i2p::transport::transports.Start(ntcp2, ssu2); if (i2p::transport::transports.IsBoundSSU2() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index f1a5e241..efc317c2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1490,7 +1490,7 @@ namespace transport if (!ec) { LogPrint (eLogDebug, "NTCP2: Connected from ", ep); - if (!i2p::util::net::IsInReservedRange(ep.address ())) + if (!i2p::transport::transports.IsInReservedRange(ep.address ())) { if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) { @@ -1537,7 +1537,7 @@ namespace transport if (!ec) { LogPrint (eLogDebug, "NTCP2: Connected from ", ep); - if (!i2p::util::net::IsInReservedRange(ep.address ()) || + if (!i2p::transport::transports.IsInReservedRange(ep.address ()) || i2p::util::net::IsYggdrasilAddress (ep.address ())) { if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 28e4db24..5fdc2fae 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -687,18 +687,16 @@ namespace data while (it != end) { boost::asio::ip::tcp::endpoint ep = *it; - if ( - ( - !i2p::util::net::IsInReservedRange(ep.address ()) && ( - (ep.address ().is_v4 () && i2p::context.SupportsV4 ()) || - (ep.address ().is_v6 () && i2p::context.SupportsV6 ()) - ) - ) || - ( - i2p::util::net::IsYggdrasilAddress (ep.address ()) && - i2p::context.SupportsMesh () - ) - ) + bool supported = false; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + supported = i2p::context.SupportsV4 (); + else if (ep.address ().is_v6 ()) + supported = i2p::util::net::IsYggdrasilAddress (ep.address ()) ? + i2p::context.SupportsMesh () : i2p::context.SupportsV6 (); + } + if (supported) { s.lowest_layer().connect (ep, ecode); if (!ecode) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 60f9a518..7cde7c33 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -21,6 +21,7 @@ #include "Base.h" #include "Timestamp.h" #include "Log.h" +#include "Transports.h" #include "NetDb.hpp" #include "RouterContext.h" #include "RouterInfo.h" @@ -253,7 +254,7 @@ namespace data address->host = boost::asio::ip::address::from_string (value, ecode); if (!ecode && !address->host.is_unspecified ()) { - if (!i2p::util::net::IsInReservedRange (address->host) || + if (!i2p::transport::transports.IsInReservedRange (address->host) || i2p::util::net::IsYggdrasilAddress (address->host)) isHost = true; else diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 6a8615d5..1503b404 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, The PurpleI2P Project +* Copyright (c) 2022-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -566,7 +566,7 @@ namespace transport else it1->second->ProcessRetry (buf, len); } - else if (!i2p::util::net::IsInReservedRange(senderEndpoint.address ()) && senderEndpoint.port ()) + else if (!i2p::transport::transports.IsInReservedRange(senderEndpoint.address ()) && senderEndpoint.port ()) { // assume new incoming session auto session = std::make_shared (*this); @@ -666,7 +666,7 @@ namespace transport bool isValidEndpoint = !address->host.is_unspecified () && address->port; if (isValidEndpoint) { - if (i2p::util::net::IsInReservedRange(address->host)) return false; + if (i2p::transport::transports.IsInReservedRange(address->host)) return false; auto s = FindPendingOutgoingSession (boost::asio::ip::udp::endpoint (address->host, address->port)); if (s) { @@ -753,7 +753,7 @@ namespace transport if (addr) { bool isValidEndpoint = !addr->host.is_unspecified () && addr->port && - !i2p::util::net::IsInReservedRange(addr->host); + !i2p::transport::transports.IsInReservedRange(addr->host); if (isValidEndpoint) { auto s = FindPendingOutgoingSession (boost::asio::ip::udp::endpoint (addr->host, addr->port)); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index e5261622..8cb39102 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1471,7 +1471,7 @@ namespace transport ResendHandshakePacket (); // assume we receive return; } - if (from != m_RemoteEndpoint && !i2p::util::net::IsInReservedRange (from.address ())) + if (from != m_RemoteEndpoint && !i2p::transport::transports.IsInReservedRange (from.address ())) { LogPrint (eLogInfo, "SSU2: Remote endpoint update ", m_RemoteEndpoint, "->", from); m_RemoteEndpoint = from; @@ -1753,7 +1753,7 @@ namespace transport if (ExtractEndpoint (buf, len, ep)) { LogPrint (eLogInfo, "SSU2: Our external address is ", ep); - if (!i2p::util::net::IsInReservedRange (ep.address ())) + if (!i2p::transport::transports.IsInReservedRange (ep.address ())) { i2p::context.UpdateAddress (ep.address ()); // check our port diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b6e2e261..318d410f 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -505,7 +505,7 @@ namespace transport if (!m_NTCP2Server) continue; std::shared_ptr address = (tr == i2p::data::RouterInfo::eNTCP2V6) ? peer.router->GetPublishedNTCP2V6Address () : peer.router->GetPublishedNTCP2V4Address (); - if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) + if (address && IsInReservedRange(address->host)) address = nullptr; if (address) { @@ -524,7 +524,7 @@ namespace transport if (!m_SSU2Server) continue; std::shared_ptr address = (tr == i2p::data::RouterInfo::eSSU2V6) ? peer.router->GetSSU2V6Address () : peer.router->GetSSU2V4Address (); - if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) + if (address && IsInReservedRange(address->host)) address = nullptr; if (address && address->IsReachableSSU ()) { @@ -1084,6 +1084,11 @@ namespace transport } } + bool Transports::IsInReservedRange (const boost::asio::ip::address& host) const + { + return IsCheckReserved () && i2p::util::net::IsInReservedRange (host); + } + void InitAddressFromIface () { bool ipv6; i2p::config::GetOption("ipv6", ipv6); @@ -1196,6 +1201,8 @@ namespace transport i2p::context.PublishSSU2Address (ssu2port, false, ipv4, ipv6); // unpublish } + bool checkReserved; i2p::config::GetOption("reservedrange", checkReserved); + transports.SetCheckReserved (checkReserved); } } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index cb63ca91..7ef7f9b2 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -167,7 +167,8 @@ namespace transport void PeerTest (bool ipv4 = true, bool ipv6 = true); void SetCheckReserved (bool check) { m_CheckReserved = check; }; - bool IsCheckReserved () { return m_CheckReserved; }; + bool IsCheckReserved () const { return m_CheckReserved; }; + bool IsInReservedRange (const boost::asio::ip::address& host) const; private: From 34d75b08ddac5a3655dab2f89793528562af30d2 Mon Sep 17 00:00:00 2001 From: Vort Date: Fri, 12 Jan 2024 17:13:07 +0200 Subject: [PATCH 0380/1160] handle 'reservedrange' param properly --- daemon/Daemon.cpp | 4 ++++ libi2pd/Transports.cpp | 3 --- libi2pd/api.cpp | 5 ++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 308daa4c..17d17f72 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -160,6 +160,10 @@ namespace util int netID; i2p::config::GetOption("netid", netID); i2p::context.SetNetID (netID); + + bool checkReserved; i2p::config::GetOption("reservedrange", checkReserved); + i2p::transport::transports.SetCheckReserved(checkReserved); + i2p::context.Init (); i2p::transport::InitTransports (); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 318d410f..0bd17104 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1200,9 +1200,6 @@ namespace transport else i2p::context.PublishSSU2Address (ssu2port, false, ipv4, ipv6); // unpublish } - - bool checkReserved; i2p::config::GetOption("reservedrange", checkReserved); - transports.SetCheckReserved (checkReserved); } } } diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index ad24519f..05f962f3 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -44,6 +44,9 @@ namespace api int netID; i2p::config::GetOption("netid", netID); i2p::context.SetNetID (netID); + bool checkReserved; i2p::config::GetOption("reservedrange", checkReserved); + i2p::transport::transports.SetCheckReserved(checkReserved); + i2p::context.Init (); } From d8f6c4a93dc1722463754eb5c1670a4bab2f2304 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Jan 2024 17:16:31 -0500 Subject: [PATCH 0381/1160] correct encryption and path for follow on lookup request --- libi2pd/NetDb.cpp | 42 +++-------------- libi2pd/NetDbRequests.cpp | 94 +++++++++++++++++++++++++-------------- libi2pd/NetDbRequests.h | 24 ++++++---- 3 files changed, 83 insertions(+), 77 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 6e023c45..8eb5d653 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -721,7 +721,7 @@ namespace data void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) { - auto dest = m_Requests.CreateRequest (destination, false, requestComplete); // non-exploratory + auto dest = m_Requests.CreateRequest (destination, false, direct, requestComplete); // non-exploratory if (!dest) { LogPrint (eLogWarning, "NetDb: Destination ", destination.ToBase64(), " is requested already"); @@ -761,10 +761,10 @@ namespace data } } - void NetDb::RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete) + void NetDb::RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploratory, RequestedDestination::RequestComplete requestComplete) { - auto dest = m_Requests.CreateRequest (destination, exploritory, requestComplete); // non-exploratory + auto dest = m_Requests.CreateRequest (destination, exploratory, true, requestComplete); // non-exploratory if (!dest) { LogPrint (eLogWarning, "NetDb: Destination ", destination.ToBase64(), " is requested already"); @@ -919,39 +919,9 @@ namespace data auto dest = m_Requests.FindRequest (ident); if (dest) { - bool deleteDest = true; if (num > 0) - { - auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; - auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr; - if (!dest->IsExploratory ()) - { - // reply to our destination. Try other floodfills - if (outbound && inbound) - { - auto count = dest->GetExcludedPeers ().size (); - if (count < 7) - { - auto nextFloodfill = GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); - if (nextFloodfill) - { - // request destination - LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); - outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, - dest->CreateRequestMessage (nextFloodfill, inbound)); - deleteDest = false; - } - } - else - LogPrint (eLogWarning, "NetDb: ", key, " was not found on ", count, " floodfills"); - } - } - - if (deleteDest) - // no more requests for the destinationation. delete it - m_Requests.RequestComplete (ident, nullptr); - } + // try to send next requests + m_Requests.SendNextRequest (dest); else // no more requests for destination possible. delete it m_Requests.RequestComplete (ident, nullptr); @@ -1156,7 +1126,7 @@ namespace data for (int i = 0; i < numDestinations; i++) { RAND_bytes (randomHash, 32); - auto dest = m_Requests.CreateRequest (randomHash, true); // exploratory + auto dest = m_Requests.CreateRequest (randomHash, true, !throughTunnels); // exploratory if (!dest) { LogPrint (eLogWarning, "NetDb: Exploratory destination is requested already"); diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 4011b8aa..2cb578e2 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,6 +11,7 @@ #include "Transports.h" #include "NetDb.hpp" #include "NetDbRequests.h" +#include "ECIESX25519AEADRatchetSession.h" namespace i2p { @@ -74,14 +75,15 @@ namespace data } - std::shared_ptr NetDbRequests::CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete) + std::shared_ptr NetDbRequests::CreateRequest (const IdentHash& destination, + bool isExploratory, bool direct, RequestedDestination::RequestComplete requestComplete) { // request RouterInfo directly - auto dest = std::make_shared (destination, isExploratory); + auto dest = std::make_shared (destination, isExploratory, direct); dest->SetRequestComplete (requestComplete); { - std::unique_lock l(m_RequestedDestinationsMutex); - if (!m_RequestedDestinations.insert (std::make_pair (destination, dest)).second) // not inserted + std::unique_lock l(m_RequestedDestinationsMutex); + if (!m_RequestedDestinations.emplace (destination, dest).second) // not inserted return nullptr; } return dest; @@ -125,35 +127,10 @@ namespace data { auto& dest = it->second; bool done = false; - if (ts < dest->GetCreationTime () + 60) // request is worthless after 1 minute + if (ts < dest->GetCreationTime () + MAX_REQUEST_TIME) // request becomes worthless { - if (ts > dest->GetCreationTime () + 5) // no response for 5 seconds - { - auto count = dest->GetExcludedPeers ().size (); - if (!dest->IsExploratory () && count < 7) - { - auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = pool->GetNextOutboundTunnel (); - auto inbound = pool->GetNextInboundTunnel (); - auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); - if (nextFloodfill && outbound && inbound) - outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, - dest->CreateRequestMessage (nextFloodfill, inbound)); - else - { - done = true; - if (!inbound) LogPrint (eLogWarning, "NetDbReq: No inbound tunnels"); - if (!outbound) LogPrint (eLogWarning, "NetDbReq: No outbound tunnels"); - if (!nextFloodfill) LogPrint (eLogWarning, "NetDbReq: No more floodfills"); - } - } - else - { - if (!dest->IsExploratory ()) - LogPrint (eLogWarning, "NetDbReq: ", dest->GetDestination ().ToBase64 (), " not found after 7 attempts"); - done = true; - } - } + if (ts > dest->GetCreationTime () + MIN_REQUEST_TIME) // retry in no response after min interval + done = !SendNextRequest (dest); } else // delete obsolete request done = true; @@ -164,5 +141,56 @@ namespace data ++it; } } + + bool NetDbRequests::SendNextRequest (std::shared_ptr dest) + { + if (!dest) return false; + bool ret = true; + auto count = dest->GetExcludedPeers ().size (); + if (!dest->IsExploratory () && count < MAX_NUM_REQUEST_ATTEMPTS) + { + auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); + if (nextFloodfill) + { + bool direct = dest->IsDirect (); + if (direct && !nextFloodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) && + !i2p::transport::transports.IsConnected (nextFloodfill->GetIdentHash ())) + direct = false; // floodfill can't be reached directly + if (direct) + i2p::transport::transports.SendMessage (nextFloodfill->GetIdentHash (), dest->CreateRequestMessage (nextFloodfill->GetIdentHash ())); + else + { + auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = pool->GetNextOutboundTunnel (); + auto inbound = pool->GetNextInboundTunnel (); + if (nextFloodfill && outbound && inbound) + { + LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); + auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); + outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, + i2p::garlic::WrapECIESX25519MessageForRouter (msg, nextFloodfill->GetIdentity ()->GetEncryptionPublicKey ())); + } + else + { + ret = false; + if (!inbound) LogPrint (eLogWarning, "NetDbReq: No inbound tunnels"); + if (!outbound) LogPrint (eLogWarning, "NetDbReq: No outbound tunnels"); + } + } + } + else + { + ret = false; + if (!nextFloodfill) LogPrint (eLogWarning, "NetDbReq: No more floodfills"); + } + } + else + { + if (!dest->IsExploratory ()) + LogPrint (eLogWarning, "NetDbReq: ", dest->GetDestination ().ToBase64 (), " not found after 7 attempts"); + ret = false; + } + return ret; + } } } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index cf2f0915..a4d1cf21 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -9,9 +9,10 @@ #ifndef NETDB_REQUESTS_H__ #define NETDB_REQUESTS_H__ +#include #include #include -#include +#include #include "Identity.h" #include "RouterInfo.h" @@ -19,14 +20,18 @@ namespace i2p { namespace data { + const size_t MAX_NUM_REQUEST_ATTEMPTS = 7; + const uint64_t MIN_REQUEST_TIME = 5; // in seconds + const uint64_t MAX_REQUEST_TIME = 60; // in seconds + class RequestedDestination { public: typedef std::function)> RequestComplete; - RequestedDestination (const IdentHash& destination, bool isExploratory = false): - m_Destination (destination), m_IsExploratory (isExploratory), m_CreationTime (0) {}; + RequestedDestination (const IdentHash& destination, bool isExploratory = false, bool direct = true): + m_Destination (destination), m_IsExploratory (isExploratory), m_IsDirect (direct), m_CreationTime (0) {}; ~RequestedDestination () { if (m_RequestComplete) m_RequestComplete (nullptr); }; const IdentHash& GetDestination () const { return m_Destination; }; @@ -34,6 +39,7 @@ namespace data const std::set& GetExcludedPeers () { return m_ExcludedPeers; }; void ClearExcludedPeers (); bool IsExploratory () const { return m_IsExploratory; }; + bool IsDirect () const { return m_IsDirect; }; bool IsExcluded (const IdentHash& ident) const { return m_ExcludedPeers.count (ident); }; uint64_t GetCreationTime () const { return m_CreationTime; }; std::shared_ptr CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); @@ -47,7 +53,7 @@ namespace data private: IdentHash m_Destination; - bool m_IsExploratory; + bool m_IsExploratory, m_IsDirect; std::set m_ExcludedPeers; uint64_t m_CreationTime; RequestComplete m_RequestComplete; @@ -60,15 +66,17 @@ namespace data void Start (); void Stop (); - std::shared_ptr CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr); + std::shared_ptr CreateRequest (const IdentHash& destination, bool isExploratory, + bool direct = false, RequestedDestination::RequestComplete requestComplete = nullptr); void RequestComplete (const IdentHash& ident, std::shared_ptr r); std::shared_ptr FindRequest (const IdentHash& ident) const; void ManageRequests (); - + bool SendNextRequest (std::shared_ptr dest); + private: mutable std::mutex m_RequestedDestinationsMutex; - std::map > m_RequestedDestinations; + std::unordered_map > m_RequestedDestinations; }; } } From 4afdca090d33ba2d2bb390e46637ba42aa42fc5d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Jan 2024 18:54:21 -0500 Subject: [PATCH 0382/1160] support multiple RouterInfo request callbacks --- libi2pd/NetDbRequests.cpp | 20 +++++++++++++++++++- libi2pd/NetDbRequests.h | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 2cb578e2..167095d7 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -83,8 +83,26 @@ namespace data dest->SetRequestComplete (requestComplete); { std::unique_lock l(m_RequestedDestinationsMutex); - if (!m_RequestedDestinations.emplace (destination, dest).second) // not inserted + auto ret = m_RequestedDestinations.emplace (destination, dest); + if (!ret.second) // not inserted + { + dest->SetRequestComplete (nullptr); // don't call requestComplete in destructor + if (requestComplete) + { + auto prev = ret.first->second->GetRequestComplete (); + if (prev) // if already set + ret.first->second->SetRequestComplete ( + [requestComplete, prev](std::shared_ptr r) + { + prev (r); // call previous + requestComplete (r); // then new + }); + else + ret.first->second->SetRequestComplete (requestComplete); + } + return nullptr; + } } return dest; } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index a4d1cf21..001b0f07 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -46,6 +46,7 @@ namespace data std::shared_ptr CreateRequestMessage (const IdentHash& floodfill); void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; }; + RequestComplete GetRequestComplete () const { return m_RequestComplete; }; bool IsRequestComplete () const { return m_RequestComplete != nullptr; }; void Success (std::shared_ptr r); void Fail (); From 49f4dc53adf1c3d464f4d9baaae3c49dfe6ae8af Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 15 Jan 2024 19:32:17 -0500 Subject: [PATCH 0383/1160] try next floodfill for router request on demand --- libi2pd/NetDbRequests.cpp | 21 +++++++++++++++++---- libi2pd/NetDbRequests.h | 8 ++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 167095d7..92e5a7b8 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -17,6 +17,17 @@ namespace i2p { namespace data { + RequestedDestination::RequestedDestination (const IdentHash& destination, bool isExploratory, bool direct): + m_Destination (destination), m_IsExploratory (isExploratory), m_IsDirect (direct), + m_CreationTime (i2p::util::GetSecondsSinceEpoch ()), m_LastRequestTime (0) + { + } + + RequestedDestination::~RequestedDestination () + { + if (m_RequestComplete) m_RequestComplete (nullptr); + } + std::shared_ptr RequestedDestination::CreateRequestMessage (std::shared_ptr router, std::shared_ptr replyTunnel) { @@ -29,7 +40,7 @@ namespace data msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers); if(router) m_ExcludedPeers.insert (router->GetIdentHash ()); - m_CreationTime = i2p::util::GetSecondsSinceEpoch (); + m_LastRequestTime = i2p::util::GetSecondsSinceEpoch (); return msg; } @@ -38,7 +49,7 @@ namespace data auto msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, i2p::context.GetRouterInfo ().GetIdentHash () , 0, false, &m_ExcludedPeers); m_ExcludedPeers.insert (floodfill); - m_CreationTime = i2p::util::GetSecondsSinceEpoch (); + m_LastRequestTime = i2p::util::GetSecondsSinceEpoch (); return msg; } @@ -100,7 +111,9 @@ namespace data else ret.first->second->SetRequestComplete (requestComplete); } - + if (i2p::util::GetSecondsSinceEpoch () > ret.first->second->GetLastRequestTime () + MIN_REQUEST_TIME) + if (!SendNextRequest (ret.first->second)) // try next floodfill + m_RequestedDestinations.erase (ret.first); // delete request if failed return nullptr; } } @@ -147,7 +160,7 @@ namespace data bool done = false; if (ts < dest->GetCreationTime () + MAX_REQUEST_TIME) // request becomes worthless { - if (ts > dest->GetCreationTime () + MIN_REQUEST_TIME) // retry in no response after min interval + if (ts > dest->GetLastRequestTime () + MIN_REQUEST_TIME) // try next floodfill if no response after min interval done = !SendNextRequest (dest); } else // delete obsolete request diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 001b0f07..47a5d481 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -30,9 +30,8 @@ namespace data typedef std::function)> RequestComplete; - RequestedDestination (const IdentHash& destination, bool isExploratory = false, bool direct = true): - m_Destination (destination), m_IsExploratory (isExploratory), m_IsDirect (direct), m_CreationTime (0) {}; - ~RequestedDestination () { if (m_RequestComplete) m_RequestComplete (nullptr); }; + RequestedDestination (const IdentHash& destination, bool isExploratory = false, bool direct = true); + ~RequestedDestination (); const IdentHash& GetDestination () const { return m_Destination; }; int GetNumExcludedPeers () const { return m_ExcludedPeers.size (); }; @@ -42,6 +41,7 @@ namespace data bool IsDirect () const { return m_IsDirect; }; bool IsExcluded (const IdentHash& ident) const { return m_ExcludedPeers.count (ident); }; uint64_t GetCreationTime () const { return m_CreationTime; }; + uint64_t GetLastRequestTime () const { return m_LastRequestTime; }; std::shared_ptr CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); std::shared_ptr CreateRequestMessage (const IdentHash& floodfill); @@ -56,7 +56,7 @@ namespace data IdentHash m_Destination; bool m_IsExploratory, m_IsDirect; std::set m_ExcludedPeers; - uint64_t m_CreationTime; + uint64_t m_CreationTime, m_LastRequestTime; // in seconds RequestComplete m_RequestComplete; }; From 7cfcb12c7b0f3e9c3f6408c404b22e0a3e3e53bf Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jan 2024 14:33:36 -0500 Subject: [PATCH 0384/1160] don't create peer for unreachable router --- libi2pd/Transports.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 0bd17104..eb836354 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -436,6 +436,10 @@ namespace transport auto it = m_Peers.find (ident); if (it == m_Peers.end ()) { + // check if not known as unreachable + auto profile = i2p::data::GetRouterProfile (ident); + if (profile && profile->IsUnreachable ()) return; // don't create peer to unreachable router + // try to connect bool connected = false; try { From 39e378a03dda77cb380182c1c0c192478caa44e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jan 2024 18:15:49 -0500 Subject: [PATCH 0385/1160] check received data size --- libi2pd/NTCP2.cpp | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index efc317c2..c52c5cc2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -809,10 +809,15 @@ namespace transport void NTCP2Session::HandleReceivedLength (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode) + if (ecode || bytes_transferred != 2) { if (ecode != boost::asio::error::operation_aborted) - LogPrint (eLogWarning, "NTCP2: Receive length read error: ", ecode.message ()); + { + if (ecode) + LogPrint (eLogWarning, "NTCP2: Receive length read error: ", ecode.message ()); + else if (bytes_transferred != 2) + LogPrint (eLogError, "NTCP2: Receive length of ", bytes_transferred, " bytes"); + } Terminate (); } else @@ -833,14 +838,19 @@ namespace transport CreateNextReceivedBuffer (m_NextReceivedLen); boost::system::error_code ec; size_t moreBytes = m_Socket.available(ec); - if (!ec && moreBytes >= m_NextReceivedLen) - { - // read and process message immediately if available - moreBytes = boost::asio::read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), ec); - HandleReceived (ec, moreBytes); - } + if (!ec) + { + if (moreBytes >= m_NextReceivedLen) + { + // read and process message immediately if available + moreBytes = boost::asio::read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), ec); + HandleReceived (ec, moreBytes); + } + else + Receive (); + } else - Receive (); + LogPrint (eLogWarning, "NTCP2: Socket error: ", ec.message ()); } else { @@ -864,10 +874,15 @@ namespace transport void NTCP2Session::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode) + if (ecode || bytes_transferred != m_NextReceivedLen) { - if (ecode != boost::asio::error::operation_aborted) - LogPrint (eLogWarning, "NTCP2: Receive read error: ", ecode.message ()); + if (ecode != boost::asio::error::operation_aborted) + { + if (ecode) + LogPrint (eLogWarning, "NTCP2: Receive read error: ", ecode.message ()); + else if (bytes_transferred != m_NextReceivedLen) + LogPrint (eLogError, "NTCP2: Received ", bytes_transferred, " bytes. Instead ", m_NextReceivedLen); + } Terminate (); } else From 1e5604ed4373dcea18a8353df188451d592bd864 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 18 Jan 2024 19:18:51 -0500 Subject: [PATCH 0386/1160] check if peer is connected before trying to connect --- libi2pd/Transports.cpp | 15 ++++++++------- libi2pd/Transports.h | 2 ++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index eb836354..5d3027a9 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -458,7 +458,7 @@ namespace transport } if (!connected) return; } - if (!it->second.sessions.empty ()) + if (it->second.IsConnected ()) it->second.sessions.front ()->SendI2NPMessages (msgs); else { @@ -616,7 +616,8 @@ namespace transport { LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect"); it->second.SetRouter (r); - ConnectToPeer (ident, it->second); + if (!it->second.IsConnected ()) + ConnectToPeer (ident, it->second); } else { @@ -810,13 +811,13 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { - auto before = it->second.sessions.size (); + bool wasConnected = it->second.IsConnected (); it->second.sessions.remove (session); - if (it->second.sessions.empty ()) + if (!it->second.IsConnected ()) { if (it->second.delayedMessages.size () > 0) { - if (before > 0) // we had an active session before + if (wasConnected) // we had an active session before it->second.numAttempts = 0; // start over ConnectToPeer (ident, it->second); } @@ -849,7 +850,7 @@ namespace transport { return !session || !session->IsEstablished (); }); - if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) + if (!it->second.IsConnected () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) { LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); /* if (!it->second.router) @@ -991,7 +992,7 @@ namespace transport [isHighBandwidth](const Peer& peer)->bool { // connected, not overloaded and not slow - return !peer.router && !peer.sessions.empty () && peer.isReachable && + return !peer.router && peer.IsConnected () && peer.isReachable && peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE && !peer.sessions.front ()->IsSlow () && !peer.sessions.front ()->IsBandwidthExceeded (peer.isHighBandwidth) && (!isHighBandwidth || peer.isHighBandwidth); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 7ef7f9b2..0e5518b1 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -101,6 +101,8 @@ namespace transport isReachable = (bool)router->GetCompatibleTransports (true); } } + + bool IsConnected () const { return !sessions.empty (); } }; const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds From b4484c8e8f7615b6beeab872515c3f9ff1dc3bc9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 19 Jan 2024 21:54:10 +0300 Subject: [PATCH 0387/1160] [gha] msvc: switch back to boost 1.81.0 --- .github/workflows/build-windows-msvc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index 5af526e2..dea64644 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -38,7 +38,7 @@ jobs: - name: Install Boost run: | - powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.84.0/boost_1_84_0-msvc-14.3-64.exe/download -OutFile boost_1_84_0-msvc-14.3-64.exe)" + powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.81.0/boost_1_81_0-msvc-14.3-64.exe/download -OutFile boost_1_84_0-msvc-14.3-64.exe)" ./boost_1_84_0-msvc-14.3-64.exe /VERYSILENT - name: Install OpenSSL From 140146e433a83eb9137d668baedc13282a5a03c0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Jan 2024 14:09:48 -0500 Subject: [PATCH 0388/1160] limit mininal received packet size to 40 bytes --- libi2pd/SSU2.cpp | 9 ++++++++- libi2pd/SSU2.h | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 1503b404..1fb10927 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -283,8 +283,15 @@ namespace transport // but better to find out which host were sent it and mark that router as unreachable { i2p::transport::transports.UpdateReceivedBytes (bytes_transferred); + if (bytes_transferred < SSU2_MIN_RECEIVED_PACKET_SIZE) + { + // drop too short packets + m_PacketsPool.ReleaseMt (packet); + Receive (socket); + return; + } packet->len = bytes_transferred; - + boost::system::error_code ec; size_t moreBytes = socket.available (ec); if (!ec && moreBytes) diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 03e22245..6d07f7fa 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, The PurpleI2P Project +* Copyright (c) 2022-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -27,6 +27,7 @@ namespace transport const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K const size_t SSU2_MAX_NUM_INTRODUCERS = 3; + const size_t SSU2_MIN_RECEIVED_PACKET_SIZE = 40; // 16 byte short header + 8 byte minimum payload + 16 byte MAC const int SSU2_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour const int SSU2_TO_INTRODUCER_SESSION_EXPIRATION = 4800; // 80 minutes const int SSU2_KEEP_ALIVE_INTERVAL = 15; // in seconds From 0b47f65b069e47187efed3707c90866d0b036f39 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Jan 2024 18:29:17 -0500 Subject: [PATCH 0389/1160] don't remove another NTCP2 session with same address --- libi2pd/NTCP2.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index c52c5cc2..a58ab0a2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1415,7 +1415,11 @@ namespace transport void NTCP2Server::RemoveNTCP2Session (std::shared_ptr session) { if (session && session->GetRemoteIdentity ()) - m_NTCP2Sessions.erase (session->GetRemoteIdentity ()->GetIdentHash ()); + { + auto it = m_NTCP2Sessions.find (session->GetRemoteIdentity ()->GetIdentHash ()); + if (it != m_NTCP2Sessions.end () && it->second == session) + m_NTCP2Sessions.erase (it); + } } std::shared_ptr NTCP2Server::FindNTCP2Session (const i2p::data::IdentHash& ident) From 5e19e361e7ececd3008615a623e48f7f2f351e8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 20 Jan 2024 17:33:28 -0500 Subject: [PATCH 0390/1160] check max frame sizebefore sending --- libi2pd/NTCP2.cpp | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index a58ab0a2..45968f7d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -809,15 +809,10 @@ namespace transport void NTCP2Session::HandleReceivedLength (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode || bytes_transferred != 2) + if (ecode) { if (ecode != boost::asio::error::operation_aborted) - { - if (ecode) - LogPrint (eLogWarning, "NTCP2: Receive length read error: ", ecode.message ()); - else if (bytes_transferred != 2) - LogPrint (eLogError, "NTCP2: Receive length of ", bytes_transferred, " bytes"); - } + LogPrint (eLogWarning, "NTCP2: Receive length read error: ", ecode.message ()); Terminate (); } else @@ -874,15 +869,10 @@ namespace transport void NTCP2Session::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode || bytes_transferred != m_NextReceivedLen) + if (ecode) { if (ecode != boost::asio::error::operation_aborted) - { - if (ecode) - LogPrint (eLogWarning, "NTCP2: Receive read error: ", ecode.message ()); - else if (bytes_transferred != m_NextReceivedLen) - LogPrint (eLogError, "NTCP2: Received ", bytes_transferred, " bytes. Instead ", m_NextReceivedLen); - } + LogPrint (eLogWarning, "NTCP2: Receive read error: ", ecode.message ()); Terminate (); } else @@ -1061,6 +1051,11 @@ namespace transport macBuf = m_NextSendBuffer + paddingLen; totalLen += paddingLen; } + if (totalLen > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) + { + LogPrint (eLogError, "NTCP2: Frame to send is too long ", totalLen); + return; + } uint8_t nonce[12]; CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; i2p::crypto::AEADChaCha20Poly1305Encrypt (encryptBufs, m_SendKey, nonce, macBuf); // encrypt buffers @@ -1085,6 +1080,12 @@ namespace transport delete[] m_NextSendBuffer; m_NextSendBuffer = nullptr; return; } + if (payloadLen > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) + { + LogPrint (eLogError, "NTCP2: Buffer to send is too long ", payloadLen); + delete[] m_NextSendBuffer; m_NextSendBuffer = nullptr; + return; + } // encrypt uint8_t nonce[12]; CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; @@ -1160,7 +1161,12 @@ namespace transport len -= 3; if (msgLen < 256) msgLen = 256; // for short message padding should not be always zero size_t paddingSize = (msgLen*NTCP2_MAX_PADDING_RATIO)/100; - if (msgLen + paddingSize + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) paddingSize = NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; + if (msgLen + paddingSize + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) + { + ssize_t l = NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; + if (l <= 0) return 0; + paddingSize = l; + } if (paddingSize > len) paddingSize = len; if (paddingSize) { @@ -1169,7 +1175,7 @@ namespace transport RAND_bytes ((uint8_t *)m_PaddingSizes, sizeof (m_PaddingSizes)); m_NextPaddingSize = 0; } - paddingSize = m_PaddingSizes[m_NextPaddingSize++] % paddingSize; + paddingSize = m_PaddingSizes[m_NextPaddingSize++] % (paddingSize + 1); } buf[0] = eNTCP2BlkPadding; // blk htobe16buf (buf + 1, paddingSize); // size From 9f217f8a117089e7a4e3d9eeb732f7a741f11edf Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 21 Jan 2024 18:59:04 -0500 Subject: [PATCH 0391/1160] don't send expired I2NP messages --- libi2pd/I2NPProtocol.cpp | 10 +++++++--- libi2pd/I2NPProtocol.h | 3 ++- libi2pd/NTCP2.cpp | 7 +++++++ libi2pd/SSU2Session.cpp | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b8147555..ebd5f8d6 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -72,11 +72,15 @@ namespace i2p SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT); } - bool I2NPMessage::IsExpired () const + bool I2NPMessage::IsExpired (uint64_t ts) const { - auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto exp = GetExpiration (); return (ts > exp + I2NP_MESSAGE_CLOCK_SKEW) || (ts < exp - 3*I2NP_MESSAGE_CLOCK_SKEW); // check if expired or too far in future + } + + bool I2NPMessage::IsExpired () const + { + return IsExpired (i2p::util::GetMillisecondsSinceEpoch ()); } std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 6c64f2ab..e86f4f32 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -252,6 +252,7 @@ namespace tunnel void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0, bool checksum = true); void RenewI2NPMessageHeader (); bool IsExpired () const; + bool IsExpired (uint64_t ts) const; // in milliseconds }; template diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 45968f7d..925c89dd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1132,10 +1132,17 @@ namespace transport if (!m_SendQueue.empty ()) { std::vector > msgs; + auto ts = i2p::util::GetMillisecondsSinceEpoch (); size_t s = 0; while (!m_SendQueue.empty ()) { auto msg = m_SendQueue.front (); + if (!msg || msg->IsExpired (ts)) + { + // drop null or expired message + m_SendQueue.pop_front (); + continue; + } size_t len = msg->GetNTCP2Length (); if (s + len + 3 <= NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) // 3 bytes block header { diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 8cb39102..3ea07629 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -379,8 +379,9 @@ namespace transport while (!m_SendQueue.empty () && m_SentPackets.size () <= m_WindowSize) { auto msg = m_SendQueue.front (); - if (!msg) + if (!msg || msg->IsExpired (ts)) { + // drop null or expired message m_SendQueue.pop_front (); continue; } From a2249f0a82ca29215b039e15e7755be9f6012735 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jan 2024 13:52:13 -0500 Subject: [PATCH 0392/1160] identify server tunnel session but from ant to ports --- libi2pd_client/UDPTunnel.cpp | 57 +++++++++++++++++++++++++----------- libi2pd_client/UDPTunnel.h | 7 +++-- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/libi2pd_client/UDPTunnel.cpp b/libi2pd_client/UDPTunnel.cpp index 1e4b3d7c..3fcf8b35 100644 --- a/libi2pd_client/UDPTunnel.cpp +++ b/libi2pd_client/UDPTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -27,8 +27,17 @@ namespace client m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); } - void I2PUDPServerTunnel::HandleRecvFromI2PRaw (uint16_t, uint16_t, const uint8_t * buf, size_t len) + void I2PUDPServerTunnel::HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { + if (m_LastSession && (fromPort != m_LastSession->RemotePort || toPort != m_LastSession->LocalPort)) + { + std::lock_guard lock(m_SessionsMutex); + auto it = m_Sessions.find (GetSessionIndex (fromPort, toPort)); + if (it != m_Sessions.end ()) + m_LastSession = it->second; + else + m_LastSession = nullptr; + } if (m_LastSession) { m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); @@ -41,11 +50,12 @@ namespace client std::lock_guard lock(m_SessionsMutex); uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); auto itr = m_Sessions.begin(); - while(itr != m_Sessions.end()) { - if(now - (*itr)->LastActivity >= delta ) + while(itr != m_Sessions.end()) + { + if(now - itr->second->LastActivity >= delta ) itr = m_Sessions.erase(itr); else - ++itr; + itr++; } } @@ -66,15 +76,25 @@ namespace client UDPSessionPtr I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort) { auto ih = from.GetIdentHash(); - for (auto & s : m_Sessions ) + auto idx = GetSessionIndex (remotePort, localPort); { - if (s->Identity.GetLL()[0] == ih.GetLL()[0] && remotePort == s->RemotePort) + std::lock_guard lock(m_SessionsMutex); + auto it = m_Sessions.find (idx); + if (it != m_Sessions.end ()) { - /** found existing session */ - LogPrint(eLogDebug, "UDPServer: Found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); - return s; - } - } + if (it->second->Identity.GetLL()[0] == ih.GetLL()[0]) + { + LogPrint(eLogDebug, "UDPServer: Found session ", it->second->IPSocket.local_endpoint(), " ", ih.ToBase32()); + return it->second; + } + else + { + LogPrint(eLogWarning, "UDPServer: Session with from ", remotePort, " and to ", localPort, " ports already exists. But from differend address. Removed"); + m_Sessions.erase (it); + } + } + } + boost::asio::ip::address addr; /** create new udp session */ if(m_IsUniqueLocal && m_LocalAddress.is_loopback()) @@ -84,10 +104,12 @@ namespace client } else addr = m_LocalAddress; - boost::asio::ip::udp::endpoint ep(addr, 0); - m_Sessions.push_back(std::make_shared(ep, m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort)); - auto & back = m_Sessions.back(); - return back; + + auto s = std::make_shared(boost::asio::ip::udp::endpoint(addr, 0), + m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort); + std::lock_guard lock(m_SessionsMutex); + m_Sessions.emplace (idx, s); + return s; } UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint, @@ -175,8 +197,9 @@ namespace client std::vector > sessions; std::lock_guard lock (m_SessionsMutex); - for (UDPSessionPtr s: m_Sessions) + for (auto it: m_Sessions) { + auto s = it.second; if (!s->m_Destination) continue; auto info = s->m_Destination->GetInfoForRemote (s->Identity); if (!info) continue; diff --git a/libi2pd_client/UDPTunnel.h b/libi2pd_client/UDPTunnel.h index 3233c3f0..6dff41ea 100644 --- a/libi2pd_client/UDPTunnel.h +++ b/libi2pd_client/UDPTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -104,7 +104,8 @@ namespace client void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession (const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); - + uint32_t GetSessionIndex (uint16_t fromPort, uint16_t toPort) const { return ((uint32_t)fromPort << 16) + toPort; } + private: bool m_IsUniqueLocal; @@ -112,7 +113,7 @@ namespace client boost::asio::ip::address m_LocalAddress; boost::asio::ip::udp::endpoint m_RemoteEndpoint; std::mutex m_SessionsMutex; - std::vector m_Sessions; + std::unordered_map m_Sessions; // (from port, to port)->session std::shared_ptr m_LocalDest; UDPSessionPtr m_LastSession; bool m_Gzip; From c5a18065281e45469518d6db032264971252199b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jan 2024 13:58:42 -0500 Subject: [PATCH 0393/1160] fixed possible deadlock --- libi2pd_client/UDPTunnel.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libi2pd_client/UDPTunnel.cpp b/libi2pd_client/UDPTunnel.cpp index 3fcf8b35..0bf3202f 100644 --- a/libi2pd_client/UDPTunnel.cpp +++ b/libi2pd_client/UDPTunnel.cpp @@ -19,10 +19,7 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0] || fromPort != m_LastSession->RemotePort) - { - std::lock_guard lock(m_SessionsMutex); m_LastSession = ObtainUDPSession(from, toPort, fromPort); - } m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); } From 70639f11396ad514d3bf358b8dccdd9aee7aff80 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jan 2024 19:05:38 -0500 Subject: [PATCH 0394/1160] don't adjust clock if offsets came from same router --- libi2pd/SSU2.cpp | 29 +++++++++++++++++++++-------- libi2pd/SSU2.h | 3 ++- libi2pd/SSU2Session.cpp | 6 +++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 1fb10927..0ebeab6d 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -210,27 +210,40 @@ namespace transport return ep.port (); } - void SSU2Server::AdjustTimeOffset (int64_t offset) + void SSU2Server::AdjustTimeOffset (int64_t offset, std::shared_ptr from) { if (offset) { if (m_PendingTimeOffset) // one more { - if (std::abs (m_PendingTimeOffset - offset) < SSU2_CLOCK_SKEW) + if (m_PendingTimeOffsetFrom && from && + m_PendingTimeOffsetFrom->GetIdentHash ().GetLL()[0] != from->GetIdentHash ().GetLL()[0]) // from different routers { - offset = (m_PendingTimeOffset + offset)/2; // average - LogPrint (eLogWarning, "SSU2: Clock adjusted by ", offset, " seconds"); - i2p::util::AdjustTimeOffset (offset); - } + if (std::abs (m_PendingTimeOffset - offset) < SSU2_CLOCK_SKEW) + { + offset = (m_PendingTimeOffset + offset)/2; // average + LogPrint (eLogWarning, "SSU2: Clock adjusted by ", offset, " seconds"); + i2p::util::AdjustTimeOffset (offset); + } + else + LogPrint (eLogWarning, "SSU2: Time offsets are too different. Clock not adjusted"); + m_PendingTimeOffset = 0; + m_PendingTimeOffsetFrom = nullptr; + } else - LogPrint (eLogWarning, "SSU2: Time offsets are too different. Clock not adjusted"); - m_PendingTimeOffset = 0; + LogPrint (eLogWarning, "SSU2: Time offsets from same router. Clock not adjusted"); } else + { m_PendingTimeOffset = offset; // first + m_PendingTimeOffsetFrom = from; + } } else + { m_PendingTimeOffset = 0; // reset + m_PendingTimeOffsetFrom = nullptr; + } } boost::asio::ip::udp::socket& SSU2Server::OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint) diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 6d07f7fa..da682746 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -67,7 +67,7 @@ namespace transport bool IsSupported (const boost::asio::ip::address& addr) const; uint16_t GetPort (bool v4) const; bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; }; - void AdjustTimeOffset (int64_t offset); + void AdjustTimeOffset (int64_t offset, std::shared_ptr from); void AddSession (std::shared_ptr session); void RemoveSession (uint64_t connID); @@ -164,6 +164,7 @@ namespace transport bool m_IsPublished; // if we maintain introducers bool m_IsSyncClockFromPeers; int64_t m_PendingTimeOffset; // during peer test + std::shared_ptr m_PendingTimeOffsetFrom; // proxy bool m_IsThroughProxy; diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 3ea07629..5c951391 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1671,10 +1671,10 @@ namespace transport if (std::abs (offset) > SSU2_CLOCK_THRESHOLD) { LogPrint (eLogWarning, "SSU2: Time offset ", offset, " from ", m_RemoteEndpoint); - m_Server.AdjustTimeOffset (-offset); + m_Server.AdjustTimeOffset (-offset, GetRemoteIdentity ()); } else - m_Server.AdjustTimeOffset (0); + m_Server.AdjustTimeOffset (0, nullptr); } else if (std::abs (offset) > SSU2_CLOCK_SKEW) { @@ -2485,7 +2485,7 @@ namespace transport i2p::context.SetTestingV6 (testing); } if (!testing) - m_Server.AdjustTimeOffset (0); // reset time offset when testing is over + m_Server.AdjustTimeOffset (0, nullptr); // reset time offset when testing is over } size_t SSU2Session::CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep) From 5b93558bd0d7b46bf004a198f15282d217e5c7d8 Mon Sep 17 00:00:00 2001 From: weko Date: Thu, 25 Jan 2024 01:05:58 +0000 Subject: [PATCH 0395/1160] Add support for multiple udp server tunnels on one destionation --- libi2pd/Datagram.cpp | 68 ++++++++++++++++++++++++++++++-- libi2pd/Datagram.h | 28 +++++++------ libi2pd_client/ClientContext.cpp | 2 +- libi2pd_client/SAM.cpp | 53 ++++++++++++++----------- libi2pd_client/UDPTunnel.cpp | 46 ++++++++++++++------- libi2pd_client/UDPTunnel.h | 3 +- 6 files changed, 143 insertions(+), 57 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 64738ebe..c99db584 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -19,7 +19,7 @@ namespace i2p namespace datagram { DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): - m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) + m_Owner (owner), m_DefaultReceiver (nullptr), m_DefaultRawReceiver (nullptr), m_Gzip (gzip) { if (m_Gzip) m_Deflator.reset (new i2p::data::GzipDeflator); @@ -119,19 +119,79 @@ namespace datagram void DatagramDestination::HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - if (m_RawReceiver) - m_RawReceiver (fromPort, toPort, buf, len); + auto r = FindRawReceiver(toPort); + + if (r) + r (fromPort, toPort, buf, len); else LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram"); } + void DatagramDestination::SetReceiver (const Receiver& receiver, uint16_t port) + { + std::lock_guard lock(m_ReceiversMutex); + m_ReceiversByPorts[port] = receiver; + if (!m_DefaultReceiver) { + m_DefaultReceiver = receiver; + m_DefaultReceiverPort = port; + } + } + + void DatagramDestination::ResetReceiver (uint16_t port) + { + std::lock_guard lock(m_ReceiversMutex); + m_ReceiversByPorts.erase (port); + if (m_DefaultReceiverPort == port) { + m_DefaultReceiver = nullptr; + m_DefaultReceiverPort = 0; + } + } + + + void DatagramDestination::SetRawReceiver (const RawReceiver& receiver, uint16_t port) + { + std::lock_guard lock(m_RawReceiversMutex); + m_RawReceiversByPorts[port] = receiver; + if (!m_DefaultRawReceiver) { + m_DefaultRawReceiver = receiver; + m_DefaultRawReceiverPort = port; + } + }; + + void DatagramDestination::ResetRawReceiver (uint16_t port) + { + std::lock_guard lock(m_RawReceiversMutex); + m_RawReceiversByPorts.erase (port); + if (m_DefaultRawReceiverPort == port) { + m_DefaultRawReceiver = nullptr; + m_DefaultRawReceiverPort = 0; + } + } + + DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port) { std::lock_guard lock(m_ReceiversMutex); - Receiver r = m_Receiver; + Receiver r = nullptr; auto itr = m_ReceiversByPorts.find(port); if (itr != m_ReceiversByPorts.end()) r = itr->second; + else { + r = m_DefaultReceiver; + } + return r; + } + + DatagramDestination::RawReceiver DatagramDestination::FindRawReceiver(uint16_t port) + { + std::lock_guard lock(m_RawReceiversMutex); + RawReceiver r = nullptr; + auto itr = m_RawReceiversByPorts.find(port); + if (itr != m_RawReceiversByPorts.end()) + r = itr->second; + else { + r = m_DefaultRawReceiver; + } return r; } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index e6d1f7b6..fd6af909 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -126,14 +126,12 @@ namespace datagram void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); - void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; - void ResetReceiver () { m_Receiver = nullptr; }; - void SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard lock(m_ReceiversMutex); m_ReceiversByPorts[port] = receiver; }; - void ResetReceiver (uint16_t port) { std::lock_guard lock(m_ReceiversMutex); m_ReceiversByPorts.erase (port); }; + void SetReceiver (const Receiver& receiver, uint16_t port); + void ResetReceiver (uint16_t port); - void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; }; - void ResetRawReceiver () { m_RawReceiver = nullptr; }; + void SetRawReceiver (const RawReceiver& receiver, uint16_t port); + void ResetRawReceiver (uint16_t port); std::shared_ptr GetInfoForRemote(const i2p::data::IdentHash & remote); @@ -150,20 +148,26 @@ namespace datagram void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); - /** find a receiver by port, if none by port is found try default receiver, otherwise returns nullptr */ Receiver FindReceiver(uint16_t port); + RawReceiver FindRawReceiver(uint16_t port); private: std::shared_ptr m_Owner; - Receiver m_Receiver; // default - RawReceiver m_RawReceiver; // default - bool m_Gzip; // gzip compression of data messages + std::mutex m_SessionsMutex; std::map m_Sessions; - std::mutex m_ReceiversMutex; - std::map m_ReceiversByPorts; + Receiver m_DefaultReceiver; + RawReceiver m_DefaultRawReceiver; + uint16_t m_DefaultReceiverPort; + uint16_t m_DefaultRawReceiverPort; + std::mutex m_ReceiversMutex; + std::mutex m_RawReceiversMutex; + std::unordered_map m_ReceiversByPorts; + std::unordered_map m_RawReceiversByPorts; + + bool m_Gzip; // gzip compression of data messages i2p::data::GzipInflator m_Inflator; std::unique_ptr m_Deflator; std::vector m_From, m_Signature; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index d8c0bd2d..4efe252d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -775,7 +775,7 @@ namespace client address = "127.0.0.1"; } auto localAddress = boost::asio::ip::address::from_string(address); - auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); + auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, inPort, gzip); if(!isUniqueLocal) { LogPrint(eLogInfo, "Clients: Disabling loopback address mapping"); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 1a3afb58..e4cbae8a 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -415,12 +415,17 @@ namespace client { session->UDPEndpoint = forward; auto dest = session->GetLocalDestination ()->CreateDatagramDestination (); + auto port = std::stoi(params[SAM_PARAM_PORT]); if (type == eSAMSessionTypeDatagram) dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), + port + ); else // raw dest->SetRawReceiver (std::bind (&SAMSocket::HandleI2PRawDatagramReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), + port + ); } if (session->GetLocalDestination ()->IsReady ()) @@ -524,7 +529,7 @@ namespace client if (addr->IsIdentHash ()) { if (session->GetLocalDestination ()->GetIdentHash () != addr->identHash) - { + { auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash); if (leaseSet) Connect(leaseSet, session); @@ -556,7 +561,7 @@ namespace client if (session) { if (session->GetLocalDestination ()->SupportsEncryptionType (remote->GetEncryptionType ())) - { + { m_SocketType = eSAMSocketTypeStream; m_Stream = session->GetLocalDestination ()->CreateStream (remote); if (m_Stream) @@ -570,7 +575,7 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } else - SendStreamCantReachPeer ("Incompatible crypto"); + SendStreamCantReachPeer ("Incompatible crypto"); } else SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); @@ -583,7 +588,7 @@ namespace client else { LogPrint (eLogError, "SAM: Destination to connect not found"); - SendStreamCantReachPeer ("LeaseSet not found"); + SendStreamCantReachPeer ("LeaseSet not found"); } } @@ -612,27 +617,27 @@ namespace client session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } else - { + { auto ts = i2p::util::GetSecondsSinceEpoch (); while (!session->acceptQueue.empty () && session->acceptQueue.front ().second + SAM_SESSION_MAX_ACCEPT_INTERVAL > ts) - { + { auto socket = session->acceptQueue.front ().first; session->acceptQueue.pop_front (); if (socket) m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); - } + } if (session->acceptQueue.size () < SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE) { // already accepting, queue up SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); session->acceptQueue.push_back (std::make_pair(shared_from_this(), ts)); - } - else - { + } + else + { LogPrint (eLogInfo, "SAM: Session ", m_ID, " accept queue is full ", session->acceptQueue.size ()); SendStreamI2PError ("Already accepting"); - } - } + } + } } else SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); @@ -875,8 +880,8 @@ namespace client size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, reply, msg.c_str()); #endif SendMessageReply (m_Buffer, len, true); - } - + } + void SAMSocket::SendSessionI2PError(const std::string & msg) { LogPrint (eLogError, "SAM: Session I2P error: ", msg); @@ -886,14 +891,14 @@ namespace client void SAMSocket::SendStreamI2PError(const std::string & msg) { LogPrint (eLogError, "SAM: Stream I2P error: ", msg); - SendReplyWithMessage (SAM_STREAM_STATUS_I2P_ERROR, msg); + SendReplyWithMessage (SAM_STREAM_STATUS_I2P_ERROR, msg); } void SAMSocket::SendStreamCantReachPeer(const std::string & msg) { - SendReplyWithMessage (SAM_STREAM_STATUS_CANT_REACH_PEER, msg); - } - + SendReplyWithMessage (SAM_STREAM_STATUS_CANT_REACH_PEER, msg); + } + void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name) { if (leaseSet) @@ -1093,14 +1098,14 @@ namespace client // pending acceptors auto ts = i2p::util::GetSecondsSinceEpoch (); while (!session->acceptQueue.empty () && session->acceptQueue.front ().second + SAM_SESSION_MAX_ACCEPT_INTERVAL > ts) - { + { auto socket = session->acceptQueue.front ().first; session->acceptQueue.pop_front (); if (socket) m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); - } + } if (!session->acceptQueue.empty ()) - { + { auto socket = session->acceptQueue.front ().first; session->acceptQueue.pop_front (); if (socket && socket->GetSocketType () == eSAMSocketTypeAcceptor) @@ -1108,7 +1113,7 @@ namespace client socket->m_IsAccepting = true; session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, socket, std::placeholders::_1)); } - } + } } if (!m_IsSilent) { diff --git a/libi2pd_client/UDPTunnel.cpp b/libi2pd_client/UDPTunnel.cpp index 0bf3202f..cd17bbf0 100644 --- a/libi2pd_client/UDPTunnel.cpp +++ b/libi2pd_client/UDPTunnel.cpp @@ -32,7 +32,7 @@ namespace client auto it = m_Sessions.find (GetSessionIndex (fromPort, toPort)); if (it != m_Sessions.end ()) m_LastSession = it->second; - else + else m_LastSession = nullptr; } if (m_LastSession) @@ -47,7 +47,7 @@ namespace client std::lock_guard lock(m_SessionsMutex); uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); auto itr = m_Sessions.begin(); - while(itr != m_Sessions.end()) + while(itr != m_Sessions.end()) { if(now - itr->second->LastActivity >= delta ) itr = m_Sessions.erase(itr); @@ -88,10 +88,10 @@ namespace client { LogPrint(eLogWarning, "UDPServer: Session with from ", remotePort, " and to ", localPort, " ports already exists. But from differend address. Removed"); m_Sessions.erase (it); - } - } - } - + } + } + } + boost::asio::ip::address addr; /** create new udp session */ if(m_IsUniqueLocal && m_LocalAddress.is_loopback()) @@ -102,7 +102,7 @@ namespace client else addr = m_LocalAddress; - auto s = std::make_shared(boost::asio::ip::udp::endpoint(addr, 0), + auto s = std::make_shared(boost::asio::ip::udp::endpoint(addr, 0), m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort); std::lock_guard lock(m_SessionsMutex); m_Sessions.emplace (idx, s); @@ -163,9 +163,9 @@ namespace client } I2PUDPServerTunnel::I2PUDPServerTunnel (const std::string & name, std::shared_ptr localDestination, - const boost::asio::ip::address& localAddress, const boost::asio::ip::udp::endpoint& forwardTo, uint16_t port, bool gzip) : + const boost::asio::ip::address& localAddress, const boost::asio::ip::udp::endpoint& forwardTo, uint16_t inPort, bool gzip) : m_IsUniqueLocal (true), m_Name (name), m_LocalAddress (localAddress), - m_RemoteEndpoint (forwardTo), m_LocalDest (localDestination), m_Gzip (gzip) + m_RemoteEndpoint (forwardTo), m_LocalDest (localDestination), m_inPort(inPort), m_Gzip (gzip) { } @@ -179,14 +179,23 @@ namespace client m_LocalDest->Start (); auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip); - dgram->SetReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - dgram->SetRawReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + dgram->SetReceiver ( + std::bind (&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), + m_inPort + ); + dgram->SetRawReceiver ( + std::bind (&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), + m_inPort + ); } void I2PUDPServerTunnel::Stop () { auto dgram = m_LocalDest->GetDatagramDestination (); - if (dgram) dgram->ResetReceiver (); + if (dgram) { + dgram->ResetReceiver (m_inPort); + dgram->ResetRawReceiver (m_inPort); + } } std::vector > I2PUDPServerTunnel::GetSessions () @@ -240,9 +249,13 @@ namespace client dgram->SetReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, - std::placeholders::_5)); + std::placeholders::_5), + RemotePort + ); dgram->SetRawReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), + RemotePort + ); m_LocalDest->Start (); if (m_ResolveThread == nullptr) @@ -253,7 +266,10 @@ namespace client void I2PUDPClientTunnel::Stop () { auto dgram = m_LocalDest->GetDatagramDestination (); - if (dgram) dgram->ResetReceiver (); + if (dgram) { + dgram->ResetReceiver (RemotePort); + dgram->ResetRawReceiver (RemotePort); + } m_cancel_resolve = true; m_Sessions.clear(); diff --git a/libi2pd_client/UDPTunnel.h b/libi2pd_client/UDPTunnel.h index 6dff41ea..5650124c 100644 --- a/libi2pd_client/UDPTunnel.h +++ b/libi2pd_client/UDPTunnel.h @@ -105,7 +105,7 @@ namespace client void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession (const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); uint32_t GetSessionIndex (uint16_t fromPort, uint16_t toPort) const { return ((uint32_t)fromPort << 16) + toPort; } - + private: bool m_IsUniqueLocal; @@ -116,6 +116,7 @@ namespace client std::unordered_map m_Sessions; // (from port, to port)->session std::shared_ptr m_LocalDest; UDPSessionPtr m_LastSession; + uint16_t m_inPort; bool m_Gzip; public: From 4b167fdbafe577bca8b745e64ed0b15140c90b34 Mon Sep 17 00:00:00 2001 From: weko Date: Thu, 25 Jan 2024 01:57:24 +0000 Subject: [PATCH 0396/1160] Update copyright year --- libi2pd/Datagram.cpp | 2 +- libi2pd/Datagram.h | 2 +- libi2pd_client/ClientContext.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index c99db584..717e3312 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index fd6af909..45edecab 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 4efe252d..c27ce625 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * From 67c4d4bcaafbe67ee5dd7bbd4fda44eb1d91a6e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 25 Jan 2024 09:09:44 -0500 Subject: [PATCH 0397/1160] fixed VS build error --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 925c89dd..fff2fdc7 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1170,7 +1170,7 @@ namespace transport size_t paddingSize = (msgLen*NTCP2_MAX_PADDING_RATIO)/100; if (msgLen + paddingSize + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) { - ssize_t l = NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; + int l = (int)NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; if (l <= 0) return 0; paddingSize = l; } From 75c2cb751f493c4bf96249e1b1e800868806943c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 25 Jan 2024 18:51:46 -0500 Subject: [PATCH 0398/1160] lock mutex before deleting RouterInfo's buffer --- libi2pd/NetDb.cpp | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 8eb5d653..f1be7520 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -240,7 +240,7 @@ namespace data { bool wasFloodfill = r->IsFloodfill (); { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); if (!r->Update (buf, len)) { updated = false; @@ -254,7 +254,7 @@ namespace data m_RouterInfos.erase (ident); if (wasFloodfill) { - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); m_Floodfills.Remove (r->GetIdentHash ()); } m_Requests.RequestComplete (ident, nullptr); @@ -265,7 +265,7 @@ namespace data if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated { LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); if (wasFloodfill) m_Floodfills.Remove (r->GetIdentHash ()); else if (r->IsEligibleFloodfill ()) @@ -291,7 +291,7 @@ namespace data { bool inserted = false; { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); inserted = m_RouterInfos.insert ({r->GetIdentHash (), r}).second; } if (inserted) @@ -302,7 +302,7 @@ namespace data if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ()) // don't insert floodfill until it's known real if we have enough { - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); m_Floodfills.Insert (r); } else @@ -325,7 +325,7 @@ namespace data bool NetDb::AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len) { - std::unique_lock lock(m_LeaseSetsMutex); + std::lock_guard lock(m_LeaseSetsMutex); bool updated = false; auto it = m_LeaseSets.find(ident); if (it != m_LeaseSets.end () && it->second->GetStoreType () == i2p::data::NETDB_STORE_TYPE_LEASESET) @@ -366,7 +366,7 @@ namespace data auto leaseSet = std::make_shared (storeType, buf, len, false); // we don't need leases in netdb if (leaseSet->IsValid ()) { - std::unique_lock lock(m_LeaseSetsMutex); + std::lock_guard lock(m_LeaseSetsMutex); auto it = m_LeaseSets.find(ident); if (it == m_LeaseSets.end () || it->second->GetStoreType () != storeType || leaseSet->GetPublishedTimestamp () > it->second->GetPublishedTimestamp ()) @@ -393,7 +393,7 @@ namespace data std::shared_ptr NetDb::FindRouter (const IdentHash& ident) const { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); auto it = m_RouterInfos.find (ident); if (it != m_RouterInfos.end ()) return it->second; @@ -403,7 +403,7 @@ namespace data std::shared_ptr NetDb::FindLeaseSet (const IdentHash& destination) const { - std::unique_lock lock(m_LeaseSetsMutex); + std::lock_guard lock(m_LeaseSetsMutex); auto it = m_LeaseSets.find (destination); if (it != m_LeaseSets.end ()) return it->second; @@ -437,7 +437,7 @@ namespace data auto r = FindRouter (ident); if (r) { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); r->ExcludeReachableTransports (transports); } } @@ -527,7 +527,7 @@ namespace data void NetDb::VisitLeaseSets(LeaseSetVisitor v) { - std::unique_lock lock(m_LeaseSetsMutex); + std::lock_guard lock(m_LeaseSetsMutex); for ( auto & entry : m_LeaseSets) v(entry.first, entry.second); } @@ -543,7 +543,7 @@ namespace data void NetDb::VisitRouterInfos(RouterInfoVisitor v) { - std::unique_lock lock(m_RouterInfosMutex); + std::lock_guard lock(m_RouterInfosMutex); for ( const auto & item : m_RouterInfos ) v(item.second); } @@ -555,7 +555,7 @@ namespace data size_t iters = max_iters_per_cyle; while(n > 0) { - std::unique_lock lock(m_RouterInfosMutex); + std::lock_guard lock(m_RouterInfosMutex); uint32_t idx = rand () % m_RouterInfos.size (); uint32_t i = 0; for (const auto & it : m_RouterInfos) { @@ -638,6 +638,7 @@ namespace data // we have something to save it.second->SaveToFile (m_Storage.Path(ident)); it.second->SetUnreachable (false); + std::lock_guard l(m_RouterInfosMutex); // possible collision between DeleteBuffer and Update it.second->DeleteBuffer (); } it.second->SetUpdated (false); @@ -696,7 +697,7 @@ namespace data LogPrint (eLogInfo, "NetDb: Deleting ", deletedCount, " unreachable routers"); // clean up RouterInfos table { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();) { if (!it->second || it->second->IsUnreachable ()) @@ -710,7 +711,7 @@ namespace data } // clean up expired floodfills or not floodfills anymore { - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); m_Floodfills.Cleanup ([](const std::shared_ptr& r)->bool { return r && r->IsFloodfill () && !r->IsUnreachable (); @@ -1249,7 +1250,7 @@ namespace data return 0; uint16_t inds[3]; RAND_bytes ((uint8_t *)inds, sizeof (inds)); - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); auto count = m_RouterInfos.size (); if(count == 0) return nullptr; inds[0] %= count; @@ -1311,7 +1312,7 @@ namespace data const std::set& excluded) const { IdentHash destKey = CreateRoutingKey (destination); - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); return m_Floodfills.FindClosest (destKey, [&excluded](const std::shared_ptr& r)->bool { return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && @@ -1326,7 +1327,7 @@ namespace data IdentHash destKey = CreateRoutingKey (destination); std::vector > v; { - std::unique_lock l(m_FloodfillsMutex); + std::lock_guard l(m_FloodfillsMutex); v = m_Floodfills.FindClosest (destKey, num, [&excluded](const std::shared_ptr& r)->bool { return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && @@ -1381,7 +1382,7 @@ namespace data { auto ts = i2p::util::GetSecondsSinceEpoch (); { - std::unique_lock l(m_RouterInfosMutex); + std::lock_guard l(m_RouterInfosMutex); for (auto& it: m_RouterInfos) it.second->UpdateIntroducers (ts); } From 530c353b00f73dcc497cf13206d50051b0748615 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Jan 2024 12:17:59 -0500 Subject: [PATCH 0399/1160] don't send Ack with NACK immediately but after 2 milliseconds --- libi2pd/Streaming.cpp | 37 ++++++++++++++++--------------------- libi2pd/Streaming.h | 3 ++- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 629039ab..c43f99ad 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -179,13 +179,9 @@ namespace stream { if (!m_IsAckSendScheduled) { - m_IsAckSendScheduled = true; auto ackTimeout = m_RTT/10; if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay; - else if (ackTimeout < MIN_SEND_ACK_TIMEOUT) ackTimeout = MIN_SEND_ACK_TIMEOUT; - m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ackTimeout)); - m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer, - shared_from_this (), std::placeholders::_1)); + ScheduleAck (ackTimeout); } } else if (packet->IsSYN ()) @@ -207,23 +203,11 @@ namespace stream // save message and wait for missing message again SavePacket (packet); if (m_LastReceivedSequenceNumber >= 0) - { - // send NACKs for missing messages ASAP - if (m_IsAckSendScheduled) - { - m_IsAckSendScheduled = false; - m_AckSendTimer.cancel (); - } - SendQuickAck (); - } + // send NACKs for missing messages with minimal timeout + ScheduleAck (MIN_SEND_ACK_TIMEOUT); else - { // wait for SYN - m_IsAckSendScheduled = true; - m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(SYN_TIMEOUT)); - m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer, - shared_from_this (), std::placeholders::_1)); - } + ScheduleAck (SYN_TIMEOUT); } } } @@ -1029,6 +1013,17 @@ namespace stream } } + void Stream::ScheduleAck (int timeout) + { + if (m_IsAckSendScheduled) + m_AckSendTimer.cancel (); + m_IsAckSendScheduled = true; + if (timeout < MIN_SEND_ACK_TIMEOUT) timeout = MIN_SEND_ACK_TIMEOUT; + m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(timeout)); + m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer, + shared_from_this (), std::placeholders::_1)); + } + void Stream::HandleAckSendTimer (const boost::system::error_code& ecode) { if (m_IsAckSendScheduled) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 1db59118..ed79edc9 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -227,6 +227,7 @@ namespace stream void ScheduleResend (); void HandleResendTimer (const boost::system::error_code& ecode); + void ScheduleAck (int timeout); void HandleAckSendTimer (const boost::system::error_code& ecode); private: From a3246cd9dc92f91219801e6ef8c6fa22f0056616 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Jan 2024 17:57:50 -0500 Subject: [PATCH 0400/1160] doen't send Ack packet too often if missing packets --- libi2pd/Streaming.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index c43f99ad..a4604892 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -203,8 +203,11 @@ namespace stream // save message and wait for missing message again SavePacket (packet); if (m_LastReceivedSequenceNumber >= 0) - // send NACKs for missing messages with minimal timeout - ScheduleAck (MIN_SEND_ACK_TIMEOUT); + { + if (!m_IsAckSendScheduled) + // send NACKs for missing messages + ScheduleAck (MIN_SEND_ACK_TIMEOUT*m_SavedPackets.size ()); + } else // wait for SYN ScheduleAck (SYN_TIMEOUT); From 81015a52285651e0c6fe2a8bf33d7dd0b2c96b83 Mon Sep 17 00:00:00 2001 From: Vort Date: Sun, 28 Jan 2024 15:37:14 +0200 Subject: [PATCH 0401/1160] log changes of network status --- libi2pd/RouterContext.cpp | 4 ++++ libi2pd/RouterContext.h | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 10d33bf5..b3c51ca6 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -303,6 +303,8 @@ namespace i2p SetTesting (false); if (status != m_Status) { + LogPrint(eLogInfo, "Router: network status v4 changed ", + ROUTER_STATUS_NAMES[m_Status], " -> ", ROUTER_STATUS_NAMES[status]); m_Status = status; switch (m_Status) { @@ -323,6 +325,8 @@ namespace i2p SetTestingV6 (false); if (status != m_StatusV6) { + LogPrint(eLogInfo, "Router: network status v6 changed ", + ROUTER_STATUS_NAMES[m_StatusV6], " -> ", ROUTER_STATUS_NAMES[status]); m_StatusV6 = status; switch (m_StatusV6) { diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 91a553ba..ddfc65de 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -48,6 +48,15 @@ namespace garlic eRouterStatusMesh = 4 }; + const char* const ROUTER_STATUS_NAMES[] = + { + "OK", // 0 + "Firewalled", // 1 + "Unknown", // 2 + "Proxy", // 3 + "Mesh" // 4 + }; + enum RouterError { eRouterErrorNone = 0, From 822cb35efe35b95c269329275b1d00f3b7f3b7c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 28 Jan 2024 18:12:40 -0500 Subject: [PATCH 0402/1160] limit send Ack timeout by Ack delay interval --- libi2pd/Streaming.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index a4604892..74fb3d97 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -205,8 +205,12 @@ namespace stream if (m_LastReceivedSequenceNumber >= 0) { if (!m_IsAckSendScheduled) + { // send NACKs for missing messages - ScheduleAck (MIN_SEND_ACK_TIMEOUT*m_SavedPackets.size ()); + int ackTimeout = MIN_SEND_ACK_TIMEOUT*m_SavedPackets.size (); + if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay; + ScheduleAck (ackTimeout); + } } else // wait for SYN From d926a310645d9778848f8fadb710a70dc66ebd34 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jan 2024 18:01:41 -0500 Subject: [PATCH 0403/1160] fixed warning --- libi2pd/Datagram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 717e3312..f87f9653 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -156,7 +156,7 @@ namespace datagram m_DefaultRawReceiver = receiver; m_DefaultRawReceiverPort = port; } - }; + } void DatagramDestination::ResetRawReceiver (uint16_t port) { From f0084785059b8e78acef3301e1fd818ec6b0c73b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jan 2024 19:54:43 -0500 Subject: [PATCH 0404/1160] handle I2NP messages drops --- libi2pd/I2NPProtocol.h | 7 +++++-- libi2pd/NTCP2.cpp | 1 + libi2pd/NetDb.cpp | 6 +++++- libi2pd/NetDbRequests.cpp | 6 +++++- libi2pd/SSU2Session.cpp | 1 + libi2pd/Transports.h | 7 +++++++ 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index e86f4f32..a2877a08 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "Crypto.h" #include "I2PEndian.h" #include "Identity.h" @@ -149,7 +150,8 @@ namespace tunnel uint8_t * buf; size_t len, offset, maxLen; std::shared_ptr from; - + std::function onDrop; + I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2), offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header @@ -241,7 +243,6 @@ namespace tunnel SetSize (len - offset - I2NP_HEADER_SIZE); SetChks (0); } - void ToNTCP2 () { uint8_t * ntcp2 = GetNTCP2Header (); @@ -253,6 +254,8 @@ namespace tunnel void RenewI2NPMessageHeader (); bool IsExpired () const; bool IsExpired (uint64_t ts) const; // in milliseconds + + void Drop () { if (onDrop) { onDrop (); onDrop = nullptr; }; } }; template diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index fff2fdc7..ad8ef51d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1140,6 +1140,7 @@ namespace transport if (!msg || msg->IsExpired (ts)) { // drop null or expired message + if (msg) msg->Drop (); m_SendQueue.pop_front (); continue; } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index f1be7520..0bf7af9d 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -736,7 +736,11 @@ namespace data !i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) direct = false; // floodfill can't be reached directly if (direct) - transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + { + auto msg = dest->CreateRequestMessage (floodfill->GetIdentHash ()); + msg->onDrop = [this, dest]() { this->m_Requests.SendNextRequest (dest); }; + transports.SendMessage (floodfill->GetIdentHash (), msg); + } else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 92e5a7b8..4099f921 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -188,7 +188,11 @@ namespace data !i2p::transport::transports.IsConnected (nextFloodfill->GetIdentHash ())) direct = false; // floodfill can't be reached directly if (direct) - i2p::transport::transports.SendMessage (nextFloodfill->GetIdentHash (), dest->CreateRequestMessage (nextFloodfill->GetIdentHash ())); + { + auto msg = dest->CreateRequestMessage (nextFloodfill->GetIdentHash ()); + msg->onDrop = [this, dest]() { this->SendNextRequest (dest); }; + i2p::transport::transports.SendMessage (nextFloodfill->GetIdentHash (), msg); + } else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 5c951391..fa6d9eca 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -382,6 +382,7 @@ namespace transport if (!msg || msg->IsExpired (ts)) { // drop null or expired message + if (msg) msg->Drop (); m_SendQueue.pop_front (); continue; } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 0e5518b1..c78a8bd0 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -86,6 +86,13 @@ namespace transport } } + ~Peer () + { + // drop not sent delayed messages + for (auto& it: delayedMessages) + it->Drop (); + } + void Done () { for (auto& it: sessions) From 85f5f5b91e669d626adb1daaa98a35fbc0321245 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jan 2024 10:04:19 -0500 Subject: [PATCH 0405/1160] fixed potential deadlock --- libi2pd/Transports.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index c78a8bd0..540bafb4 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -85,18 +85,14 @@ namespace transport isReachable = (bool)router->GetCompatibleTransports (true); } } - - ~Peer () - { - // drop not sent delayed messages - for (auto& it: delayedMessages) - it->Drop (); - } void Done () { for (auto& it: sessions) it->Done (); + // drop not sent delayed messages + for (auto& it: delayedMessages) + it->Drop (); } void SetRouter (std::shared_ptr r) From e40b656ecf8ea4bdbb92c2c5f5c996ffae7aa2d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jan 2024 15:41:57 -0500 Subject: [PATCH 0406/1160] Drop for tunnel and encrypted messages --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 ++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- libi2pd/NetDb.cpp | 1 + libi2pd/NetDbRequests.cpp | 1 + libi2pd/TunnelGateway.cpp | 11 +++++++++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3b3ed485..6f56f2e5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1171,7 +1171,7 @@ namespace garlic return m; } - std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { // Noise_N, we are Alice, routerPublicKey is Bob's i2p::crypto::NoiseSymmetricState noiseState; @@ -1205,6 +1205,12 @@ namespace garlic htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); + if (msg->onDrop) + { + // move onDrop to the wrapping I2NP messages + m->onDrop = msg->onDrop; + msg->onDrop = nullptr; + } return m; } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 301f597a..517833e8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -246,7 +246,7 @@ namespace garlic }; std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); - std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); } } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 0bf7af9d..bedb19f6 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -749,6 +749,7 @@ namespace data if (outbound && inbound) { auto msg = dest->CreateRequestMessage (floodfill, inbound); + msg->onDrop = [this, dest]() { this->m_Requests.SendNextRequest (dest); }; outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); } diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 4099f921..3b5f41b6 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -202,6 +202,7 @@ namespace data { LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); + msg->onDrop = [this, dest]() { this->SendNextRequest (dest); }; outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, i2p::garlic::WrapECIESX25519MessageForRouter (msg, nextFloodfill->GetIdentity ()->GetEncryptionPublicKey ())); } diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 12e7652f..85ff224e 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -35,6 +35,13 @@ namespace tunnel if (!m_CurrentTunnelDataMsg) { CreateCurrentTunnelDataMessage (); + if (block.data && block.data->onDrop) + { + // onDrop is called for the first fragment in tunnel message + // that's usually true for short TBMs or lookups + m_CurrentTunnelDataMsg->onDrop = block.data->onDrop; + block.data->onDrop = nullptr; + } messageCreated = true; } @@ -155,7 +162,6 @@ namespace tunnel void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage () { - m_CurrentTunnelDataMsg = nullptr; 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; @@ -223,6 +229,7 @@ namespace tunnel m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg); htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ()); newMsg->FillI2NPMessageHeader (eI2NPTunnelData); + if (tunnelMsg->onDrop) newMsg->onDrop = tunnelMsg->onDrop; newTunnelMsgs.push_back (newMsg); m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } From 0ca782ed717bc8ad631efd4bf252c1b78894b72b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jan 2024 18:02:14 -0500 Subject: [PATCH 0407/1160] drop unsent messages if session disconnects --- libi2pd/NTCP2.cpp | 2 ++ libi2pd/SSU2Session.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ad8ef51d..6fe88509 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -373,6 +373,8 @@ namespace transport m_Socket.close (); transports.PeerDisconnected (shared_from_this ()); m_Server.RemoveNTCP2Session (shared_from_this ()); + for (auto& it: m_SendQueue) + it->Drop (); m_SendQueue.clear (); SetSendQueueSize (0); auto remoteIdentity = GetRemoteIdentity (); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index fa6d9eca..9180ccc8 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -262,6 +262,8 @@ namespace transport m_SentHandshakePacket.reset (nullptr); m_SessionConfirmedFragment.reset (nullptr); m_PathChallenge.reset (nullptr); + for (auto& it: m_SendQueue) + it->Drop (); m_SendQueue.clear (); SetSendQueueSize (0); m_SentPackets.clear (); From 2e9f2d4a3b1513797a73f94b1b661d4f9b76bb9b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jan 2024 21:52:18 -0500 Subject: [PATCH 0408/1160] Drop for LeaseSet request --- libi2pd/Destination.cpp | 67 ++++++++++++++++++++++++----------------- libi2pd/Destination.h | 3 +- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b9555abe..9b173f24 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -502,38 +502,43 @@ namespace client if (it != m_LeaseSetRequests.end ()) { auto request = it->second; - bool found = false; - if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) + for (int i = 0; i < num; i++) { - for (int i = 0; i < num; i++) + i2p::data::IdentHash peerHash (buf + 33 + i*32); + if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) { - i2p::data::IdentHash peerHash (buf + 33 + i*32); - if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) - { - LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); - i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory - } - } - - auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); - if (floodfill) - { - LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); - if (SendLeaseSetRequest (key, floodfill, request)) - found = true; + LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); + i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory } } - if (!found) - { - LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); - request->Complete (nullptr); - m_LeaseSetRequests.erase (key); - } + SendNextLeaseSetRequest (key, request); } else LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found"); } + void LeaseSetDestination::SendNextLeaseSetRequest (const i2p::data::IdentHash& key, + std::shared_ptr request) + { + bool found = false; + if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) + { + auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); + if (floodfill) + { + LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); + if (SendLeaseSetRequest (key, floodfill, request)) + found = true; + } + } + if (!found) + { + LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); + request->Complete (nullptr); + m_LeaseSetRequests.erase (key); + } + } + void LeaseSetDestination::HandleDeliveryStatusMessage (uint32_t msgID) { if (msgID == m_PublishReplyToken) @@ -822,14 +827,22 @@ namespace client AddECIESx25519Key (replyKey, replyTag); else AddSessionKey (replyKey, replyTag); - auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, - request->excluded, request->replyTunnel, replyKey, replyTag, isECIES)); + auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES); + auto s = shared_from_this (); + msg->onDrop = [s, dest, request]() + { + s->GetService ().post([s, dest, request]() + { + s->SendNextLeaseSetRequest (dest, request); + }); + }; + auto encryptedMsg = WrapMessageForRouter (nextFloodfill, msg); request->outboundTunnel->SendTunnelDataMsgs ( { i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, msg + nextFloodfill->GetIdentHash (), 0, encryptedMsg } }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 3b395f4d..a066c64c 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -176,6 +176,7 @@ namespace client void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey = nullptr); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); + void SendNextLeaseSetRequest (const i2p::data::IdentHash& key, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); From ffdd5935e90e65300da10164ca72a0de64a52b4a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 31 Jan 2024 11:46:01 -0500 Subject: [PATCH 0409/1160] Handle drop of own RouterInfo publishing message --- libi2pd/RouterContext.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b3c51ca6..40949891 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1378,10 +1378,19 @@ namespace i2p uint32_t replyToken; RAND_bytes ((uint8_t *)&replyToken, 4); LogPrint (eLogInfo, "Router: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); + auto onDrop = [this]() + { + if (m_Service) + m_Service->GetService ().post ([this]() { HandlePublishResendTimer (boost::system::error_code ()); }); + }; if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect? i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ? + { // send directly - i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); + auto msg = CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken); + msg->onDrop = onDrop; + i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), msg); + } else { // otherwise through exploratory @@ -1392,6 +1401,7 @@ namespace i2p { // encrypt for floodfill auto msg = CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound); + msg->onDrop = onDrop; outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); } From 83cb3a1820802a5ddf01fb3de1f0654f9f56e237 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 31 Jan 2024 15:41:21 -0500 Subject: [PATCH 0410/1160] reduce router unreachable interval --- libi2pd/Profiling.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 6531e060..ed23fb12 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -35,7 +35,7 @@ namespace data const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes) - const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) + const int PEER_PROFILE_UNREACHABLE_INTERVAL = 480; // in seconds (8 minutes) const int PEER_PROFILE_USEFUL_THRESHOLD = 3; class RouterProfile From 96cf6ca531289328aeda9c8ea7f6eae06b338c57 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Feb 2024 18:14:45 -0500 Subject: [PATCH 0411/1160] drop earlier if outgoing queue is semi-full --- libi2pd/NTCP2.cpp | 7 ++++++- libi2pd/SSU2Session.cpp | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 6fe88509..76f3a940 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1250,8 +1250,13 @@ namespace transport void NTCP2Session::PostI2NPMessages (std::vector > msgs) { if (m_IsTerminated) return; + bool isSemiFull = m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE/2; for (auto it: msgs) - m_SendQueue.push_back (std::move (it)); + if (isSemiFull && it->onDrop) + it->Drop (); // drop earlier because we can handle it + else + m_SendQueue.push_back (std::move (it)); + if (!m_IsSending) SendQueue (); else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 9180ccc8..12671f4f 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -351,8 +351,12 @@ namespace transport void SSU2Session::PostI2NPMessages (std::vector > msgs) { if (m_State == eSSU2SessionStateTerminated) return; + bool isSemiFull = m_SendQueue.size () > SSU2_MAX_OUTGOING_QUEUE_SIZE/2; for (auto it: msgs) - m_SendQueue.push_back (std::move (it)); + if (isSemiFull && it->onDrop) + it->Drop (); // drop earlier because we can handle it + else + m_SendQueue.push_back (std::move (it)); SendQueue (); if (m_SendQueue.size () > 0) // windows is full From 8f28cee32fa76c87d8b2930a6197732a21f84852 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Feb 2024 18:55:10 -0500 Subject: [PATCH 0412/1160] drop earlier if delayed queue is semi-full --- libi2pd/Transports.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5d3027a9..a70e77b4 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -477,7 +477,10 @@ namespace transport } } for (auto& it1: msgs) - it->second.delayedMessages.push_back (it1); + if (sz > MAX_NUM_DELAYED_MESSAGES/2 && it1->onDrop) + it1->Drop (); // drop earlier because we can handle it + else + it->second.delayedMessages.push_back (it1); } else { From 47578b69c621a6d8b6a812530b8a6da31bbd9a9a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Feb 2024 19:38:12 -0500 Subject: [PATCH 0413/1160] handle drop of tunnel test message --- libi2pd/TunnelPool.cpp | 74 +++++++++++++++++++++++++++--------------- libi2pd/TunnelPool.h | 4 +-- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5339c9be..93df99be 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -360,36 +360,58 @@ namespace tunnel } // new tests - std::unique_lock l1(m_OutboundTunnelsMutex); - auto it1 = m_OutboundTunnels.begin (); - std::unique_lock l2(m_InboundTunnelsMutex); - auto it2 = m_InboundTunnels.begin (); - while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) + std::vector, std::shared_ptr > > newTests; { - bool failed = false; - if ((*it1)->IsFailed ()) + std::unique_lock l1(m_OutboundTunnelsMutex); + auto it1 = m_OutboundTunnels.begin (); + std::unique_lock l2(m_InboundTunnelsMutex); + auto it2 = m_InboundTunnels.begin (); + while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { - failed = true; - ++it1; - } - if ((*it2)->IsFailed ()) - { - failed = true; - ++it2; - } - if (!failed) - { - uint32_t msgID; - RAND_bytes ((uint8_t *)&msgID, 4); + bool failed = false; + if ((*it1)->IsFailed ()) { - std::unique_lock l(m_TestsMutex); - m_Tests[msgID] = std::make_pair (*it1, *it2); + failed = true; + ++it1; + } + if ((*it2)->IsFailed ()) + { + failed = true; + ++it2; + } + if (!failed) + { + newTests.push_back(std::make_pair (*it1, *it2)); + ++it1; ++it2; } - (*it1)->SendTunnelDataMsgTo ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), - CreateDeliveryStatusMsg (msgID)); - ++it1; ++it2; } - } + } + for (auto& it: newTests) + { + uint32_t msgID; + RAND_bytes ((uint8_t *)&msgID, 4); + { + std::unique_lock l(m_TestsMutex); + m_Tests[msgID] = it; + } + auto msg = CreateDeliveryStatusMsg (msgID); + auto outbound = it.first; + auto s = shared_from_this (); + msg->onDrop = [msgID, outbound, s]() + { + // if test msg dropped locally it's outbound tunnel to blame + outbound->SetState (eTunnelStateFailed); + { + std::unique_lock l(s->m_TestsMutex); + s->m_Tests.erase (msgID); + } + { + std::unique_lock l(s->m_OutboundTunnelsMutex); + s->m_OutboundTunnels.erase (outbound); + } + }; + outbound->SendTunnelDataMsgTo (it.second->GetNextIdentHash (), it.second->GetNextTunnelID (), msg); + } } void TunnelPool::ManageTunnels (uint64_t ts) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index c1fd19cd..7cb1f5c9 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -30,7 +30,7 @@ namespace tunnel const int TUNNEL_POOL_MANAGE_INTERVAL = 10; // in seconds const int TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY = 16; const int TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY = 16; - const int TUNNEL_POOL_MAX_NUM_BUILD_REQUESTS = 2; + const int TUNNEL_POOL_MAX_NUM_BUILD_REQUESTS = 3; class Tunnel; class InboundTunnel; From 7b776666a3dcec3e7237a064c2ce97139e7a86ea Mon Sep 17 00:00:00 2001 From: StormyCloudInc <64628149+WaxySteelWorm@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:21:19 -0600 Subject: [PATCH 0414/1160] Add files via upload --- .../reseed/admin_at_stormycloud.org.crt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 contrib/certificates/reseed/admin_at_stormycloud.org.crt diff --git a/contrib/certificates/reseed/admin_at_stormycloud.org.crt b/contrib/certificates/reseed/admin_at_stormycloud.org.crt new file mode 100644 index 00000000..ae44521b --- /dev/null +++ b/contrib/certificates/reseed/admin_at_stormycloud.org.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF1zCCA7+gAwIBAgIRAMDqFR09Xuj8ZUu+oetSvAEwDQYJKoZIhvcNAQELBQAw +dTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE +ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxHjAcBgNVBAMM +FWFkbWluQHN0b3JteWNsb3VkLm9yZzAeFw0yNDAxMjUxNDE1MzBaFw0zNDAxMjUx +NDE1MzBaMHUxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx +HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR4w +HAYDVQQDDBVhZG1pbkBzdG9ybXljbG91ZC5vcmcwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDbGX+GikPzQXr9zvkrhfO9g0l49KHLNQhUKYqd6T+PfnGo +Fm0d3ZZVVQZ045vWgroOXDGGZZWxUIlb2inRaR2DF1TxN3pPYt59RgY9ZQ9+TL7o +isY91krCRygY8EcAmHIjlfZQ9dBVcL7CfyT0MYZA5Efee9+NDHSewTfQP9T2faIE +83Fcyd93a2mIHYjKUbJnojng/wgsy8srbsEuuTok4MIQmDj+B5nz+za2FgI0/ydh +srlMt4aGJF4/DIem9z9d0zBCOkwrmtFIzjNF1mOSA8ES4m5YnKA/y9rZlRidLPGu +prbXhPVnqHeOnHMz2QCw1wbVo504kl0bMqyEz2tVWsO9ep7iZoQs2xkFAEaegYNT +QLUpwVGlyuq3wXXwopFRffOSimGSazICwWI6j+K0pOtgefNJaWrqKYvtkj1SbK2L +LBNUIENz6VnB7KPRckuX6zxC8PpOiBK9BcftfO+xAz/wC6qq3riBPw30KKSym0nC +Zp5KciDn4Phtw9PGq8Bkl8SyWl0jtFnfTB1tzJkisf2qKcNHaFTEe2JW763YLbh/ +AU+8X8evFu40qLgvOgKoyy5DLy6i8zetX+3t9K0Fxt9+Vzzq6lm5V/RS8iIPPn+M +q1/3Z5kD0KQBG9h/Gl8BH+lB71ZxPAOZ3SMu8DJZcxBLVmDWqQPCr5CKnoz0swID +AQABo2IwYDAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG +AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHgYDVR0OBBcEFWFkbWluQHN0b3JteWNs +b3VkLm9yZzANBgkqhkiG9w0BAQsFAAOCAgEARWOJ69vTHMneSXYscha+4Ytjg0RM +faewJNEGj8qy/Qvh9si2bWYNPRK6BlbHFS7pRYBLAnhaeLBGVv1CCR6GUMMe74zQ +UuMeAoWU6qMDmB3GfYoZJh8sIxpwHqyJeTdeccRbZ4sX4F6u3IHPXYiU/AgbYqH7 +pYXQg2lCjXZYaDFAlEf5SlYUDOhhXe5kR8Edhlrsu32/JzA1DQK0JjxKCBp+DQmA +ltdOpQtAg03fHP4ssdj7VvjIDl28iIlATwBvHrdNm7T0tYWn6TWhvxbRqvfTxfaH +MvxnPdIJwNP4/9TyQkwjwHb1h+ucho3CnxI/AxspdOvT1ElMhP6Ce6rcS9pk11Rl +x0ChsqpWwDg7KYpg0qZFSKCTBp4zBq9xoMJ6BQcgMfyl736WbsCzFTEyfifp8beg +NxUa/Qk7w7cuSPGyMIKNOmOR7FLlFbtocy8sXVsUQdqnp/edelufdNe39U9uNtY6 +yoXI9//Tc6NgOwy2Oyia0slZ5qHRkB7e4USXMRzJ3p4q9eCVKjAJs81Utp7O2U+9 +vhbhwWP8CAnNTT1E5WS6EKtfrdqF7wjkV+noPGLDGmrXi01J1fSMAjMfVO+7/LOL +UN+G4ybKWnEhhOO27yidN8Xx6UrCS23DBlPPQAeA74dTsTExiOxf1o1EXzcQiMyO +LAj3/Ojbi1xkWhI= +-----END CERTIFICATE----- From de2b0f6e0986c16d394e1d9b34dcd10266d96e2f Mon Sep 17 00:00:00 2001 From: StormyCloudInc <64628149+WaxySteelWorm@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:24:11 -0600 Subject: [PATCH 0415/1160] Update Config.cpp --- libi2pd/Config.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 4deb59ac..18cc69ee 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -223,7 +223,8 @@ namespace config { "https://i2p.ghativega.in/," "https://i2p.novg.net/," "https://reseed.is.prestium.org/," - "https://reseed.us.prestium.org/" + "https://reseed.us.prestium.org/", + "https://reseed.stormycloud.org/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From ce356378667fac05b192ec5e9ae1e4c7fbf7bc31 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Feb 2024 15:45:22 -0500 Subject: [PATCH 0416/1160] handle drop of tunnel build message --- libi2pd/Tunnel.cpp | 14 ++++++++++---- libi2pd/Tunnel.h | 14 +++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index b8e17920..b578217f 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -90,7 +90,13 @@ namespace tunnel hop = hop->prev; } msg->FillI2NPMessageHeader (m_Config->IsShort () ? eI2NPShortTunnelBuild : eI2NPVariableTunnelBuild); - + auto s = shared_from_this (); + msg->onDrop = [s]() + { + LogPrint (eLogInfo, "I2NP: Tunnel ", s->GetTunnelID (), " request was not sent"); + s->SetState (i2p::tunnel::eTunnelStateBuildFailed); + }; + // send message if (outboundTunnel) { @@ -246,7 +252,7 @@ namespace tunnel { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive EncryptTunnelMsg (msg, msg); - msg->from = shared_from_this (); + msg->from = GetSharedFromThis (); m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } @@ -261,7 +267,7 @@ namespace tunnel if (msg) { m_NumReceivedBytes += msg->GetLength (); - msg->from = shared_from_this (); + msg->from = GetSharedFromThis (); HandleI2NPMessage (msg); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index e6e3c3a5..47ff0465 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -65,7 +65,8 @@ namespace tunnel class OutboundTunnel; class InboundTunnel; - class Tunnel: public TunnelBase + class Tunnel: public TunnelBase, + public std::enable_shared_from_this { struct TunnelHop { @@ -155,7 +156,7 @@ namespace tunnel i2p::data::IdentHash m_EndpointIdentHash; }; - class InboundTunnel: public Tunnel, public std::enable_shared_from_this + class InboundTunnel: public Tunnel { public: @@ -167,6 +168,13 @@ namespace tunnel // override TunnelBase void Cleanup () override { m_Endpoint.Cleanup (); }; + protected: + + std::shared_ptr GetSharedFromThis () + { + return std::static_pointer_cast(shared_from_this ()); + } + private: TunnelEndpoint m_Endpoint; From be815804e66c878c81cb802193b589204d66005b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 5 Feb 2024 15:44:17 -0500 Subject: [PATCH 0417/1160] expire transit tunnel is not sent further --- libi2pd/I2NPProtocol.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index ebd5f8d6..70cefbdc 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -584,13 +584,14 @@ namespace i2p memcpy (ivKey, noiseState.m_CK , 32); // check if we accept this tunnel + std::shared_ptr transitTunnel; uint8_t retCode = 0; if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ()) retCode = 30; if (!retCode) { // create new transit tunnel - auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( + transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), @@ -624,11 +625,22 @@ namespace i2p reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } // send reply + auto onDrop = [transitTunnel]() + { + if (transitTunnel) + { + auto t = transitTunnel->GetCreationTime (); + if (t > i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT) + // make transit tunnel expired + transitTunnel->SetCreationTime (t - i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT); + } + }; if (isEndpoint) { auto replyMsg = NewI2NPShortMessage (); replyMsg->Concat (buf, len); replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); + if (transitTunnel) replyMsg->onDrop = onDrop; if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local? { @@ -652,9 +664,12 @@ namespace i2p } } else - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, - bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + { + auto msg = CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); + if (transitTunnel) msg->onDrop = onDrop; + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, msg); + } return; } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; @@ -714,7 +729,11 @@ namespace i2p return msg; } else - return CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ()); + { + auto newMsg = CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ()); + if (msg->onDrop) newMsg->onDrop = msg->onDrop; + return newMsg; + } } std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, From f64b136f5a8426c304e38946c5cf8cfa62de5281 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Feb 2024 13:37:08 -0500 Subject: [PATCH 0418/1160] remove prestium reseeds --- .../reseed/null_at_i2pmail.org.crt | 33 ------------------ .../reheatedburger_at_protonmail.com.crt | 34 ------------------- libi2pd/Config.cpp | 4 +-- 3 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 contrib/certificates/reseed/null_at_i2pmail.org.crt delete mode 100644 contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt diff --git a/contrib/certificates/reseed/null_at_i2pmail.org.crt b/contrib/certificates/reseed/null_at_i2pmail.org.crt deleted file mode 100644 index d736a95e..00000000 --- a/contrib/certificates/reseed/null_at_i2pmail.org.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFyDCCA7CgAwIBAgIRAO8lBnTo+hlvglQwug2jHZkwDQYJKoZIhvcNAQELBQAw -cDELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE -ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGTAXBgNVBAMM -EG51bGxAaTJwbWFpbC5vcmcwHhcNMjMwOTIxMjIzMTM2WhcNMzMwOTIxMjIzMTM2 -WjBwMQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYD -VQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UE -AwwQbnVsbEBpMnBtYWlsLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBAMMpAvaHwzuZZ6qelRU4jcgpuAIZFH++F1Te4b1t02pRfnQ0Eeh04VC1JxO0 -XjUr1/iszEyvrI4+AdxaobDyRFPylkOLtfec4d2ciDc1cupj6y2vyYhMVN31rrvE -ve7sKoTHJ5Dx+UPGOVZZsSsmK9TXIU23W2bo7k2VnjVBXdWZyNE4twfTYCosDnYA -1HIEaIUFVv+COqw2pktxkMmfUAlnDLeVSfsAzEr37K+x0Xk5hO8m6GWQx0NRjjYp -gyEcFhWAJjAYaF3gUVR9rVVky1OeFhZgxE/KzVrW7uc84ZCMKITEPwT0qqIpsTJp -486YXzuPSc+ef78cKSQf5992l7imySJ24I/5H73HkovGAFGZdwvl6V6Ta5YqO7RR -gVDOL1EIVUnMCqFBCE6RmyZqXBVrv4Cacdc6lZ4fj42SRtWZfe6rNCpJzTRtbOyW -DBmYpK6q/jddfqI1sX0PXIn9U+Rod5Z4uz82PAjhamqyr5fpAnoQxKppBvQ3tNfn -KQhmP73Hdpvl24pRyQLBIRUL86i7TPBBn7n3XZlQfXP7lp8+KJYLkL2/zCVDrwLX -kC9hRIxCU9bZbXlkRE2R/PrK53LZecjk2KcgINA4ZlguNgze/Qj8BXelUF4izbpV -bTSvniTM46AECvjDcICAOky9Ku4RnmUJxQVf3ahDEuso7/N7AgMBAAGjXTBbMA4G -A1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYD -VR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQbnVsbEBpMnBtYWlsLm9yZzANBgkqhkiG -9w0BAQsFAAOCAgEAEUfYJTdDH7uCojnpF0Gs2tXxPJ22UhdqEsXfqR7KhhmmApss -q5kiiPIYoy5T/4IM7NVyeeJAMYwQsdJjwZ4QyxLBb9EqMS2krREcPZNRfFzBr2Wj -EBhJEYTnbIn4docwJWyXsJVG0CqFXPF1qGd0Sc2u87yj2xZNTnloWKAEQAO7DE39 -gWfDH6slM/3h3WD3Mjuk7JoYSYmBfvvm2hkBbC6lzD7XY7rdSmIUwJ050e9UrJaV -La51dd5r4q8d1cHrVUwLiACAaXJ15AEqUDLHQcvKvyfhkabwRy+v0wsodSMgSMEH -xA+kGhkIW7yV7o2exYOYypHCca3IA+pimMpEseNNrHSwbHOMfauiN7jiZLEPg6D6 -a8XwK7qmMYUq7j6QWuIqI81o29WZRf4LZ0GFoVce+e5VxkVKSItKcJoedIAp1ML8 -NhFwd9s/nqWidu/StscEEbGzz6ZuDXwshERXC0QR8HjHEPi4U8220juf4cxUahxK -heEU91l7VksSZYRUN98h28vovGcukLcnVoLj5H/+Z4r/BgxMrOUJKetxf8fU7FjO -j1U6XV36tGi+IOwYQb9D5fTVafC3hHkuUIjlOdUGYadse98ILhn9kaNtqkBtk/EU -vK+McnrEv7tcKrbvYEop/KaUayhjFiL+wGWnpxt7gLhIiavnIeUyD7acltw= ------END CERTIFICATE----- diff --git a/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt b/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt deleted file mode 100644 index d14c5fe1..00000000 --- a/contrib/certificates/reseed/reheatedburger_at_protonmail.com.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIRANVB/+wEuXS0Ttoh5teJt90wDQYJKoZIhvcNAQELBQAw -fTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE -ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxJjAkBgNVBAMM -HXJlaGVhdGVkYnVyZ2VyQHByb3Rvbm1haWwuY29tMB4XDTIzMDkyMTE4MDAyOVoX -DTMzMDkyMTE4MDAyOVowfTELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYD -VQQJEwJYWDEeMBwGA1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQL -EwNJMlAxJjAkBgNVBAMMHXJlaGVhdGVkYnVyZ2VyQHByb3Rvbm1haWwuY29tMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuNwmiIY3MLSBS5sL5PXRDVK6 -MoSNw4qx0o8nDHvVBxNtzgc0/qjYvsuUggY0tZbPpxhML6GHd4qo7Z3Ip1x0MxhI -Ao5MJaflaEdm4+HeMy0IE3aU73KRUwp+nF3cUHZdlps+9mtYs4oncVEWkFQwGsgt -4yrLtXf6PmPWfFH28ffeaev90e+hdhQpTvr54Ewx6NTaMQr8mkhXL2utvPpjnPM5 -UAhOeJCMgfhLzgS4rahG0O8CQMtH5gKZ+6zjoSRatnjj0j1mBO7+e1TL5O7dVS9k -P83tmkIDDl4tXBzXr9aXQMJstbM2CEvinVcCsR74GjPcg4iB0Ift71Dx7oGKI06t -3bSvll0GZm2mFhIba/4q6f4oAJ2aeq6ejt1Kcm8g5cxtwrRZnXv5JXHZqba3y8J5 -zWaRHzhc9tyEqRBRkc6c7xMdZQ31iJ6TlxUT8vAJ1N7OnX87oHrCjwyikpyOen4r -Uvv1Ge054XPTeoHz+Jyt34t71ty1W13uPHpuvtPVR9MfgGrxd4Z9+LWvAjmMbFsZ -lC3Ll+94nUk+O0puU6KisuCGP4hCtdEtebkIqT8zo8LicLAYUMjX7KwnS7681Cu1 -sY2mB2oZAytN9Zy42oOoNeY5x39kxfwuut/2E1kxKX75O0bwfIXr611abCKc3bbz -euMrIsaB/2VFp9nAah8CAwEAAaNqMGgwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQW -MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCYGA1UdDgQf -BB1yZWhlYXRlZGJ1cmdlckBwcm90b25tYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOC -AgEATuHi2Yz52OK7e+sKVdHu2KrSLCGm98BG1UIMHFi3WRBTOFyp+lZ519bJ1rFj -tmP9E1a+k/vlbc7FbV4PcV6HJYfGEv/ImtJsEnrzbhrQphC1zMFv7q6JCTUbAzl6 -ySlJ++mVxQ6AzPNH3TQgL1wPKuLh76/Y4053fg+NI3PmzzhkTUheVDkg0/a9ENSf -xMnCa3fIm869735qHk67QlikFvAfWwc4zT1Ncwodh8G4+oX0GFzIl+OZaM1GTMuD -UCcFKoqwtjyLCr22xNk8CfyiExPJXQG1HzEvDcxyoxQtnh9occR9PgqXySz26/NM -XDyM+l4utLMGBcVY4x9fksRiaWEfxiygYOxY9zDl6clh6S10b3CLut4UMiS1RTtE -Mjx2BZN3p0nxpT2leJdGxtBPGrvxuiCOEmTbOMLc3DQtppXO97B3dVMtJ5Ee8Y6p -Tq/8eiHI6eQXat6dgFT5X16vzF7w7XO7fAxuqk4Kx1D1aTVyikdo+Fcdg44dWOjq -NZu8VcCzZij/Dfjlce6t6h8D+wvDD8AkiivaDljpvbNDx/QQlQXFgH98TZA8Rnvr -QcyNNATfz+1yQUiyO6Lrjaw64OJwXYX/llgnDC+qQpP6kqZabi2TsG0EVPukVvr9 -0HyAUu4lnXtTIDq2yPNenegCloqDL1ZQdaYd2XIItnfZdTY= ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 18cc69ee..b2ad7a17 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -222,8 +222,6 @@ namespace config { "https://www2.mk16.de/," "https://i2p.ghativega.in/," "https://i2p.novg.net/," - "https://reseed.is.prestium.org/," - "https://reseed.us.prestium.org/", "https://reseed.stormycloud.org/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( From c01fd3299ffb23f0497957ac6f10d8564a4fd7e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Feb 2024 18:51:59 -0500 Subject: [PATCH 0419/1160] handle drop of destination publish msg --- libi2pd/Destination.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 9b173f24..ef0d5db3 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -626,6 +626,15 @@ namespace client 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)); + auto s = shared_from_this (); + msg->onDrop = [s]() + { + s->GetService ().post([s]() + { + s->m_PublishConfirmationTimer.cancel (); + s->HandlePublishConfirmationTimer (boost::system::error_code()); + }); + }; m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -642,7 +651,7 @@ namespace client m_PublishReplyToken = 0; if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) { - LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); + LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds or failed. will try again"); Publish (); } else @@ -827,7 +836,9 @@ namespace client AddECIESx25519Key (replyKey, replyTag); else AddSessionKey (replyKey, replyTag); - auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES); + + auto msg = WrapMessageForRouter (nextFloodfill, + CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES)); auto s = shared_from_this (); msg->onDrop = [s, dest, request]() { @@ -836,13 +847,12 @@ namespace client s->SendNextLeaseSetRequest (dest, request); }); }; - auto encryptedMsg = WrapMessageForRouter (nextFloodfill, msg); request->outboundTunnel->SendTunnelDataMsgs ( { i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, encryptedMsg + nextFloodfill->GetIdentHash (), 0, msg } }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); From c158bbe90a7c502b9a5fc23d6a8218bf7372b3d3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Feb 2024 19:43:29 -0500 Subject: [PATCH 0420/1160] send frame when it exceeds 16K --- libi2pd/NTCP2.cpp | 3 +++ libi2pd/NTCP2.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 76f3a940..0dbccbca 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1152,10 +1152,13 @@ namespace transport msgs.push_back (msg); s += (len + 3); m_SendQueue.pop_front (); + if (s >= NTCP2_SEND_AFTER_FRAME_SIZE) + break; // send frame right a way } else if (len + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) { LogPrint (eLogError, "NTCP2: I2NP message of size ", len, " can't be sent. Dropped"); + msg->Drop (); m_SendQueue.pop_front (); } else diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index ba1380c3..1eac23f0 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -28,6 +28,7 @@ namespace transport { const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519; + const size_t NTCP2_SEND_AFTER_FRAME_SIZE = 16386; // send frame when exceeds this size const size_t NTCP2_SESSION_REQUEST_MAX_SIZE = 287; const size_t NTCP2_SESSION_CREATED_MAX_SIZE = 287; const int NTCP2_MAX_PADDING_RATIO = 6; // in % From 586695673b6b6e8fc9e6d3a17d963da196e98b71 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Feb 2024 18:48:10 -0500 Subject: [PATCH 0421/1160] correct log message for next netdb request --- libi2pd/NetDbRequests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 3b5f41b6..4893fa1b 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -189,6 +189,7 @@ namespace data direct = false; // floodfill can't be reached directly if (direct) { + LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination ().ToBase64 (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 (), " directly"); auto msg = dest->CreateRequestMessage (nextFloodfill->GetIdentHash ()); msg->onDrop = [this, dest]() { this->SendNextRequest (dest); }; i2p::transport::transports.SendMessage (nextFloodfill->GetIdentHash (), msg); @@ -200,7 +201,7 @@ namespace data auto inbound = pool->GetNextInboundTunnel (); if (nextFloodfill && outbound && inbound) { - LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); + LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination ().ToBase64 (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 (), " through tunnels"); auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); msg->onDrop = [this, dest]() { this->SendNextRequest (dest); }; outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, From f98027755281c4d168bd4843b1850ce7ceb2cfc6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Feb 2024 19:55:54 -0500 Subject: [PATCH 0422/1160] don't flood failed router --- libi2pd/NetDb.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index bedb19f6..f2166bf0 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -226,7 +226,8 @@ namespace data bool NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len) { bool updated; - AddRouterInfo (ident, buf, len, updated); + if (!AddRouterInfo (ident, buf, len, updated)) + updated = false; return updated; } @@ -874,7 +875,7 @@ namespace data } else // RouterInfo { - LogPrint (eLogDebug, "NetDb: Store request: RouterInfo"); + LogPrint (eLogDebug, "NetDb: Store request: RouterInfo ", ident.ToBase64()); size_t size = bufbe16toh (buf + offset); offset += 2; if (size > MAX_RI_BUFFER_SIZE || size > len - offset) From 1b23aa2d7b7e4696713f7ce0a4d90e1a92baee85 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Feb 2024 21:44:12 -0500 Subject: [PATCH 0423/1160] increase request timeout --- libi2pd/NetDb.cpp | 2 +- libi2pd/NetDbRequests.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index f2166bf0..f3822997 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -149,7 +149,7 @@ namespace data if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastManageRequest >= 15 || ts + 15 < lastManageRequest) // manage requests every 15 seconds + if (ts - lastManageRequest >= MANAGE_REQUESTS_INTERVAL || ts + MANAGE_REQUESTS_INTERVAL < lastManageRequest) // manage requests every 15 seconds { m_Requests.ManageRequests (); lastManageRequest = ts; diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 47a5d481..25c102de 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -21,8 +21,9 @@ namespace i2p namespace data { const size_t MAX_NUM_REQUEST_ATTEMPTS = 7; + const uint64_t MANAGE_REQUESTS_INTERVAL = 15; // in seconds const uint64_t MIN_REQUEST_TIME = 5; // in seconds - const uint64_t MAX_REQUEST_TIME = 60; // in seconds + const uint64_t MAX_REQUEST_TIME = MAX_NUM_REQUEST_ATTEMPTS*MANAGE_REQUESTS_INTERVAL; class RequestedDestination { From 7dd9a7a0afc0acfad81421ba681fc889ea08a8ce Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Feb 2024 21:45:57 -0500 Subject: [PATCH 0424/1160] added CheckLogLevel --- libi2pd/Log.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 1ec0c5fe..0164ea4f 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -87,8 +87,8 @@ namespace log { Log (); ~Log (); - LogType GetLogType () { return m_Destination; }; - LogLevel GetLogLevel () { return m_MinLevel; }; + LogType GetLogType () const { return m_Destination; }; + LogLevel GetLogLevel () const { return m_MinLevel; }; void Start (); void Stop (); @@ -160,6 +160,11 @@ namespace log { } // log } // i2p +inline bool CheckLogLevel (LogLevel level) noexcept +{ + return level <= i2p::log::Logger().GetLogLevel (); +} + /** internal usage only -- folding args array to single string */ template void LogPrint (std::stringstream& s, TValue&& arg) noexcept @@ -185,9 +190,7 @@ void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept template void LogPrint (LogLevel level, TArgs&&... args) noexcept { - i2p::log::Log &log = i2p::log::Logger(); - if (level > log.GetLogLevel ()) - return; + if (!CheckLogLevel (level)) return; // fold message to single string std::stringstream ss; @@ -200,7 +203,7 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept auto msg = std::make_shared(level, std::time(nullptr), std::move(ss).str()); msg->tid = std::this_thread::get_id(); - log.Append(msg); + i2p::log::Logger().Append(msg); } /** From 592d6ae4f47c7f1647e3b61862d28674fac882ad Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Feb 2024 21:56:25 -0500 Subject: [PATCH 0425/1160] check log level before calculating base32 or base64 of ident --- libi2pd/NetDb.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index f3822997..026ae53e 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -262,10 +262,12 @@ namespace data return nullptr; } } - LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64()); + if (CheckLogLevel (eLogInfo)) + LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64()); if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated { - LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); + if (CheckLogLevel (eLogDebug)) + LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); std::lock_guard l(m_FloodfillsMutex); if (wasFloodfill) m_Floodfills.Remove (r->GetIdentHash ()); @@ -280,7 +282,8 @@ namespace data } else { - LogPrint (eLogDebug, "NetDb: RouterInfo is older: ", ident.ToBase64()); + if (CheckLogLevel (eLogDebug)) + LogPrint (eLogDebug, "NetDb: RouterInfo is older: ", ident.ToBase64()); updated = false; } } @@ -297,7 +300,8 @@ namespace data } if (inserted) { - LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); + if (CheckLogLevel (eLogInfo)) + LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); if (r->IsFloodfill () && r->IsEligibleFloodfill ()) { if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || @@ -338,10 +342,11 @@ namespace data if(it->second->GetExpirationTime() < expires) { it->second->Update (buf, len, false); // signature is verified already - LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32()); + if (CheckLogLevel (eLogInfo)) + LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32()); updated = true; } - else + else if (CheckLogLevel (eLogDebug)) LogPrint(eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32()); } else @@ -352,7 +357,8 @@ namespace data auto leaseSet = std::make_shared (buf, len, false); // we don't need leases in netdb if (leaseSet->IsValid ()) { - LogPrint (eLogInfo, "NetDb: LeaseSet added: ", ident.ToBase32()); + if (CheckLogLevel (eLogInfo)) + LogPrint (eLogInfo, "NetDb: LeaseSet added: ", ident.ToBase32()); m_LeaseSets[ident] = leaseSet; updated = true; } @@ -376,7 +382,8 @@ namespace data i2p::util::GetSecondsSinceEpoch () + NETDB_EXPIRATION_TIMEOUT_THRESHOLD > leaseSet->GetPublishedTimestamp ()) { // TODO: implement actual update - LogPrint (eLogInfo, "NetDb: LeaseSet2 updated: ", ident.ToBase32()); + if (CheckLogLevel (eLogInfo)) + LogPrint (eLogInfo, "NetDb: LeaseSet2 updated: ", ident.ToBase32()); m_LeaseSets[ident] = leaseSet; return true; } @@ -863,19 +870,22 @@ namespace data { if (storeType == NETDB_STORE_TYPE_LEASESET) // 1 { - LogPrint (eLogDebug, "NetDb: Store request: LeaseSet for ", ident.ToBase32()); + if (CheckLogLevel (eLogDebug)) + LogPrint (eLogDebug, "NetDb: Store request: LeaseSet for ", ident.ToBase32()); updated = AddLeaseSet (ident, buf + offset, len - offset); } else // all others are considered as LeaseSet2 { - LogPrint (eLogDebug, "NetDb: Store request: LeaseSet2 of type ", int(storeType), " for ", ident.ToBase32()); + if (CheckLogLevel (eLogDebug)) + LogPrint (eLogDebug, "NetDb: Store request: LeaseSet2 of type ", int(storeType), " for ", ident.ToBase32()); updated = AddLeaseSet2 (ident, buf + offset, len - offset, storeType); } } } else // RouterInfo { - LogPrint (eLogDebug, "NetDb: Store request: RouterInfo ", ident.ToBase64()); + if (CheckLogLevel (eLogDebug)) + LogPrint (eLogDebug, "NetDb: Store request: RouterInfo ", ident.ToBase64()); size_t size = bufbe16toh (buf + offset); offset += 2; if (size > MAX_RI_BUFFER_SIZE || size > len - offset) From d96803a2909a966bad9cc0599a46191c982dce84 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Feb 2024 15:24:48 -0500 Subject: [PATCH 0426/1160] always request through tunnels in case of restricted routes --- libi2pd/NetDb.cpp | 1 + libi2pd/Transports.cpp | 25 ++++++++++++++++--------- libi2pd/Transports.h | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 026ae53e..e8c92658 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -730,6 +730,7 @@ namespace data void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) { + if (direct && i2p::transport::transports.RoutesRestricted ()) direct = false; // always use tunnels for restricted routes auto dest = m_Requests.CreateRequest (destination, false, direct, requestComplete); // non-exploratory if (!dest) { diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index a70e77b4..0afe47a1 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1015,18 +1015,25 @@ namespace transport } } - void Transports::RestrictRoutesToRouters(std::set routers) + void Transports::RestrictRoutesToRouters(const std::set& routers) { - std::unique_lock lock(m_TrustedRoutersMutex); + std::lock_guard lock(m_TrustedRoutersMutex); m_TrustedRouters.clear(); for (const auto & ri : routers ) m_TrustedRouters.push_back(ri); } - bool Transports::RoutesRestricted() const { - std::unique_lock famlock(m_FamilyMutex); - std::unique_lock routerslock(m_TrustedRoutersMutex); - return m_TrustedFamilies.size() > 0 || m_TrustedRouters.size() > 0; + bool Transports::RoutesRestricted() const + { + { + std::lock_guard routerslock(m_TrustedRoutersMutex); + if (!m_TrustedRouters.empty ()) return true; + } + { + std::lock_guard famlock(m_FamilyMutex); + if (!m_TrustedFamilies.empty ()) return true; + } + return false; } /** XXX: if routes are not restricted this dies */ @@ -1050,7 +1057,7 @@ namespace transport return i2p::data::netdb.GetRandomRouterInFamily(fam); } { - std::unique_lock l(m_TrustedRoutersMutex); + std::lock_guard l(m_TrustedRoutersMutex); auto sz = m_TrustedRouters.size(); if (sz) { @@ -1067,12 +1074,12 @@ namespace transport bool Transports::IsRestrictedPeer(const i2p::data::IdentHash & ih) const { { - std::unique_lock l(m_TrustedRoutersMutex); + std::lock_guard l(m_TrustedRoutersMutex); for (const auto & r : m_TrustedRouters ) if ( r == ih ) return true; } { - std::unique_lock l(m_FamilyMutex); + std::lock_guard l(m_FamilyMutex); auto ri = i2p::data::netdb.FindRouter(ih); for (const auto & fam : m_TrustedFamilies) if(ri->IsFamily(fam)) return true; diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 540bafb4..206b0256 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -165,7 +165,7 @@ namespace transport /** restrict routes to use only these router families for first hops */ void RestrictRoutesToFamilies(const std::set& families); /** restrict routes to use only these routers for first hops */ - void RestrictRoutesToRouters(std::set routers); + void RestrictRoutesToRouters(const std::set& routers); bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; From 36dbc15bca1a41f7f764a15e2c272394aa06154d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Feb 2024 18:08:51 -0500 Subject: [PATCH 0427/1160] keep SSU2 socket open even if failed to bind --- libi2pd/SSU2.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 0ebeab6d..3e0583ea 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -258,13 +258,22 @@ namespace transport socket.set_option (boost::asio::ip::v6_only (true)); socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU2_SOCKET_RECEIVE_BUFFER_SIZE)); socket.set_option (boost::asio::socket_base::send_buffer_size (SSU2_SOCKET_SEND_BUFFER_SIZE)); + } + catch (std::exception& ex ) + { + LogPrint (eLogCritical, "SSU2: Failed to open socket on ", localEndpoint.address (), ": ", ex.what()); + ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint.address (), ": ", ex.what ()); + return socket; + } + try + { socket.bind (localEndpoint); LogPrint (eLogInfo, "SSU2: Start listening on ", localEndpoint); } catch (std::exception& ex ) { - LogPrint (eLogCritical, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what()); - ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ()); + LogPrint (eLogWarning, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what(), ". Actual endpoint is ", socket.local_endpoint ()); + // we can continue without binding being firewalled } return socket; } From adba3987f84f67f6ab8b2be8762f51ff29154a71 Mon Sep 17 00:00:00 2001 From: Vort Date: Sat, 10 Feb 2024 17:10:21 +0200 Subject: [PATCH 0428/1160] logging fixes --- libi2pd/NTCP2.cpp | 2 +- libi2pd/RouterInfo.cpp | 2 +- libi2pd/SSU2Session.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 0dbccbca..19609b0b 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -381,7 +381,7 @@ namespace transport if (remoteIdentity) { LogPrint (eLogDebug, "NTCP2: Session with ", GetRemoteEndpoint (), - " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ") terminated"); + " (", i2p::data::GetIdentHashAbbreviation (remoteIdentity->GetIdentHash ()), ") terminated"); } else { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 7cde7c33..a034691a 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -131,7 +131,7 @@ namespace data m_BufferLen = s.tellg (); if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE) { - LogPrint(eLogError, "RouterInfo: File", fullPath, " is malformed"); + LogPrint(eLogError, "RouterInfo: File ", fullPath, " is malformed"); return false; } s.seekg(0, std::ios::beg); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 12671f4f..4015dcac 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -277,7 +277,7 @@ namespace transport if (remoteIdentity) { LogPrint (eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (), - " (", i2p::data::GetIdentHashAbbreviation (GetRemoteIdentity ()->GetIdentHash ()), ") terminated"); + " (", i2p::data::GetIdentHashAbbreviation (remoteIdentity->GetIdentHash ()), ") terminated"); } else { From 158160f5c0256bd91bb68c5550d5fe97150dcda2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Feb 2024 20:03:36 -0500 Subject: [PATCH 0429/1160] common code for SOCKS5 proxy connectivity --- libi2pd/NTCP2.cpp | 119 ++++------------------------ libi2pd/NTCP2.h | 3 +- libi2pd/SSU2.h | 1 + libi2pd/Socks5.h | 154 +++++++++++++++++++++++++++++++++++++ libi2pd/TransportSession.h | 11 +-- 5 files changed, 170 insertions(+), 118 deletions(-) create mode 100644 libi2pd/Socks5.h diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 19609b0b..58a1c539 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -19,9 +19,10 @@ #include "RouterContext.h" #include "Transports.h" #include "NetDb.hpp" -#include "NTCP2.h" #include "HTTP.h" #include "util.h" +#include "Socks5.h" +#include "NTCP2.h" #if defined(__linux__) && !defined(_NETINET_IN_H) #include @@ -1728,47 +1729,18 @@ namespace transport case eSocksProxy: { // TODO: support username/password auth etc - static const uint8_t buff[3] = {SOCKS5_VER, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), - [] (const boost::system::error_code & ec, std::size_t transferred) - { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP2: SOCKS5 write error ", ec.message()); - } - }); - auto readbuff = std::make_shared >(2); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), - [this, readbuff, timer, conn](const boost::system::error_code & ec, std::size_t transferred) - { - if(ec) - { - LogPrint(eLogError, "NTCP2: SOCKS5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if((*readbuff)[1] == 0x00) - { - AfterSocksHandshake(conn, timer); - return; - } - else if ((*readbuff)[1] == 0xff) - { - LogPrint(eLogError, "NTCP2: SOCKS5 proxy rejected authentication"); - timer->cancel(); - conn->Terminate(); - return; - } - LogPrint(eLogError, "NTCP2:", (int)(*readbuff)[1]); - } - LogPrint(eLogError, "NTCP2: SOCKS5 server gave invalid response"); + Socks5Handshake (conn->GetSocket(), conn->GetRemoteEndpoint (), + [conn, timer](const boost::system::error_code& ec) + { timer->cancel(); - conn->Terminate(); - }); + if (!ec) + conn->ClientLogin(); + else + { + LogPrint(eLogError, "NTCP2: SOCKS proxy handshake error ", ec.message()); + conn->Terminate(); + } + }); break; } case eHTTPProxy: @@ -1836,71 +1808,6 @@ namespace transport } } - void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer) - { - // build request - size_t sz = 6; // header + port - auto buff = std::make_shared >(256); - auto readbuff = std::make_shared >(256); - (*buff)[0] = SOCKS5_VER; - (*buff)[1] = SOCKS5_CMD_CONNECT; - (*buff)[2] = 0x00; - - auto& ep = conn->GetRemoteEndpoint (); - if(ep.address ().is_v4 ()) - { - (*buff)[3] = SOCKS5_ATYP_IPV4; - auto addrbytes = ep.address ().to_v4().to_bytes(); - sz += 4; - memcpy(buff->data () + 4, addrbytes.data(), 4); - } - else if (ep.address ().is_v6 ()) - { - (*buff)[3] = SOCKS5_ATYP_IPV6; - auto addrbytes = ep.address ().to_v6().to_bytes(); - sz += 16; - memcpy(buff->data () + 4, addrbytes.data(), 16); - } - else - { - // We mustn't really fall here because all connections are made to IP addresses - LogPrint(eLogError, "NTCP2: Tried to connect to unexpected address via proxy"); - return; - } - htobe16buf(buff->data () + sz - 2, ep.port ()); - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), - [buff](const boost::system::error_code & ec, std::size_t written) - { - if(ec) - { - LogPrint(eLogError, "NTCP2: Failed to write handshake to socks proxy ", ec.message()); - return; - } - }); - - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), SOCKS5_UDP_IPV4_REQUEST_HEADER_SIZE), // read min reply size - boost::asio::transfer_all(), - [timer, conn, readbuff](const boost::system::error_code & e, std::size_t transferred) - { - if (e) - LogPrint(eLogError, "NTCP2: SOCKS proxy read error ", e.message()); - else if (!(*readbuff)[1]) // succeeded - { - boost::system::error_code ec; - size_t moreBytes = conn->GetSocket ().available(ec); - if (moreBytes) // read remaining portion of reply if ipv6 received - boost::asio::read (conn->GetSocket (), boost::asio::buffer(readbuff->data (), moreBytes), boost::asio::transfer_all (), ec); - timer->cancel(); - conn->ClientLogin(); - return; - } - else - LogPrint(eLogError, "NTCP2: Proxy reply error ", (int)(*readbuff)[1]); - timer->cancel(); - conn->Terminate(); - }); - } - void NTCP2Server::SetLocalAddress (const boost::asio::ip::address& localAddress) { auto addr = std::make_shared(boost::asio::ip::tcp::endpoint(localAddress, 0)); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 1eac23f0..a566b38d 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -267,8 +267,7 @@ namespace transport void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); - void AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer); - + // timer void ScheduleTermination (); void HandleTerminationTimer (const boost::system::error_code& ecode); diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index da682746..da5ca317 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -13,6 +13,7 @@ #include #include "util.h" #include "SSU2Session.h" +#include "Socks5.h" namespace i2p { diff --git a/libi2pd/Socks5.h b/libi2pd/Socks5.h new file mode 100644 index 00000000..84a23997 --- /dev/null +++ b/libi2pd/Socks5.h @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2024, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +* +*/ + +#ifndef SOCKS5_H__ +#define SOCKS5_H__ + +#include +#include +#include +#include "I2PEndian.h" + +namespace i2p +{ +namespace transport +{ + // SOCKS5 constants + const uint8_t SOCKS5_VER = 0x05; + const uint8_t SOCKS5_CMD_CONNECT = 0x01; + const uint8_t SOCKS5_CMD_UDP_ASSOCIATE = 0x03; + const uint8_t SOCKS5_ATYP_IPV4 = 0x01; + const uint8_t SOCKS5_ATYP_IPV6 = 0x04; + const uint8_t SOCKS5_ATYP_NAME = 0x03; + const size_t SOCKS5_UDP_IPV4_REQUEST_HEADER_SIZE = 10; + const size_t SOCKS5_UDP_IPV6_REQUEST_HEADER_SIZE = 22; + + // SOCKS5 handshake + template + void Socks5Connect (Socket& s, Handler handler, std::shared_ptr > buff, uint16_t port) + { + if (buff && buff->size () >= 6) + { + (*buff)[0] = SOCKS5_VER; + (*buff)[1] = SOCKS5_CMD_CONNECT; + (*buff)[2] = 0x00; + htobe16buf(buff->data () + buff->size () - 2, port); + boost::asio::async_write(s, boost::asio::buffer(*buff), boost::asio::transfer_all(), + [buff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) + { + (void) transferred; + if (!ec) + { + auto readbuff = std::make_shared >(262); // max possible + boost::asio::async_read(s, boost::asio::buffer(readbuff->data (), 7), boost::asio::transfer_all(), // read min reply size + [readbuff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) + { + if (!ec) + { + if (!(*readbuff)[1]) // succeeded + { + boost::system::error_code ec; + size_t moreBytes = s.available(ec); + if (!ec && moreBytes) // read remaining portion of reply + boost::asio::read (s, boost::asio::buffer(readbuff->data (), moreBytes), boost::asio::transfer_all (), ec); + if (!ec) + handler (boost::system::error_code ()); + else + handler (boost::asio::error::make_error_code (boost::asio::error::connection_aborted)); + } + else + handler (boost::asio::error::make_error_code (boost::asio::error::connection_refused)); + } + else + handler (ec); + }); + } + else + handler (ec); + }); + } + else + handler (boost::asio::error::make_error_code (boost::asio::error::no_buffer_space)); + } + + template + void Socks5Connect (Socket& s, const boost::asio::ip::tcp::endpoint& ep, Handler handler) + { + std::shared_ptr > buff; + if(ep.address ().is_v4 ()) + { + buff = std::make_shared >(10); + (*buff)[3] = SOCKS5_ATYP_IPV4; + auto addrbytes = ep.address ().to_v4().to_bytes(); + memcpy(buff->data () + 4, addrbytes.data(), 4); + } + else if (ep.address ().is_v6 ()) + { + buff = std::make_shared >(22); + (*buff)[3] = SOCKS5_ATYP_IPV6; + auto addrbytes = ep.address ().to_v6().to_bytes(); + memcpy(buff->data () + 4, addrbytes.data(), 16); + } + if (buff) + Socks5Connect (s, handler, buff, ep.port ()); + else + handler (boost::asio::error::make_error_code (boost::asio::error::fault)); + } + + template + void Socks5Connect (Socket& s, const std::pair& ep, Handler handler) + { + auto& addr = ep.first; + if (addr.length () <= 255) + { + auto buff = std::make_shared >(addr.length () + 7); + (*buff)[3] = SOCKS5_ATYP_NAME; + (*buff)[4] = addr.length (); + memcpy (buff->data () + 5, addr.c_str (), addr.length ()); + Socks5Connect (s, handler, buff, ep.second); + } + else + handler (boost::asio::error::make_error_code (boost::asio::error::name_too_long)); + } + + + template + void Socks5Handshake (Socket& s, Endpoint ep, Handler handler) + { + static const uint8_t methodSelection[3] = { SOCKS5_VER, 0x01, 0x00 }; // 1 method, no auth + boost::asio::async_write(s, boost::asio::buffer(methodSelection, 3), boost::asio::transfer_all(), + [&s, ep, handler] (const boost::system::error_code& ec, std::size_t transferred) + { + (void) transferred; + if (!ec) + { + auto readbuff = std::make_shared >(2); + boost::asio::async_read(s, boost::asio::buffer(*readbuff), boost::asio::transfer_all(), + [&s, ep, handler, readbuff] (const boost::system::error_code& ec, std::size_t transferred) + { + if (!ec) + { + if (transferred == 2 && (*readbuff)[1] == 0x00) // no auth + Socks5Connect (s, ep, handler); + else + handler (boost::asio::error::make_error_code (boost::asio::error::invalid_argument)); + } + else + handler (ec); + }); + } + else + handler (ec); + }); + } + +} +} + +#endif diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index f4668116..c6bf0de3 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -187,15 +187,6 @@ namespace transport uint64_t m_LastActivityTimestamp, m_LastBandwidthUpdateTimestamp; uint32_t m_InBandwidth, m_OutBandwidth; }; - - // SOCKS5 proxy - const uint8_t SOCKS5_VER = 0x05; - const uint8_t SOCKS5_CMD_CONNECT = 0x01; - const uint8_t SOCKS5_CMD_UDP_ASSOCIATE = 0x03; - const uint8_t SOCKS5_ATYP_IPV4 = 0x01; - const uint8_t SOCKS5_ATYP_IPV6 = 0x04; - const size_t SOCKS5_UDP_IPV4_REQUEST_HEADER_SIZE = 10; - const size_t SOCKS5_UDP_IPV6_REQUEST_HEADER_SIZE = 22; } } From 0ae7931a6f4d0299f64f95bea8249b8d6fd7b17d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Feb 2024 11:23:37 -0500 Subject: [PATCH 0430/1160] replaced SOCKS4 outproxy by SOCKS5 --- libi2pd_client/HTTPProxy.cpp | 71 ++++++++++-------------------------- 1 file changed, 19 insertions(+), 52 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index a0fc8f07..5f9ee1de 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -29,6 +29,7 @@ #include "Config.h" #include "HTTP.h" #include "I18N.h" +#include "Socks5.h" namespace i2p { namespace proxy { @@ -93,9 +94,6 @@ namespace proxy { void HTTPConnect(const std::string & host, uint16_t port); void HandleHTTPConnectStreamRequestComplete(std::shared_ptr stream); - void HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transfered); - void HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transfered); - typedef std::function ProxyResolvedHandler; void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr, ProxyResolvedHandler handler); @@ -612,43 +610,30 @@ namespace proxy { void HTTPReqHandler::HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec) { - if(!ec) { - if(m_RequestURL.host.size() > 255) { + if(!ec) + { + if(m_RequestURL.host.size() > 255) + { GenericProxyError(tr("Hostname is too long"), m_RequestURL.host); return; } uint16_t port = m_RequestURL.port; if(!port) port = 80; LogPrint(eLogDebug, "HTTPProxy: Connected to SOCKS upstream"); - std::string host = m_RequestURL.host; - std::size_t reqsize = 0; - m_socks_buf[0] = '\x04'; - m_socks_buf[1] = 1; - htobe16buf(m_socks_buf+2, port); - m_socks_buf[4] = 0; - m_socks_buf[5] = 0; - m_socks_buf[6] = 0; - m_socks_buf[7] = 1; - // user id - m_socks_buf[8] = 'i'; - m_socks_buf[9] = '2'; - m_socks_buf[10] = 'p'; - m_socks_buf[11] = 'd'; - m_socks_buf[12] = 0; - reqsize += 13; - memcpy(m_socks_buf+ reqsize, host.c_str(), host.size()); - reqsize += host.size(); - m_socks_buf[++reqsize] = 0; - boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2)); - } else GenericProxyError(tr("Cannot connect to upstream SOCKS proxy"), ec.message()); - } - - void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred) - { - LogPrint(eLogDebug, "HTTPProxy: Upstream SOCKS handshake sent"); - if(ec) GenericProxyError(tr("Cannot negotiate with SOCKS proxy"), ec.message()); - else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2)); + auto s = shared_from_this (); + i2p::transport::Socks5Handshake (*m_proxysock, std::make_pair(host, port), + [s](const boost::system::error_code& ec) + { + if (!ec) + s->SocksProxySuccess(); + else + s->GenericProxyError(tr("SOCKS proxy error"), ec.message ()); + }); + + } + else + GenericProxyError(tr("Cannot connect to upstream SOCKS proxy"), ec.message()); } void HTTPReqHandler::HandoverToUpstreamProxy() @@ -714,24 +699,6 @@ namespace proxy { } } - void HTTPReqHandler::HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transferred) - { - if(!ec) - { - if(m_socks_buf[1] == 90) { - // success - SocksProxySuccess(); - } else { - std::stringstream ss; - ss << "error code: "; - ss << (int) m_socks_buf[1]; - std::string msg = ss.str(); - GenericProxyError(tr("SOCKS proxy error"), msg); - } - } - else GenericProxyError(tr("No reply from SOCKS proxy"), ec.message()); - } - void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec) { if(!ec) { From b07530a8a17f49745fbee0b6df6ddd6644779796 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Feb 2024 11:44:15 -0500 Subject: [PATCH 0431/1160] don't print error message if operation cancelled --- libi2pd_client/I2PService.cpp | 88 ++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index c30b7c9f..9b0b8028 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -240,54 +240,68 @@ namespace client void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { - LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) bytes_transfered, " bytes received"); - if (ecode) - { - LogPrint(eLogError, "TCPIPPipe: Downstream read error:" , ecode.message()); - if (ecode != boost::asio::error::operation_aborted) + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) bytes_transfered, " bytes received"); + if (ecode) + { + LogPrint(eLogWarning, "TCPIPPipe: Downstream read error:" , ecode.message()); Terminate(); - } else { - if (bytes_transfered > 0 ) - memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered); - UpstreamWrite(bytes_transfered); - } + } + else + { + if (bytes_transfered > 0 ) + memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered); + UpstreamWrite(bytes_transfered); + } + } } - void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) { - if (ecode) - { - LogPrint(eLogError, "TCPIPPipe: Downstream write error:" , ecode.message()); - if (ecode != boost::asio::error::operation_aborted) + void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + if (ecode) + { + LogPrint(eLogWarning, "TCPIPPipe: Downstream write error:" , ecode.message()); Terminate(); - } - else - AsyncReceiveUpstream(); + } + else + AsyncReceiveUpstream(); + } } - void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) { - if (ecode) - { - LogPrint(eLogError, "TCPIPPipe: Upstream write error:" , ecode.message()); - if (ecode != boost::asio::error::operation_aborted) + void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + if (ecode) + { + LogPrint(eLogWarning, "TCPIPPipe: Upstream write error:" , ecode.message()); Terminate(); - } - else - AsyncReceiveDownstream(); + } + else + AsyncReceiveDownstream(); + } } void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { - LogPrint(eLogDebug, "TCPIPPipe: Upstream ", (int)bytes_transfered, " bytes received"); - if (ecode) - { - LogPrint(eLogError, "TCPIPPipe: Upstream read error:" , ecode.message()); - if (ecode != boost::asio::error::operation_aborted) + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint(eLogDebug, "TCPIPPipe: Upstream ", (int)bytes_transfered, " bytes received"); + if (ecode) + { + LogPrint(eLogWarning, "TCPIPPipe: Upstream read error:" , ecode.message()); Terminate(); - } else { - if (bytes_transfered > 0 ) - memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered); - DownstreamWrite(bytes_transfered); - } + } + else + { + if (bytes_transfered > 0 ) + memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered); + DownstreamWrite(bytes_transfered); + } + } } void TCPIPAcceptor::Start () From 075f80aea23eab9b81c925c352291b73c4b34946 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Feb 2024 15:33:37 -0500 Subject: [PATCH 0432/1160] use SOCK5 proxy for upstream --- libi2pd_client/SOCKS.cpp | 121 ++++++--------------------------------- 1 file changed, 18 insertions(+), 103 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 547a2da2..49a04b81 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,6 +19,7 @@ #include "I2PTunnel.h" #include "I2PService.h" #include "util.h" +#include "Socks5.h" namespace i2p { @@ -27,10 +28,6 @@ namespace proxy static const size_t socks_buffer_size = 8192; static const size_t max_socks_hostname_size = 255; // Limit for socks5 and bad idea to traverse - //static const size_t SOCKS_FORWARDER_BUFFER_SIZE = 8192; - - static const size_t SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE = 8; - struct SOCKSDnsAddress { uint8_t size; @@ -132,7 +129,6 @@ namespace proxy boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method); boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); - boost::asio::const_buffers_1 GenerateUpstreamRequest(); bool Socks5ChooseAuth(); void Socks5UserPasswdResponse (); void SocksRequestFailed(errTypes error); @@ -146,9 +142,6 @@ namespace proxy void SocksUpstreamSuccess(); void AsyncUpstreamSockRead(); void SendUpstreamRequest(); - void HandleUpstreamData(uint8_t * buff, std::size_t len); - void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); - void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, @@ -161,9 +154,6 @@ namespace proxy uint8_t *m_remaining_data; //Data left to be sent uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded uint8_t m_response[7+max_socks_hostname_size]; - uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; - uint8_t m_upstream_request[14+max_socks_hostname_size]; - std::size_t m_upstream_response_len; address m_address; //Address std::size_t m_remaining_data_len; //Size of the data left to be sent uint32_t m_4aip; //Used in 4a requests @@ -280,37 +270,6 @@ namespace proxy return boost::asio::const_buffers_1(m_response, size); } - boost::asio::const_buffers_1 SOCKSHandler::GenerateUpstreamRequest() - { - size_t upstreamRequestSize = 0; - // TODO: negotiate with upstream - // SOCKS 4a - m_upstream_request[0] = '\x04'; //version - m_upstream_request[1] = m_cmd; - htobe16buf(m_upstream_request + 2, m_port); - m_upstream_request[4] = 0; - m_upstream_request[5] = 0; - m_upstream_request[6] = 0; - m_upstream_request[7] = 1; - // user id - m_upstream_request[8] = 'i'; - m_upstream_request[9] = '2'; - m_upstream_request[10] = 'p'; - m_upstream_request[11] = 'd'; - m_upstream_request[12] = 0; - upstreamRequestSize += 13; - if (m_address.dns.size <= max_socks_hostname_size - ( upstreamRequestSize + 1) ) { - // bounds check okay - memcpy(m_upstream_request + upstreamRequestSize, m_address.dns.value, m_address.dns.size); - upstreamRequestSize += m_address.dns.size; - // null terminate - m_upstream_request[++upstreamRequestSize] = 0; - } else { - LogPrint(eLogError, "SOCKS: BUG!!! m_addr.dns.sizs > max_socks_hostname - ( upstreamRequestSize + 1 ) )"); - } - return boost::asio::const_buffers_1(m_upstream_request, upstreamRequestSize); - } - bool SOCKSHandler::Socks5ChooseAuth() { m_response[0] = '\x05'; // Version @@ -724,32 +683,6 @@ namespace proxy std::placeholders::_1, std::placeholders::_2)); } - void SOCKSHandler::AsyncUpstreamSockRead() - { - LogPrint(eLogDebug, "SOCKS: Async upstream sock read"); - if (m_upstreamSock) { - m_upstreamSock->async_read_some(boost::asio::buffer(m_upstream_response, SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE), - std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); - } else { - LogPrint(eLogError, "SOCKS: No upstream socket for read"); - SocksRequestFailed(SOCKS5_GEN_FAIL); - } - } - - void SOCKSHandler::HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered) - { - if (ecode) { - if (m_state == UPSTREAM_HANDSHAKE ) { - // we are trying to handshake but it failed - SocksRequestFailed(SOCKS5_NET_UNREACH); - } else { - LogPrint(eLogError, "SOCKS: Bad state when reading from upstream: ", (int) m_state); - } - return; - } - HandleUpstreamData(m_upstream_response, bytes_transfered); - } - void SOCKSHandler::SocksUpstreamSuccess() { LogPrint(eLogInfo, "SOCKS: Upstream success"); @@ -776,46 +709,28 @@ namespace proxy } - void SOCKSHandler::HandleUpstreamData(uint8_t * dataptr, std::size_t len) - { - if (m_state == UPSTREAM_HANDSHAKE) { - m_upstream_response_len += len; - // handle handshake data - if (m_upstream_response_len < SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE) { - // too small, continue reading - AsyncUpstreamSockRead(); - } else if (len == SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE) { - // just right - uint8_t resp = m_upstream_response[1]; - if (resp == SOCKS4_OK) { - // we have connected ! - SocksUpstreamSuccess(); - } else { - // upstream failure - LogPrint(eLogError, "SOCKS: Upstream proxy failure: ", (int) resp); - // TODO: runtime error? - SocksRequestFailed(SOCKS5_GEN_FAIL); - } - } else { - // too big - SocksRequestFailed(SOCKS5_GEN_FAIL); - } - } else { - // invalid state - LogPrint(eLogError, "SOCKS: Invalid state reading from upstream: ", (int) m_state); - } - } void SOCKSHandler::SendUpstreamRequest() { LogPrint(eLogInfo, "SOCKS: Negotiating with upstream proxy"); EnterState(UPSTREAM_HANDSHAKE); - if (m_upstreamSock) { - boost::asio::write(*m_upstreamSock, GenerateUpstreamRequest()); - AsyncUpstreamSockRead(); - } else { + if (m_upstreamSock) + { + auto s = shared_from_this (); + i2p::transport::Socks5Handshake (*m_upstreamSock, std::make_pair(m_address.dns.ToString (), m_port), + [s](const boost::system::error_code& ec) + { + if (!ec) + s->SocksUpstreamSuccess(); + else + { + s->SocksRequestFailed(SOCKS5_NET_UNREACH); + LogPrint(eLogError, "SOCKS: Upstream proxy failure: ", ec.message ()); + } + }); + } + else LogPrint(eLogError, "SOCKS: No upstream socket to send handshake to"); - } } void SOCKSHandler::HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr) From d9b6262a6e903507697f323926ba9c5f321a234a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Feb 2024 12:10:29 -0500 Subject: [PATCH 0433/1160] removed unused field --- libi2pd_client/HTTPProxy.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 5f9ee1de..8f9f8ada 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -111,7 +111,6 @@ namespace proxy { bool m_Addresshelper; i2p::http::URL m_ProxyURL; i2p::http::URL m_RequestURL; - uint8_t m_socks_buf[255+8]; // for socks request/response int m_req_len; i2p::http::URL m_ClientRequestURL; i2p::http::HTTPReq m_ClientRequest; From 7691a5b4a92acd72cb2b676bf921928f978cdf3b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Feb 2024 13:22:26 -0500 Subject: [PATCH 0434/1160] use common SOCK5 code for reseed --- libi2pd/Reseed.cpp | 66 +++++++++------------------------------------- 1 file changed, 13 insertions(+), 53 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 5fdc2fae..f8307a56 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -26,6 +26,7 @@ #include "HTTP.h" #include "util.h" #include "Config.h" +#include "Socks5.h" namespace i2p { @@ -615,62 +616,21 @@ namespace data { // assume socks if not http, is checked before this for other types // TODO: support username/password auth etc - uint8_t hs_writebuf[3] = {0x05, 0x01, 0x00}; - uint8_t hs_readbuf[2]; - boost::asio::write(sock, boost::asio::buffer(hs_writebuf, 3), boost::asio::transfer_all(), ecode); - if(ecode) + bool success = false; + i2p::transport::Socks5Handshake (sock, std::make_pair(url.host, url.port), + [&success](const boost::system::error_code& ec) + { + if (!ec) + success = true; + else + LogPrint (eLogError, "Reseed: SOCKS handshake failed: ", ec.message()); + }); + service.run (); // execute all async operations + if (!success) { sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake write failed: ", ecode.message()); return ""; - } - boost::asio::read(sock, boost::asio::buffer(hs_readbuf, 2), ecode); - if(ecode) - { - sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake read failed: ", ecode.message()); - return ""; - } - size_t sz = 0; - uint8_t buf[256]; - - buf[0] = 0x05; - buf[1] = 0x01; - buf[2] = 0x00; - buf[3] = 0x03; - sz += 4; - size_t hostsz = url.host.size(); - if(1 + 2 + hostsz + sz > sizeof(buf)) - { - sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake failed, hostname too big: ", url.host); - return ""; - } - buf[4] = (uint8_t) hostsz; - memcpy(buf+5, url.host.c_str(), hostsz); - sz += hostsz + 1; - htobe16buf(buf+sz, url.port); - sz += 2; - boost::asio::write(sock, boost::asio::buffer(buf, sz), boost::asio::transfer_all(), ecode); - if(ecode) - { - sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake failed writing: ", ecode.message()); - return ""; - } - boost::asio::read(sock, boost::asio::buffer(buf, 10), ecode); - if(ecode) - { - sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake failed reading: ", ecode.message()); - return ""; - } - if(buf[1] != 0x00) - { - sock.close(); - LogPrint(eLogError, "Reseed: SOCKS handshake bad reply code: ", std::to_string(buf[1])); - return ""; - } + } } } } From 967627e58a3730d143aa0b15693a54bb93f0d0e8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Feb 2024 21:55:30 -0500 Subject: [PATCH 0435/1160] read correct reply length and handle reply codes --- libi2pd/Socks5.h | 106 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 25 deletions(-) diff --git a/libi2pd/Socks5.h b/libi2pd/Socks5.h index 84a23997..d611bff3 100644 --- a/libi2pd/Socks5.h +++ b/libi2pd/Socks5.h @@ -29,7 +29,87 @@ namespace transport const size_t SOCKS5_UDP_IPV4_REQUEST_HEADER_SIZE = 10; const size_t SOCKS5_UDP_IPV6_REQUEST_HEADER_SIZE = 22; + const uint8_t SOCKS5_REPLY_SUCCESS = 0x00; + const uint8_t SOCKS5_REPLY_SERVER_FAILURE = 0x01; + const uint8_t SOCKS5_REPLY_CONNECTION_NOT_ALLOWED = 0x02; + const uint8_t SOCKS5_REPLY_NETWORK_UNREACHABLE = 0x03; + const uint8_t SOCKS5_REPLY_HOST_UNREACHABLE = 0x04; + const uint8_t SOCKS5_REPLY_CONNECTION_REFUSED = 0x05; + const uint8_t SOCKS5_REPLY_TTL_EXPIRED = 0x06; + const uint8_t SOCKS5_REPLY_COMMAND_NOT_SUPPORTED = 0x07; + const uint8_t SOCKS5_REPLY_ADDRESS_TYPE_NOT_SUPPORTED = 0x08; + // SOCKS5 handshake + template + void Socks5ReadReply (Socket& s, Handler handler) + { + auto readbuff = std::make_shared >(258); // max possible + boost::asio::async_read(s, boost::asio::buffer(readbuff->data (), 5), boost::asio::transfer_all(), // read 4 bytes of header + first byte of address + [readbuff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) + { + if (!ec) + { + if ((*readbuff)[1] == SOCKS5_REPLY_SUCCESS) + { + size_t len = 0; + switch ((*readbuff)[3]) // ATYP + { + case SOCKS5_ATYP_IPV4: len = 3; break; // address length 4 bytes + case SOCKS5_ATYP_IPV6: len = 15; break; // address length 16 bytes + case SOCKS5_ATYP_NAME: len += (*readbuff)[4]; break; // first byte of address is length + default: ; + } + if (len) + { + len += 2; // port + boost::asio::async_read(s, boost::asio::buffer(readbuff->data (), len), boost::asio::transfer_all(), + [readbuff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) + { + if (!ec) + handler (boost::system::error_code ()); // success + else + handler (boost::asio::error::make_error_code (boost::asio::error::connection_aborted)); + }); + } + else + handler (boost::asio::error::make_error_code (boost::asio::error::fault)); // unknown address type + } + else + switch ((*readbuff)[1]) // REP + { + case SOCKS5_REPLY_SERVER_FAILURE: + handler (boost::asio::error::make_error_code (boost::asio::error::access_denied )); + break; + case SOCKS5_REPLY_CONNECTION_NOT_ALLOWED: + handler (boost::asio::error::make_error_code (boost::asio::error::no_permission)); + break; + case SOCKS5_REPLY_HOST_UNREACHABLE: + handler (boost::asio::error::make_error_code (boost::asio::error::host_unreachable)); + break; + case SOCKS5_REPLY_NETWORK_UNREACHABLE: + handler (boost::asio::error::make_error_code (boost::asio::error::network_unreachable)); + break; + case SOCKS5_REPLY_CONNECTION_REFUSED: + handler (boost::asio::error::make_error_code (boost::asio::error::connection_refused)); + break; + case SOCKS5_REPLY_TTL_EXPIRED: + handler (boost::asio::error::make_error_code (boost::asio::error::timed_out)); + break; + case SOCKS5_REPLY_COMMAND_NOT_SUPPORTED: + handler (boost::asio::error::make_error_code (boost::asio::error::operation_not_supported)); + break; + case SOCKS5_REPLY_ADDRESS_TYPE_NOT_SUPPORTED: + handler (boost::asio::error::make_error_code (boost::asio::error::no_protocol_option)); + break; + default: + handler (boost::asio::error::make_error_code (boost::asio::error::connection_aborted)); + } + } + else + handler (ec); + }); + } + template void Socks5Connect (Socket& s, Handler handler, std::shared_ptr > buff, uint16_t port) { @@ -44,31 +124,7 @@ namespace transport { (void) transferred; if (!ec) - { - auto readbuff = std::make_shared >(262); // max possible - boost::asio::async_read(s, boost::asio::buffer(readbuff->data (), 7), boost::asio::transfer_all(), // read min reply size - [readbuff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) - { - if (!ec) - { - if (!(*readbuff)[1]) // succeeded - { - boost::system::error_code ec; - size_t moreBytes = s.available(ec); - if (!ec && moreBytes) // read remaining portion of reply - boost::asio::read (s, boost::asio::buffer(readbuff->data (), moreBytes), boost::asio::transfer_all (), ec); - if (!ec) - handler (boost::system::error_code ()); - else - handler (boost::asio::error::make_error_code (boost::asio::error::connection_aborted)); - } - else - handler (boost::asio::error::make_error_code (boost::asio::error::connection_refused)); - } - else - handler (ec); - }); - } + Socks5ReadReply (s, handler); else handler (ec); }); From a9ad6fc31e3b733d285dcdad61dfa42bc262c13c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Feb 2024 18:52:18 -0500 Subject: [PATCH 0436/1160] renamed TCPIPPipe to SocketsPipe --- libi2pd_client/HTTPProxy.cpp | 2 +- libi2pd_client/I2PService.cpp | 52 +++++++++++++++++------------------ libi2pd_client/I2PService.h | 28 ++++++++++++------- libi2pd_client/SOCKS.cpp | 3 +- 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 8f9f8ada..01678f4a 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -638,7 +638,7 @@ namespace proxy { void HTTPReqHandler::HandoverToUpstreamProxy() { LogPrint(eLogDebug, "HTTPProxy: Handover to SOCKS proxy"); - auto connection = std::make_shared(GetOwner(), m_proxysock, m_sock); + auto connection = CreateSocketsPipe (GetOwner(), m_proxysock, m_sock); m_sock = nullptr; m_proxysock = nullptr; GetOwner()->AddHandler(connection); diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 9b0b8028..27e34b69 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -148,25 +148,25 @@ namespace client } } - TCPIPPipe::TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream) + SocketsPipe::SocketsPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream) { - boost::asio::socket_base::receive_buffer_size option(TCP_IP_PIPE_BUFFER_SIZE); + boost::asio::socket_base::receive_buffer_size option(SOCKETS_PIPE_BUFFER_SIZE); upstream->set_option(option); downstream->set_option(option); } - TCPIPPipe::~TCPIPPipe() + SocketsPipe::~SocketsPipe() { Terminate(); } - void TCPIPPipe::Start() + void SocketsPipe::Start() { AsyncReceiveUpstream(); AsyncReceiveDownstream(); } - void TCPIPPipe::Terminate() + void SocketsPipe::Terminate() { if(Kill()) return; if (m_up) @@ -184,52 +184,52 @@ namespace client Done(shared_from_this()); } - void TCPIPPipe::AsyncReceiveUpstream() + void SocketsPipe::AsyncReceiveUpstream() { if (m_up) { - m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE), - std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), + m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, SOCKETS_PIPE_BUFFER_SIZE), + std::bind(&SocketsPipe::HandleUpstreamReceived, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else - LogPrint(eLogError, "TCPIPPipe: Upstream receive: No socket"); + LogPrint(eLogError, "SocketsPipe: Upstream receive: No socket"); } - void TCPIPPipe::AsyncReceiveDownstream() + void SocketsPipe::AsyncReceiveDownstream() { if (m_down) { - m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE), - std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), + m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, SOCKETS_PIPE_BUFFER_SIZE), + std::bind(&SocketsPipe::HandleDownstreamReceived, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else - LogPrint(eLogError, "TCPIPPipe: Downstream receive: No socket"); + LogPrint(eLogError, "SocketsPipe: Downstream receive: No socket"); } - void TCPIPPipe::UpstreamWrite(size_t len) + void SocketsPipe::UpstreamWrite(size_t len) { if (m_up) { - LogPrint(eLogDebug, "TCPIPPipe: Upstream: ", (int) len, " bytes written"); + LogPrint(eLogDebug, "SocketsPipe: Upstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len), boost::asio::transfer_all(), - std::bind(&TCPIPPipe::HandleUpstreamWrite, + std::bind(&SocketsPipe::HandleUpstreamWrite, shared_from_this(), std::placeholders::_1)); } else - LogPrint(eLogError, "TCPIPPipe: Upstream write: no socket"); + LogPrint(eLogError, "SocketsPipe: Upstream write: no socket"); } - void TCPIPPipe::DownstreamWrite(size_t len) + void SocketsPipe::DownstreamWrite(size_t len) { if (m_down) { LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len), boost::asio::transfer_all(), - std::bind(&TCPIPPipe::HandleDownstreamWrite, + std::bind(&SocketsPipe::HandleDownstreamWrite, shared_from_this(), std::placeholders::_1)); } @@ -238,7 +238,7 @@ namespace client } - void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) + void SocketsPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { if (ecode != boost::asio::error::operation_aborted) { @@ -257,7 +257,7 @@ namespace client } } - void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) + void SocketsPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) { if (ecode != boost::asio::error::operation_aborted) { @@ -271,13 +271,13 @@ namespace client } } - void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) + void SocketsPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) { if (ecode != boost::asio::error::operation_aborted) { if (ecode) { - LogPrint(eLogWarning, "TCPIPPipe: Upstream write error:" , ecode.message()); + LogPrint(eLogWarning, "SocketsPipe: Upstream write error:" , ecode.message()); Terminate(); } else @@ -285,14 +285,14 @@ namespace client } } - void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) + void SocketsPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { if (ecode != boost::asio::error::operation_aborted) { - LogPrint(eLogDebug, "TCPIPPipe: Upstream ", (int)bytes_transfered, " bytes received"); + LogPrint(eLogDebug, "SocketsPipe: Upstream ", (int)bytes_transfered, " bytes received"); if (ecode) { - LogPrint(eLogWarning, "TCPIPPipe: Upstream read error:" , ecode.message()); + LogPrint(eLogWarning, "SocketsPipe: Upstream read error:" , ecode.message()); Terminate(); } else diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index 4f67e19c..4be7f2ca 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -99,6 +99,7 @@ namespace client virtual ~I2PServiceHandler() { } //If you override this make sure you call it from the children virtual void Handle() {}; //Start handling the socket + virtual void Start () {}; void Terminate () { Kill (); }; @@ -119,16 +120,16 @@ namespace client std::atomic m_Dead; //To avoid cleaning up multiple times }; - const size_t TCP_IP_PIPE_BUFFER_SIZE = 8192 * 8; + const size_t SOCKETS_PIPE_BUFFER_SIZE = 8192 * 8; - // bidirectional pipe for 2 tcp/ip sockets - class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this + // bidirectional pipe for 2 stream sockets + class SocketsPipe: public I2PServiceHandler, public std::enable_shared_from_this { public: - TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); - ~TCPIPPipe(); - void Start(); + SocketsPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); + ~SocketsPipe(); + void Start() override; protected: @@ -144,11 +145,18 @@ namespace client private: - uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE]; - uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; - std::shared_ptr m_up, m_down; + uint8_t m_upstream_to_down_buf[SOCKETS_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[SOCKETS_PIPE_BUFFER_SIZE]; + uint8_t m_upstream_buf[SOCKETS_PIPE_BUFFER_SIZE], m_downstream_buf[SOCKETS_PIPE_BUFFER_SIZE]; + std::shared_ptr m_up; + std::shared_ptr m_down; }; + template + std::shared_ptr CreateSocketsPipe (I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) + { + return std::make_shared(owner, upstream, downstream); + } + /* TODO: support IPv6 too */ //This is a service that listens for connections on the IP network and interacts with I2P class TCPIPAcceptor: public I2PService diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 49a04b81..65bad1cf 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -700,13 +700,12 @@ namespace proxy break; } m_sock->send(response); - auto forwarder = std::make_shared(GetOwner(), m_sock, m_upstreamSock); + auto forwarder = CreateSocketsPipe (GetOwner(), m_sock, m_upstreamSock); m_upstreamSock = nullptr; m_sock = nullptr; GetOwner()->AddHandler(forwarder); forwarder->Start(); Terminate(); - } From 710b27688ba03dc580839fb7b4270ecfd4943014 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 15:35:47 -0500 Subject: [PATCH 0437/1160] generic SocketsPipe for different socket types --- libi2pd_client/I2PService.cpp | 156 ---------------------------------- libi2pd_client/I2PService.h | 99 ++++++++++++++++----- 2 files changed, 76 insertions(+), 179 deletions(-) diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 27e34b69..5604f950 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -148,162 +148,6 @@ namespace client } } - SocketsPipe::SocketsPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream) - { - boost::asio::socket_base::receive_buffer_size option(SOCKETS_PIPE_BUFFER_SIZE); - upstream->set_option(option); - downstream->set_option(option); - } - - SocketsPipe::~SocketsPipe() - { - Terminate(); - } - - void SocketsPipe::Start() - { - AsyncReceiveUpstream(); - AsyncReceiveDownstream(); - } - - void SocketsPipe::Terminate() - { - if(Kill()) return; - if (m_up) - { - if (m_up->is_open()) - m_up->close(); - m_up = nullptr; - } - if (m_down) - { - if (m_down->is_open()) - m_down->close(); - m_down = nullptr; - } - Done(shared_from_this()); - } - - void SocketsPipe::AsyncReceiveUpstream() - { - if (m_up) - { - m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, SOCKETS_PIPE_BUFFER_SIZE), - std::bind(&SocketsPipe::HandleUpstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); - } - else - LogPrint(eLogError, "SocketsPipe: Upstream receive: No socket"); - } - - void SocketsPipe::AsyncReceiveDownstream() - { - if (m_down) { - m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, SOCKETS_PIPE_BUFFER_SIZE), - std::bind(&SocketsPipe::HandleDownstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); - } - else - LogPrint(eLogError, "SocketsPipe: Downstream receive: No socket"); - } - - void SocketsPipe::UpstreamWrite(size_t len) - { - if (m_up) - { - LogPrint(eLogDebug, "SocketsPipe: Upstream: ", (int) len, " bytes written"); - boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len), - boost::asio::transfer_all(), - std::bind(&SocketsPipe::HandleUpstreamWrite, - shared_from_this(), - std::placeholders::_1)); - } - else - LogPrint(eLogError, "SocketsPipe: Upstream write: no socket"); - } - - void SocketsPipe::DownstreamWrite(size_t len) - { - if (m_down) - { - LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) len, " bytes written"); - boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len), - boost::asio::transfer_all(), - std::bind(&SocketsPipe::HandleDownstreamWrite, - shared_from_this(), - std::placeholders::_1)); - } - else - LogPrint(eLogError, "TCPIPPipe: Downstream write: No socket"); - } - - - void SocketsPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) bytes_transfered, " bytes received"); - if (ecode) - { - LogPrint(eLogWarning, "TCPIPPipe: Downstream read error:" , ecode.message()); - Terminate(); - } - else - { - if (bytes_transfered > 0 ) - memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered); - UpstreamWrite(bytes_transfered); - } - } - } - - void SocketsPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - if (ecode) - { - LogPrint(eLogWarning, "TCPIPPipe: Downstream write error:" , ecode.message()); - Terminate(); - } - else - AsyncReceiveUpstream(); - } - } - - void SocketsPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - if (ecode) - { - LogPrint(eLogWarning, "SocketsPipe: Upstream write error:" , ecode.message()); - Terminate(); - } - else - AsyncReceiveDownstream(); - } - } - - void SocketsPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint(eLogDebug, "SocketsPipe: Upstream ", (int)bytes_transfered, " bytes received"); - if (ecode) - { - LogPrint(eLogWarning, "SocketsPipe: Upstream read error:" , ecode.message()); - Terminate(); - } - else - { - if (bytes_transfered > 0 ) - memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered); - DownstreamWrite(bytes_transfered); - } - } - } - void TCPIPAcceptor::Start () { m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index 4be7f2ca..b8973f9d 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -123,38 +123,91 @@ namespace client const size_t SOCKETS_PIPE_BUFFER_SIZE = 8192 * 8; // bidirectional pipe for 2 stream sockets - class SocketsPipe: public I2PServiceHandler, public std::enable_shared_from_this + template + class SocketsPipe: public I2PServiceHandler, + public std::enable_shared_from_this > { public: - SocketsPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); - ~SocketsPipe(); - void Start() override; - - protected: - - void Terminate(); - void AsyncReceiveUpstream(); - void AsyncReceiveDownstream(); - void HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); - void HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); - void HandleUpstreamWrite(const boost::system::error_code & ecode); - void HandleDownstreamWrite(const boost::system::error_code & ecode); - void UpstreamWrite(size_t len); - void DownstreamWrite(size_t len); + SocketsPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream): + I2PServiceHandler(owner), m_up(upstream), m_down(downstream) + { + boost::asio::socket_base::receive_buffer_size option(SOCKETS_PIPE_BUFFER_SIZE); + upstream->set_option(option); + downstream->set_option(option); + } + ~SocketsPipe() { Terminate(); } + + void Start() override + { + Transfer (m_up, m_down, m_upstream_to_down_buf, SOCKETS_PIPE_BUFFER_SIZE); // receive from upstream + Transfer (m_down, m_up, m_downstream_to_up_buf, SOCKETS_PIPE_BUFFER_SIZE); // receive from upstream + } private: - uint8_t m_upstream_to_down_buf[SOCKETS_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[SOCKETS_PIPE_BUFFER_SIZE]; - uint8_t m_upstream_buf[SOCKETS_PIPE_BUFFER_SIZE], m_downstream_buf[SOCKETS_PIPE_BUFFER_SIZE]; - std::shared_ptr m_up; - std::shared_ptr m_down; + void Terminate() + { + if(Kill()) return; + if (m_up) + { + if (m_up->is_open()) + m_up->close(); + m_up = nullptr; + } + if (m_down) + { + if (m_down->is_open()) + m_down->close(); + m_down = nullptr; + } + Done(SocketsPipe::shared_from_this()); + } + + template + void Transfer (std::shared_ptr from, std::shared_ptr to, uint8_t * buf, size_t len) + { + if (!from || !to || !buf) return; + auto s = SocketsPipe::shared_from_this (); + from->async_read_some(boost::asio::buffer(buf, len), + [from, to, s, buf, len](const boost::system::error_code& ecode, std::size_t transferred) + { + if (ecode == boost::asio::error::operation_aborted) return; + if (!ecode) + { + boost::asio::async_write(*to, boost::asio::buffer(buf, transferred), boost::asio::transfer_all(), + [from, to, s, buf, len](const boost::system::error_code& ecode, std::size_t transferred) + { + (void) transferred; + if (ecode == boost::asio::error::operation_aborted) return; + if (!ecode) + s->Transfer (from, to, buf, len); + else + { + LogPrint(eLogWarning, "SocketsPipe: Write error:" , ecode.message()); + s->Terminate(); + } + }); + } + else + { + LogPrint(eLogWarning, "SocketsPipe: Read error:" , ecode.message()); + s->Terminate(); + } + }); + } + + private: + + uint8_t m_upstream_to_down_buf[SOCKETS_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[SOCKETS_PIPE_BUFFER_SIZE]; + std::shared_ptr m_up; + std::shared_ptr m_down; }; - template - std::shared_ptr CreateSocketsPipe (I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) + template + std::shared_ptr CreateSocketsPipe (I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) { - return std::make_shared(owner, upstream, downstream); + return std::make_shared >(owner, upstream, downstream); } /* TODO: support IPv6 too */ From 0e502c49b5c8274e8c2e6d8b1b226e1002ef02de Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 18:53:28 -0500 Subject: [PATCH 0438/1160] show correct tunnel status. restore tunnel if delivery status or data for inbound tunnel received --- daemon/HTTPServer.cpp | 18 +++++++----------- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelPool.cpp | 4 ++-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 2d6800b4..862d6e4a 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -133,23 +133,19 @@ namespace http { static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) { std::string state, stateText; - switch (eState) { + switch (eState) + { case i2p::tunnel::eTunnelStateBuildReplyReceived : case i2p::tunnel::eTunnelStatePending : state = "building"; break; - case i2p::tunnel::eTunnelStateBuildFailed : - case i2p::tunnel::eTunnelStateTestFailed : + case i2p::tunnel::eTunnelStateBuildFailed : state = "failed"; stateText = "declined"; break; + case i2p::tunnel::eTunnelStateTestFailed : state = "failed"; stateText = "test failed"; break; case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; default: state = "unknown"; break; } - - if (state == "building") stateText = tr("building"); - else if (state == "failed") stateText = tr("failed"); - else if (state == "expiring") stateText = tr("expiring"); - else if (state == "established") stateText = tr("established"); - else stateText = tr("unknown"); - + if (stateText.empty ()) stateText = tr(state); + s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; ShowTraffic(s, bytes); s << "\r\n"; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index b578217f..d46da5b9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -250,7 +250,7 @@ namespace tunnel void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr&& msg) { - if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive + if (GetState () != eTunnelStateExpiring) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive EncryptTunnelMsg (msg, msg); msg->from = GetSharedFromThis (); m_Endpoint.HandleDecryptedTunnelDataMsg (msg); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 93df99be..dc43a025 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -461,7 +461,7 @@ namespace tunnel // restore from test failed state if any if (test.first) { - if (test.first->GetState () == eTunnelStateTestFailed) + if (test.first->GetState () != eTunnelStateExpiring) test.first->SetState (eTunnelStateEstablished); // update latency uint64_t latency = 0; @@ -471,7 +471,7 @@ namespace tunnel } if (test.second) { - if (test.second->GetState () == eTunnelStateTestFailed) + if (test.second->GetState () != eTunnelStateExpiring) test.second->SetState (eTunnelStateEstablished); // update latency uint64_t latency = 0; From 56619caa71bdf306dbd480445d6e2835a5ec603d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 20:16:36 -0500 Subject: [PATCH 0439/1160] random shuffle of tunnels for peer test pairs --- libi2pd/TunnelPool.cpp | 56 +++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index dc43a025..2e306ba3 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -361,31 +361,43 @@ namespace tunnel // new tests std::vector, std::shared_ptr > > newTests; + std::random_device rd; + std::mt19937 rnd(rd()); + std::vector > outboundTunnels; { - std::unique_lock l1(m_OutboundTunnelsMutex); - auto it1 = m_OutboundTunnels.begin (); - std::unique_lock l2(m_InboundTunnelsMutex); - auto it2 = m_InboundTunnels.begin (); - while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) + std::unique_lock l(m_OutboundTunnelsMutex); + for (auto& it: m_OutboundTunnels) + outboundTunnels.push_back (it); + } + std::shuffle (outboundTunnels.begin(), outboundTunnels.end(), rnd); + std::vector > inboundTunnels; + { + std::unique_lock l(m_InboundTunnelsMutex); + for (auto& it: m_InboundTunnels) + inboundTunnels.push_back (it); + } + std::shuffle (inboundTunnels.begin(), inboundTunnels.end(), rnd); + auto it1 = outboundTunnels.begin (); + auto it2 = inboundTunnels.begin (); + while (it1 != outboundTunnels.end () && it2 != inboundTunnels.end ()) + { + bool failed = false; + if ((*it1)->IsFailed ()) { - bool failed = false; - if ((*it1)->IsFailed ()) - { - failed = true; - ++it1; - } - if ((*it2)->IsFailed ()) - { - failed = true; - ++it2; - } - if (!failed) - { - newTests.push_back(std::make_pair (*it1, *it2)); - ++it1; ++it2; - } + failed = true; + ++it1; } - } + if ((*it2)->IsFailed ()) + { + failed = true; + ++it2; + } + if (!failed) + { + newTests.push_back(std::make_pair (*it1, *it2)); + ++it1; ++it2; + } + } for (auto& it: newTests) { uint32_t msgID; From dddbca6ffbd316cb4195181e955a804d17dfd2ff Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 21:35:41 -0500 Subject: [PATCH 0440/1160] common rng for random shuffle --- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelPool.cpp | 9 +++------ libi2pd/TunnelPool.h | 6 ++++++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index d46da5b9..ac0418d7 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -52,7 +52,7 @@ namespace tunnel // shuffle records std::vector recordIndicies; for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i); - std::shuffle (recordIndicies.begin(), recordIndicies.end(), std::mt19937(std::random_device()())); + std::shuffle (recordIndicies.begin(), recordIndicies.end(), m_Pool ? m_Pool->GetRng () : std::mt19937(std::random_device()())); // create real records uint8_t * records = msg->GetPayload () + 1; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 2e306ba3..550a75c5 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -7,7 +7,6 @@ */ #include -#include #include "I2PEndian.h" #include "Crypto.h" #include "Tunnel.h" @@ -45,7 +44,7 @@ namespace tunnel m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance), - m_IsActive (true), m_CustomPeerSelector(nullptr) + m_IsActive (true), m_CustomPeerSelector(nullptr), m_Rng(m_Rd()) { if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY) m_NumInboundTunnels = TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY; @@ -361,22 +360,20 @@ namespace tunnel // new tests std::vector, std::shared_ptr > > newTests; - std::random_device rd; - std::mt19937 rnd(rd()); std::vector > outboundTunnels; { std::unique_lock l(m_OutboundTunnelsMutex); for (auto& it: m_OutboundTunnels) outboundTunnels.push_back (it); } - std::shuffle (outboundTunnels.begin(), outboundTunnels.end(), rnd); + std::shuffle (outboundTunnels.begin(), outboundTunnels.end(), m_Rng); std::vector > inboundTunnels; { std::unique_lock l(m_InboundTunnelsMutex); for (auto& it: m_InboundTunnels) inboundTunnels.push_back (it); } - std::shuffle (inboundTunnels.begin(), inboundTunnels.end(), rnd); + std::shuffle (inboundTunnels.begin(), inboundTunnels.end(), m_Rng); auto it1 = outboundTunnels.begin (); auto it2 = inboundTunnels.begin (); while (it1 != outboundTunnels.end () && it2 != inboundTunnels.end ()) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 7cb1f5c9..3d3d4e33 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "Identity.h" #include "LeaseSet.h" #include "RouterInfo.h" @@ -115,6 +116,8 @@ namespace tunnel std::shared_ptr SelectNextHop (std::shared_ptr prevHop, bool reverse, bool endpoint) const; bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); + std::mt19937& GetRng () { return m_Rng; } + private: void TestTunnels (); @@ -148,6 +151,9 @@ namespace tunnel uint64_t m_MinLatency = 0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms uint64_t m_MaxLatency = 0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms + std::random_device m_Rd; + std::mt19937 m_Rng; + public: // for HTTP only From d8be5b8ce1876f28615e051b683c840481c1b00f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 21:58:03 -0500 Subject: [PATCH 0441/1160] fixed warning --- libi2pd/Socks5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Socks5.h b/libi2pd/Socks5.h index d611bff3..8db8939b 100644 --- a/libi2pd/Socks5.h +++ b/libi2pd/Socks5.h @@ -63,7 +63,7 @@ namespace transport { len += 2; // port boost::asio::async_read(s, boost::asio::buffer(readbuff->data (), len), boost::asio::transfer_all(), - [readbuff, &s, handler](const boost::system::error_code& ec, std::size_t transferred) + [readbuff, handler](const boost::system::error_code& ec, std::size_t transferred) { if (!ec) handler (boost::system::error_code ()); // success From def404b61aceaf02ff247392f56984430b90aa6b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Feb 2024 22:19:07 -0500 Subject: [PATCH 0442/1160] skip failed and expiring tunnels for peer tests --- libi2pd/TunnelPool.cpp | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 550a75c5..5b472232 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -364,36 +364,24 @@ namespace tunnel { std::unique_lock l(m_OutboundTunnelsMutex); for (auto& it: m_OutboundTunnels) - outboundTunnels.push_back (it); + if (it->IsEstablished () || it->GetState () == eTunnelStateTestFailed) + outboundTunnels.push_back (it); } std::shuffle (outboundTunnels.begin(), outboundTunnels.end(), m_Rng); std::vector > inboundTunnels; { std::unique_lock l(m_InboundTunnelsMutex); for (auto& it: m_InboundTunnels) - inboundTunnels.push_back (it); + if (it->IsEstablished () || it->GetState () == eTunnelStateTestFailed) + inboundTunnels.push_back (it); } std::shuffle (inboundTunnels.begin(), inboundTunnels.end(), m_Rng); auto it1 = outboundTunnels.begin (); auto it2 = inboundTunnels.begin (); while (it1 != outboundTunnels.end () && it2 != inboundTunnels.end ()) { - bool failed = false; - if ((*it1)->IsFailed ()) - { - failed = true; - ++it1; - } - if ((*it2)->IsFailed ()) - { - failed = true; - ++it2; - } - if (!failed) - { - newTests.push_back(std::make_pair (*it1, *it2)); - ++it1; ++it2; - } + newTests.push_back(std::make_pair (*it1, *it2)); + ++it1; ++it2; } for (auto& it: newTests) { From 6439e227f67d88cb9bc6ac95c04b397faa148727 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Feb 2024 19:29:33 -0500 Subject: [PATCH 0443/1160] consider test failed state as established. Delete failed tunnels sooner --- libi2pd/Tunnel.cpp | 9 +++++---- libi2pd/Tunnel.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index ac0418d7..3e10ef1b 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -679,9 +679,10 @@ namespace tunnel for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) { auto tunnel = *it; - if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + if (tunnel->IsFailed () || ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT || + ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ()) { - LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); + LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired or failed"); auto pool = tunnel->GetTunnelPool (); if (pool) pool->TunnelExpired (tunnel); @@ -730,10 +731,10 @@ namespace tunnel for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) { auto tunnel = *it; - if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT || + if (tunnel->IsFailed () || ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT || ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ()) { - LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired"); + LogPrint (eLogDebug, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " expired or failed"); auto pool = tunnel->GetTunnelPool (); if (pool) pool->TunnelExpired (tunnel); diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 47ff0465..a0815cba 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -91,7 +91,7 @@ namespace tunnel 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; }; + bool IsEstablished () const { return m_State == eTunnelStateEstablished || m_State == eTunnelStateTestFailed; }; bool IsFailed () const { return m_State == eTunnelStateFailed; }; bool IsRecreated () const { return m_IsRecreated; }; void SetRecreated (bool recreated) { m_IsRecreated = recreated; }; From 441e847de8278d3cc9703ec9bbefec836296ff8f Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Feb 2024 14:49:12 -0500 Subject: [PATCH 0444/1160] don't try to decrypt dulpicate message --- libi2pd/Garlic.cpp | 18 +++++++++++++++--- libi2pd/Garlic.h | 4 ++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 3f885186..7157052c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -588,11 +588,17 @@ namespace garlic auto it = m_ECIESx25519Tags.find (tag); if (it != m_ECIESx25519Tags.end ()) { - if (it->second.tagset && it->second.tagset->HandleNextMessage (buf, len, it->second.index)) + if (!it->second.tagset) return true; // duplicate + if (it->second.tagset->HandleNextMessage (buf, len, it->second.index)) + { m_LastTagset = it->second.tagset; + it->second.tagset = nullptr; // mark as used + } else + { LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message"); - m_ECIESx25519Tags.erase (it); + m_ECIESx25519Tags.erase (it); + } return true; } return false; @@ -879,6 +885,12 @@ namespace garlic numExpiredTags = 0; for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { + if (!it->second.tagset) + { + // delete used tag + it = m_ECIESx25519Tags.erase (it); + continue; + } if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) { it->second.tagset->DeleteSymmKey (it->second.index); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b926abda..83e3b050 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -221,7 +221,7 @@ namespace garlic struct ECIESX25519AEADRatchetIndexTagset { int index; - ReceiveRatchetTagSetPtr tagset; + ReceiveRatchetTagSetPtr tagset; // null if used }; class GarlicDestination: public i2p::data::LocalDestination From 900153765abbe87101a586f9648d21ee97d7a1b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Feb 2024 18:56:04 -0500 Subject: [PATCH 0445/1160] move router's tags cleanup to router's thread --- libi2pd/NetDb.cpp | 9 +-------- libi2pd/RouterContext.cpp | 39 ++++++++++++++++++++++++++------------- libi2pd/RouterContext.h | 8 +++++--- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index e8c92658..0adeb2e7 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -106,7 +106,7 @@ namespace data { i2p::util::SetThreadName("NetDB"); - uint64_t lastManage = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; + uint64_t lastManage = 0, lastExploratory = 0, lastManageRequest = 0; uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch (); int16_t profilesCleanupVariance = 0; @@ -165,13 +165,6 @@ namespace data lastManage = ts; } - if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT || - ts + i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT < lastDestinationCleanup) - { - i2p::context.CleanupDestination (); - lastDestinationCleanup = ts; - } - if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) || ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup) { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 40949891..02ebf22c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -61,9 +61,11 @@ namespace i2p { m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); ScheduleInitialPublish (); - m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); - ScheduleCongestionUpdate (); } + m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); + ScheduleCongestionUpdate (); + m_CleanupTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); + ScheduleCleanupTimer (); } } @@ -1223,17 +1225,6 @@ namespace i2p else LogPrint (eLogError, "Router: service is NULL"); } - - void RouterContext::CleanupDestination () - { - if (m_Service) - m_Service->GetService ().post ([this]() - { - this->i2p::garlic::GarlicDestination::CleanupExpiredTags (); - }); - else - LogPrint (eLogError, "Router: service is NULL"); - } uint32_t RouterContext::GetUptime () const { @@ -1465,4 +1456,26 @@ namespace i2p ScheduleCongestionUpdate (); } } + + void RouterContext::ScheduleCleanupTimer () + { + if (m_CleanupTimer) + { + m_CleanupTimer->cancel (); + m_CleanupTimer->expires_from_now (boost::posix_time::minutes(ROUTER_INFO_CLEANUP_INTERVAL)); + m_CleanupTimer->async_wait (std::bind (&RouterContext::HandleCleanupTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Cleanup timer is NULL"); + } + + void RouterContext::HandleCleanupTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + CleanupExpiredTags (); + ScheduleCleanupTimer (); + } + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ddfc65de..d85ef282 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -38,6 +38,7 @@ namespace garlic const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 5; // in seconds const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 12*60; // in seconds + const int ROUTER_INFO_CLEANUP_INTERVAL = 5; // in minutes enum RouterStatus { @@ -181,7 +182,6 @@ namespace garlic void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove void UpdateStats (); void UpdateTimestamp (uint64_t ts); // in seconds, called from NetDb before publishing - void CleanupDestination (); // garlic destination // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; @@ -230,6 +230,8 @@ namespace garlic void HandlePublishResendTimer (const boost::system::error_code& ecode); void ScheduleCongestionUpdate (); void HandleCongestionUpdateTimer (const boost::system::error_code& ecode); + void ScheduleCleanupTimer (); + void HandleCleanupTimer (const boost::system::error_code& ecode); private: @@ -253,7 +255,7 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; // publish std::unique_ptr m_Service; - std::unique_ptr m_PublishTimer, m_CongestionUpdateTimer; + std::unique_ptr m_PublishTimer, m_CongestionUpdateTimer, m_CleanupTimer; std::set m_PublishExcluded; uint32_t m_PublishReplyToken; bool m_IsHiddenMode; // not publish From 2b6a95cbee8c5216beafbac6116ade4c5230cfc2 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Feb 2024 21:30:40 -0500 Subject: [PATCH 0446/1160] don't check session for symmetric key tagset. re-create tags hash if too many used tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 6 +++ libi2pd/ECIESX25519AEADRatchetSession.h | 10 ++-- libi2pd/Garlic.cpp | 56 +++++++++++++++-------- libi2pd/Garlic.h | 3 +- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 6f56f2e5..3513b7ac 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -117,6 +117,12 @@ namespace garlic return session->HandleNextMessage (buf, len, shared_from_this (), index); } + bool ReceiveRatchetTagSet::IsSessionTerminated () const + { + return !m_Session || m_Session->IsTerminated (); + } + + SymmetricKeyTagSet::SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key): ReceiveRatchetTagSet (nullptr), m_Destination (destination) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 517833e8..030e2c45 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -86,7 +86,8 @@ namespace garlic virtual bool IsIndexExpired (int index) const; virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); - + virtual bool IsSessionTerminated () const; + private: int m_TrimBehindIndex = 0; @@ -101,9 +102,10 @@ namespace garlic SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key); - bool IsIndexExpired (int index) const { return false; }; - bool HandleNextMessage (uint8_t * buf, size_t len, int index); - + bool IsIndexExpired (int index) const override { return false; }; + bool HandleNextMessage (uint8_t * buf, size_t len, int index) override; + bool IsSessionTerminated () const override { return false; } + private: GarlicDestination * m_Destination; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 7157052c..ba35995f 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -431,7 +431,8 @@ namespace garlic } GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default - m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard + m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0), // 0 means standard + m_NumUsedECIESx25519Tags (0) { } @@ -599,6 +600,7 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it); } + m_NumUsedECIESx25519Tags++; return true; } return false; @@ -883,24 +885,41 @@ namespace garlic } numExpiredTags = 0; - for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) + if (m_NumUsedECIESx25519Tags > ECIESX25519_TAGSET_MAX_NUM_TAGS) // too many used tags { - if (!it->second.tagset) + std::unordered_map oldTags; + std::swap (m_ECIESx25519Tags, oldTags); // re-create + for (auto& it: oldTags) + if (it.second.tagset) + { + if (it.second.tagset->IsExpired (ts) || it.second.tagset->IsIndexExpired (it.second.index)) + { + it.second.tagset->DeleteSymmKey (it.second.index); + numExpiredTags++; + } + else if (it.second.tagset->IsSessionTerminated()) + numExpiredTags++; + else + m_ECIESx25519Tags.emplace (it); + } + } + else + { + for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { - // delete used tag - it = m_ECIESx25519Tags.erase (it); - continue; - } - if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) - { - it->second.tagset->DeleteSymmKey (it->second.index); - it = m_ECIESx25519Tags.erase (it); - numExpiredTags++; - } - else - { - auto session = it->second.tagset->GetSession (); - if (!session || session->IsTerminated()) + if (!it->second.tagset) + { + // delete used tag + it = m_ECIESx25519Tags.erase (it); + continue; + } + if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) + { + it->second.tagset->DeleteSymmKey (it->second.index); + it = m_ECIESx25519Tags.erase (it); + numExpiredTags++; + } + else if (it->second.tagset->IsSessionTerminated()) { it = m_ECIESx25519Tags.erase (it); numExpiredTags++; @@ -908,7 +927,8 @@ namespace garlic else ++it; } - } + } + m_NumUsedECIESx25519Tags = 0; if (numExpiredTags > 0) LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); if (m_LastTagset && m_LastTagset->IsExpired (ts)) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 83e3b050..0386752b 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -291,6 +291,7 @@ namespace garlic std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session ReceiveRatchetTagSetPtr m_LastTagset; // tagset last message came for + int m_NumUsedECIESx25519Tags; // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session @@ -299,7 +300,7 @@ namespace garlic // for HTTP only size_t GetNumIncomingTags () const { return m_Tags.size (); } - size_t GetNumIncomingECIESx25519Tags () const { return m_ECIESx25519Tags.size (); } + size_t GetNumIncomingECIESx25519Tags () const { return m_ECIESx25519Tags.size () - m_NumUsedECIESx25519Tags; } const decltype(m_Sessions)& GetSessions () const { return m_Sessions; }; const decltype(m_ECIESx25519Sessions)& GetECIESx25519Sessions () const { return m_ECIESx25519Sessions; } }; From 7e3157b162b644e8624aaea1057fb712052c4761 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Feb 2024 21:28:06 -0500 Subject: [PATCH 0447/1160] don't process packet in terminated stream --- libi2pd/Streaming.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 74fb3d97..fa809c19 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -129,6 +129,11 @@ namespace stream void Stream::HandleNextPacket (Packet * packet) { + if (m_Status == eStreamStatusTerminated) + { + m_LocalDestination.DeletePacket (packet); + return; + } m_NumReceivedBytes += packet->GetLength (); if (!m_SendStreamID) { @@ -159,7 +164,8 @@ namespace stream { // we have received next in sequence message ProcessPacket (packet); - + if (m_Status == eStreamStatusTerminated) return; + // we should also try stored messages if any for (auto it = m_SavedPackets.begin (); it != m_SavedPackets.end ();) { @@ -169,6 +175,7 @@ namespace stream m_SavedPackets.erase (it++); ProcessPacket (savedPacket); + if (m_Status == eStreamStatusTerminated) return; } else break; From d677d67676eed2d84384797a6b662758878446bb Mon Sep 17 00:00:00 2001 From: Vort Date: Sun, 18 Feb 2024 22:54:43 +0200 Subject: [PATCH 0448/1160] implement medium congestion indication --- libi2pd/I2NPProtocol.cpp | 4 +- libi2pd/RouterContext.cpp | 25 +++++++---- libi2pd/RouterContext.h | 2 +- libi2pd/Transports.cpp | 87 ++++++++++++++++++++++++--------------- libi2pd/Transports.h | 26 ++++++++---- libi2pd/Tunnel.h | 2 +- 6 files changed, 92 insertions(+), 54 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 70cefbdc..78493df2 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -376,7 +376,7 @@ namespace i2p if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; // replace record to reply - if (i2p::context.AcceptsTunnels () && !i2p::context.IsHighCongestion ()) + if (i2p::context.AcceptsTunnels () && i2p::context.GetCongestionLevel (false) < 100) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -586,7 +586,7 @@ namespace i2p // check if we accept this tunnel std::shared_ptr transitTunnel; uint8_t retCode = 0; - if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ()) + if (!i2p::context.AcceptsTunnels () || i2p::context.GetCongestionLevel (false) >= 100) retCode = 30; if (!retCode) { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 02ebf22c..64dd43e4 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1137,13 +1137,14 @@ namespace i2p return i2p::tunnel::tunnels.GetExploratoryPool (); } - bool RouterContext::IsHighCongestion () const + int RouterContext::GetCongestionLevel (bool longTerm) const { - return i2p::tunnel::tunnels.IsTooManyTransitTunnels () || - i2p::transport::transports.IsBandwidthExceeded () || - i2p::transport::transports.IsTransitBandwidthExceeded (); - } - + return std::max ( + i2p::tunnel::tunnels.GetCongestionLevel (), + i2p::transport::transports.GetCongestionLevel (longTerm) + ); + } + void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len) { i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); @@ -1447,10 +1448,16 @@ namespace i2p if (ecode != boost::asio::error::operation_aborted) { auto c = i2p::data::RouterInfo::eLowCongestion; - if (!AcceptsTunnels ()) + if (!AcceptsTunnels () || m_ShareRatio == 0) c = i2p::data::RouterInfo::eRejectAll; - else if (IsHighCongestion ()) - c = i2p::data::RouterInfo::eHighCongestion; + else + { + int congestionLevel = GetCongestionLevel (true); + if (congestionLevel > 90) + c = i2p::data::RouterInfo::eHighCongestion; + else if (congestionLevel > 70) + c = i2p::data::RouterInfo::eMediumCongestion; + } if (m_RouterInfo.UpdateCongestion (c)) UpdateRouterInfo (); ScheduleCongestionUpdate (); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index d85ef282..062c187d 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -167,7 +167,7 @@ namespace garlic void SetShareRatio (int percents); // 0 - 100 bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; - bool IsHighCongestion () const; + int GetCongestionLevel (bool longTerm) const; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; bool SupportsMesh () const { return m_RouterInfo.IsMesh (); }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 0afe47a1..a3914d7c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -140,10 +140,8 @@ namespace transport m_X25519KeysPairSupplier (15), // 15 pre-generated keys m_TotalSentBytes (0), m_TotalReceivedBytes (0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth (0), - m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastTransitBandwidthUpdateBytes (0), m_InBandwidth15s (0), m_OutBandwidth15s (0), m_TransitBandwidth15s (0), - m_LastInBandwidth15sUpdateBytes (0), m_LastOutBandwidth15sUpdateBytes (0), m_LastTransitBandwidth15sUpdateBytes (0), - m_LastBandwidth15sUpdateTime (0) + m_InBandwidth5m (0), m_OutBandwidth5m (0), m_TransitBandwidth5m (0) { } @@ -306,6 +304,16 @@ namespace transport m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5 * SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); + uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); + for (int i = 0; i < TRAFFIC_SAMPLE_COUNT; i++) + { + m_TrafficSamples[i].Timestamp = ts - (TRAFFIC_SAMPLE_COUNT - i - 1) * 1000; + m_TrafficSamples[i].TotalReceivedBytes = 0; + m_TrafficSamples[i].TotalSentBytes = 0; + m_TrafficSamples[i].TotalTransitTransmittedBytes = 0; + } + m_TrafficSamplePtr = TRAFFIC_SAMPLE_COUNT - 1; + m_UpdateBandwidthTimer->expires_from_now (boost::posix_time::seconds(1)); m_UpdateBandwidthTimer->async_wait (std::bind (&Transports::HandleUpdateBandwidthTimer, this, std::placeholders::_1)); @@ -364,51 +372,62 @@ namespace transport } } + void Transports::UpdateBandwidthValues(int interval, uint32_t& in, uint32_t& out, uint32_t& transit) + { + TrafficSample& sample1 = m_TrafficSamples[m_TrafficSamplePtr]; + TrafficSample& sample2 = m_TrafficSamples[(TRAFFIC_SAMPLE_COUNT + m_TrafficSamplePtr - interval) % TRAFFIC_SAMPLE_COUNT]; + auto delta = sample1.Timestamp - sample2.Timestamp; + in = (sample1.TotalReceivedBytes - sample2.TotalReceivedBytes) * 1000 / delta; + out = (sample1.TotalSentBytes - sample2.TotalSentBytes) * 1000 / delta; + transit = (sample1.TotalTransitTransmittedBytes - sample2.TotalTransitTransmittedBytes) * 1000 / delta; + } + void Transports::HandleUpdateBandwidthTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) { - uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); + m_TrafficSamplePtr++; + if (m_TrafficSamplePtr == TRAFFIC_SAMPLE_COUNT) + m_TrafficSamplePtr = 0; - // updated every second - m_InBandwidth = m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes; - m_OutBandwidth = m_TotalSentBytes - m_LastOutBandwidthUpdateBytes; - m_TransitBandwidth = m_TotalTransitTransmittedBytes - m_LastTransitBandwidthUpdateBytes; + TrafficSample& sample = m_TrafficSamples[m_TrafficSamplePtr]; + sample.Timestamp = i2p::util::GetMillisecondsSinceEpoch(); + sample.TotalReceivedBytes = m_TotalReceivedBytes; + sample.TotalSentBytes = m_TotalSentBytes; + sample.TotalTransitTransmittedBytes = m_TotalTransitTransmittedBytes; - m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes; - m_LastOutBandwidthUpdateBytes = m_TotalSentBytes; - m_LastTransitBandwidthUpdateBytes = m_TotalTransitTransmittedBytes; - - // updated every 15 seconds - auto delta = ts - m_LastBandwidth15sUpdateTime; - if (delta > 15 * 1000) - { - m_InBandwidth15s = (m_TotalReceivedBytes - m_LastInBandwidth15sUpdateBytes) * 1000 / delta; - m_OutBandwidth15s = (m_TotalSentBytes - m_LastOutBandwidth15sUpdateBytes) * 1000 / delta; - m_TransitBandwidth15s = (m_TotalTransitTransmittedBytes - m_LastTransitBandwidth15sUpdateBytes) * 1000 / delta; - - m_LastBandwidth15sUpdateTime = ts; - m_LastInBandwidth15sUpdateBytes = m_TotalReceivedBytes; - m_LastOutBandwidth15sUpdateBytes = m_TotalSentBytes; - m_LastTransitBandwidth15sUpdateBytes = m_TotalTransitTransmittedBytes; - } + UpdateBandwidthValues (1, m_InBandwidth, m_OutBandwidth, m_TransitBandwidth); + UpdateBandwidthValues (15, m_InBandwidth15s, m_OutBandwidth15s, m_TransitBandwidth15s); + UpdateBandwidthValues (300, m_InBandwidth5m, m_OutBandwidth5m, m_TransitBandwidth5m); m_UpdateBandwidthTimer->expires_from_now (boost::posix_time::seconds(1)); m_UpdateBandwidthTimer->async_wait (std::bind (&Transports::HandleUpdateBandwidthTimer, this, std::placeholders::_1)); } } - bool Transports::IsBandwidthExceeded () const + int Transports::GetCongestionLevel (bool longTerm) const { - auto limit = i2p::context.GetBandwidthLimit() * 1024; // convert to bytes - auto bw = std::max (m_InBandwidth15s, m_OutBandwidth15s); - return bw > limit; - } + auto bwLimit = i2p::context.GetBandwidthLimit () * 1024; // convert to bytes + auto tbwLimit = i2p::context.GetTransitBandwidthLimit () * 1024; // convert to bytes - bool Transports::IsTransitBandwidthExceeded () const - { - auto limit = i2p::context.GetTransitBandwidthLimit() * 1024; // convert to bytes - return m_TransitBandwidth > limit; + if (tbwLimit == 0 || bwLimit == 0) + return 100; + + uint32_t bw; + uint32_t tbw; + if (longTerm) + { + bw = std::max (m_InBandwidth5m, m_OutBandwidth5m); + tbw = m_TransitBandwidth5m; + } + else + { + bw = std::max (m_InBandwidth15s, m_OutBandwidth15s); + tbw = m_TransitBandwidth; + } + auto bwCongestionLevel = 100 * bw / bwLimit; + auto tbwCongestionLevel = 100 * tbw / tbwLimit; + return std::max (bwCongestionLevel, tbwCongestionLevel); } void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 206b0256..92d75efd 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -114,6 +114,17 @@ namespace transport const int PEER_TEST_DELAY_INTERVAL_VARIANCE = 30; // in milliseconds const int MAX_NUM_DELAYED_MESSAGES = 150; const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after + + const int TRAFFIC_SAMPLE_COUNT = 301; // seconds + + struct TrafficSample + { + uint64_t Timestamp; + uint64_t TotalReceivedBytes; + uint64_t TotalSentBytes; + uint64_t TotalTransitTransmittedBytes; + }; + class Transports { public: @@ -153,8 +164,7 @@ namespace transport uint32_t GetInBandwidth15s () const { return m_InBandwidth15s; }; uint32_t GetOutBandwidth15s () const { return m_OutBandwidth15s; }; uint32_t GetTransitBandwidth15s () const { return m_TransitBandwidth15s; }; - bool IsBandwidthExceeded () const; - bool IsTransitBandwidthExceeded () const; + int GetCongestionLevel (bool longTerm) const; size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer (bool isHighBandwidth) const; @@ -186,6 +196,7 @@ namespace transport void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerTestTimer (const boost::system::error_code& ecode); void HandleUpdateBandwidthTimer (const boost::system::error_code& ecode); + void UpdateBandwidthValues (int interval, uint32_t& in, uint32_t& out, uint32_t& transit); void DetectExternalIP (); @@ -210,14 +221,15 @@ namespace transport std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; + TrafficSample m_TrafficSamples[TRAFFIC_SAMPLE_COUNT]; + int m_TrafficSamplePtr; + // Bandwidth per second uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; - uint64_t m_LastInBandwidthUpdateBytes, m_LastOutBandwidthUpdateBytes, m_LastTransitBandwidthUpdateBytes; - - // Bandwidth every 15 seconds + // Bandwidth during last 15 seconds uint32_t m_InBandwidth15s, m_OutBandwidth15s, m_TransitBandwidth15s; - uint64_t m_LastInBandwidth15sUpdateBytes, m_LastOutBandwidth15sUpdateBytes, m_LastTransitBandwidth15sUpdateBytes; - uint64_t m_LastBandwidth15sUpdateTime; + // Bandwidth during last 5 minutes + uint32_t m_InBandwidth5m, m_OutBandwidth5m, m_TransitBandwidth5m; /** which router families to trust for first hops */ std::vector m_TrustedFamilies; diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a0815cba..0b125c70 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -240,7 +240,7 @@ namespace tunnel void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; - bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; }; + int GetCongestionLevel() const { return 100 * m_TransitTunnels.size() / m_MaxNumTransitTunnels; } private: From a4a3f8e96b55c83bcf3af66abf7e500cd47684b8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 19 Feb 2024 22:04:43 -0500 Subject: [PATCH 0449/1160] support upstream proxy through local sockets --- libi2pd_client/SOCKS.cpp | 77 +++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 65bad1cf..3174bdb3 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -139,9 +139,11 @@ namespace proxy void HandleStreamRequestComplete (std::shared_ptr stream); void ForwardSOCKS(); - void SocksUpstreamSuccess(); + template + void SocksUpstreamSuccess(std::shared_ptr& upstreamSock); void AsyncUpstreamSockRead(); - void SendUpstreamRequest(); + template + void SendUpstreamRequest(std::shared_ptr& upstreamSock); void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, @@ -150,6 +152,9 @@ namespace proxy boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; std::shared_ptr m_sock, m_upstreamSock; +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + std::shared_ptr m_upstreamLocalSock; +#endif std::shared_ptr m_stream; uint8_t *m_remaining_data; //Data left to be sent uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded @@ -212,6 +217,14 @@ namespace proxy m_upstreamSock->close(); m_upstreamSock = nullptr; } +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + if (m_upstreamLocalSock) + { + LogPrint(eLogDebug, "SOCKS: Closing upstream local socket"); + m_upstreamLocalSock->close(); + m_upstreamLocalSock = nullptr; + } +#endif if (m_stream) { LogPrint(eLogDebug, "SOCKS: Closing stream"); @@ -677,13 +690,45 @@ namespace proxy void SOCKSHandler::ForwardSOCKS() { LogPrint(eLogInfo, "SOCKS: Forwarding to upstream"); - EnterState(UPSTREAM_RESOLVE); - boost::asio::ip::tcp::resolver::query q(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort)); - m_proxy_resolver.async_resolve(q, std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + if (m_UpstreamProxyPort) // TCP + { + EnterState(UPSTREAM_RESOLVE); + boost::asio::ip::tcp::resolver::query q(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort)); + m_proxy_resolver.async_resolve(q, std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); + } + else if (!m_UpstreamProxyAddress.empty ())// local + { +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + EnterState(UPSTREAM_CONNECT); + m_upstreamLocalSock = std::make_shared(GetOwner()->GetService()); + auto s = shared_from_this (); + m_upstreamLocalSock->async_connect(m_UpstreamProxyAddress, + [s](const boost::system::error_code& ecode) + { + if (ecode) + { + LogPrint(eLogWarning, "SOCKS: Could not connect to local upstream proxy: ", ecode.message()); + s->SocksRequestFailed(SOCKS5_NET_UNREACH); + return; + } + LogPrint(eLogInfo, "SOCKS: Connected to local upstream proxy"); + s->SendUpstreamRequest(s->m_upstreamLocalSock); + }); +#else + LogPrint(eLogError, "SOCKS: Local sockets for upstream proxy not supported"); + SocksRequestFailed(SOCKS5_ADDR_UNSUP); +#endif + } + else + { + LogPrint(eLogError, "SOCKS: Incorrect upstream proxy address"); + SocksRequestFailed(SOCKS5_ADDR_UNSUP); + } } - void SOCKSHandler::SocksUpstreamSuccess() + template + void SOCKSHandler::SocksUpstreamSuccess(std::shared_ptr& upstreamSock) { LogPrint(eLogInfo, "SOCKS: Upstream success"); boost::asio::const_buffers_1 response(nullptr, 0); @@ -700,27 +745,27 @@ namespace proxy break; } m_sock->send(response); - auto forwarder = CreateSocketsPipe (GetOwner(), m_sock, m_upstreamSock); - m_upstreamSock = nullptr; + auto forwarder = CreateSocketsPipe (GetOwner(), m_sock, upstreamSock); + upstreamSock = nullptr; m_sock = nullptr; GetOwner()->AddHandler(forwarder); forwarder->Start(); Terminate(); } - - void SOCKSHandler::SendUpstreamRequest() + template + void SOCKSHandler::SendUpstreamRequest(std::shared_ptr& upstreamSock) { LogPrint(eLogInfo, "SOCKS: Negotiating with upstream proxy"); EnterState(UPSTREAM_HANDSHAKE); - if (m_upstreamSock) + if (upstreamSock) { auto s = shared_from_this (); - i2p::transport::Socks5Handshake (*m_upstreamSock, std::make_pair(m_address.dns.ToString (), m_port), - [s](const boost::system::error_code& ec) + i2p::transport::Socks5Handshake (*upstreamSock, std::make_pair(m_address.dns.ToString (), m_port), + [s, &upstreamSock](const boost::system::error_code& ec) { if (!ec) - s->SocksUpstreamSuccess(); + s->SocksUpstreamSuccess(upstreamSock); else { s->SocksRequestFailed(SOCKS5_NET_UNREACH); @@ -740,7 +785,7 @@ namespace proxy return; } LogPrint(eLogInfo, "SOCKS: Connected to upstream proxy"); - SendUpstreamRequest(); + SendUpstreamRequest(m_upstreamSock); } void SOCKSHandler::HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr) From 19e23b34da807476c4e1ed0dea3c1bef15df3a06 Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 20 Feb 2024 10:30:05 +0200 Subject: [PATCH 0450/1160] add constants for congestion levels --- libi2pd/I2NPProtocol.cpp | 4 ++-- libi2pd/I2NPProtocol.h | 4 ++++ libi2pd/RouterContext.cpp | 6 +++--- libi2pd/Transports.cpp | 6 +++--- libi2pd/Tunnel.h | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 78493df2..a1638326 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -376,7 +376,7 @@ namespace i2p if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; // replace record to reply - if (i2p::context.AcceptsTunnels () && i2p::context.GetCongestionLevel (false) < 100) + if (i2p::context.AcceptsTunnels () && i2p::context.GetCongestionLevel (false) < CONGESTION_LEVEL_FULL) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -586,7 +586,7 @@ namespace i2p // check if we accept this tunnel std::shared_ptr transitTunnel; uint8_t retCode = 0; - if (!i2p::context.AcceptsTunnels () || i2p::context.GetCongestionLevel (false) >= 100) + if (!i2p::context.AcceptsTunnels () || i2p::context.GetCongestionLevel (false) >= CONGESTION_LEVEL_FULL) retCode = 30; if (!retCode) { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index a2877a08..36facbe3 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -139,6 +139,10 @@ namespace tunnel class TunnelPool; } + const int CONGESTION_LEVEL_MEDIUM = 70; + const int CONGESTION_LEVEL_HIGH = 90; + const int CONGESTION_LEVEL_FULL = 100; + const size_t I2NP_MAX_MESSAGE_SIZE = 62708; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; const size_t I2NP_MAX_MEDIUM_MESSAGE_SIZE = 16384; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 64dd43e4..013f4dc5 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1448,14 +1448,14 @@ namespace i2p if (ecode != boost::asio::error::operation_aborted) { auto c = i2p::data::RouterInfo::eLowCongestion; - if (!AcceptsTunnels () || m_ShareRatio == 0) + if (!AcceptsTunnels () || !m_ShareRatio) c = i2p::data::RouterInfo::eRejectAll; else { int congestionLevel = GetCongestionLevel (true); - if (congestionLevel > 90) + if (congestionLevel > CONGESTION_LEVEL_HIGH) c = i2p::data::RouterInfo::eHighCongestion; - else if (congestionLevel > 70) + else if (congestionLevel > CONGESTION_LEVEL_MEDIUM) c = i2p::data::RouterInfo::eMediumCongestion; } if (m_RouterInfo.UpdateCongestion (c)) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index a3914d7c..bb5dcecc 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -411,7 +411,7 @@ namespace transport auto tbwLimit = i2p::context.GetTransitBandwidthLimit () * 1024; // convert to bytes if (tbwLimit == 0 || bwLimit == 0) - return 100; + return CONGESTION_LEVEL_FULL; uint32_t bw; uint32_t tbw; @@ -425,8 +425,8 @@ namespace transport bw = std::max (m_InBandwidth15s, m_OutBandwidth15s); tbw = m_TransitBandwidth; } - auto bwCongestionLevel = 100 * bw / bwLimit; - auto tbwCongestionLevel = 100 * tbw / tbwLimit; + auto bwCongestionLevel = CONGESTION_LEVEL_FULL * bw / bwLimit; + auto tbwCongestionLevel = CONGESTION_LEVEL_FULL * tbw / tbwLimit; return std::max (bwCongestionLevel, tbwCongestionLevel); } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 0b125c70..cc5b9461 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -240,7 +240,7 @@ namespace tunnel void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; - int GetCongestionLevel() const { return 100 * m_TransitTunnels.size() / m_MaxNumTransitTunnels; } + int GetCongestionLevel() const { return CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels; } private: From b092e712ec0d9616eef7d73eb2d9e2bd11afba6d Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 20 Feb 2024 17:39:48 +0200 Subject: [PATCH 0451/1160] make more attempts to select not bad hop --- libi2pd/NetDb.cpp | 2 +- libi2pd/TunnelPool.cpp | 22 +++++++++++++++++----- libi2pd/TunnelPool.h | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 0adeb2e7..bfd07df3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1257,7 +1257,7 @@ namespace data std::shared_ptr NetDb::GetRandomRouter (Filter filter) const { if (m_RouterInfos.empty()) - return 0; + return nullptr; uint16_t inds[3]; RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::lock_guard l(m_RouterInfosMutex); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5b472232..c342d546 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -494,11 +494,23 @@ namespace tunnel std::shared_ptr TunnelPool::SelectNextHop (std::shared_ptr prevHop, bool reverse, bool endpoint) const { - auto hop = IsExploratory () ? i2p::data::netdb.GetRandomRouter (prevHop, reverse, endpoint): - i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse, endpoint); - - if (!hop || hop->GetProfile ()->IsBad ()) - hop = i2p::data::netdb.GetRandomRouter (prevHop, reverse, endpoint); + bool tryHighBandwidth = !IsExploratory (); + std::shared_ptr hop; + for (int i = 0; i < TUNNEL_POOL_MAX_HOP_SELECTION_ATTEMPTS; i++) + { + hop = tryHighBandwidth ? + i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse, endpoint) : + i2p::data::netdb.GetRandomRouter (prevHop, reverse, endpoint); + if (hop) + { + if (!hop->GetProfile ()->IsBad ()) + break; + } + else if (tryHighBandwidth) + tryHighBandwidth = false; + else + return nullptr; + } return hop; } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 3d3d4e33..d9f5966d 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -32,6 +32,7 @@ namespace tunnel const int TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY = 16; const int TUNNEL_POOL_MAX_OUTBOUND_TUNNELS_QUANTITY = 16; const int TUNNEL_POOL_MAX_NUM_BUILD_REQUESTS = 3; + const int TUNNEL_POOL_MAX_HOP_SELECTION_ATTEMPTS = 3; class Tunnel; class InboundTunnel; From d524105727797825cf8e0310eef7120060b28c60 Mon Sep 17 00:00:00 2001 From: Vort Date: Tue, 20 Feb 2024 22:48:45 +0200 Subject: [PATCH 0452/1160] skip bandwidth updates in case of time going backwards --- libi2pd/Transports.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index bb5dcecc..04c58cf3 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -376,7 +376,12 @@ namespace transport { TrafficSample& sample1 = m_TrafficSamples[m_TrafficSamplePtr]; TrafficSample& sample2 = m_TrafficSamples[(TRAFFIC_SAMPLE_COUNT + m_TrafficSamplePtr - interval) % TRAFFIC_SAMPLE_COUNT]; - auto delta = sample1.Timestamp - sample2.Timestamp; + auto delta = (int64_t)sample1.Timestamp - (int64_t)sample2.Timestamp; + if (delta <= 0) + { + LogPrint (eLogError, "Transports: Backward clock jump detected, got ", delta, " instead of ", interval * 1000); + return; + } in = (sample1.TotalReceivedBytes - sample2.TotalReceivedBytes) * 1000 / delta; out = (sample1.TotalSentBytes - sample2.TotalSentBytes) * 1000 / delta; transit = (sample1.TotalTransitTransmittedBytes - sample2.TotalTransitTransmittedBytes) * 1000 / delta; From 2692aef53d45eb7b9a2a82a1c241a0f7ca9b175a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 21 Feb 2024 01:36:32 +0300 Subject: [PATCH 0453/1160] [gha] update windows msvc action --- .github/workflows/build-windows-msvc.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index dea64644..36a70d5a 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -38,13 +38,13 @@ jobs: - name: Install Boost run: | - powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.81.0/boost_1_81_0-msvc-14.3-64.exe/download -OutFile boost_1_84_0-msvc-14.3-64.exe)" - ./boost_1_84_0-msvc-14.3-64.exe /VERYSILENT + powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/boost/files/boost-binaries/1.81.0/boost_1_81_0-msvc-14.3-64.exe/download -OutFile boost_1_81_0-msvc-14.3-64.exe)" + ./boost_1_81_0-msvc-14.3-64.exe /VERYSILENT - name: Install OpenSSL run: | - powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://slproweb.com/download/Win64OpenSSL-3_2_0.exe -OutFile Win64OpenSSL-3_2_0.exe)" - ./Win64OpenSSL-3_2_0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- + powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://slproweb.com/download/Win64OpenSSL-3_2_1.exe -OutFile Win64OpenSSL-3_2_1.exe)" + ./Win64OpenSSL-3_2_1.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- - name: Configure working-directory: build From 695dc96a837d029999375ef80084c923d65cc4ad Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Feb 2024 18:32:51 -0500 Subject: [PATCH 0454/1160] common ServiceAcceptor for all stream protocols --- libi2pd_client/I2PService.cpp | 49 ---------------- libi2pd_client/I2PService.h | 103 +++++++++++++++++++++++----------- 2 files changed, 71 insertions(+), 81 deletions(-) diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 5604f950..e9513e48 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -147,54 +147,5 @@ namespace client m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); } } - - void TCPIPAcceptor::Start () - { - m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); - // update the local end point in case port has been set zero and got updated now - m_LocalEndpoint = m_Acceptor->local_endpoint(); - m_Acceptor->listen (); - Accept (); - } - - void TCPIPAcceptor::Stop () - { - if (m_Acceptor) - { - m_Acceptor->close(); - m_Acceptor.reset (nullptr); - } - m_Timer.cancel (); - ClearHandlers(); - } - - void TCPIPAcceptor::Accept () - { - auto newSocket = std::make_shared (GetService ()); - m_Acceptor->async_accept (*newSocket, std::bind (&TCPIPAcceptor::HandleAccept, this, - std::placeholders::_1, newSocket)); - } - - void TCPIPAcceptor::HandleAccept (const boost::system::error_code& ecode, std::shared_ptr socket) - { - if (!ecode) - { - LogPrint(eLogDebug, "I2PService: ", GetName(), " accepted"); - auto handler = CreateHandler(socket); - if (handler) - { - AddHandler(handler); - handler->Handle(); - } - else - socket->close(); - Accept(); - } - else - { - if (ecode != boost::asio::error::operation_aborted) - LogPrint (eLogError, "I2PService: ", GetName(), " closing socket on accept because: ", ecode.message ()); - } - } } } diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index b8973f9d..d35c954d 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -210,42 +210,81 @@ namespace client return std::make_shared >(owner, upstream, downstream); } - /* TODO: support IPv6 too */ - //This is a service that listens for connections on the IP network and interacts with I2P - class TCPIPAcceptor: public I2PService + //This is a service that listens for connections on the IP network or local socket and interacts with I2P + template + class ServiceAcceptor: public I2PService + { + public: + + ServiceAcceptor (const typename Protocol::endpoint& localEndpoint, std::shared_ptr localDestination = nullptr) : + I2PService(localDestination), m_LocalEndpoint (localEndpoint) {} + + virtual ~ServiceAcceptor () { Stop(); } + void Start () override + { + m_Acceptor.reset (new typename Protocol::acceptor (GetService (), m_LocalEndpoint)); + // update the local end point in case port has been set zero and got updated now + m_LocalEndpoint = m_Acceptor->local_endpoint(); + m_Acceptor->listen (); + Accept (); + } + void Stop () override + { + if (m_Acceptor) + { + m_Acceptor->close(); + m_Acceptor.reset (nullptr); + } + ClearHandlers(); + } + const typename Protocol::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; + + const char* GetName() override { return "Generic TCP/IP accepting daemon"; } + + protected: + + virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; + + private: + + void Accept() + { + auto newSocket = std::make_shared (GetService ()); + m_Acceptor->async_accept (*newSocket, + [newSocket, this](const boost::system::error_code& ecode) + { + if (ecode == boost::asio::error::operation_aborted) return; + if (!ecode) + { + LogPrint(eLogDebug, "ServiceAcceptor: ", GetName(), " accepted"); + auto handler = CreateHandler(newSocket); + if (handler) + { + AddHandler(handler); + handler->Handle(); + } + else + newSocket->close(); + Accept(); + } + else + LogPrint (eLogError, "ServiceAcceptor: ", GetName(), " closing socket on accept because: ", ecode.message ()); + }); + } + + private: + + typename Protocol::endpoint m_LocalEndpoint; + std::unique_ptr m_Acceptor; + }; + + class TCPIPAcceptor: public ServiceAcceptor { public: TCPIPAcceptor (const std::string& address, uint16_t port, std::shared_ptr localDestination = nullptr) : - I2PService(localDestination), - m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), - m_Timer (GetService ()) {} - TCPIPAcceptor (const std::string& address, uint16_t port, i2p::data::SigningKeyType kt) : - I2PService(kt), - m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), - m_Timer (GetService ()) {} - virtual ~TCPIPAcceptor () { TCPIPAcceptor::Stop(); } - //If you override this make sure you call it from the children - void Start (); - //If you override this make sure you call it from the children - void Stop (); - - const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; - - virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } - - protected: - - virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; - - private: - - void Accept(); - void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); - boost::asio::ip::tcp::endpoint m_LocalEndpoint; - std::unique_ptr m_Acceptor; - boost::asio::deadline_timer m_Timer; - }; + ServiceAcceptor (boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port), localDestination) {} + }; } } From 577ed56af023c792dccee3bed9fe731b59e137bd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Feb 2024 18:51:37 -0500 Subject: [PATCH 0455/1160] store HTTP and SOCKS proxy as pointer to I2PService --- libi2pd_client/ClientContext.cpp | 1 + libi2pd_client/ClientContext.h | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c27ce625..62295842 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -16,6 +16,7 @@ #include "Identity.h" #include "util.h" #include "ClientContext.h" +#include "HTTPProxy.h" #include "SOCKS.h" #include "MatchedDestination.h" diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 4e969a6b..adec607a 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,8 +15,6 @@ #include #include "Destination.h" #include "I2PService.h" -#include "HTTPProxy.h" -#include "SOCKS.h" #include "I2PTunnel.h" #include "UDPTunnel.h" #include "SAM.h" @@ -141,8 +139,7 @@ namespace client AddressBook m_AddressBook; - i2p::proxy::HTTPProxy * m_HttpProxy; - i2p::proxy::SOCKSProxy * m_SocksProxy; + I2PService * m_HttpProxy, * m_SocksProxy; std::map > m_ClientTunnels; // local endpoint -> tunnel std::map, std::shared_ptr > m_ServerTunnels; // -> tunnel @@ -167,8 +164,8 @@ namespace client const decltype(m_ServerTunnels)& GetServerTunnels () const { return m_ServerTunnels; }; const decltype(m_ClientForwards)& GetClientForwards () const { return m_ClientForwards; } const decltype(m_ServerForwards)& GetServerForwards () const { return m_ServerForwards; } - const i2p::proxy::HTTPProxy * GetHttpProxy () const { return m_HttpProxy; } - const i2p::proxy::SOCKSProxy * GetSocksProxy () const { return m_SocksProxy; } + const I2PService * GetHttpProxy () const { return m_HttpProxy; } + const I2PService * GetSocksProxy () const { return m_SocksProxy; } }; extern ClientContext context; From 36a060d50f66230251fe737b4c497eed961c1e67 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Feb 2024 12:37:33 -0500 Subject: [PATCH 0456/1160] Consider 'M' routers as low bandwidth --- libi2pd/RouterContext.cpp | 6 +++--- libi2pd/RouterInfo.cpp | 5 ++--- libi2pd/RouterInfo.h | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 013f4dc5..864d2c61 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -602,9 +602,9 @@ namespace i2p { case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = i2p::data::LOW_BANDWIDTH_LIMIT; type = low; break; // 48 - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 64; type = high; break; - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; - case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = i2p::data::HIGH_BANDWIDTH_LIMIT; type = high; break; // 256 + case i2p::data::CAPS_FLAG_LOW_BANDWIDTH3 : limit = 64; type = low; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1 : limit = 128; type = high; break; + case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = i2p::data::HIGH_BANDWIDTH_LIMIT; type = high; break; // 256 case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = i2p::data::EXTRA_BANDWIDTH_LIMIT; type = extra; break; // 2048 case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s default: diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index a034691a..a9c43b2e 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -516,7 +516,6 @@ namespace data break; case CAPS_FLAG_HIGH_BANDWIDTH1: case CAPS_FLAG_HIGH_BANDWIDTH2: - case CAPS_FLAG_HIGH_BANDWIDTH3: m_Caps |= Caps::eHighBandwidth; break; case CAPS_FLAG_EXTRA_BANDWIDTH1: @@ -1178,7 +1177,7 @@ namespace data CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X' CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' else - caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' + caps += CAPS_FLAG_HIGH_BANDWIDTH2; // 'O' caps += CAPS_FLAG_FLOODFILL; // floodfill } else @@ -1186,7 +1185,7 @@ namespace data if (c & eExtraBandwidth) caps += (c & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */ else - caps += (c & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth + caps += (c & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH2 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth } if (c & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden if (c & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index a95119ed..9e074b9a 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -39,9 +39,9 @@ namespace data /* bandwidth flags */ const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K'; /* < 12 KBps */ const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L'; /* 12-48 KBps */ - const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M'; /* 48-64 KBps */ - const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N'; /* 64-128 KBps */ - const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O'; /* 128-256 KBps */ + const char CAPS_FLAG_LOW_BANDWIDTH3 = 'M'; /* 48-64 KBps */ + const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'N'; /* 64-128 KBps */ + const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'O'; /* 128-256 KBps */ const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2048 KBps */ const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /* > 2048 KBps */ // bandwidth limits in kBps From 5d7c6fb0b3e89d672a631392f6b15f19156dee2c Mon Sep 17 00:00:00 2001 From: r4sas Date: Wed, 21 Feb 2024 22:31:20 +0300 Subject: [PATCH 0457/1160] [gha] msvc: copy openssl libraries to fix build Signed-off-by: r4sas --- .github/workflows/build-windows-msvc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-windows-msvc.yml b/.github/workflows/build-windows-msvc.yml index 36a70d5a..ef0bc52c 100644 --- a/.github/workflows/build-windows-msvc.yml +++ b/.github/workflows/build-windows-msvc.yml @@ -45,6 +45,7 @@ jobs: run: | powershell -Command "(Invoke-WebRequest -UserAgent "Wget" -Uri https://slproweb.com/download/Win64OpenSSL-3_2_1.exe -OutFile Win64OpenSSL-3_2_1.exe)" ./Win64OpenSSL-3_2_1.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- + xcopy "c:\Program Files\OpenSSL-Win64\lib\VC\x64\MTd\*" "c:\Program Files\OpenSSL-Win64\lib\" - name: Configure working-directory: build From d25206abcefff1c914ee16adad8229197f14ca3b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Feb 2024 19:46:29 -0500 Subject: [PATCH 0458/1160] encrypted tunnel test messages --- libi2pd/Destination.cpp | 5 ++-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 8 +++++- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/RouterContext.cpp | 7 +++++ libi2pd/TunnelPool.cpp | 33 ++++++++++++++++------- libi2pd/TunnelPool.h | 1 + 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ef0d5db3..64e5d085 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -367,8 +367,9 @@ namespace client HandleDataMessage (payload, len); break; case eI2NPDeliveryStatus: - // we assume tunnel tests non-encrypted - HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); + // try tunnel test first + if (!m_Pool || !m_Pool->ProcessDeliveryStatus (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET), bufbe64toh (payload + DELIVERY_STATUS_TIMESTAMP_OFFSET))) + HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (payload, len); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3513b7ac..b4730d0e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1154,7 +1154,7 @@ namespace garlic return len; } - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -1174,6 +1174,12 @@ namespace garlic htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); + if (msg->onDrop) + { + // move onDrop to the wrapping I2NP messages + m->onDrop = msg->onDrop; + msg->onDrop = nullptr; + } return m; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 030e2c45..e6deb2bc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -247,7 +247,7 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; }; - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 864d2c61..2c1dc979 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1152,6 +1152,13 @@ namespace i2p bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { + if (typeID == eI2NPDeliveryStatus) + { + // try tunnel test + auto pool = GetTunnelPool (); + if (pool && pool->ProcessDeliveryStatus (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET), bufbe64toh (payload + DELIVERY_STATUS_TIMESTAMP_OFFSET))) + return true; + } auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index c342d546..898a05bc 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -13,6 +13,7 @@ #include "NetDb.hpp" #include "Timestamp.h" #include "Garlic.h" +#include "ECIESX25519AEADRatchetSession.h" #include "Transports.h" #include "Log.h" #include "Tunnel.h" @@ -383,6 +384,7 @@ namespace tunnel newTests.push_back(std::make_pair (*it1, *it2)); ++it1; ++it2; } + bool encrypt = m_LocalDestination ? m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) : false; for (auto& it: newTests) { uint32_t msgID; @@ -407,6 +409,14 @@ namespace tunnel s->m_OutboundTunnels.erase (outbound); } }; + if (encrypt) + { + // encrypt + uint8_t key[32]; RAND_bytes (key, 32); + uint64_t tag; RAND_bytes ((uint8_t *)&tag, 8); + m_LocalDestination->SubmitECIESx25519Key (key, tag); + msg = i2p::garlic::WrapECIESX25519Message (msg, key, tag); + } outbound->SendTunnelDataMsgTo (it.second->GetNextIdentHash (), it.second->GetNextTunnelID (), msg); } } @@ -436,6 +446,17 @@ namespace tunnel buf += 4; uint64_t timestamp = bufbe64toh (buf); + if (!ProcessDeliveryStatus (msgID, timestamp)) + { + if (m_LocalDestination) + m_LocalDestination->ProcessDeliveryStatusMessage (msg); + else + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); + } + } + + bool TunnelPool::ProcessDeliveryStatus (uint32_t msgID, uint64_t timestamp) + { decltype(m_Tests)::mapped_type test; bool found = false; { @@ -477,15 +498,9 @@ namespace tunnel test.second->AddLatencySample(latency); } } - else - { - if (m_LocalDestination) - m_LocalDestination->ProcessDeliveryStatusMessage (msg); - else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); - } - } - + return found; + } + bool TunnelPool::IsExploratory () const { return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this (); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index d9f5966d..3e845c0e 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -85,6 +85,7 @@ namespace tunnel void ManageTunnels (uint64_t ts); void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatus (std::shared_ptr msg); + bool ProcessDeliveryStatus (uint32_t msgID, uint64_t timestamp); bool IsExploratory () const; bool IsActive () const { return m_IsActive; }; From 7d73c304b5b77493079b9aa2c5f9e927c89e2907 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Feb 2024 14:22:11 -0500 Subject: [PATCH 0459/1160] Extend transit tunnels limit to 4 bytes. Bump default value to 10K --- daemon/Daemon.cpp | 2 +- daemon/HTTPServer.cpp | 2 +- daemon/HTTPServer.h | 4 ++-- libi2pd/Config.cpp | 2 +- libi2pd/Tunnel.cpp | 2 +- libi2pd/Tunnel.h | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 17d17f72..090792bf 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -179,7 +179,7 @@ namespace util bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); - uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); + uint32_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); if (isFloodfill && i2p::config::IsDefault ("limits.transittunnels")) transitTunnels *= 2; // double default number of transit tunnels for floodfill i2p::tunnel::tunnels.SetMaxNumTransitTunnels (transitTunnels); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 862d6e4a..494a4e8e 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -772,7 +772,7 @@ namespace http { s << " info \r\n"; s << " debug
\r\n
\r\n"; - uint16_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels (); + uint32_t maxTunnels = i2p::tunnel::tunnels.GetMaxNumTransitTunnels (); s << "" << tr("Transit tunnels limit") << "
\r\n"; s << "
\r\n"; s << " \r\n"; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index f41d925d..f751c5a8 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -25,7 +25,7 @@ namespace http const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds const int COMMAND_REDIRECT_TIMEOUT = 5; // in seconds - const int TRANSIT_TUNNELS_LIMIT = 65535; + const int TRANSIT_TUNNELS_LIMIT = 1000000; class HTTPConnection: public std::enable_shared_from_this { diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b2ad7a17..a6885178 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -77,7 +77,7 @@ namespace config { limits.add_options() ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.openfiles", value()->default_value(0), "Maximum number of open files (0 - use system default)") - ("limits.transittunnels", value()->default_value(5000), "Maximum active transit tunnels (default:5000)") + ("limits.transittunnels", value()->default_value(10000), "Maximum active transit tunnels (default:10000)") ("limits.zombies", value()->default_value(0), "Minimum percentage of successfully created tunnels under which tunnel cleanup is paused (default [%]: 0.00)") ("limits.ntcpsoft", value()->default_value(0), "Ignored") ("limits.ntcphard", value()->default_value(0), "Ignored") diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 3e10ef1b..246f68e4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -986,7 +986,7 @@ namespace tunnel return m_OutboundTunnels.size(); } - void Tunnels::SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) + void Tunnels::SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels) { if (maxNumTransitTunnels > 0 && m_MaxNumTransitTunnels != maxNumTransitTunnels) { diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index cc5b9461..4903c75b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -238,8 +238,8 @@ namespace tunnel std::shared_ptr NewI2NPTunnelMessage (bool endpoint); - void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); - uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; + void SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels); + uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; int GetCongestionLevel() const { return CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels; } private: @@ -300,7 +300,7 @@ namespace tunnel i2p::util::Queue > m_Queue; i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; - uint16_t m_MaxNumTransitTunnels; + uint32_t m_MaxNumTransitTunnels; // count of tunnels for total TCSR algorithm int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; From 5415598f60878cd4879f3ce265f5d791da9b7fe8 Mon Sep 17 00:00:00 2001 From: Vort Date: Thu, 22 Feb 2024 21:50:05 +0200 Subject: [PATCH 0460/1160] add zero check to congestion level calculations --- libi2pd/Tunnel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 4903c75b..4d9ea830 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -240,7 +240,7 @@ namespace tunnel void SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels); uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; - int GetCongestionLevel() const { return CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels; } + int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; } private: From fd4513ebb232b42c6246b1d226be0a05ef863b72 Mon Sep 17 00:00:00 2001 From: Vort Date: Thu, 22 Feb 2024 23:07:07 +0200 Subject: [PATCH 0461/1160] show bandwidth caps for hops --- daemon/HTTPServer.cpp | 25 +++++++++++++++++++++---- libi2pd/RouterInfo.cpp | 7 +++++++ libi2pd/RouterInfo.h | 2 ++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 494a4e8e..7a6656dc 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -417,6 +417,15 @@ namespace http { } } + static void ShowHop(std::stringstream& s, const i2p::data::IdentityEx& ident) + { + auto identHash = ident.GetIdentHash(); + auto router = i2p::data::netdb.FindRouter(identHash); + s << i2p::data::GetIdentHashAbbreviation(identHash); + if (router) + s << " " << router->GetBandwidthCap() << ""; + } + static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest, uint32_t token) { s << "Base32:
\r\n\r\n
\r\n
\r\n" @@ -1434,7 +1432,6 @@ namespace http { "\r\n" "\r\n
\r\n"; delete[] signature; - delete[] sig; } else s << "" << tr("ERROR") << ": " << tr("Domain can't end with .b32.i2p") << "\r\n
\r\n
\r\n"; diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index bce303a2..bc9da4fb 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -58,15 +58,13 @@ namespace data /* * Reverse Substitution Table (built in run time) */ - static char iT64[256]; static int isFirstTime = 1; /* * Padding */ - - static char P64 = '='; + static constexpr char P64 = '='; /* * @@ -76,80 +74,6 @@ namespace data * Converts binary encoded data to BASE64 format. * */ - - size_t ByteStreamToBase64 ( // Number of bytes in the encoded buffer - const uint8_t * InBuffer, // Input buffer, binary data - size_t InCount, // Number of bytes in the input buffer - char * OutBuffer, // output buffer - size_t len // length of output buffer - ) - { - unsigned char * ps; - unsigned char * pd; - unsigned char acc_1; - unsigned char acc_2; - int i; - int n; - int m; - size_t outCount; - - ps = (unsigned char *)InBuffer; - n = InCount / 3; - m = InCount % 3; - if (!m) - outCount = 4 * n; - else - outCount = 4 * (n + 1); - - if (outCount > len) return 0; - - pd = (unsigned char *)OutBuffer; - for ( i = 0; i < n; i++ ) - { - acc_1 = *ps++; - acc_2 = (acc_1 << 4) & 0x30; - acc_1 >>= 2; // base64 digit #1 - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; // base64 digit #2 - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<= 2; - acc_2 = *ps++; - acc_1 |= acc_2 >> 6; // base64 digit #3 - *pd++ = T64[acc_1]; - acc_2 &= 0x3f; // base64 digit #4 - *pd++ = T64[acc_2]; - } - if ( m == 1 ) - { - acc_1 = *ps++; - acc_2 = (acc_1 << 4) & 0x3f; // base64 digit #2 - acc_1 >>= 2; // base64 digit #1 - *pd++ = T64[acc_1]; - *pd++ = T64[acc_2]; - *pd++ = P64; - *pd++ = P64; - - } - else if ( m == 2 ) - { - acc_1 = *ps++; - acc_2 = (acc_1 << 4) & 0x3f; - acc_1 >>= 2; // base64 digit #1 - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; // base64 digit #2 - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<= 2; // base64 digit #3 - *pd++ = T64[acc_1]; - *pd++ = P64; - } - - return outCount; - } - std::string ByteStreamToBase64 (// base64 encoded string const uint8_t * InBuffer, // Input buffer, binary data size_t InCount // Number of bytes in the input buffer diff --git a/libi2pd/Base.h b/libi2pd/Base.h index daf0f7ed..945dc8b3 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -18,7 +18,6 @@ namespace i2p { namespace data { - size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); // called from SAM TODO: rewrite std::string ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount); size_t Base64ToByteStream (std::string_view base64Str, uint8_t * OutBuffer, size_t len); From 609cd401bb80129d00add10c2808b8b932033eb7 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Mar 2025 20:08:39 -0400 Subject: [PATCH 1104/1160] don't calculate key's base64 if not used --- libi2pd/NetDb.cpp | 5 +++-- libi2pd/NetDbRequests.cpp | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 2bfaa8d8..e53738e5 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -951,12 +951,13 @@ namespace data LogPrint (eLogError, "NetDb: DatabaseLookup for zero ident. Ignored"); return; } - auto key = i2p::data::ByteStreamToBase64 (buf, 32); + std::string key; + if (CheckLogLevel (eLogInfo)) + key = i2p::data::ByteStreamToBase64 (buf, 32); IdentHash replyIdent(buf + 32); uint8_t flag = buf[64]; - LogPrint (eLogDebug, "NetDb: DatabaseLookup for ", key, " received flags=", (int)flag); uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK; const uint8_t * excluded = buf + 65; diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 0648d6bf..94633e10 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -360,9 +360,12 @@ namespace data void NetDbRequests::HandleDatabaseSearchReplyMsg (std::shared_ptr msg) { const uint8_t * buf = msg->GetPayload (); - auto key = i2p::data::ByteStreamToBase64 (buf, 32); + std::string key; size_t num = buf[32]; // num + if (CheckLogLevel (eLogInfo)) + key = i2p::data::ByteStreamToBase64 (buf, 32); LogPrint (eLogDebug, "NetDbReq: DatabaseSearchReply for ", key, " num=", num); + IdentHash ident (buf); bool isExploratory = false; auto dest = FindRequest (ident); From bd2b96627c7328ee23ed43a3d6c83c9f0b30d878 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Mar 2025 19:23:13 -0400 Subject: [PATCH 1105/1160] calculate crypto key length from key type --- libi2pd/CryptoKey.cpp | 17 +++++++++++------ libi2pd/CryptoKey.h | 28 ++++++++++++++++++++++++++-- libi2pd/Destination.cpp | 34 +++++++++++++++++++++------------- libi2pd/Destination.h | 13 +++++++++---- libi2pd/Identity.cpp | 4 ++-- libi2pd/Identity.h | 6 +++++- libi2pd/LeaseSet.cpp | 3 ++- libi2pd/RouterContext.cpp | 1 + libi2pd/RouterInfo.cpp | 1 + libi2pd_client/I2CP.h | 1 + 10 files changed, 79 insertions(+), 29 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index ad986129..7ea0fc2c 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -174,12 +174,17 @@ namespace crypto return m_StaticKeys.Agree (epub, sharedSecret); } - void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) + bool CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub, i2p::data::CryptoKeyType type) { - X25519Keys k; - k.GenerateKeys (); - k.GetPrivateKey (priv); - memcpy (pub, k.GetPublicKey (), 32); + if (type == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + { + X25519Keys k; + k.GenerateKeys (); + k.GetPrivateKey (priv); + memcpy (pub, k.GetPublicKey (), 32); + return true; + } + return false; } } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index a7d86d09..5fe72307 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,6 +11,7 @@ #include #include "Crypto.h" +#include "Identity.h" namespace i2p { @@ -157,7 +158,30 @@ namespace crypto X25519Keys m_StaticKeys; }; - void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub); + bool CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub, + i2p::data::CryptoKeyType type = i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); + + constexpr size_t GetCryptoPrivateKeyLen (i2p::data::CryptoKeyType type) + { + switch (type) + { + case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; + }; + return 0; + } + + constexpr size_t GetCryptoPublicKeyLen (i2p::data::CryptoKeyType type) + { + switch (type) + { + case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; + }; + return 0; + } } } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index be079ee3..8ba29ca5 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1416,21 +1416,29 @@ namespace client std::string path = i2p::fs::DataDirPath("destinations", ident + "." + std::to_string (keys->keyType) + ".dat"); std::ifstream f(path, std::ifstream::binary); - if (f) { - f.read ((char *)keys->pub, 256); - f.read ((char *)keys->priv, 256); + if (f) + { + char pub[256], priv[256]; + f.read (pub, 256); + memcpy (keys->pub.data(), pub, keys->pub.size()); + f.read (priv, 256); + memcpy (keys->priv.data (), priv, keys->priv.size ()); return; } LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p"); - memset (keys->priv, 0, 256); - memset (keys->pub, 0, 256); + memset (keys->priv.data (), 0, keys->priv.size ()); + memset (keys->pub.data (), 0, keys->pub.size ()); keys->GenerateKeys (); // TODO:: persist crypto key type std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out); - if (f1) { - f1.write ((char *)keys->pub, 256); - f1.write ((char *)keys->priv, 256); + if (f1) + { + char pub[256], priv[256]; + memset (pub, 0, 256); memcpy (pub, keys->pub.data (), keys->pub.size ()); + f1.write (pub, 256); + memset (priv, 0, 256); memcpy (priv, keys->priv.data (), keys->priv.size ()); + f1.write (priv, 256); return; } LogPrint(eLogCritical, "Destinations: Can't save keys to ", path); @@ -1443,7 +1451,7 @@ namespace client { if (m_StandardEncryptionKey) { - leaseSet = std::make_shared (GetIdentity (), m_StandardEncryptionKey->pub, tunnels); + leaseSet = std::make_shared (GetIdentity (), m_StandardEncryptionKey->pub.data (), tunnels); // sign Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); } @@ -1455,9 +1463,9 @@ namespace client // standard LS2 (type 3) first i2p::data::LocalLeaseSet2::KeySections keySections; if (m_ECIESx25519EncryptionKey) - keySections.push_back ({m_ECIESx25519EncryptionKey->keyType, 32, m_ECIESx25519EncryptionKey->pub} ); + keySections.push_back ({m_ECIESx25519EncryptionKey->keyType, (uint16_t)m_ECIESx25519EncryptionKey->pub.size (), m_ECIESx25519EncryptionKey->pub.data ()} ); if (m_StandardEncryptionKey) - keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub} ); + keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub.data ()} ); auto publishedTimestamp = i2p::util::GetSecondsSinceEpoch (); if (publishedTimestamp <= m_LastPublishedTimestamp) @@ -1501,8 +1509,8 @@ namespace client const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub : nullptr; - return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub : nullptr; + return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub.data () : nullptr; + return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub.data () : nullptr; } void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 4278f1fd..7684c0f6 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -22,6 +22,7 @@ #include "Identity.h" #include "TunnelPool.h" #include "Crypto.h" +#include "CryptoKey.h" #include "LeaseSet.h" #include "Garlic.h" #include "NetDb.hpp" @@ -231,13 +232,17 @@ namespace client { struct EncryptionKey { - uint8_t pub[256], priv[256]; + std::vector pub, priv; i2p::data::CryptoKeyType keyType; std::shared_ptr decryptor; - EncryptionKey (i2p::data::CryptoKeyType t):keyType(t) { memset (pub, 0, 256); memset (priv, 0, 256); }; - void GenerateKeys () { i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv, pub); }; - void CreateDecryptor () { decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv); }; + EncryptionKey (i2p::data::CryptoKeyType t): keyType(t) + { + pub.resize (i2p::crypto::GetCryptoPublicKeyLen (keyType)); + priv.resize (i2p::crypto::GetCryptoPrivateKeyLen (keyType)); + } + void GenerateKeys () { i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv.data (), pub.data ()); }; + void CreateDecryptor () { decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv.data ()); }; }; public: diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index e98e5fbc..b5f86f11 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -10,6 +10,7 @@ #include "I2PEndian.h" #include "Log.h" #include "Timestamp.h" +#include "CryptoKey.h" #include "Identity.h" namespace i2p @@ -658,8 +659,7 @@ namespace data size_t PrivateKeys::GetPrivateKeyLen () const { - // private key length always 256, but type 4 - return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) ? 32 : 256; + return i2p::crypto::GetCryptoPrivateKeyLen (m_Public->GetCryptoKeyType ()); } uint8_t * PrivateKeys::GetPadding() diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index e08ac802..1891c7a2 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -17,10 +17,14 @@ #include #include "Base.h" #include "Signature.h" -#include "CryptoKey.h" namespace i2p { +namespace crypto +{ + class CryptoKeyEncryptor; + class CryptoKeyDecryptor; +} namespace data { typedef Tag<32> IdentHash; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index ee1964fc..3068b35d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -14,6 +14,7 @@ #include "Timestamp.h" #include "NetDb.hpp" #include "Tunnel.h" +#include "CryptoKey.h" #include "LeaseSet.h" namespace i2p diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6819a185..af90a46a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -22,6 +22,7 @@ #include "ECIESX25519AEADRatchetSession.h" #include "Transports.h" #include "Tunnel.h" +#include "CryptoKey.h" #include "RouterContext.h" namespace i2p diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 41f71e14..4af32f57 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -25,6 +25,7 @@ #include "Transports.h" #include "NetDb.hpp" #include "RouterContext.h" +#include "CryptoKey.h" #include "RouterInfo.h" namespace i2p diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index d3949eaa..597a4878 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -21,6 +21,7 @@ #include "util.h" #include "Destination.h" #include "Streaming.h" +#include "CryptoKey.h" namespace i2p { From 46f530bfcd6b32ecb6557870ec5922a230503903 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Mar 2025 21:15:37 -0400 Subject: [PATCH 1106/1160] persist temporary keys of actual size --- libi2pd/Destination.cpp | 49 +++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 8ba29ca5..bb77b804 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1415,33 +1415,50 @@ namespace client std::string ident = GetIdentHash().ToBase32(); std::string path = i2p::fs::DataDirPath("destinations", ident + "." + std::to_string (keys->keyType) + ".dat"); std::ifstream f(path, std::ifstream::binary); - if (f) { - char pub[256], priv[256]; - f.read (pub, 256); - memcpy (keys->pub.data(), pub, keys->pub.size()); - f.read (priv, 256); - memcpy (keys->priv.data (), priv, keys->priv.size ()); - return; + size_t len = 0; + if (keys->keyType == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) + len = 512; + else if (keys->keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + { + f.seekg (0, std::ios::end); + len = f.tellg(); + f.seekg (0, std::ios::beg); + } + + if (len == 512) + { + char pub[256], priv[256]; + f.read (pub, 256); + memcpy (keys->pub.data(), pub, keys->pub.size()); + f.read (priv, 256); + memcpy (keys->priv.data (), priv, keys->priv.size ()); + } + else + { + f.read ((char *)keys->pub.data(), keys->pub.size()); + f.read ((char *)keys->priv.data(), keys->priv.size()); + } + if (f) + return; + else + LogPrint(eLogWarning, "Destination: Can't read keys from ", path); } - LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p"); + LogPrint (eLogInfo, "Destination: Creating new temporary keys of type ", keys->keyType, " for address ", ident, ".b32.i2p"); memset (keys->priv.data (), 0, keys->priv.size ()); memset (keys->pub.data (), 0, keys->pub.size ()); keys->GenerateKeys (); - // TODO:: persist crypto key type + std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out); if (f1) { - char pub[256], priv[256]; - memset (pub, 0, 256); memcpy (pub, keys->pub.data (), keys->pub.size ()); - f1.write (pub, 256); - memset (priv, 0, 256); memcpy (priv, keys->priv.data (), keys->priv.size ()); - f1.write (priv, 256); - return; + f1.write ((char *)keys->pub.data (), keys->pub.size ()); + f1.write ((char *)keys->priv.data (), keys->priv.size ()); } - LogPrint(eLogCritical, "Destinations: Can't save keys to ", path); + if (!f1) + LogPrint(eLogError, "Destination: Can't save keys to ", path); } void ClientDestination::CreateNewLeaseSet (const std::vector >& tunnels) From 9ce515ff793271363b3a33fcd333154eb75455cd Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2025 08:40:10 -0400 Subject: [PATCH 1107/1160] MLKEM512_X25519 crypto key added --- libi2pd/CryptoKey.cpp | 15 +++++---------- libi2pd/CryptoKey.h | 5 +++-- libi2pd/Destination.cpp | 8 ++++---- libi2pd/Identity.h | 1 + 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 7ea0fc2c..bac5d740 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -174,17 +174,12 @@ namespace crypto return m_StaticKeys.Agree (epub, sharedSecret); } - bool CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub, i2p::data::CryptoKeyType type) + void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) { - if (type == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - { - X25519Keys k; - k.GenerateKeys (); - k.GetPrivateKey (priv); - memcpy (pub, k.GetPublicKey (), 32); - return true; - } - return false; + X25519Keys k; + k.GenerateKeys (); + k.GetPrivateKey (priv); + memcpy (pub, k.GetPublicKey (), 32); } } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 5fe72307..14ef4fa8 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -158,8 +158,7 @@ namespace crypto X25519Keys m_StaticKeys; }; - bool CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub, - i2p::data::CryptoKeyType type = i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); + void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub); // including hybrid constexpr size_t GetCryptoPrivateKeyLen (i2p::data::CryptoKeyType type) { @@ -168,6 +167,7 @@ namespace crypto case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return 32; }; return 0; } @@ -179,6 +179,7 @@ namespace crypto case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return 32; }; return 0; } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index bb77b804..4621e147 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1520,14 +1520,14 @@ namespace client bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { - return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? (bool)m_ECIESx25519EncryptionKey : (bool)m_StandardEncryptionKey; + return keyType == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL ? (bool)m_StandardEncryptionKey : (bool)m_ECIESx25519EncryptionKey; } const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { - if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub.data () : nullptr; - return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub.data () : nullptr; + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) + return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub.data () : nullptr; + return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub.data () : nullptr; } void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 1891c7a2..576ede0d 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -70,6 +70,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD = 4; + const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD = 5; const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0; const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; From b2fd30d042588349f8587e38f9eeb6e5d309162e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2025 15:22:09 -0400 Subject: [PATCH 1108/1160] map of encryption keys --- libi2pd/Destination.cpp | 60 ++++++++++++++++++++++++----------------- libi2pd/Destination.h | 5 ++-- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 4621e147..414ef61c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1046,20 +1046,15 @@ namespace client for (auto& it: encryptionKeyTypes) { - auto encryptionKey = new EncryptionKey (it); + auto encryptionKey = std::make_shared (it); if (IsPublic ()) PersistTemporaryKeys (encryptionKey); else encryptionKey->GenerateKeys (); encryptionKey->CreateDecryptor (); - if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - { - m_ECIESx25519EncryptionKey.reset (encryptionKey); - if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) - SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2 - } - else - m_StandardEncryptionKey.reset (encryptionKey); + if (it > i2p::data::CRYPTO_KEY_TYPE_ELGAMAL && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) + SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Only DSA can use LeaseSet1 + m_EncryptionKeys.emplace (it, encryptionKey); } if (IsPublic ()) @@ -1409,7 +1404,7 @@ namespace client return ret; } - void ClientDestination::PersistTemporaryKeys (EncryptionKey * keys) + void ClientDestination::PersistTemporaryKeys (std::shared_ptr keys) { if (!keys) return; std::string ident = GetIdentHash().ToBase32(); @@ -1466,9 +1461,10 @@ namespace client std::shared_ptr leaseSet; if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) { - if (m_StandardEncryptionKey) + auto it = m_EncryptionKeys.find (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); + if (it != m_EncryptionKeys.end ()) { - leaseSet = std::make_shared (GetIdentity (), m_StandardEncryptionKey->pub.data (), tunnels); + leaseSet = std::make_shared (GetIdentity (), it->second->pub.data (), tunnels); // sign Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); } @@ -1479,10 +1475,8 @@ namespace client { // standard LS2 (type 3) first i2p::data::LocalLeaseSet2::KeySections keySections; - if (m_ECIESx25519EncryptionKey) - keySections.push_back ({m_ECIESx25519EncryptionKey->keyType, (uint16_t)m_ECIESx25519EncryptionKey->pub.size (), m_ECIESx25519EncryptionKey->pub.data ()} ); - if (m_StandardEncryptionKey) - keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub.data ()} ); + for (const auto& it: m_EncryptionKeys) + keySections.push_back ({it.first, (uint16_t)it.second->pub.size (), it.second->pub.data ()} ); auto publishedTimestamp = i2p::util::GetSecondsSinceEpoch (); if (publishedTimestamp <= m_LastPublishedTimestamp) @@ -1508,11 +1502,22 @@ namespace client bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { - if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor) - return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data); - if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) - return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data); + std::shared_ptr encryptionKey; + if (!m_EncryptionKeys.empty ()) + { + if (m_EncryptionKeys.rbegin ()->first == preferredCrypto) + encryptionKey = m_EncryptionKeys.rbegin ()->second; + else + { + auto it = m_EncryptionKeys.find (preferredCrypto); + if (it != m_EncryptionKeys.end ()) + encryptionKey = it->second; + } + if (!encryptionKey) + encryptionKey = m_EncryptionKeys.rbegin ()->second; + } + if (encryptionKey) + return encryptionKey->decryptor->Decrypt (encrypted, data); else LogPrint (eLogError, "Destinations: Decryptor is not set"); return false; @@ -1520,14 +1525,19 @@ namespace client bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { - return keyType == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL ? (bool)m_StandardEncryptionKey : (bool)m_ECIESx25519EncryptionKey; +#if __cplusplus >= 202002L // C++20 + return m_EncryptionKeys.contains (keyType); +#else + return m_EncryptionKeys.count (keyType) > 0; +#endif } const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { - if (keyType == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) - return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub.data () : nullptr; - return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub.data () : nullptr; + auto it = m_EncryptionKeys.find (keyType); + if (it != m_EncryptionKeys.end ()) + return it->second->pub.data (); + return nullptr; } void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 7684c0f6..df87256d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -306,7 +306,7 @@ namespace client std::shared_ptr GetSharedFromThis () { return std::static_pointer_cast(shared_from_this ()); } - void PersistTemporaryKeys (EncryptionKey * keys); + void PersistTemporaryKeys (std::shared_ptr keys); void ReadAuthKey (const std::string& group, const std::map * params); template @@ -315,8 +315,7 @@ namespace client private: i2p::data::PrivateKeys m_Keys; - std::unique_ptr m_StandardEncryptionKey; - std::unique_ptr m_ECIESx25519EncryptionKey; + std::map > m_EncryptionKeys; // last is most preferable int m_StreamingAckDelay,m_StreamingOutboundSpeed, m_StreamingInboundSpeed, m_StreamingMaxConcurrentStreams; bool m_IsStreamingAnswerPings; From 9684c86a6939667a96fdb7abcdd4cfd31df74930 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2025 20:49:52 -0400 Subject: [PATCH 1109/1160] select key with max key type if no preferred. Changed default preferred type to 4 --- libi2pd/LeaseSet.cpp | 18 +++++++++++------- libi2pd/LeaseSet.h | 6 +++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 3068b35d..e4edcb31 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -400,6 +400,7 @@ namespace data offset += propertiesLen; // skip for now. TODO: implement properties // key sections CryptoKeyType preferredKeyType = m_EncryptionType; + m_EncryptionType = 0; bool preferredKeyFound = false; if (offset + 1 > len) return 0; int numKeySections = buf[offset]; offset++; @@ -411,14 +412,17 @@ namespace data if (offset + encryptionKeyLen > len) return 0; if (IsStoreLeases () && !preferredKeyFound) // create encryptor with leases only { - // we pick first valid key if preferred not found - auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); - if (encryptor && (!m_Encryptor || keyType == preferredKeyType)) + // we pick max key type if preferred not found + if (keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType) { - m_Encryptor = encryptor; // TODO: atomic - m_EncryptionType = keyType; - if (keyType == preferredKeyType) preferredKeyFound = true; - } + auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); + if (encryptor) + { + m_Encryptor = encryptor; // TODO: atomic + m_EncryptionType = keyType; + if (keyType == preferredKeyType) preferredKeyFound = true; + } + } } offset += encryptionKeyLen; } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index a365ae77..1a89229a 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -150,8 +150,8 @@ namespace data public: LeaseSet2 (uint8_t storeType): LeaseSet (true), m_StoreType (storeType) {}; // for update - LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); - LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); // store type 5, called from local netdb only + LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); + LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; bool IsPublic () const { return m_IsPublic; }; From 9769ab0a465a6a1dca8a73995d3f169f1a85019c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2025 21:56:59 -0400 Subject: [PATCH 1110/1160] changed ML-DSA-44 code --- libi2pd/Identity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 576ede0d..ee736441 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -84,7 +84,7 @@ namespace data const uint16_t SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256 = 9; const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512 = 10; // approved by FSB const uint16_t SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 = 11; // for LeaseSet2 only - const uint16_t SIGNING_KEY_TYPE_MLDSA44 = 15; + const uint16_t SIGNING_KEY_TYPE_MLDSA44 = 12; typedef uint16_t SigningKeyType; typedef uint16_t CryptoKeyType; From 935c055a35d92dcd045e9d2fd29e2913f0458c3e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2025 22:00:08 -0400 Subject: [PATCH 1111/1160] encryptor/decryptor/keygen for ECIES_MLKEM512_X25519_AEAD --- libi2pd/Identity.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index b5f86f11..3b2f5b97 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -419,6 +419,7 @@ namespace data return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -685,6 +686,7 @@ namespace data return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -772,6 +774,7 @@ namespace data i2p::crypto::CreateECIESP256RandomKeys (priv, pub); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: From 9fdbb14075c57e6c9baa5e0df0869d011448c90e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Mar 2025 18:56:10 -0400 Subject: [PATCH 1112/1160] calculate preferred crypto based i2cp.leaseSetEncType --- libi2pd/Destination.cpp | 14 +++++--------- libi2pd/Destination.h | 21 ++++++++++++--------- libi2pd_client/I2CP.cpp | 8 +++++++- libi2pd_client/I2CP.h | 18 ++++++++++-------- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 414ef61c..d7f311cf 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -994,17 +994,10 @@ namespace client } } - i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const - { - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; - return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; - } - ClientDestination::ClientDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (service, isPublic, params), - m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + m_Keys (keys), m_PreferredCryptoType (0), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_StreamingOutboundSpeed (DEFAULT_MAX_OUTBOUND_SPEED), m_StreamingInboundSpeed (DEFAULT_MAX_INBOUND_SPEED), m_StreamingMaxConcurrentStreams (DEFAULT_MAX_CONCURRENT_STREAMS), @@ -1029,7 +1022,10 @@ namespace client { try { - encryptionKeyTypes.insert (std::stoi(it1)); + i2p::data::CryptoKeyType preferredCryptoType = std::stoi(it1); + if (!m_PreferredCryptoType && preferredCryptoType) + m_PreferredCryptoType = preferredCryptoType; // first non-zero in the list + encryptionKeyTypes.insert (preferredCryptoType); } catch (std::exception& ex) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index df87256d..d844c085 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -171,10 +171,11 @@ namespace client void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; int GetAuthType () const { return m_AuthType; }; virtual void CleanupDestination () {}; // additional clean up in derived classes + virtual i2p::data::CryptoKeyType GetPreferredCryptoType () const = 0; // I2CP virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0; virtual void CreateNewLeaseSet (const std::vector >& tunnels) = 0; - + private: void UpdateLeaseSet (); @@ -193,7 +194,6 @@ namespace client void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); - i2p::data::CryptoKeyType GetPreferredCryptoType () const; private: @@ -289,18 +289,20 @@ namespace client i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; - std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; - const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const override; + std::shared_ptr GetIdentity () const override { return m_Keys.GetPublic (); }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const override; + const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const override; protected: - void CleanupDestination (); + // LeaseSetDestination + void CleanupDestination () override; + i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; } // I2CP void HandleDataMessage (const uint8_t * buf, size_t len); void CreateNewLeaseSet (const std::vector >& tunnels); - + private: std::shared_ptr GetSharedFromThis () { @@ -316,7 +318,8 @@ namespace client i2p::data::PrivateKeys m_Keys; std::map > m_EncryptionKeys; // last is most preferable - + i2p::data::CryptoKeyType m_PreferredCryptoType; + int m_StreamingAckDelay,m_StreamingOutboundSpeed, m_StreamingInboundSpeed, m_StreamingMaxConcurrentStreams; bool m_IsStreamingAnswerPings; std::shared_ptr m_StreamingDestination; // default diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index df93082b..09fcee71 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -79,7 +79,13 @@ namespace client return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType; } - + i2p::data::CryptoKeyType I2CPDestination::GetPreferredCryptoType () const + { + if (m_ECIESx25519Decryptor) + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; + return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; + } + void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 597a4878..936f3c49 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -101,18 +101,20 @@ namespace client bool SendMsg (const uint8_t * payload, size_t len, std::shared_ptr remoteSession, uint32_t nonce); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; - const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only - std::shared_ptr GetIdentity () const { return m_Identity; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const override; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const override; + const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const override; // for 4 only + std::shared_ptr GetIdentity () const override { return m_Identity; }; protected: - void CleanupDestination (); + // LeaseSetDestination + void CleanupDestination () override; + i2p::data::CryptoKeyType GetPreferredCryptoType () const override; // I2CP - void HandleDataMessage (const uint8_t * buf, size_t len); - void CreateNewLeaseSet (const std::vector >& tunnels); - + void HandleDataMessage (const uint8_t * buf, size_t len) override; + void CreateNewLeaseSet (const std::vector >& tunnels) override; + private: std::shared_ptr GetSharedFromThis () From 7b98dd84d880a4ef8286d442f233fdab74c14ec2 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 21 Mar 2025 19:40:02 -0400 Subject: [PATCH 1113/1160] pass type with static key --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +- libi2pd/ECIESX25519AEADRatchetSession.h | 9 +++-- libi2pd/Garlic.cpp | 48 ++++++++++++----------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bdf5f7f7..7a799d29 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -167,7 +167,7 @@ namespace garlic } ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS): - GarlicRoutingSession (owner, true) + GarlicRoutingSession (owner, true), m_RemoteStaticKeyType (0) { if (!attachLeaseSetNS) SetLeaseSetUpdateStatus (eLeaseSetUpToDate); RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0; @@ -291,7 +291,7 @@ namespace garlic if (isStatic) { // static key, fs is apk - memcpy (m_RemoteStaticKey, fs, 32); + SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD, fs); // TODO: actual key type if (!GetOwner ()->Decrypt (fs, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index d17565a8..5614e6cb 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -168,14 +168,16 @@ namespace garlic std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } - void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } - + void SetRemoteStaticKey (i2p::data::CryptoKeyType keyType, const uint8_t * key) + { + m_RemoteStaticKeyType = keyType; + memcpy (m_RemoteStaticKey, key, 32); + } void Terminate () { m_IsTerminated = true; } void SetDestination (const i2p::data::IdentHash& dest) { if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } @@ -219,6 +221,7 @@ namespace garlic private: + i2p::data::CryptoKeyType m_RemoteStaticKeyType; uint8_t m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 89737db0..0098bdcd 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -747,31 +747,35 @@ namespace garlic std::shared_ptr destination, bool attachLeaseSet, bool requestNewIfNotFound) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && - SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + if (destination->GetEncryptionType () >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) { - ECIESX25519AEADRatchetSessionPtr session; - uint8_t staticKey[32]; - destination->Encrypt (nullptr, staticKey); // we are supposed to get static key - auto it = m_ECIESx25519Sessions.find (staticKey); - if (it != m_ECIESx25519Sessions.end ()) - { - session = it->second; - if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ())) + if (SupportsEncryptionType (destination->GetEncryptionType ())) + { + ECIESX25519AEADRatchetSessionPtr session; + uint8_t staticKey[32]; + destination->Encrypt (nullptr, staticKey); // we are supposed to get static key + auto it = m_ECIESx25519Sessions.find (staticKey); + if (it != m_ECIESx25519Sessions.end ()) { - LogPrint (eLogDebug, "Garlic: Session restarted"); - requestNewIfNotFound = true; // it's not a new session - session = nullptr; + session = it->second; + if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ())) + { + LogPrint (eLogDebug, "Garlic: Session restarted"); + requestNewIfNotFound = true; // it's not a new session + session = nullptr; + } } + if (!session && requestNewIfNotFound) + { + session = std::make_shared (this, true); + session->SetRemoteStaticKey (destination->GetEncryptionType (), staticKey); + } + if (session && destination->IsDestination ()) + session->SetDestination (destination->GetIdentHash ()); // NS or NSR + return session; } - if (!session && requestNewIfNotFound) - { - session = std::make_shared (this, true); - session->SetRemoteStaticKey (staticKey); - } - if (session && destination->IsDestination ()) - session->SetDestination (destination->GetIdentHash ()); // NS or NSR - return session; + else + LogPrint (eLogError, "Garlic: Non-supported encryption type ", destination->GetEncryptionType ()); } else { From af5d2a415c26fffb7c5158cbea9fa716d5e2960e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Mar 2025 12:01:47 -0400 Subject: [PATCH 1114/1160] c++20 --- Makefile.haiku | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.haiku b/Makefile.haiku index bc3094f6..5dce7d7f 100644 --- a/Makefile.haiku +++ b/Makefile.haiku @@ -1,8 +1,8 @@ CXX = g++ -CXXFLAGS := -Wall -std=c++17 +CXXFLAGS := -Wall -std=c++20 INCFLAGS = -I/system/develop/headers DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE -LDLIBS = -lbe -lbsd -lnetwork -lz -lssl -lcrypto -lboost_system -lboost_program_options -lpthread +LDLIBS = -lbe -lbsd -lnetwork -lz -lssl -lcrypto -lboost_program_options -lpthread ifeq ($(USE_UPNP),yes) DEFINES += -DUSE_UPNP From 029e279b487af61cb9577d40baa46642060c76f2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Mar 2025 12:30:51 -0400 Subject: [PATCH 1115/1160] fixed typo --- libi2pd_client/AddressBook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index c0f440f9..8333e87d 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -584,7 +584,7 @@ namespace client } #if __cplusplus >= 202002L // C++20 - if (name.ends_with (".i2p")) + if (!name.ends_with (".i2p")) #else if (name.find(".i2p") == name.npos) #endif From 41197264c626f908c3afcea0b0d162e6349aac2a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Mar 2025 15:42:22 -0400 Subject: [PATCH 1116/1160] fixed warning --- libi2pd/Destination.h | 8 ++++---- libi2pd_client/I2CP.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index d844c085..802d7780 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -251,8 +251,8 @@ namespace client bool isPublic, const std::map * params = nullptr); ~ClientDestination (); - void Start (); - void Stop (); + void Start () override; + void Stop () override; const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; @@ -300,8 +300,8 @@ namespace client void CleanupDestination () override; i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; } // I2CP - void HandleDataMessage (const uint8_t * buf, size_t len); - void CreateNewLeaseSet (const std::vector >& tunnels); + void HandleDataMessage (const uint8_t * buf, size_t len) override; + void CreateNewLeaseSet (const std::vector >& tunnels) override; private: diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 936f3c49..3a9a7e7f 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -90,7 +90,7 @@ namespace client const std::map& params); ~I2CPDestination () {}; - void Stop (); + void Stop () override; void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; From a193186935a4098200ecfd19da1678b21bbc57dd Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 Mar 2025 22:25:06 -0400 Subject: [PATCH 1117/1160] MLKEM512 keygen added --- libi2pd/Crypto.cpp | 73 +++++++++++++++++++++++++++++++++++++--------- libi2pd/Crypto.h | 20 +++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 095f25d6..cd3b0fbc 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -29,7 +29,7 @@ namespace i2p { namespace crypto { - const uint8_t elgp_[256]= + constexpr uint8_t elgp_[256]= { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, @@ -49,9 +49,9 @@ namespace crypto 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - const int elgg_ = 2; + constexpr int elgg_ = 2; - const uint8_t dsap_[128]= + constexpr uint8_t dsap_[128]= { 0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c, 0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15, @@ -63,13 +63,13 @@ namespace crypto 0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93 }; - const uint8_t dsaq_[20]= + constexpr uint8_t dsaq_[20]= { 0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d, 0x68, 0x40, 0x46, 0xb7 }; - const uint8_t dsag_[128]= + constexpr uint8_t dsag_[128]= { 0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0, 0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81, @@ -81,7 +81,7 @@ namespace crypto 0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82 }; - const int rsae_ = 65537; + constexpr int rsae_ = 65537; struct CryptoConstants { @@ -824,8 +824,8 @@ namespace crypto void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) { - static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars - static const uint8_t hh[32] = + static constexpr char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars + static constexpr uint8_t hh[32] = { 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 @@ -835,12 +835,12 @@ namespace crypto void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) { - static const uint8_t protocolNameHash[32] = + static constexpr uint8_t protocolNameHash[32] = { 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 }; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256") - static const uint8_t hh[32] = + static constexpr uint8_t hh[32] = { 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e @@ -850,12 +850,12 @@ namespace crypto void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub) { - static const uint8_t protocolNameHash[32] = + static constexpr uint8_t protocolNameHash[32] = { 0xb1, 0x37, 0x22, 0x81, 0x74, 0x23, 0xa8, 0xfd, 0xf4, 0x2d, 0xf2, 0xe6, 0x0e, 0xd1, 0xed, 0xf4, 0x1b, 0x93, 0x07, 0x1d, 0xb1, 0xec, 0x24, 0xa3, 0x67, 0xf7, 0x84, 0xec, 0x27, 0x0d, 0x81, 0x32 }; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256") - static const uint8_t hh[32] = + static constexpr uint8_t hh[32] = { 0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53, 0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33 @@ -865,12 +865,12 @@ namespace crypto void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) { - static const uint8_t protocolNameHash[32] = + static constexpr uint8_t protocolNameHash[32] = { 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes - static const uint8_t hh[32] = + static constexpr uint8_t hh[32] = { 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c @@ -878,6 +878,21 @@ namespace crypto InitNoiseState (state, protocolNameHash, hh, pub); } + void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub) + { + static constexpr uint8_t protocolNameHash[32] = + { + 0xb0, 0x8f, 0xb1, 0x73, 0x92, 0x66, 0xc9, 0x90, 0x45, 0x7f, 0xdd, 0xc6, 0x4e, 0x55, 0x40, 0xd8, + 0x0a, 0x37, 0x99, 0x06, 0x92, 0x2a, 0x78, 0xc4, 0xb1, 0xef, 0x86, 0x06, 0xd0, 0x15, 0x9f, 0x4d + }; // SHA256("Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256") + static constexpr uint8_t hh[32] = + { + 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, + 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb + }; // SHA256 (protocolNameHash) + InitNoiseState (state, protocolNameHash, hh, pub); + } + // init and terminate /* std::vector > m_OpenSSLMutexes; @@ -926,5 +941,35 @@ namespace crypto /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } + +#if OPENSSL_PQ +#include + + MLKEM512Keys::MLKEM512Keys (): + m_Pkey (nullptr) + { + } + + MLKEM512Keys::~MLKEM512Keys () + { + if (m_Pkey) EVP_PKEY_free (m_Pkey); + } + + void MLKEM512Keys::GenerateKeys () + { + if (m_Pkey) + { + EVP_PKEY_free (m_Pkey); + m_Pkey = nullptr; + } + m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-KEM-512"); + } + + void MLKEM512Keys::GetPublicKey (uint8_t * pub) const + { + size_t len = MLKEM512_KEY_LENGTH; + EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, MLKEM512_KEY_LENGTH, &len); + } +#endif } } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index b2fa0292..6b7b0e30 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -261,10 +261,30 @@ namespace crypto void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2) void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (SSU2) void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) + void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) PQ ML-KEM512 // init and terminate void InitCrypto (bool precomputation); void TerminateCrypto (); + +#if OPENSSL_PQ +// Post Quantum + constexpr size_t MLKEM512_KEY_LENGTH = 800; + class MLKEM512Keys + { + public: + + MLKEM512Keys (); + ~MLKEM512Keys (); + + void GenerateKeys (); + void GetPublicKey (uint8_t * pub) const; + + private: + + EVP_PKEY * m_Pkey; + }; +#endif } } From 75d5c6036e9b9df63443b04ce93606a1f34106fb Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 Mar 2025 18:53:32 -0400 Subject: [PATCH 1118/1160] use EVP interface for DSA sign/verify with OpenSSL 3 --- libi2pd/Crypto.cpp | 39 +++++++++- libi2pd/Crypto.h | 4 ++ libi2pd/Signature.cpp | 164 +++++++++++++++++++++++++++++++++++++++++- libi2pd/Signature.h | 88 +++++++---------------- 4 files changed, 227 insertions(+), 68 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index cd3b0fbc..414314cf 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -19,6 +19,10 @@ #if OPENSSL_HKDF #include #endif +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 +#include +#include +#endif #include "CPU.h" #include "Crypto.h" #include "Ed25519.h" @@ -146,6 +150,37 @@ namespace crypto #define dsap GetCryptoConstants ().dsap #define dsaq GetCryptoConstants ().dsaq #define dsag GetCryptoConstants ().dsag +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 + EVP_PKEY * CreateDSA (BIGNUM * pubKey, BIGNUM * privKey) + { + EVP_PKEY * pkey = nullptr; + int selection = EVP_PKEY_KEY_PARAMETERS; + auto bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, dsap); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, dsaq); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, dsag); + if (pubKey) + { + OSSL_PARAM_BLD_push_BN (bld, OSSL_PKEY_PARAM_PUB_KEY, pubKey); + selection = EVP_PKEY_PUBLIC_KEY; + } + if (privKey) + { + OSSL_PARAM_BLD_push_BN (bld, OSSL_PKEY_PARAM_PRIV_KEY, privKey); + selection = EVP_PKEY_KEYPAIR; + } + auto params = OSSL_PARAM_BLD_to_param(bld); + + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "DSA", NULL); + EVP_PKEY_fromdata_init(ctx); + EVP_PKEY_fromdata(ctx, &pkey, selection, params); + + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(bld); + return pkey; + } +#else DSA * CreateDSA () { DSA * dsa = DSA_new (); @@ -153,7 +188,8 @@ namespace crypto DSA_set0_key (dsa, NULL, NULL); return dsa; } - +#endif + // DH/ElGamal #if !IS_X86_64 @@ -943,7 +979,6 @@ namespace crypto } #if OPENSSL_PQ -#include MLKEM512Keys::MLKEM512Keys (): m_Pkey (nullptr) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 6b7b0e30..b6ab3fa4 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -45,7 +45,11 @@ namespace crypto bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len); // DSA +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 + EVP_PKEY * CreateDSA (BIGNUM * pubKey = nullptr, BIGNUM * privKey = nullptr); +#else DSA * CreateDSA (); +#endif // RSA const BIGNUM * GetRSAE (); diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index f684f10f..3e4b451b 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -7,6 +7,10 @@ */ #include +#include +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 +#include +#endif #include "Log.h" #include "Signature.h" @@ -14,6 +18,163 @@ namespace i2p { namespace crypto { +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 + DSAVerifier::DSAVerifier (): + m_PublicKey (nullptr) + { + } + + DSAVerifier::~DSAVerifier () + { + if (m_PublicKey) + EVP_PKEY_free (m_PublicKey); + } + + void DSAVerifier::SetPublicKey (const uint8_t * signingKey) + { + if (m_PublicKey) + EVP_PKEY_free (m_PublicKey); + BIGNUM * pub = BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL); + m_PublicKey = CreateDSA (pub); + BN_free (pub); + } + + bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const + { + // calculate SHA1 digest + uint8_t digest[20], sign[48]; + SHA1 (buf, len, digest); + // signature + DSA_SIG * sig = DSA_SIG_new(); + DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); + // to DER format + uint8_t * s = sign; + auto l = i2d_DSA_SIG (sig, &s); + DSA_SIG_free(sig); + // verify + auto ctx = EVP_PKEY_CTX_new (m_PublicKey, NULL); + EVP_PKEY_verify_init(ctx); + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()); + bool ret = EVP_PKEY_verify(ctx, sign, l, digest, 20); + EVP_PKEY_CTX_free(ctx); + return ret; + } + + DSASigner::DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + { + BIGNUM * priv = BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL); + m_PrivateKey = CreateDSA (nullptr, priv); + BN_free (priv); + } + + DSASigner::~DSASigner () + { + if (m_PrivateKey) + EVP_PKEY_free (m_PrivateKey); + } + + void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + uint8_t digest[20], sign[48]; + SHA1 (buf, len, digest); + auto ctx = EVP_PKEY_CTX_new (m_PrivateKey, NULL); + EVP_PKEY_sign_init(ctx); + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()); + size_t l = 48; + EVP_PKEY_sign(ctx, sign, &l, digest, 20); + const uint8_t * s1 = sign; + DSA_SIG * sig = d2i_DSA_SIG (NULL, &s1, l); + const BIGNUM * r, * s; + DSA_SIG_get0 (sig, &r, &s); + bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); + bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); + DSA_SIG_free(sig); + EVP_PKEY_CTX_free(ctx); + } + + void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) + { + EVP_PKEY * paramskey = CreateDSA(); + EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new_from_pkey(NULL, paramskey, NULL); + EVP_PKEY_keygen_init(ctx); + EVP_PKEY * pkey = nullptr; + EVP_PKEY_keygen(ctx, &pkey); + BIGNUM * pub = NULL, * priv = NULL; + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pub); + bn2buf (pub, signingPublicKey, DSA_PUBLIC_KEY_LENGTH); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv); + bn2buf (priv, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH); + BN_free (pub); BN_free (priv); + EVP_PKEY_free (pkey); + EVP_PKEY_free (paramskey); + EVP_PKEY_CTX_free (ctx); + } +#else + + DSAVerifier::DSAVerifier () + { + m_PublicKey = CreateDSA (); + } + + DSAVerifier::~DSAVerifier () + { + DSA_free (m_PublicKey); + } + + void DSAVerifier::SetPublicKey (const uint8_t * signingKey) + { + DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); + } + + bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const + { + // calculate SHA1 digest + uint8_t digest[20]; + SHA1 (buf, len, digest); + // signature + DSA_SIG * sig = DSA_SIG_new(); + DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); + // DSA verification + int ret = DSA_do_verify (digest, 20, sig, m_PublicKey); + DSA_SIG_free(sig); + return ret; + } + + DSASigner::DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + { + m_PrivateKey = CreateDSA (); + DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); + } + + DSASigner::~DSASigner () + { + DSA_free (m_PrivateKey); + } + + void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + uint8_t digest[20]; + SHA1 (buf, len, digest); + DSA_SIG * sig = DSA_do_sign (digest, 20, m_PrivateKey); + const BIGNUM * r, * s; + DSA_SIG_get0 (sig, &r, &s); + bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); + bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); + DSA_SIG_free(sig); + } + + void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) + { + DSA * dsa = CreateDSA (); + DSA_generate_key (dsa); + const BIGNUM * pub_key, * priv_key; + DSA_get0_key(dsa, &pub_key, &priv_key); + bn2buf (priv_key, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH); + bn2buf (pub_key, signingPublicKey, DSA_PUBLIC_KEY_LENGTH); + DSA_free (dsa); + } +#endif + #if OPENSSL_EDDSA EDDSA25519Verifier::EDDSA25519Verifier (): m_Pkey (nullptr) @@ -202,8 +363,7 @@ namespace crypto #endif #if OPENSSL_PQ -#include - + MLDSA44Verifier::MLDSA44Verifier (): m_Pkey (nullptr) { diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index c77e10dd..20c7e11b 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -43,94 +43,55 @@ namespace crypto virtual void Sign (const uint8_t * buf, int len, uint8_t * signature) const = 0; }; + // DSA const size_t DSA_PUBLIC_KEY_LENGTH = 128; const size_t DSA_SIGNATURE_LENGTH = 40; const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2; class DSAVerifier: public Verifier { public: + + DSAVerifier (); + ~DSAVerifier (); - DSAVerifier () - { - m_PublicKey = CreateDSA (); - } - - void SetPublicKey (const uint8_t * signingKey) - { - DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); - } - - ~DSAVerifier () - { - DSA_free (m_PublicKey); - } - - bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const - { - // calculate SHA1 digest - uint8_t digest[20]; - SHA1 (buf, len, digest); - // signature - DSA_SIG * sig = DSA_SIG_new(); - DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); - // DSA verification - int ret = DSA_do_verify (digest, 20, sig, m_PublicKey); - DSA_SIG_free(sig); - return ret; - } - - size_t GetPublicKeyLen () const { return DSA_PUBLIC_KEY_LENGTH; }; - size_t GetSignatureLen () const { return DSA_SIGNATURE_LENGTH; }; - + // implements Verifier + void SetPublicKey (const uint8_t * signingKey) override; + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const override; + size_t GetPublicKeyLen () const override { return DSA_PUBLIC_KEY_LENGTH; }; + size_t GetSignatureLen () const override { return DSA_SIGNATURE_LENGTH; }; + private: +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 + EVP_PKEY * m_PublicKey; +#else DSA * m_PublicKey; +#endif }; class DSASigner: public Signer { public: - DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey); // openssl 1.1 always requires DSA public key even for signing - { - m_PrivateKey = CreateDSA (); - DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); - } + ~DSASigner (); - ~DSASigner () - { - DSA_free (m_PrivateKey); - } - - void Sign (const uint8_t * buf, int len, uint8_t * signature) const - { - uint8_t digest[20]; - SHA1 (buf, len, digest); - DSA_SIG * sig = DSA_do_sign (digest, 20, m_PrivateKey); - const BIGNUM * r, * s; - DSA_SIG_get0 (sig, &r, &s); - bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); - bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); - DSA_SIG_free(sig); - } + // implements Signer + void Sign (const uint8_t * buf, int len, uint8_t * signature) const override; private: +#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 + EVP_PKEY * m_PrivateKey; +#else DSA * m_PrivateKey; +#endif }; - inline void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) - { - DSA * dsa = CreateDSA (); - DSA_generate_key (dsa); - const BIGNUM * pub_key, * priv_key; - DSA_get0_key(dsa, &pub_key, &priv_key); - bn2buf (priv_key, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH); - bn2buf (pub_key, signingPublicKey, DSA_PUBLIC_KEY_LENGTH); - DSA_free (dsa); - } + void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey); + // ECDSA struct SHA256Hash { static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) @@ -161,7 +122,6 @@ namespace crypto enum { hashLen = 64 }; }; - // EcDSA template class ECDSAVerifier: public Verifier { From 22d854a6be8d34cd63401c32f7afc1f6a7606913 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Mar 2025 15:45:06 -0400 Subject: [PATCH 1119/1160] ML-KEM-512 encaps/decaps --- libi2pd/Crypto.cpp | 66 +++++++++++++++++++++++++++++++++++++++++----- libi2pd/Crypto.h | 4 +++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 414314cf..9bdfe43f 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -992,19 +992,71 @@ namespace crypto void MLKEM512Keys::GenerateKeys () { - if (m_Pkey) - { - EVP_PKEY_free (m_Pkey); - m_Pkey = nullptr; - } + if (m_Pkey) EVP_PKEY_free (m_Pkey); m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-KEM-512"); } void MLKEM512Keys::GetPublicKey (uint8_t * pub) const { - size_t len = MLKEM512_KEY_LENGTH; - EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, MLKEM512_KEY_LENGTH, &len); + if (m_Pkey) + { + size_t len = MLKEM512_KEY_LENGTH; + EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, MLKEM512_KEY_LENGTH, &len); + } } + + void MLKEM512Keys::SetPublicKey (const uint8_t * pub) + { + if (m_Pkey) + { + EVP_PKEY_free (m_Pkey); + m_Pkey = nullptr; + } + OSSL_PARAM params[] = + { + OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)pub, MLKEM512_KEY_LENGTH), + OSSL_PARAM_END + }; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "ML-KEM-512", NULL); + if (ctx) + { + EVP_PKEY_fromdata_init (ctx); + EVP_PKEY_fromdata (ctx, &m_Pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } + + void MLKEM512Keys::Encaps (uint8_t * ciphertext, uint8_t * shared) + { + if (!m_Pkey) return; + auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); + if (ctx) + { + EVP_PKEY_encapsulate_init (ctx, NULL); + size_t len = MLKEM512_CIPHER_TEXT_LENGTH, sharedLen = 32; + EVP_PKEY_encapsulate (ctx, ciphertext, &len, shared, &sharedLen); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } + + void MLKEM512Keys::Decaps (const uint8_t * ciphertext, uint8_t * shared) + { + if (!m_Pkey) return; + auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); + if (ctx) + { + EVP_PKEY_decapsulate_init (ctx, NULL); + size_t sharedLen = 32; + EVP_PKEY_decapsulate (ctx, shared, &sharedLen, ciphertext, MLKEM512_CIPHER_TEXT_LENGTH); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } #endif } } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index b6ab3fa4..dcdc27d3 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -274,6 +274,7 @@ namespace crypto #if OPENSSL_PQ // Post Quantum constexpr size_t MLKEM512_KEY_LENGTH = 800; + constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; class MLKEM512Keys { public: @@ -283,6 +284,9 @@ namespace crypto void GenerateKeys (); void GetPublicKey (uint8_t * pub) const; + void SetPublicKey (const uint8_t * pub); + void Encaps (uint8_t * ciphertext, uint8_t * shared); + void Decaps (const uint8_t * ciphertext, uint8_t * shared); private: From d3cfbbd6b0484c6b0c2c225de00f9bfbea384d29 Mon Sep 17 00:00:00 2001 From: AsciiMoth Date: Tue, 25 Mar 2025 09:35:00 +0400 Subject: [PATCH 1120/1160] Update dates range in licence --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 93280084..f59491f5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2023, The PurpleI2P Project +Copyright (c) 2013-2025, The PurpleI2P Project All rights reserved. From ecf19278e86d75e4834ad0af61a0c534f7332703 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 25 Mar 2025 18:55:28 -0400 Subject: [PATCH 1121/1160] skip post-quantum keys if not supported --- libi2pd/Destination.cpp | 13 +++++++++---- libi2pd/LeaseSet.cpp | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d7f311cf..e20249c5 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1022,10 +1022,15 @@ namespace client { try { - i2p::data::CryptoKeyType preferredCryptoType = std::stoi(it1); - if (!m_PreferredCryptoType && preferredCryptoType) - m_PreferredCryptoType = preferredCryptoType; // first non-zero in the list - encryptionKeyTypes.insert (preferredCryptoType); + i2p::data::CryptoKeyType cryptoType = std::stoi(it1); +#if !OPENSSL_PQ + if (cryptoType <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // skip PQ keys if not supported +#endif + { + if (!m_PreferredCryptoType && cryptoType) + m_PreferredCryptoType = cryptoType; // first non-zero in the list + encryptionKeyTypes.insert (cryptoType); + } } catch (std::exception& ex) { diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index e4edcb31..db8c1aad 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -413,15 +413,20 @@ namespace data if (IsStoreLeases () && !preferredKeyFound) // create encryptor with leases only { // we pick max key type if preferred not found - if (keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType) - { - auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); - if (encryptor) +#if !OPENSSL_PQ + if (keyType <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // skip PQ keys if not supported +#endif + { + if (keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType) { - m_Encryptor = encryptor; // TODO: atomic - m_EncryptionType = keyType; - if (keyType == preferredKeyType) preferredKeyFound = true; - } + auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); + if (encryptor) + { + m_Encryptor = encryptor; // TODO: atomic + m_EncryptionType = keyType; + if (keyType == preferredKeyType) preferredKeyFound = true; + } + } } } offset += encryptionKeyLen; From 81ba19e1ae060347add0179f9594e0c3b9383473 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 25 Mar 2025 21:31:16 -0400 Subject: [PATCH 1122/1160] use find_directory to detect data dir in Haiku --- libi2pd/FS.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index a623a4eb..3f5fc6b9 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,6 +15,10 @@ #include #endif +#if defined(__HAIKU__) +#include +#endif + #ifdef _WIN32 #include #include @@ -169,12 +173,11 @@ namespace fs { dataDir += "/Library/Application Support/" + appName; return; #elif defined(__HAIKU__) - char *home = getenv("HOME"); - if (home != NULL && strlen(home) > 0) { - dataDir = std::string(home) + "/config/settings/" + appName; - } else { + char home[PATH_MAX]; // /boot/home/config/settings + if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, home, PATH_MAX) == B_OK) + dataDir = std::string(home) + "/" + appName; + else dataDir = "/tmp/" + appName; - } return; #else /* other unix */ #if defined(ANDROID) From 871fc14ba64bdeeab7a51914b5a9d266832afd27 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 27 Mar 2025 16:24:02 -0400 Subject: [PATCH 1123/1160] ML-KEM section for NS and NSR outgoing sessions --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 54 ++++++++++++++++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7a799d29..865fc973 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -492,7 +492,16 @@ namespace garlic offset += 32; // KDF1 - i2p::crypto::InitNoiseIKState (GetNoiseState (), m_RemoteStaticKey); // bpk +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + { + i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), m_RemoteStaticKey); // bpk + m_PQKeys = std::make_unique(); + m_PQKeys->GenerateKeys (); + } + else +#endif + i2p::crypto::InitNoiseIKState (GetNoiseState (), m_RemoteStaticKey); // bpk MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) @@ -501,9 +510,29 @@ namespace garlic return false; } MixKey (sharedSecret); + uint64_t n = 0; // seqn +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + { + uint8_t encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; + m_PQKeys->GetPublicKey (encapsKey); + // encrypt encapsKey + uint8_t nonce[12]; + CreateNonce (n, nonce); + if (!i2p::crypto::AEADChaCha20Poly1305 (encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH, + m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: ML-KEM encap_key section AEAD encryption failed "); + return false; + } + MixHash (out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16); // h = SHA256(h || ciphertext) + offset += i2p::crypto::MLKEM512_KEY_LENGTH + 16; + n++; + } +#endif // encrypt flags/static key section uint8_t nonce[12]; - CreateNonce (0, nonce); + CreateNonce (n, nonce); const uint8_t * fs; if (isStatic) fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); @@ -675,6 +704,24 @@ namespace garlic uint8_t nonce[12]; CreateNonce (0, nonce); +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + { + // decrypt kem_ciphertext section + uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, + m_H, 32, m_CK + 32, nonce, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + { + LogPrint (eLogWarning, "Garlic: Reply ML-KEM ciphertext section AEAD decryption failed"); + return false; + } + MixHash (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); + buf += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + // decaps + m_PQKeys->Decaps (kemCiphertext, sharedSecret); + MixKey (sharedSecret); + } +#endif // calculate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { @@ -711,6 +758,9 @@ namespace garlic { m_State = eSessionStateEstablished; //m_EphemeralKeys = nullptr; // TODO: delete after a while +#if OPENSSL_PQ + // m_PQKeys = nullptr; // TODO: delete after a while +#endif m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 5614e6cb..cd32cb98 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -226,6 +226,9 @@ namespace garlic uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only std::shared_ptr m_EphemeralKeys; +#if OPENSSL_PQ + std::unique_ptr m_PQKeys; +#endif SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds) m_LastSentTimestamp = 0; // in milliseconds From 7404ce7fd2e69b8e3e70d90b594a04e44053836c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Mar 2025 19:34:36 -0400 Subject: [PATCH 1124/1160] update session's remote enpoint after receiving path response --- libi2pd/SSU2Session.cpp | 24 +++++++++++++++--------- libi2pd/SSU2Session.h | 4 ++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index e0a9a48f..dd170714 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1498,11 +1498,11 @@ namespace transport ResendHandshakePacket (); // assume we receive return; } - if (from != m_RemoteEndpoint && !i2p::transport::transports.IsInReservedRange (from.address ())) + if (from != m_RemoteEndpoint && !i2p::transport::transports.IsInReservedRange (from.address ()) && + (!m_PathChallenge || from != m_PathChallenge->second)) // path challenge was not sent to this endpoint yet { LogPrint (eLogInfo, "SSU2: Remote endpoint update ", m_RemoteEndpoint, "->", from); - m_RemoteEndpoint = from; - SendPathChallenge (); + SendPathChallenge (from); } if (len < 32) { @@ -1660,10 +1660,13 @@ namespace transport LogPrint (eLogDebug, "SSU2: Path response"); if (m_PathChallenge) { - i2p::data::IdentHash hash; + i2p::data::Tag<32> hash; SHA256 (buf + offset, size, hash); - if (hash == *m_PathChallenge) + if (hash == m_PathChallenge->first) + { + m_RemoteEndpoint = m_PathChallenge->second; m_PathChallenge.reset (nullptr); + } } break; } @@ -3070,7 +3073,7 @@ namespace transport SendData (payload, payloadSize); } - void SSU2Session::SendPathChallenge () + void SSU2Session::SendPathChallenge (const boost::asio::ip::udp::endpoint& to) { uint8_t payload[SSU2_MAX_PACKET_SIZE]; payload[0] = eSSU2BlkPathChallenge; @@ -3078,15 +3081,18 @@ namespace transport htobe16buf (payload + 1, len); if (len > 0) { + m_PathChallenge = std::make_unique, boost::asio::ip::udp::endpoint> >(); RAND_bytes (payload + 3, len); - i2p::data::IdentHash * hash = new i2p::data::IdentHash (); - SHA256 (payload + 3, len, *hash); - m_PathChallenge.reset (hash); + SHA256 (payload + 3, len, m_PathChallenge->first); + m_PathChallenge->second = to; } len += 3; if (len < m_MaxPayloadSize) len += CreatePaddingBlock (payload + len, m_MaxPayloadSize - len, len < 8 ? 8 : 0); + auto existing = m_RemoteEndpoint; + m_RemoteEndpoint = to; // send path challenge to new endpoint SendData (payload, len); + m_RemoteEndpoint = existing; // restore endpoint back until path response received } void SSU2Session::CleanUp (uint64_t ts) diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index ee295acb..6d2bf103 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -327,7 +327,7 @@ namespace transport void SendQuickAck (); void SendTermination (); void SendPathResponse (const uint8_t * data, size_t len); - void SendPathChallenge (); + void SendPathChallenge (const boost::asio::ip::udp::endpoint& to); void HandleDateTime (const uint8_t * buf, size_t len); void HandleRouterInfo (const uint8_t * buf, size_t len); @@ -394,7 +394,7 @@ namespace transport boost::asio::deadline_timer m_ConnectTimer; SSU2TerminationReason m_TerminationReason; size_t m_MaxPayloadSize; - std::unique_ptr m_PathChallenge; + std::unique_ptr, boost::asio::ip::udp::endpoint> > m_PathChallenge; std::unordered_map m_ReceivedI2NPMsgIDs; // msgID -> timestamp in seconds uint64_t m_LastResendTime, m_LastResendAttemptTime; // in milliseconds int m_NumRanges; From c2f68d70216466af48d805ad2fc3416ca9ea01da Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 29 Mar 2025 21:34:16 -0400 Subject: [PATCH 1125/1160] send datetime and address blocks with path challenge --- libi2pd/SSU2Session.cpp | 42 +++++++++++++++++++++++++++-------------- libi2pd/SSU2Session.h | 2 +- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index dd170714..a4a9fa03 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -2562,17 +2562,19 @@ namespace transport return nullptr; } - void SSU2Session::AdjustMaxPayloadSize () + void SSU2Session::AdjustMaxPayloadSize (size_t maxMtu) { auto addr = FindLocalAddress (); if (addr && addr->ssu) { int mtu = addr->ssu->mtu; if (!mtu && addr->IsV4 ()) mtu = SSU2_MAX_PACKET_SIZE; + if (mtu > (int)maxMtu) mtu = maxMtu; if (m_Address && m_Address->ssu && (!mtu || m_Address->ssu->mtu < mtu)) mtu = m_Address->ssu->mtu; if (mtu) { + if (mtu > (int)SSU2_MAX_PACKET_SIZE) mtu = SSU2_MAX_PACKET_SIZE; if (mtu < (int)SSU2_MIN_PACKET_SIZE) mtu = SSU2_MIN_PACKET_SIZE; m_MaxPayloadSize = mtu - (addr->IsV6 () ? IPV6_HEADER_SIZE: IPV4_HEADER_SIZE) - UDP_HEADER_SIZE - 32; LogPrint (eLogDebug, "SSU2: Session MTU=", mtu, ", max payload size=", m_MaxPayloadSize); @@ -3075,23 +3077,35 @@ namespace transport void SSU2Session::SendPathChallenge (const boost::asio::ip::udp::endpoint& to) { + AdjustMaxPayloadSize (SSU2_MIN_PACKET_SIZE); // reduce to minimum + m_WindowSize = SSU2_MIN_WINDOW_SIZE; // reduce window to minimum + uint8_t payload[SSU2_MAX_PACKET_SIZE]; - payload[0] = eSSU2BlkPathChallenge; - size_t len = m_Server.GetRng ()() % (m_MaxPayloadSize - 3); - htobe16buf (payload + 1, len); - if (len > 0) - { - m_PathChallenge = std::make_unique, boost::asio::ip::udp::endpoint> >(); - RAND_bytes (payload + 3, len); - SHA256 (payload + 3, len, m_PathChallenge->first); + size_t payloadSize = 0; + // datetime block + payload[0] = eSSU2BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); + payloadSize += 7; + // address block with new address + payloadSize += CreateAddressBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, to); + // path challenge block + payload[payloadSize] = eSSU2BlkPathChallenge; + size_t len = m_Server.GetRng ()() % (m_MaxPayloadSize - payloadSize - 3 - 8) + 8; // 8 bytes min + htobe16buf (payload + payloadSize + 1, len); + payloadSize += 3; + m_PathChallenge = std::make_unique, boost::asio::ip::udp::endpoint> >(); + RAND_bytes (payload + payloadSize, len); + SHA256 (payload + payloadSize, len, m_PathChallenge->first); m_PathChallenge->second = to; - } - len += 3; - if (len < m_MaxPayloadSize) - len += CreatePaddingBlock (payload + len, m_MaxPayloadSize - len, len < 8 ? 8 : 0); + payloadSize += len; + // padding block + if (payloadSize < m_MaxPayloadSize) + payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); + // send to new endpoint auto existing = m_RemoteEndpoint; m_RemoteEndpoint = to; // send path challenge to new endpoint - SendData (payload, len); + SendData (payload, payloadSize); m_RemoteEndpoint = existing; // restore endpoint back until path response received } diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 6d2bf103..7edc01a5 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -336,7 +336,7 @@ namespace transport virtual void HandleAddress (const uint8_t * buf, size_t len); size_t CreateEndpoint (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep); std::shared_ptr FindLocalAddress () const; - void AdjustMaxPayloadSize (); + void AdjustMaxPayloadSize (size_t maxMtu = SSU2_MAX_PACKET_SIZE); bool GetTestingState () const; void SetTestingState(bool testing) const; std::shared_ptr ExtractRouterInfo (const uint8_t * buf, size_t size); From 567183647e8dab9bde51b4a29ebb2432bf77d43e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 30 Mar 2025 12:37:40 -0400 Subject: [PATCH 1126/1160] non-copyable RouterInfo --- libi2pd/RouterInfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 387906ad..cb3ae499 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -210,8 +210,8 @@ namespace data typedef boost::shared_ptr AddressesPtr; #endif RouterInfo (const std::string& fullPath); - RouterInfo (const RouterInfo& ) = default; - RouterInfo& operator=(const RouterInfo& ) = default; + RouterInfo (const RouterInfo& ) = delete; + RouterInfo& operator=(const RouterInfo& ) = delete; RouterInfo (std::shared_ptr&& buf, size_t len); RouterInfo (const uint8_t * buf, size_t len); virtual ~RouterInfo (); From 00920a049d764db6d21459ad5b28f4bfc7866d85 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 30 Mar 2025 13:28:45 -0400 Subject: [PATCH 1127/1160] use g++-x86 for 32-bits platform --- Makefile.haiku | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.haiku b/Makefile.haiku index 5dce7d7f..eb56a207 100644 --- a/Makefile.haiku +++ b/Makefile.haiku @@ -1,4 +1,8 @@ +ifeq ($(shell $(CXX) -dumpmachine | cut -c 1-4), i586) +CXX = g++-x86 +else CXX = g++ +endif CXXFLAGS := -Wall -std=c++20 INCFLAGS = -I/system/develop/headers DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE From ad3b999732ce9d70492d1980295eca300eb3ba65 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 31 Mar 2025 10:29:16 -0400 Subject: [PATCH 1128/1160] send path challenge of 8 bytes. add Ack block --- libi2pd/SSU2Session.cpp | 21 ++++++++++----------- libi2pd/SSU2Session.h | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index a4a9fa03..94a27877 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1660,9 +1660,7 @@ namespace transport LogPrint (eLogDebug, "SSU2: Path response"); if (m_PathChallenge) { - i2p::data::Tag<32> hash; - SHA256 (buf + offset, size, hash); - if (hash == m_PathChallenge->first) + if (buf64toh (buf + offset) == m_PathChallenge->first) { m_RemoteEndpoint = m_PathChallenge->second; m_PathChallenge.reset (nullptr); @@ -3091,14 +3089,15 @@ namespace transport payloadSize += CreateAddressBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, to); // path challenge block payload[payloadSize] = eSSU2BlkPathChallenge; - size_t len = m_Server.GetRng ()() % (m_MaxPayloadSize - payloadSize - 3 - 8) + 8; // 8 bytes min - htobe16buf (payload + payloadSize + 1, len); - payloadSize += 3; - m_PathChallenge = std::make_unique, boost::asio::ip::udp::endpoint> >(); - RAND_bytes (payload + payloadSize, len); - SHA256 (payload + payloadSize, len, m_PathChallenge->first); - m_PathChallenge->second = to; - payloadSize += len; + uint64_t challenge; + RAND_bytes ((uint8_t *)&challenge, 8); + htobe16buf (payload + payloadSize + 1, 8); // always 8 bytes + htobuf64 (payload + payloadSize + 3, challenge); + payloadSize += 11; + m_PathChallenge = std::make_unique >(challenge, to); + // ack block + if (payloadSize < m_MaxPayloadSize) + payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); // padding block if (payloadSize < m_MaxPayloadSize) payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 7edc01a5..ee26255f 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -394,7 +394,7 @@ namespace transport boost::asio::deadline_timer m_ConnectTimer; SSU2TerminationReason m_TerminationReason; size_t m_MaxPayloadSize; - std::unique_ptr, boost::asio::ip::udp::endpoint> > m_PathChallenge; + std::unique_ptr > m_PathChallenge; std::unordered_map m_ReceivedI2NPMsgIDs; // msgID -> timestamp in seconds uint64_t m_LastResendTime, m_LastResendAttemptTime; // in milliseconds int m_NumRanges; From 2280338900695c84e192beb6f4dac5718e02f4aa Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 31 Mar 2025 15:50:16 -0400 Subject: [PATCH 1129/1160] datetime, address, ack blocks in path response packet --- libi2pd/SSU2Session.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 94a27877..cb10f848 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -3058,18 +3058,31 @@ namespace transport void SSU2Session::SendPathResponse (const uint8_t * data, size_t len) { - if (len > m_MaxPayloadSize - 3) + uint8_t payload[SSU2_MAX_PACKET_SIZE]; + size_t payloadSize = 0; + // datetime block + payload[0] = eSSU2BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); + payloadSize += 7; + // address block + payloadSize += CreateAddressBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, m_RemoteEndpoint); + // path response + if (payloadSize + len > m_MaxPayloadSize) { LogPrint (eLogWarning, "SSU2: Incorrect data size for path response ", len); return; - } - uint8_t payload[SSU2_MAX_PACKET_SIZE]; - payload[0] = eSSU2BlkPathResponse; - htobe16buf (payload + 1, len); - memcpy (payload + 3, data, len); - size_t payloadSize = len + 3; + } + payload[payloadSize] = eSSU2BlkPathResponse; + htobe16buf (payload + payloadSize + 1, len); + memcpy (payload + payloadSize + 3, data, len); + payloadSize += len + 3; + // ack block if (payloadSize < m_MaxPayloadSize) - payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize, payloadSize < 8 ? 8 : 0); + payloadSize += CreateAckBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); + // padding + if (payloadSize < m_MaxPayloadSize) + payloadSize += CreatePaddingBlock (payload + payloadSize, m_MaxPayloadSize - payloadSize); SendData (payload, payloadSize); } From 78d97179b8a994ae2509517840ccc70069f41584 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 1 Apr 2025 20:46:41 -0400 Subject: [PATCH 1130/1160] handle ML-KEM section for new session and create for new session reply --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 86 +++++++++++++++++++---- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 865fc973..82be0ebd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -257,27 +257,66 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - i2p::crypto::InitNoiseIKState (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk - + if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { LogPrint (eLogError, "Garlic: Can't decode elligator"); return false; } buf += 32; len -= 32; - MixHash (m_Aepk, 32); // h = SHA256(h || aepk) + uint64_t n = 0; uint8_t sharedSecret[32]; - if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + bool decrypted = false; +#if OPENSSL_PQ + if (GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) { - LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); - return false; - } - MixKey (sharedSecret); + i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)); // bpk + MixHash (m_Aepk, 32); // h = SHA256(h || aepk) + + if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + { + MixKey (sharedSecret); + + uint8_t nonce[12], encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; + CreateNonce (n, nonce); + if (i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_KEY_LENGTH, + m_H, 32, m_CK + 32, nonce, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH , false)) // decrypt + { + decrypted = true; // encaps section has right hash + MixHash (buf, i2p::crypto::MLKEM512_KEY_LENGTH); + n++; + + m_PQKeys = std::make_unique(); + m_PQKeys->SetPublicKey (encapsKey); + } + } + } +#endif + if (!decrypted) + { + if (GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + { + i2p::crypto::InitNoiseIKState (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk + MixHash (m_Aepk, 32); // h = SHA256(h || aepk) + + if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); + return false; + } + MixKey (sharedSecret); + } + else + { + LogPrint (eLogWarning, "Garlic: No supported encryption type"); + return false; + } + } // decrypt flags/static uint8_t nonce[12], fs[32]; - CreateNonce (0, nonce); + CreateNonce (n, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); @@ -291,8 +330,13 @@ namespace garlic if (isStatic) { // static key, fs is apk - SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD, fs); // TODO: actual key type - if (!GetOwner ()->Decrypt (fs, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) +#if OPENSSL_PQ + if (m_PQKeys) + SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD, fs); + else +#endif + SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD, fs); + if (!GetOwner ()->Decrypt (fs, sharedSecret, m_RemoteStaticKeyType)) // x25519(bsk, apk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); return false; @@ -596,7 +640,7 @@ namespace garlic } memcpy (m_NSREncodedKey, out + offset, 32); // for possible next NSR memcpy (m_NSRH, m_H, 32); - offset += 32; + offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) @@ -613,8 +657,26 @@ namespace garlic return false; } MixKey (sharedSecret); + uint8_t nonce[12]; CreateNonce (0, nonce); +#if OPENSSL_PQ + if (m_PQKeys) + { + uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; + m_PQKeys->Encaps (kemCiphertext, sharedSecret); + + if (!i2p::crypto::AEADChaCha20Poly1305 (kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, + m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed"); + return false; + } + MixHash (out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); + MixKey (sharedSecret); + offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + } +#endif // calculate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { From 3be4c7217f29bf837e0591cb1435f856e3f7a0d1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 3 Apr 2025 18:42:34 -0400 Subject: [PATCH 1131/1160] move buffer when insert to buffer queue. clean entire queue in one call --- libi2pd/Streaming.cpp | 58 ++++++++++++++++++++++++++--------------- libi2pd/Streaming.h | 4 +-- libi2pd_client/I2CP.cpp | 4 +-- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 0ed6067c..d21cfa62 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,39 +19,55 @@ namespace i2p { namespace stream { - void SendBufferQueue::Add (std::shared_ptr buf) + void SendBufferQueue::Add (std::shared_ptr&& buf) { if (buf) { - m_Buffers.push_back (buf); m_Size += buf->len; + m_Buffers.push_back (std::move (buf)); } } size_t SendBufferQueue::Get (uint8_t * buf, size_t len) { + if (!m_Size) return 0; size_t offset = 0; - while (!m_Buffers.empty () && offset < len) + if (len >= m_Size) { - auto nextBuffer = m_Buffers.front (); - auto rem = nextBuffer->GetRemainingSize (); - if (offset + rem <= len) + for (auto& it: m_Buffers) { - // whole buffer - memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem); + auto rem = it->GetRemainingSize (); + memcpy (buf + offset, it->GetRemaningBuffer (), rem); offset += rem; - m_Buffers.pop_front (); // delete it } - else + m_Buffers.clear (); + m_Size = 0; + return offset; + } + else + { + while (!m_Buffers.empty () && offset < len) { - // partially - rem = len - offset; - memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem); - nextBuffer->offset += rem; - offset = len; // break + auto nextBuffer = m_Buffers.front (); + auto rem = nextBuffer->GetRemainingSize (); + if (offset + rem <= len) + { + // whole buffer + memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem); + offset += rem; + m_Buffers.pop_front (); // delete it + } + else + { + // partially + rem = len - offset; + memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), rem); + nextBuffer->offset += rem; + offset = len; // break + } } - } - m_Size -= offset; + m_Size -= offset; + } return offset; } @@ -59,7 +75,7 @@ namespace stream { if (!m_Buffers.empty ()) { - for (auto it: m_Buffers) + for (auto& it: m_Buffers) it->Cancel (); m_Buffers.clear (); m_Size = 0; @@ -717,10 +733,10 @@ namespace stream else if (handler) handler(boost::system::error_code ()); auto s = shared_from_this (); - boost::asio::post (m_Service, [s, buffer]() + boost::asio::post (m_Service, [s, buffer = std::move(buffer)]() mutable { if (buffer) - s->m_SendBuffer.Add (buffer); + s->m_SendBuffer.Add (std::move(buffer)); s->SendBuffer (); }); } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index d75cb6eb..8280477b 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -150,7 +150,7 @@ namespace stream SendBufferQueue (): m_Size (0) {}; ~SendBufferQueue () { CleanUp (); }; - void Add (std::shared_ptr buf); + void Add (std::shared_ptr&& buf); size_t Get (uint8_t * buf, size_t len); size_t GetSize () const { return m_Size; }; bool IsEmpty () const { return m_Buffers.empty (); }; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 09fcee71..11278e7a 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -533,7 +533,7 @@ namespace client if (sendBuf) { if (m_SendQueue.GetSize () < I2CP_MAX_SEND_QUEUE_SIZE) - m_SendQueue.Add (sendBuf); + m_SendQueue.Add (std::move(sendBuf)); else { LogPrint (eLogWarning, "I2CP: Send queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); @@ -1079,7 +1079,7 @@ namespace client if (sendBuf) { if (m_SendQueue.GetSize () < I2CP_MAX_SEND_QUEUE_SIZE) - m_SendQueue.Add (sendBuf); + m_SendQueue.Add (std::move(sendBuf)); else { LogPrint (eLogWarning, "I2CP: Send queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); From 8ca74a3e1d9ccd8b835d565fdb6383f0fd4b7840 Mon Sep 17 00:00:00 2001 From: Alexey Chernov Date: Fri, 4 Apr 2025 22:35:56 +0300 Subject: [PATCH 1132/1160] [systemd] Wait for network-online target when starting service (#2169) --- contrib/i2pd.service | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/i2pd.service b/contrib/i2pd.service index 381ae483..1ab46979 100644 --- a/contrib/i2pd.service +++ b/contrib/i2pd.service @@ -1,7 +1,8 @@ [Unit] Description=I2P Router written in C++ Documentation=man:i2pd(1) https://i2pd.readthedocs.io/en/latest/ -After=network.target +Wants=network.target +After=network.target network-online.target [Service] User=i2pd From bce0ccf161124b752d434bd58b0c3cc7bdc1818a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 4 Apr 2025 19:52:32 -0400 Subject: [PATCH 1133/1160] all ratchets types are eligible for ECIESx25519 --- libi2pd/Destination.cpp | 6 ++++++ libi2pd/Destination.h | 2 ++ libi2pd/Garlic.cpp | 4 ++-- libi2pd/Garlic.h | 2 ++ libi2pd_client/I2CP.h | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index e20249c5..a3f6a8c9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1533,6 +1533,12 @@ namespace client #endif } + bool ClientDestination::SupportsRatchets () const + { + if (m_EncryptionKeys.empty ()) return false; + return m_EncryptionKeys.rbegin ()->first >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; + } + const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { auto it = m_EncryptionKeys.find (keyType); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 802d7780..a76a1be4 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -296,6 +296,8 @@ namespace client protected: + // GarlicDestionation + bool SupportsRatchets () const override; // LeaseSetDestination void CleanupDestination () override; i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 0098bdcd..5a3e4cae 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -498,7 +498,7 @@ namespace garlic buf += 4; // length bool found = false; - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + if (SupportsRatchets ()) // try ECIESx25519 tag found = HandleECIESx25519TagMessage (buf, length); if (!found) @@ -535,7 +535,7 @@ namespace garlic decryption->Decrypt(buf + 514, length - 514, iv, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } - else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + else if (SupportsRatchets ()) { // otherwise ECIESx25519 auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6283d740..0eef4871 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -279,6 +279,8 @@ namespace garlic void SaveTags (); void LoadTags (); + virtual bool SupportsRatchets () const { return GetIdentity ()->GetCryptoKeyType () >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; } + private: void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 3a9a7e7f..84243e6f 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -108,6 +108,8 @@ namespace client protected: + // GarlicDestination + bool SupportsRatchets () const override { return (bool)m_ECIESx25519Decryptor; } // LeaseSetDestination void CleanupDestination () override; i2p::data::CryptoKeyType GetPreferredCryptoType () const override; From 2f2ecc32d2ce31530f98a450e869174b8d13d6cf Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 5 Apr 2025 18:12:38 -0400 Subject: [PATCH 1134/1160] correct key type and message size for ML-KEM-512 --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 31 +++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 82be0ebd..5e7faefe 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -274,22 +274,24 @@ namespace garlic i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)); // bpk MixHash (m_Aepk, 32); // h = SHA256(h || aepk) - if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) // x25519(bsk, aepk) { MixKey (sharedSecret); uint8_t nonce[12], encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; CreateNonce (n, nonce); if (i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_KEY_LENGTH, - m_H, 32, m_CK + 32, nonce, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH , false)) // decrypt + m_H, 32, m_CK + 32, nonce, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH, false)) // decrypt { decrypted = true; // encaps section has right hash - MixHash (buf, i2p::crypto::MLKEM512_KEY_LENGTH); + MixHash (buf, i2p::crypto::MLKEM512_KEY_LENGTH + 16); + buf += i2p::crypto::MLKEM512_KEY_LENGTH + 16; + len -= i2p::crypto::MLKEM512_KEY_LENGTH + 16; n++; m_PQKeys = std::make_unique(); m_PQKeys->SetPublicKey (encapsKey); - } + } } } #endif @@ -579,7 +581,7 @@ namespace garlic CreateNonce (n, nonce); const uint8_t * fs; if (isStatic) - fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); + fs = GetOwner ()->GetEncryptionPublicKey (m_RemoteStaticKeyType); else { memset (out + offset, 0, 32); // all zeros flags section @@ -596,7 +598,7 @@ namespace garlic // KDF2 if (isStatic) { - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bpk) MixKey (sharedSecret); } else @@ -665,7 +667,7 @@ namespace garlic { uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; m_PQKeys->Encaps (kemCiphertext, sharedSecret); - + if (!i2p::crypto::AEADChaCha20Poly1305 (kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16, true)) // encrypt { @@ -761,7 +763,7 @@ namespace garlic return false; } MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk) MixKey (sharedSecret); uint8_t nonce[12]; @@ -779,6 +781,7 @@ namespace garlic } MixHash (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); buf += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + len -= i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; // decaps m_PQKeys->Decaps (kemCiphertext, sharedSecret); MixKey (sharedSecret); @@ -945,7 +948,11 @@ namespace garlic if (!payload) return nullptr; size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload); if (!len) return nullptr; +#if OPENSSL_PQ + auto m = NewI2NPMessage (len + (m_State == eSessionStateEstablished ? 28 : i2p::crypto::MLKEM512_KEY_LENGTH + 116)); +#else auto m = NewI2NPMessage (len + 100); // 96 + 4 +#endif m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length @@ -960,11 +967,19 @@ namespace garlic if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen)) return nullptr; len += 96; +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + len += i2p::crypto::MLKEM512_KEY_LENGTH + 16; +#endif break; case eSessionStateNewSessionReceived: if (!NewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + len += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; +#endif break; case eSessionStateNewSessionReplySent: if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen)) From 3afe6455b285329198805a47e8f79d407f402415 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 6 Apr 2025 15:34:01 -0400 Subject: [PATCH 1135/1160] reset nonce to 0 before payload encrypt/decrypt for ML-KEM-512 --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5e7faefe..37481d96 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -334,7 +334,10 @@ namespace garlic // static key, fs is apk #if OPENSSL_PQ if (m_PQKeys) + { SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD, fs); + CreateNonce (0, nonce); // reset nonce + } else #endif SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD, fs); @@ -600,6 +603,10 @@ namespace garlic { GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bpk) MixKey (sharedSecret); +#if OPENSSL_PQ + if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + CreateNonce (0, nonce); // reset nonce +#endif } else CreateNonce (1, nonce); From 6b38085f277b6625c5d1ee470e603db2e475f961 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Apr 2025 18:47:53 -0400 Subject: [PATCH 1136/1160] Noise state Encrypt/Decrypt operations --- libi2pd/Crypto.cpp | 59 +++++++++++++++++------ libi2pd/Crypto.h | 6 +++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 53 ++++++++------------ 3 files changed, 72 insertions(+), 46 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 9bdfe43f..e8210a27 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -821,6 +821,18 @@ namespace crypto // Noise + void NoiseSymmetricState::Init (const uint8_t * ck, const uint8_t * hh, const uint8_t * pub) + { + // pub is Bob's public static key, hh = SHA256(h) + memcpy (m_CK, ck, 32); + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, pub, 32); + SHA256_Final (m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + m_N = 0; + } + void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) { SHA256_CTX ctx; @@ -844,20 +856,39 @@ namespace crypto { HKDF (m_CK, sharedSecret, 32, "", m_CK); // new ck is m_CK[0:31], key is m_CK[32:63] + m_N = 0; } - static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck, - const uint8_t * hh, const uint8_t * pub) + bool NoiseSymmetricState::Encrypt (const uint8_t * in, uint8_t * out, size_t len) { - // pub is Bob's public static key, hh = SHA256(h) - memcpy (state.m_CK, ck, 32); - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, pub, 32); - SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + uint8_t nonce[12]; + if (m_N) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, m_N); + } + else + memset (nonce, 0, 12); + auto ret = AEADChaCha20Poly1305 (in, len, m_H, 32, m_CK + 32, nonce, out, len + 16, true); + if (ret) m_N++; + return ret; } + bool NoiseSymmetricState::Decrypt (const uint8_t * in, uint8_t * out, size_t len) + { + uint8_t nonce[12]; + if (m_N) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, m_N); + } + else + memset (nonce, 0, 12); + auto ret = AEADChaCha20Poly1305 (in, len, m_H, 32, m_CK + 32, nonce, out, len, false); + if (ret) m_N++; + return ret; + } + void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) { static constexpr char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars @@ -866,7 +897,7 @@ namespace crypto 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 }; // hh = SHA256(protocol_name || 0) - InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0 + state.Init ((const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0 } void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) @@ -881,7 +912,7 @@ namespace crypto 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e }; // SHA256 (protocolNameHash) - InitNoiseState (state, protocolNameHash, hh, pub); + state.Init (protocolNameHash, hh, pub); } void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub) @@ -896,7 +927,7 @@ namespace crypto 0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53, 0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33 }; // SHA256 (protocolNameHash) - InitNoiseState (state, protocolNameHash, hh, pub); + state.Init (protocolNameHash, hh, pub); } void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) @@ -911,7 +942,7 @@ namespace crypto 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c }; // SHA256 (protocolNameHash) - InitNoiseState (state, protocolNameHash, hh, pub); + state.Init (protocolNameHash, hh, pub); } void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub) @@ -926,7 +957,7 @@ namespace crypto 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb }; // SHA256 (protocolNameHash) - InitNoiseState (state, protocolNameHash, hh, pub); + state.Init (protocolNameHash, hh, pub); } // init and terminate diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index dcdc27d3..aa6466be 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -255,10 +255,16 @@ namespace crypto struct NoiseSymmetricState { uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/; + uint64_t m_N; + void Init (const uint8_t * ck, const uint8_t * hh, const uint8_t * pub); + void MixHash (const uint8_t * buf, size_t len); void MixHash (const std::vector >& bufs); void MixKey (const uint8_t * sharedSecret); + + bool Encrypt (const uint8_t * in, uint8_t * out, size_t len); // out length = len + 16 + bool Decrypt (const uint8_t * in, uint8_t * out, size_t len); // len without 16 bytes tag }; void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 37481d96..467a3752 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -559,29 +559,22 @@ namespace garlic return false; } MixKey (sharedSecret); - uint64_t n = 0; // seqn #if OPENSSL_PQ if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { uint8_t encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; m_PQKeys->GetPublicKey (encapsKey); // encrypt encapsKey - uint8_t nonce[12]; - CreateNonce (n, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH, - m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16, true)) // encrypt + if (!Encrypt (encapsKey, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH)) { LogPrint (eLogWarning, "Garlic: ML-KEM encap_key section AEAD encryption failed "); return false; } MixHash (out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16); // h = SHA256(h || ciphertext) offset += i2p::crypto::MLKEM512_KEY_LENGTH + 16; - n++; } #endif // encrypt flags/static key section - uint8_t nonce[12]; - CreateNonce (n, nonce); const uint8_t * fs; if (isStatic) fs = GetOwner ()->GetEncryptionPublicKey (m_RemoteStaticKeyType); @@ -590,7 +583,7 @@ namespace garlic memset (out + offset, 0, 32); // all zeros flags section fs = out + offset; } - if (!i2p::crypto::AEADChaCha20Poly1305 (fs, 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + if (!Encrypt (fs, out + offset, 32)) { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed "); return false; @@ -602,16 +595,10 @@ namespace garlic if (isStatic) { GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bpk) - MixKey (sharedSecret); -#if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) - CreateNonce (0, nonce); // reset nonce -#endif + MixKey (sharedSecret); } - else - CreateNonce (1, nonce); // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt + if (!Encrypt (payload, out + offset, len)) { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; @@ -667,16 +654,13 @@ namespace garlic } MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); #if OPENSSL_PQ if (m_PQKeys) { uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; m_PQKeys->Encaps (kemCiphertext, sharedSecret); - if (!i2p::crypto::AEADChaCha20Poly1305 (kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, - m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16, true)) // encrypt + if (!Encrypt (kemCiphertext, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH)) { LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed"); return false; @@ -687,7 +671,7 @@ namespace garlic } #endif // calculate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + if (!Encrypt (sharedSecret /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; @@ -708,6 +692,7 @@ namespace garlic GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload + uint8_t nonce[12]; memset (nonce, 0, 12); // seqn = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); @@ -729,16 +714,22 @@ namespace garlic memcpy (m_H, m_NSRH, 32); MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) - uint8_t nonce[12]; - CreateNonce (0, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + m_N = 0; + size_t offset = 40; +#if OPENSSL_PQ + if (m_PQKeys) + // TODO: encrypted ML-KEM section + offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; +#endif + if (!Encrypt (m_NSRH /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } - MixHash (out + 40, 16); // h = SHA256(h || ciphertext) + MixHash (out + offset, 16); // h = SHA256(h || ciphertext) // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt + uint8_t nonce[12]; memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset + 16, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); return false; @@ -773,15 +764,12 @@ namespace garlic GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk) MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); #if OPENSSL_PQ if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { // decrypt kem_ciphertext section uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, - m_H, 32, m_CK + 32, nonce, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + if (!Decrypt (buf, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH)) { LogPrint (eLogWarning, "Garlic: Reply ML-KEM ciphertext section AEAD decryption failed"); return false; @@ -795,7 +783,7 @@ namespace garlic } #endif // calculate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + if (!Decrypt (buf, sharedSecret/* can be anything */, 0)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed"); return false; @@ -820,6 +808,7 @@ namespace garlic } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload + uint8_t nonce[12]; memset (nonce, 0, 12); // seqn = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); From 711f5bcc6210bf2806ae477739d771303dcd6e65 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Apr 2025 20:33:19 -0400 Subject: [PATCH 1137/1160] store ML-KEM section for possible next NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 +++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 467a3752..cfcbf5bb 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -665,6 +665,8 @@ namespace garlic LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed"); return false; } + m_NSREncodedPQKey = std::make_unique >(); + memcpy (m_NSREncodedPQKey->data (), out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); MixHash (out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); MixKey (sharedSecret); offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; @@ -718,8 +720,19 @@ namespace garlic size_t offset = 40; #if OPENSSL_PQ if (m_PQKeys) - // TODO: encrypted ML-KEM section - offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + { + if (m_NSREncodedPQKey) + { + memcpy (out + offset, m_NSREncodedPQKey->data (), i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); + MixHash (out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); + offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + } + else + { + LogPrint (eLogWarning, "Garlic: No stored ML-KEM keys"); + return false; + } + } #endif if (!Encrypt (m_NSRH /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { @@ -914,6 +927,10 @@ namespace garlic m_State = eSessionStateEstablished; m_NSRSendTagset = nullptr; m_EphemeralKeys = nullptr; +#if OPENSSL_PQ + m_PQKeys = nullptr; + m_NSREncodedPQKey = nullptr; +#endif [[fallthrough]]; case eSessionStateEstablished: if (m_SendReverseKey && receiveTagset->GetTagSetID () == m_NextReceiveRatchet->GetReceiveTagSetID ()) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cd32cb98..b988263a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "Identity.h" @@ -228,6 +229,7 @@ namespace garlic std::shared_ptr m_EphemeralKeys; #if OPENSSL_PQ std::unique_ptr m_PQKeys; + std::unique_ptr > m_NSREncodedPQKey; #endif SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds) From f6abbe59086ed2ca8b32fe63e6f120c4c0258d86 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Apr 2025 14:39:46 -0400 Subject: [PATCH 1138/1160] Use noise state Encrypt/Decrypt operations --- libi2pd/NTCP2.cpp | 81 ++++++++++++++++++++++++++--------------------- libi2pd/NTCP2.h | 9 +++--- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 870fcc19..b3a51488 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -145,10 +145,12 @@ namespace transport // 2 bytes reserved htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsA, rounded to seconds // 4 bytes reserved - // sign and encrypt options, use m_H as AD - uint8_t nonce[12]; - memset (nonce, 0, 12); // set nonce to zero - i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt + // encrypt options + if (!Encrypt (options, m_SessionRequestBuffer + 32, 16)) + { + LogPrint (eLogWarning, "NTCP2: SessionRequest failed to encrypt options"); + return false; + } return true; } @@ -167,14 +169,16 @@ namespace transport memset (options, 0, 16); htobe16buf (options + 2, paddingLen); // padLen htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsB, rounded to seconds - // sign and encrypt options, use m_H as AD - uint8_t nonce[12]; - memset (nonce, 0, 12); // set nonce to zero - i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt + // encrypt options + if (!Encrypt (options, m_SessionCreatedBuffer + 32, 16)) + { + LogPrint (eLogWarning, "NTCP2: SessionCreated failed to encrypt options"); + return false; + } return true; } - void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce) + bool NTCP2Establisher::CreateSessionConfirmedMessagePart1 () { // update AD MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload @@ -182,19 +186,28 @@ namespace transport if (paddingLength > 0) MixHash (m_SessionCreatedBuffer + 64, paddingLength); - // part1 48 bytes - i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, GetH (), 32, GetK (), nonce, m_SessionConfirmedBuffer, 48, true); // encrypt + // part1 48 bytes, n = 1 + if (!Encrypt (i2p::context.GetNTCP2StaticPublicKey (), m_SessionConfirmedBuffer, 32)) + { + LogPrint (eLogWarning, "NTCP2: SessionConfirmed failed to encrypt part1"); + return false; + } + return true; } - bool NTCP2Establisher::CreateSessionConfirmedMessagePart2 (const uint8_t * nonce) + bool NTCP2Establisher::CreateSessionConfirmedMessagePart2 () { // part 2 // update AD again MixHash (m_SessionConfirmedBuffer, 48); // encrypt m3p2, it must be filled in SessionRequest - if (!KDF3Alice ()) return false; + if (!KDF3Alice ()) return false; // MixKey, n = 0 uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; - i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt + if (!Encrypt (m3p2, m3p2, m3p2Len - 16)) + { + LogPrint (eLogWarning, "NTCP2: SessionConfirmed failed to encrypt part2"); + return false; + } // update h again MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) return true; @@ -214,10 +227,9 @@ namespace transport LogPrint (eLogWarning, "NTCP2: SessionRequest KDF failed"); return false; } - // verify MAC and decrypt options block (32 bytes), use m_H as AD - uint8_t nonce[12], options[16]; - memset (nonce, 0, 12); // set nonce to zero - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, GetH (), 32, GetK (), nonce, options, 16, false)) // decrypt + // verify MAC and decrypt options block (32 bytes) + uint8_t options[16]; + if (Decrypt (m_SessionRequestBuffer + 32, options, 16)) { // options if (options[0] && options[0] != i2p::context.GetNetID ()) @@ -274,9 +286,7 @@ namespace transport } // decrypt and verify MAC uint8_t payload[16]; - uint8_t nonce[12]; - memset (nonce, 0, 12); // set nonce to zero - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, GetH (), 32, GetK (), nonce, payload, 16, false)) // decrypt + if (Decrypt (m_SessionCreatedBuffer + 32, payload, 16)) { // options paddingLen = bufbe16toh(payload + 2); @@ -297,7 +307,7 @@ namespace transport return true; } - bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce) + bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 () { // update AD MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload @@ -305,7 +315,8 @@ namespace transport if (paddingLength > 0) MixHash (m_SessionCreatedBuffer + 64, paddingLength); - if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, GetH (), 32, GetK (), nonce, m_RemoteStaticKey, 32, false)) // decrypt S + // decrypt S, n = 1 + if (!Decrypt (m_SessionConfirmedBuffer, m_RemoteStaticKey, 32)) { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); return false; @@ -313,17 +324,17 @@ namespace transport return true; } - bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf) + bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (uint8_t * m3p2Buf) { // update AD again MixHash (m_SessionConfirmedBuffer, 48); - if (!KDF3Bob ()) + if (!KDF3Bob ()) // MixKey, n = 0 { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 KDF failed"); return false; } - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt + if (Decrypt (m_SessionConfirmedBuffer + 48, m3p2Buf, m3p2Len - 16)) // calculate new h again for KDF data MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext) else @@ -657,11 +668,12 @@ namespace transport void NTCP2Session::SendSessionConfirmed () { - uint8_t nonce[12]; - CreateNonce (1, nonce); // set nonce to 1 - m_Establisher->CreateSessionConfirmedMessagePart1 (nonce); - memset (nonce, 0, 12); // set nonce back to 0 - if (!m_Establisher->CreateSessionConfirmedMessagePart2 (nonce)) + if (!m_Establisher->CreateSessionConfirmedMessagePart1 ()) + { + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } + if (!m_Establisher->CreateSessionConfirmedMessagePart2 ()) { LogPrint (eLogWarning, "NTCP2: Send SessionConfirmed Part2 KDF failed"); boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); @@ -740,14 +752,11 @@ namespace transport // run on establisher thread LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); // part 1 - uint8_t nonce[12]; - CreateNonce (1, nonce); - if (m_Establisher->ProcessSessionConfirmedMessagePart1 (nonce)) + if (m_Establisher->ProcessSessionConfirmedMessagePart1 ()) { // part 2 auto buf = std::make_shared > (m_Establisher->m3p2Len - 16); // -MAC - memset (nonce, 0, 12); // set nonce to 0 again - if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf->data ())) // TODO:handle in establisher thread + if (m_Establisher->ProcessSessionConfirmedMessagePart2 (buf->data ())) // TODO:handle in establisher thread { // payload // RI block must be first diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 47354f32..5ad5b955 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -91,7 +91,6 @@ namespace transport const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set - const uint8_t * GetK () const { return m_CK + 32; }; const uint8_t * GetCK () const { return m_CK; }; const uint8_t * GetH () const { return m_H; }; @@ -108,13 +107,13 @@ namespace transport bool CreateSessionRequestMessage (std::mt19937& rng); bool CreateSessionCreatedMessage (std::mt19937& rng); - void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce); - bool CreateSessionConfirmedMessagePart2 (const uint8_t * nonce); + bool CreateSessionConfirmedMessagePart1 (); + bool CreateSessionConfirmedMessagePart2 (); bool ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew); bool ProcessSessionCreatedMessage (uint16_t& paddingLen); - bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); - bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); + bool ProcessSessionConfirmedMessagePart1 (); + bool ProcessSessionConfirmedMessagePart2 (uint8_t * m3p2Buf); std::shared_ptr m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 From 9ab1a67f0be9d33dc0984fa284fbab792137bd54 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 13 Apr 2025 18:18:44 -0400 Subject: [PATCH 1139/1160] common ML-KEM names and key lengths --- libi2pd/Crypto.cpp | 30 ++++++------- libi2pd/Crypto.h | 30 ++++++++++--- libi2pd/CryptoKey.h | 17 +++++++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 55 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- 5 files changed, 88 insertions(+), 46 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index e8210a27..cf8303d1 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1011,32 +1011,32 @@ namespace crypto #if OPENSSL_PQ - MLKEM512Keys::MLKEM512Keys (): - m_Pkey (nullptr) + MLKEMKeys::MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen): + m_Name (name), m_KeyLen (keyLen), m_CTLen (ctLen),m_Pkey (nullptr) { } - MLKEM512Keys::~MLKEM512Keys () + MLKEMKeys::~MLKEMKeys () { if (m_Pkey) EVP_PKEY_free (m_Pkey); } - void MLKEM512Keys::GenerateKeys () + void MLKEMKeys::GenerateKeys () { if (m_Pkey) EVP_PKEY_free (m_Pkey); - m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-KEM-512"); + m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, m_Name.c_str ()); } - void MLKEM512Keys::GetPublicKey (uint8_t * pub) const + void MLKEMKeys::GetPublicKey (uint8_t * pub) const { if (m_Pkey) { - size_t len = MLKEM512_KEY_LENGTH; - EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, MLKEM512_KEY_LENGTH, &len); + size_t len = m_KeyLen; + EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, m_KeyLen, &len); } } - void MLKEM512Keys::SetPublicKey (const uint8_t * pub) + void MLKEMKeys::SetPublicKey (const uint8_t * pub) { if (m_Pkey) { @@ -1045,10 +1045,10 @@ namespace crypto } OSSL_PARAM params[] = { - OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)pub, MLKEM512_KEY_LENGTH), + OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)pub, m_KeyLen), OSSL_PARAM_END }; - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "ML-KEM-512", NULL); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, m_Name.c_str (), NULL); if (ctx) { EVP_PKEY_fromdata_init (ctx); @@ -1059,14 +1059,14 @@ namespace crypto LogPrint (eLogError, "MLKEM512 can't create PKEY context"); } - void MLKEM512Keys::Encaps (uint8_t * ciphertext, uint8_t * shared) + void MLKEMKeys::Encaps (uint8_t * ciphertext, uint8_t * shared) { if (!m_Pkey) return; auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); if (ctx) { EVP_PKEY_encapsulate_init (ctx, NULL); - size_t len = MLKEM512_CIPHER_TEXT_LENGTH, sharedLen = 32; + size_t len = m_CTLen, sharedLen = 32; EVP_PKEY_encapsulate (ctx, ciphertext, &len, shared, &sharedLen); EVP_PKEY_CTX_free (ctx); } @@ -1074,7 +1074,7 @@ namespace crypto LogPrint (eLogError, "MLKEM512 can't create PKEY context"); } - void MLKEM512Keys::Decaps (const uint8_t * ciphertext, uint8_t * shared) + void MLKEMKeys::Decaps (const uint8_t * ciphertext, uint8_t * shared) { if (!m_Pkey) return; auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); @@ -1082,7 +1082,7 @@ namespace crypto { EVP_PKEY_decapsulate_init (ctx, NULL); size_t sharedLen = 32; - EVP_PKEY_decapsulate (ctx, shared, &sharedLen, ciphertext, MLKEM512_CIPHER_TEXT_LENGTH); + EVP_PKEY_decapsulate (ctx, shared, &sharedLen, ciphertext, m_CTLen); EVP_PKEY_CTX_free (ctx); } else diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index aa6466be..9b47f806 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -11,7 +11,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -279,14 +282,13 @@ namespace crypto #if OPENSSL_PQ // Post Quantum - constexpr size_t MLKEM512_KEY_LENGTH = 800; - constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; - class MLKEM512Keys + + class MLKEMKeys { public: - MLKEM512Keys (); - ~MLKEM512Keys (); + MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen); + ~MLKEMKeys (); void GenerateKeys (); void GetPublicKey (uint8_t * pub) const; @@ -296,8 +298,26 @@ namespace crypto private: + const std::string m_Name; + const size_t m_KeyLen, m_CTLen; EVP_PKEY * m_Pkey; }; + + constexpr size_t MLKEM512_KEY_LENGTH = 800; + constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; + + constexpr std::array, 1> MLKEMS = + { + std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH) + }; + + class MLKEM512Keys: public MLKEMKeys + { + public: + + MLKEM512Keys (): MLKEMKeys (std::get<0>(MLKEMS[0]), std::get<1>(MLKEMS[0]), std::get<2>(MLKEMS[0])) {} + }; + #endif } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 14ef4fa8..1e0ea3f2 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -183,6 +183,23 @@ namespace crypto }; return 0; } + +#if OPENSSL_PQ + constexpr size_t GetMLKEMPublicKeyLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<1>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } + + constexpr size_t GetMLKEMCipherTextLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<2>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } + +#endif } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index cfcbf5bb..de95ce00 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -11,6 +11,7 @@ #include "Log.h" #include "util.h" #include "Crypto.h" +#include "CryptoKey.h" #include "Elligator.h" #include "Tag.h" #include "I2PEndian.h" @@ -560,18 +561,19 @@ namespace garlic } MixKey (sharedSecret); #if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { - uint8_t encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; - m_PQKeys->GetPublicKey (encapsKey); + auto keyLen = i2p::crypto::GetMLKEMPublicKeyLen (m_RemoteStaticKeyType); + std::vector encapsKey(keyLen); + m_PQKeys->GetPublicKey (encapsKey.data ()); // encrypt encapsKey - if (!Encrypt (encapsKey, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH)) + if (!Encrypt (encapsKey.data (), out + offset, keyLen)) { LogPrint (eLogWarning, "Garlic: ML-KEM encap_key section AEAD encryption failed "); return false; } - MixHash (out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16); // h = SHA256(h || ciphertext) - offset += i2p::crypto::MLKEM512_KEY_LENGTH + 16; + MixHash (out + offset, keyLen + 16); // h = SHA256(h || ciphertext) + offset += keyLen + 16; } #endif // encrypt flags/static key section @@ -657,19 +659,20 @@ namespace garlic #if OPENSSL_PQ if (m_PQKeys) { - uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; - m_PQKeys->Encaps (kemCiphertext, sharedSecret); + size_t cipherTextLen = i2p::crypto::GetMLKEMCipherTextLen (m_RemoteStaticKeyType); + std::vector kemCiphertext(cipherTextLen); + m_PQKeys->Encaps (kemCiphertext.data (), sharedSecret); - if (!Encrypt (kemCiphertext, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH)) + if (!Encrypt (kemCiphertext.data (), out + offset, cipherTextLen)) { LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed"); return false; } - m_NSREncodedPQKey = std::make_unique >(); - memcpy (m_NSREncodedPQKey->data (), out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); - MixHash (out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); + m_NSREncodedPQKey = std::make_unique > (cipherTextLen + 16); + memcpy (m_NSREncodedPQKey->data (), out + offset, cipherTextLen + 16); + MixHash (out + offset, cipherTextLen + 16); MixKey (sharedSecret); - offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + offset += cipherTextLen + 16; } #endif // calculate hash for zero length @@ -723,9 +726,10 @@ namespace garlic { if (m_NSREncodedPQKey) { - memcpy (out + offset, m_NSREncodedPQKey->data (), i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); - MixHash (out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); - offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + size_t cipherTextLen = i2p::crypto::GetMLKEMCipherTextLen (m_RemoteStaticKeyType); + memcpy (out + offset, m_NSREncodedPQKey->data (), cipherTextLen + 16); + MixHash (out + offset, cipherTextLen + 16); + offset += cipherTextLen + 16; } else { @@ -778,20 +782,21 @@ namespace garlic MixKey (sharedSecret); #if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { // decrypt kem_ciphertext section - uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; - if (!Decrypt (buf, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH)) + size_t cipherTextLen = i2p::crypto::GetMLKEMCipherTextLen (m_RemoteStaticKeyType); + std::vector kemCiphertext(cipherTextLen); + if (!Decrypt (buf, kemCiphertext.data (), cipherTextLen)) { LogPrint (eLogWarning, "Garlic: Reply ML-KEM ciphertext section AEAD decryption failed"); return false; } - MixHash (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16); - buf += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; - len -= i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + MixHash (buf, cipherTextLen + 16); + buf += cipherTextLen + 16; + len -= cipherTextLen + 16; // decaps - m_PQKeys->Decaps (kemCiphertext, sharedSecret); + m_PQKeys->Decaps (kemCiphertext.data (), sharedSecret); MixKey (sharedSecret); } #endif @@ -981,8 +986,8 @@ namespace garlic return nullptr; len += 96; #if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) - len += i2p::crypto::MLKEM512_KEY_LENGTH + 16; + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + len += i2p::crypto::GetMLKEMPublicKeyLen (m_RemoteStaticKeyType) + 16; #endif break; case eSessionStateNewSessionReceived: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index b988263a..2077219f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -229,7 +229,7 @@ namespace garlic std::shared_ptr m_EphemeralKeys; #if OPENSSL_PQ std::unique_ptr m_PQKeys; - std::unique_ptr > m_NSREncodedPQKey; + std::unique_ptr > m_NSREncodedPQKey; #endif SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds) From a83cd99f58f7ecd75e335a88cc94aea13381e6a6 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Apr 2025 13:29:53 -0400 Subject: [PATCH 1140/1160] all ML-KEM crypto types --- libi2pd/Crypto.h | 28 ++++++++++++++++++++++++---- libi2pd/Identity.h | 2 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 9b47f806..10f65b32 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -305,10 +305,16 @@ namespace crypto constexpr size_t MLKEM512_KEY_LENGTH = 800; constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; - - constexpr std::array, 1> MLKEMS = + constexpr size_t MLKEM768_KEY_LENGTH = 1184; + constexpr size_t MLKEM768_CIPHER_TEXT_LENGTH = 1088; + constexpr size_t MLKEM1024_KEY_LENGTH = 1568; + constexpr size_t MLKEM1024_CIPHER_TEXT_LENGTH = 1568; + + constexpr std::array, 3> MLKEMS = { - std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH) + std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-768", MLKEM768_KEY_LENGTH, MLKEM768_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-1024", MLKEM1024_KEY_LENGTH, MLKEM1024_CIPHER_TEXT_LENGTH) }; class MLKEM512Keys: public MLKEMKeys @@ -317,7 +323,21 @@ namespace crypto MLKEM512Keys (): MLKEMKeys (std::get<0>(MLKEMS[0]), std::get<1>(MLKEMS[0]), std::get<2>(MLKEMS[0])) {} }; - + + class MLKEM768Keys: public MLKEMKeys + { + public: + + MLKEM768Keys (): MLKEMKeys (std::get<0>(MLKEMS[1]), std::get<1>(MLKEMS[1]), std::get<2>(MLKEMS[1])) {} + }; + + class MLKEM1024Keys: public MLKEMKeys + { + public: + + MLKEM1024Keys (): MLKEMKeys (std::get<0>(MLKEMS[2]), std::get<1>(MLKEMS[2]), std::get<2>(MLKEMS[2])) {} + }; + #endif } } diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index ee736441..173559e9 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -71,6 +71,8 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD = 5; + const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD = 6; + const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD = 7; const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0; const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; From 459be02d18d8e9b2c7a838a956d5d437a3f1f80a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Apr 2025 13:31:37 -0400 Subject: [PATCH 1141/1160] correct sequence of MixKey for ML-KEM NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index de95ce00..d5b7150d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -649,13 +649,6 @@ namespace garlic return false; } MixKey (sharedSecret); - if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); - return false; - } - MixKey (sharedSecret); - #if OPENSSL_PQ if (m_PQKeys) { @@ -675,6 +668,12 @@ namespace garlic offset += cipherTextLen + 16; } #endif + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); + return false; + } + MixKey (sharedSecret); // calculate hash for zero length if (!Encrypt (sharedSecret /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { @@ -778,9 +777,6 @@ namespace garlic return false; } MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk) - MixKey (sharedSecret); - #if OPENSSL_PQ if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { @@ -799,7 +795,10 @@ namespace garlic m_PQKeys->Decaps (kemCiphertext.data (), sharedSecret); MixKey (sharedSecret); } -#endif +#endif + GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk) + MixKey (sharedSecret); + // calculate hash for zero length if (!Decrypt (buf, sharedSecret/* can be anything */, 0)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { From 4c5d0116f8891c272b0d150a74dfc779c5efb333 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Apr 2025 18:21:07 -0400 Subject: [PATCH 1142/1160] moved ML-KEM code to PostQuntum.h/.cpp --- libi2pd/Crypto.cpp | 81 ----------------- libi2pd/Crypto.h | 63 -------------- libi2pd/CryptoKey.h | 17 ---- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/ECIESX25519AEADRatchetSession.h | 3 +- libi2pd/PostQuantum.cpp | 101 ++++++++++++++++++++++ libi2pd/PostQuantum.h | 97 +++++++++++++++++++++ 7 files changed, 201 insertions(+), 163 deletions(-) create mode 100644 libi2pd/PostQuantum.cpp create mode 100644 libi2pd/PostQuantum.h diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index cf8303d1..be2863f4 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1008,86 +1008,5 @@ namespace crypto /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } - -#if OPENSSL_PQ - - MLKEMKeys::MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen): - m_Name (name), m_KeyLen (keyLen), m_CTLen (ctLen),m_Pkey (nullptr) - { - } - - MLKEMKeys::~MLKEMKeys () - { - if (m_Pkey) EVP_PKEY_free (m_Pkey); - } - - void MLKEMKeys::GenerateKeys () - { - if (m_Pkey) EVP_PKEY_free (m_Pkey); - m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, m_Name.c_str ()); - } - - void MLKEMKeys::GetPublicKey (uint8_t * pub) const - { - if (m_Pkey) - { - size_t len = m_KeyLen; - EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, m_KeyLen, &len); - } - } - - void MLKEMKeys::SetPublicKey (const uint8_t * pub) - { - if (m_Pkey) - { - EVP_PKEY_free (m_Pkey); - m_Pkey = nullptr; - } - OSSL_PARAM params[] = - { - OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)pub, m_KeyLen), - OSSL_PARAM_END - }; - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, m_Name.c_str (), NULL); - if (ctx) - { - EVP_PKEY_fromdata_init (ctx); - EVP_PKEY_fromdata (ctx, &m_Pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params); - EVP_PKEY_CTX_free (ctx); - } - else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); - } - - void MLKEMKeys::Encaps (uint8_t * ciphertext, uint8_t * shared) - { - if (!m_Pkey) return; - auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); - if (ctx) - { - EVP_PKEY_encapsulate_init (ctx, NULL); - size_t len = m_CTLen, sharedLen = 32; - EVP_PKEY_encapsulate (ctx, ciphertext, &len, shared, &sharedLen); - EVP_PKEY_CTX_free (ctx); - } - else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); - } - - void MLKEMKeys::Decaps (const uint8_t * ciphertext, uint8_t * shared) - { - if (!m_Pkey) return; - auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); - if (ctx) - { - EVP_PKEY_decapsulate_init (ctx, NULL); - size_t sharedLen = 32; - EVP_PKEY_decapsulate (ctx, shared, &sharedLen, ciphertext, m_CTLen); - EVP_PKEY_CTX_free (ctx); - } - else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); - } -#endif } } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 10f65b32..6abbd9b2 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -11,10 +11,7 @@ #include #include -#include #include -#include -#include #include #include #include @@ -279,66 +276,6 @@ namespace crypto // init and terminate void InitCrypto (bool precomputation); void TerminateCrypto (); - -#if OPENSSL_PQ -// Post Quantum - - class MLKEMKeys - { - public: - - MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen); - ~MLKEMKeys (); - - void GenerateKeys (); - void GetPublicKey (uint8_t * pub) const; - void SetPublicKey (const uint8_t * pub); - void Encaps (uint8_t * ciphertext, uint8_t * shared); - void Decaps (const uint8_t * ciphertext, uint8_t * shared); - - private: - - const std::string m_Name; - const size_t m_KeyLen, m_CTLen; - EVP_PKEY * m_Pkey; - }; - - constexpr size_t MLKEM512_KEY_LENGTH = 800; - constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; - constexpr size_t MLKEM768_KEY_LENGTH = 1184; - constexpr size_t MLKEM768_CIPHER_TEXT_LENGTH = 1088; - constexpr size_t MLKEM1024_KEY_LENGTH = 1568; - constexpr size_t MLKEM1024_CIPHER_TEXT_LENGTH = 1568; - - constexpr std::array, 3> MLKEMS = - { - std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH), - std::make_tuple ("ML-KEM-768", MLKEM768_KEY_LENGTH, MLKEM768_CIPHER_TEXT_LENGTH), - std::make_tuple ("ML-KEM-1024", MLKEM1024_KEY_LENGTH, MLKEM1024_CIPHER_TEXT_LENGTH) - }; - - class MLKEM512Keys: public MLKEMKeys - { - public: - - MLKEM512Keys (): MLKEMKeys (std::get<0>(MLKEMS[0]), std::get<1>(MLKEMS[0]), std::get<2>(MLKEMS[0])) {} - }; - - class MLKEM768Keys: public MLKEMKeys - { - public: - - MLKEM768Keys (): MLKEMKeys (std::get<0>(MLKEMS[1]), std::get<1>(MLKEMS[1]), std::get<2>(MLKEMS[1])) {} - }; - - class MLKEM1024Keys: public MLKEMKeys - { - public: - - MLKEM1024Keys (): MLKEMKeys (std::get<0>(MLKEMS[2]), std::get<1>(MLKEMS[2]), std::get<2>(MLKEMS[2])) {} - }; - -#endif } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 1e0ea3f2..14ef4fa8 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -183,23 +183,6 @@ namespace crypto }; return 0; } - -#if OPENSSL_PQ - constexpr size_t GetMLKEMPublicKeyLen (i2p::data::CryptoKeyType type) - { - if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || - type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; - return std::get<1>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); - } - - constexpr size_t GetMLKEMCipherTextLen (i2p::data::CryptoKeyType type) - { - if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || - type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; - return std::get<2>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); - } - -#endif } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d5b7150d..5d563d97 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -11,7 +11,7 @@ #include "Log.h" #include "util.h" #include "Crypto.h" -#include "CryptoKey.h" +#include "PostQuantum.h" #include "Elligator.h" #include "Tag.h" #include "I2PEndian.h" diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 2077219f..b7704534 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -19,6 +19,7 @@ #include #include "Identity.h" #include "Crypto.h" +#include "PostQuantum.h" #include "Garlic.h" #include "Tag.h" @@ -228,7 +229,7 @@ namespace garlic uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only std::shared_ptr m_EphemeralKeys; #if OPENSSL_PQ - std::unique_ptr m_PQKeys; + std::unique_ptr m_PQKeys; std::unique_ptr > m_NSREncodedPQKey; #endif SessionState m_State = eSessionStateNew; diff --git a/libi2pd/PostQuantum.cpp b/libi2pd/PostQuantum.cpp new file mode 100644 index 00000000..abe207d2 --- /dev/null +++ b/libi2pd/PostQuantum.cpp @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2025, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include "Log.h" +#include "PostQuantum.h" + +#if OPENSSL_PQ + +#include +#include + +namespace i2p +{ +namespace crypto +{ + MLKEMKeys::MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen): + m_Name (name), m_KeyLen (keyLen), m_CTLen (ctLen),m_Pkey (nullptr) + { + } + + MLKEMKeys::~MLKEMKeys () + { + if (m_Pkey) EVP_PKEY_free (m_Pkey); + } + + void MLKEMKeys::GenerateKeys () + { + if (m_Pkey) EVP_PKEY_free (m_Pkey); + m_Pkey = EVP_PKEY_Q_keygen(NULL, NULL, m_Name.c_str ()); + } + + void MLKEMKeys::GetPublicKey (uint8_t * pub) const + { + if (m_Pkey) + { + size_t len = m_KeyLen; + EVP_PKEY_get_octet_string_param (m_Pkey, OSSL_PKEY_PARAM_PUB_KEY, pub, m_KeyLen, &len); + } + } + + void MLKEMKeys::SetPublicKey (const uint8_t * pub) + { + if (m_Pkey) + { + EVP_PKEY_free (m_Pkey); + m_Pkey = nullptr; + } + OSSL_PARAM params[] = + { + OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)pub, m_KeyLen), + OSSL_PARAM_END + }; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, m_Name.c_str (), NULL); + if (ctx) + { + EVP_PKEY_fromdata_init (ctx); + EVP_PKEY_fromdata (ctx, &m_Pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } + + void MLKEMKeys::Encaps (uint8_t * ciphertext, uint8_t * shared) + { + if (!m_Pkey) return; + auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); + if (ctx) + { + EVP_PKEY_encapsulate_init (ctx, NULL); + size_t len = m_CTLen, sharedLen = 32; + EVP_PKEY_encapsulate (ctx, ciphertext, &len, shared, &sharedLen); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } + + void MLKEMKeys::Decaps (const uint8_t * ciphertext, uint8_t * shared) + { + if (!m_Pkey) return; + auto ctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); + if (ctx) + { + EVP_PKEY_decapsulate_init (ctx, NULL); + size_t sharedLen = 32; + EVP_PKEY_decapsulate (ctx, shared, &sharedLen, ciphertext, m_CTLen); + EVP_PKEY_CTX_free (ctx); + } + else + LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + } +} +} + +#endif \ No newline at end of file diff --git a/libi2pd/PostQuantum.h b/libi2pd/PostQuantum.h new file mode 100644 index 00000000..6081f653 --- /dev/null +++ b/libi2pd/PostQuantum.h @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2025, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef POST_QUANTUM_H__ +#define POST_QUANTUM_H__ + +#include +#include +#include +#include "Crypto.h" +#include "Identity.h" + +#if OPENSSL_PQ + +namespace i2p +{ +namespace crypto +{ + class MLKEMKeys + { + public: + + MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen); + ~MLKEMKeys (); + + void GenerateKeys (); + void GetPublicKey (uint8_t * pub) const; + void SetPublicKey (const uint8_t * pub); + void Encaps (uint8_t * ciphertext, uint8_t * shared); + void Decaps (const uint8_t * ciphertext, uint8_t * shared); + + private: + + const std::string m_Name; + const size_t m_KeyLen, m_CTLen; + EVP_PKEY * m_Pkey; + }; + + constexpr size_t MLKEM512_KEY_LENGTH = 800; + constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; + constexpr size_t MLKEM768_KEY_LENGTH = 1184; + constexpr size_t MLKEM768_CIPHER_TEXT_LENGTH = 1088; + constexpr size_t MLKEM1024_KEY_LENGTH = 1568; + constexpr size_t MLKEM1024_CIPHER_TEXT_LENGTH = 1568; + + constexpr std::array, 3> MLKEMS = + { + std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-768", MLKEM768_KEY_LENGTH, MLKEM768_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-1024", MLKEM1024_KEY_LENGTH, MLKEM1024_CIPHER_TEXT_LENGTH) + }; + + class MLKEM512Keys: public MLKEMKeys + { + public: + + MLKEM512Keys (): MLKEMKeys (std::get<0>(MLKEMS[0]), std::get<1>(MLKEMS[0]), std::get<2>(MLKEMS[0])) {} + }; + + class MLKEM768Keys: public MLKEMKeys + { + public: + + MLKEM768Keys (): MLKEMKeys (std::get<0>(MLKEMS[1]), std::get<1>(MLKEMS[1]), std::get<2>(MLKEMS[1])) {} + }; + + class MLKEM1024Keys: public MLKEMKeys + { + public: + + MLKEM1024Keys (): MLKEMKeys (std::get<0>(MLKEMS[2]), std::get<1>(MLKEMS[2]), std::get<2>(MLKEMS[2])) {} + }; + + constexpr size_t GetMLKEMPublicKeyLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<1>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } + + constexpr size_t GetMLKEMCipherTextLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<2>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } +} +} + +#endif + +#endif From 828cd9d07b4f90e39a16bec4adb36bcdb78bd48c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Apr 2025 19:38:43 -0400 Subject: [PATCH 1143/1160] common MLKEMKeys for all types --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +- libi2pd/PostQuantum.cpp | 12 +++- libi2pd/PostQuantum.h | 87 ++++++++++------------- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5d563d97..fbea786f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -290,7 +290,7 @@ namespace garlic len -= i2p::crypto::MLKEM512_KEY_LENGTH + 16; n++; - m_PQKeys = std::make_unique(); + m_PQKeys = i2p::crypto::CreateMLKEMKeys (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD); m_PQKeys->SetPublicKey (encapsKey); } } @@ -546,7 +546,7 @@ namespace garlic if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), m_RemoteStaticKey); // bpk - m_PQKeys = std::make_unique(); + m_PQKeys = i2p::crypto::CreateMLKEMKeys (m_RemoteStaticKeyType); m_PQKeys->GenerateKeys (); } else diff --git a/libi2pd/PostQuantum.cpp b/libi2pd/PostQuantum.cpp index abe207d2..16823c19 100644 --- a/libi2pd/PostQuantum.cpp +++ b/libi2pd/PostQuantum.cpp @@ -18,8 +18,9 @@ namespace i2p { namespace crypto { - MLKEMKeys::MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen): - m_Name (name), m_KeyLen (keyLen), m_CTLen (ctLen),m_Pkey (nullptr) + MLKEMKeys::MLKEMKeys (MLKEMTypes type): + m_Name (std::get<0>(MLKEMS[type])), m_KeyLen (std::get<1>(MLKEMS[type])), + m_CTLen (std::get<2>(MLKEMS[type])), m_Pkey (nullptr) { } @@ -95,6 +96,13 @@ namespace crypto else LogPrint (eLogError, "MLKEM512 can't create PKEY context"); } + + std::unique_ptr CreateMLKEMKeys (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return nullptr; + return std::make_unique((MLKEMTypes)(type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1)); + } } } diff --git a/libi2pd/PostQuantum.h b/libi2pd/PostQuantum.h index 6081f653..6bf2f238 100644 --- a/libi2pd/PostQuantum.h +++ b/libi2pd/PostQuantum.h @@ -9,6 +9,7 @@ #ifndef POST_QUANTUM_H__ #define POST_QUANTUM_H__ +#include #include #include #include @@ -21,11 +22,46 @@ namespace i2p { namespace crypto { + enum MLKEMTypes + { + eMLKEM512 = 0, + eMLKEM768, + eMLKEM1024 + }; + + constexpr size_t MLKEM512_KEY_LENGTH = 800; + constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; + constexpr size_t MLKEM768_KEY_LENGTH = 1184; + constexpr size_t MLKEM768_CIPHER_TEXT_LENGTH = 1088; + constexpr size_t MLKEM1024_KEY_LENGTH = 1568; + constexpr size_t MLKEM1024_CIPHER_TEXT_LENGTH = 1568; + + constexpr std::array, 3> MLKEMS = + { + std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-768", MLKEM768_KEY_LENGTH, MLKEM768_CIPHER_TEXT_LENGTH), + std::make_tuple ("ML-KEM-1024", MLKEM1024_KEY_LENGTH, MLKEM1024_CIPHER_TEXT_LENGTH) + }; + + constexpr size_t GetMLKEMPublicKeyLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<1>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } + + constexpr size_t GetMLKEMCipherTextLen (i2p::data::CryptoKeyType type) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; + return std::get<2>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); + } + class MLKEMKeys { public: - MLKEMKeys (std::string_view name, size_t keyLen, size_t ctLen); + MLKEMKeys (MLKEMTypes type); ~MLKEMKeys (); void GenerateKeys (); @@ -41,54 +77,7 @@ namespace crypto EVP_PKEY * m_Pkey; }; - constexpr size_t MLKEM512_KEY_LENGTH = 800; - constexpr size_t MLKEM512_CIPHER_TEXT_LENGTH = 768; - constexpr size_t MLKEM768_KEY_LENGTH = 1184; - constexpr size_t MLKEM768_CIPHER_TEXT_LENGTH = 1088; - constexpr size_t MLKEM1024_KEY_LENGTH = 1568; - constexpr size_t MLKEM1024_CIPHER_TEXT_LENGTH = 1568; - - constexpr std::array, 3> MLKEMS = - { - std::make_tuple ("ML-KEM-512", MLKEM512_KEY_LENGTH, MLKEM512_CIPHER_TEXT_LENGTH), - std::make_tuple ("ML-KEM-768", MLKEM768_KEY_LENGTH, MLKEM768_CIPHER_TEXT_LENGTH), - std::make_tuple ("ML-KEM-1024", MLKEM1024_KEY_LENGTH, MLKEM1024_CIPHER_TEXT_LENGTH) - }; - - class MLKEM512Keys: public MLKEMKeys - { - public: - - MLKEM512Keys (): MLKEMKeys (std::get<0>(MLKEMS[0]), std::get<1>(MLKEMS[0]), std::get<2>(MLKEMS[0])) {} - }; - - class MLKEM768Keys: public MLKEMKeys - { - public: - - MLKEM768Keys (): MLKEMKeys (std::get<0>(MLKEMS[1]), std::get<1>(MLKEMS[1]), std::get<2>(MLKEMS[1])) {} - }; - - class MLKEM1024Keys: public MLKEMKeys - { - public: - - MLKEM1024Keys (): MLKEMKeys (std::get<0>(MLKEMS[2]), std::get<1>(MLKEMS[2]), std::get<2>(MLKEMS[2])) {} - }; - - constexpr size_t GetMLKEMPublicKeyLen (i2p::data::CryptoKeyType type) - { - if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || - type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; - return std::get<1>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); - } - - constexpr size_t GetMLKEMCipherTextLen (i2p::data::CryptoKeyType type) - { - if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || - type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return 0; - return std::get<2>(MLKEMS[type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1]); - } + std::unique_ptr CreateMLKEMKeys (i2p::data::CryptoKeyType type); } } From 1a04b5958557be826a86058cfd7b8dcc12aee82c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Apr 2025 21:45:53 -0400 Subject: [PATCH 1144/1160] common InitNoiseIKState for all ML-KEM crypto --- libi2pd/Crypto.cpp | 15 -------------- libi2pd/Crypto.h | 3 +-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 14 ++++++------- libi2pd/PostQuantum.cpp | 25 +++++++++++++++++++++++ libi2pd/PostQuantum.h | 2 ++ 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index be2863f4..c41b4c10 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -944,21 +944,6 @@ namespace crypto }; // SHA256 (protocolNameHash) state.Init (protocolNameHash, hh, pub); } - - void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub) - { - static constexpr uint8_t protocolNameHash[32] = - { - 0xb0, 0x8f, 0xb1, 0x73, 0x92, 0x66, 0xc9, 0x90, 0x45, 0x7f, 0xdd, 0xc6, 0x4e, 0x55, 0x40, 0xd8, - 0x0a, 0x37, 0x99, 0x06, 0x92, 0x2a, 0x78, 0xc4, 0xb1, 0xef, 0x86, 0x06, 0xd0, 0x15, 0x9f, 0x4d - }; // SHA256("Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256") - static constexpr uint8_t hh[32] = - { - 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, - 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb - }; // SHA256 (protocolNameHash) - state.Init (protocolNameHash, hh, pub); - } // init and terminate diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 6abbd9b2..125a217c 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -271,8 +271,7 @@ namespace crypto void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2) void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (SSU2) void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) - void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) PQ ML-KEM512 - + // init and terminate void InitCrypto (bool precomputation); void TerminateCrypto (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index fbea786f..d38abd13 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -272,7 +272,8 @@ namespace garlic #if OPENSSL_PQ if (GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) { - i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)); // bpk + i2p::crypto::InitNoiseIKStateMLKEM (GetNoiseState (), i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD, + GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)); // bpk MixHash (m_Aepk, 32); // h = SHA256(h || aepk) if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) // x25519(bsk, aepk) @@ -281,8 +282,7 @@ namespace garlic uint8_t nonce[12], encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; CreateNonce (n, nonce); - if (i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_KEY_LENGTH, - m_H, 32, m_CK + 32, nonce, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH, false)) // decrypt + if (Decrypt (buf, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH)) { decrypted = true; // encaps section has right hash MixHash (buf, i2p::crypto::MLKEM512_KEY_LENGTH + 16); @@ -320,7 +320,7 @@ namespace garlic // decrypt flags/static uint8_t nonce[12], fs[32]; CreateNonce (n, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt + if (!Decrypt (buf, fs, 32)) { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); return false; @@ -354,7 +354,7 @@ namespace garlic // decrypt payload std::vector payload (len - 16); // we must save original ciphertext - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt + if (!Decrypt (buf, payload.data (), len - 16)) { LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); return false; @@ -543,9 +543,9 @@ namespace garlic // KDF1 #if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) { - i2p::crypto::InitNoiseIKStateMLKEM512 (GetNoiseState (), m_RemoteStaticKey); // bpk + i2p::crypto::InitNoiseIKStateMLKEM (GetNoiseState (), m_RemoteStaticKeyType, m_RemoteStaticKey); // bpk m_PQKeys = i2p::crypto::CreateMLKEMKeys (m_RemoteStaticKeyType); m_PQKeys->GenerateKeys (); } diff --git a/libi2pd/PostQuantum.cpp b/libi2pd/PostQuantum.cpp index 16823c19..0a55ca4d 100644 --- a/libi2pd/PostQuantum.cpp +++ b/libi2pd/PostQuantum.cpp @@ -103,6 +103,31 @@ namespace crypto type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)MLKEMS.size ()) return nullptr; return std::make_unique((MLKEMTypes)(type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1)); } + + static constexpr std::array, std::array >, 1> NoiseIKInitMLKEMKeys = + { + std::make_pair + ( + std::array + { + 0xb0, 0x8f, 0xb1, 0x73, 0x92, 0x66, 0xc9, 0x90, 0x45, 0x7f, 0xdd, 0xc6, 0x4e, 0x55, 0x40, 0xd8, + 0x0a, 0x37, 0x99, 0x06, 0x92, 0x2a, 0x78, 0xc4, 0xb1, 0xef, 0x86, 0x06, 0xd0, 0x15, 0x9f, 0x4d + }, // SHA256("Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256") + std::array + { + 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, + 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb + } // SHA256 (first) + ) + }; + + void InitNoiseIKStateMLKEM (NoiseSymmetricState& state, i2p::data::CryptoKeyType type, const uint8_t * pub) + { + if (type <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD > (int)NoiseIKInitMLKEMKeys.size ()) return; + auto ind = type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1; + state.Init (NoiseIKInitMLKEMKeys[ind].first.data(), NoiseIKInitMLKEMKeys[ind].second.data(), pub); + } } } diff --git a/libi2pd/PostQuantum.h b/libi2pd/PostQuantum.h index 6bf2f238..f426d661 100644 --- a/libi2pd/PostQuantum.h +++ b/libi2pd/PostQuantum.h @@ -78,6 +78,8 @@ namespace crypto }; std::unique_ptr CreateMLKEMKeys (i2p::data::CryptoKeyType type); + + void InitNoiseIKStateMLKEM (NoiseSymmetricState& state, i2p::data::CryptoKeyType type, const uint8_t * pub); // Noise_IK (ratchets) PQ ML-KEM5 } } From 9c46ff244991d7f80d01a17875a41d018d04927e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Apr 2025 13:26:19 -0400 Subject: [PATCH 1145/1160] Initial Noise states and encryptors/decryptors for ML-KEM-768 and ML-KEM-1024 --- libi2pd/CryptoKey.h | 12 ++++++++++-- libi2pd/Identity.cpp | 12 +++++++++--- libi2pd/PostQuantum.cpp | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 14ef4fa8..657a6a91 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -167,7 +167,11 @@ namespace crypto case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; - case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return 32; + // ML-KEM hybrid + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: + return 32; }; return 0; } @@ -179,7 +183,11 @@ namespace crypto case i2p::data::CRYPTO_KEY_TYPE_ELGAMAL: return 256; case i2p::data::CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: return 32; case i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return 32; - case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: return 32; + // ML-KEM hybrid + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: + case i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: + return 32; }; return 0; } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 3b2f5b97..798d9505 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -419,7 +419,9 @@ namespace data return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -686,7 +688,9 @@ namespace data return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -774,7 +778,9 @@ namespace data i2p::crypto::CreateECIESP256RandomKeys (priv, pub); break; case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: diff --git a/libi2pd/PostQuantum.cpp b/libi2pd/PostQuantum.cpp index 0a55ca4d..fa268828 100644 --- a/libi2pd/PostQuantum.cpp +++ b/libi2pd/PostQuantum.cpp @@ -64,7 +64,7 @@ namespace crypto EVP_PKEY_CTX_free (ctx); } else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + LogPrint (eLogError, "MLKEM can't create PKEY context"); } void MLKEMKeys::Encaps (uint8_t * ciphertext, uint8_t * shared) @@ -79,7 +79,7 @@ namespace crypto EVP_PKEY_CTX_free (ctx); } else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + LogPrint (eLogError, "MLKEM can't create PKEY context"); } void MLKEMKeys::Decaps (const uint8_t * ciphertext, uint8_t * shared) @@ -94,7 +94,7 @@ namespace crypto EVP_PKEY_CTX_free (ctx); } else - LogPrint (eLogError, "MLKEM512 can't create PKEY context"); + LogPrint (eLogError, "MLKEM can't create PKEY context"); } std::unique_ptr CreateMLKEMKeys (i2p::data::CryptoKeyType type) @@ -104,7 +104,7 @@ namespace crypto return std::make_unique((MLKEMTypes)(type - i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD - 1)); } - static constexpr std::array, std::array >, 1> NoiseIKInitMLKEMKeys = + static constexpr std::array, std::array >, 3> NoiseIKInitMLKEMKeys = { std::make_pair ( @@ -118,7 +118,33 @@ namespace crypto 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb } // SHA256 (first) - ) + ), + std::make_pair + ( + std::array + { + 0x36, 0x03, 0x90, 0x2d, 0xf9, 0xa2, 0x2a, 0x5e, 0xc9, 0x3d, 0xdb, 0x8f, 0xa8, 0x1b, 0xdb, 0x4b, + 0xae, 0x9d, 0x93, 0x9c, 0xdf, 0xaf, 0xde, 0x55, 0x49, 0x13, 0xfe, 0x98, 0xf8, 0x4a, 0xd4, 0xbd + }, // SHA256("Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256") + std::array + { + 0x15, 0x44, 0x89, 0xbf, 0x30, 0xf0, 0xc9, 0x77, 0x66, 0x10, 0xcb, 0xb1, 0x57, 0x3f, 0xab, 0x68, + 0x79, 0x57, 0x39, 0x57, 0x0a, 0xe7, 0xc0, 0x31, 0x8a, 0xa2, 0x96, 0xef, 0xbf, 0xa9, 0x6a, 0xbb + } // SHA256 (first) + ), + std::make_pair + ( + std::array + { + 0x86, 0xa5, 0x36, 0x44, 0xc6, 0x12, 0xd5, 0x71, 0xa1, 0x2d, 0xd8, 0xb6, 0x0a, 0x00, 0x9f, 0x2c, + 0x1a, 0xa8, 0x7d, 0x22, 0xa4, 0xff, 0x2b, 0xcd, 0x61, 0x34, 0x97, 0x6d, 0xa1, 0x49, 0xeb, 0x4a + }, // SHA256("Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256") + std::array + { + 0x42, 0x0d, 0xc2, 0x1c, 0x7b, 0x18, 0x61, 0xb7, 0x4a, 0x04, 0x3d, 0xae, 0x0f, 0xdc, 0xf2, 0x71, + 0xb9, 0xba, 0x19, 0xbb, 0xbd, 0x5f, 0xd4, 0x9c, 0x3f, 0x4b, 0x01, 0xed, 0x6d, 0x13, 0x1d, 0xa2 + } // SHA256 (first) + ) }; void InitNoiseIKStateMLKEM (NoiseSymmetricState& state, i2p::data::CryptoKeyType type, const uint8_t * pub) From f6c93f734569e778ab1873ce47de4498dea28611 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Apr 2025 15:40:09 -0400 Subject: [PATCH 1146/1160] common LocalEncryptionKey to pass to loacl LeaseSet --- libi2pd/CryptoKey.cpp | 16 ++++++++++++++++ libi2pd/CryptoKey.h | 11 +++++++++++ libi2pd/Destination.cpp | 10 +++++----- libi2pd/Destination.h | 19 ++----------------- libi2pd/LeaseSet.cpp | 10 +++++----- libi2pd/LeaseSet.h | 11 ++++------- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index bac5d740..e37d4039 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -181,5 +181,21 @@ namespace crypto k.GetPrivateKey (priv); memcpy (pub, k.GetPublicKey (), 32); } + + LocalEncryptionKey::LocalEncryptionKey (i2p::data::CryptoKeyType t): keyType(t) + { + pub.resize (GetCryptoPublicKeyLen (keyType)); + priv.resize (GetCryptoPrivateKeyLen (keyType)); + } + + void LocalEncryptionKey::GenerateKeys () + { + i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv.data (), pub.data ()); + } + + void LocalEncryptionKey::CreateDecryptor () + { + decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv.data ()); + } } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 657a6a91..b6c37ddf 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -191,6 +191,17 @@ namespace crypto }; return 0; } + + struct LocalEncryptionKey + { + std::vector pub, priv; + i2p::data::CryptoKeyType keyType; + std::shared_ptr decryptor; + + LocalEncryptionKey (i2p::data::CryptoKeyType t); + void GenerateKeys (); + void CreateDecryptor (); + }; } } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a3f6a8c9..b23d31ed 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1047,7 +1047,7 @@ namespace client for (auto& it: encryptionKeyTypes) { - auto encryptionKey = std::make_shared (it); + auto encryptionKey = std::make_shared (it); if (IsPublic ()) PersistTemporaryKeys (encryptionKey); else @@ -1405,7 +1405,7 @@ namespace client return ret; } - void ClientDestination::PersistTemporaryKeys (std::shared_ptr keys) + void ClientDestination::PersistTemporaryKeys (std::shared_ptr keys) { if (!keys) return; std::string ident = GetIdentHash().ToBase32(); @@ -1475,9 +1475,9 @@ namespace client else { // standard LS2 (type 3) first - i2p::data::LocalLeaseSet2::KeySections keySections; + i2p::data::LocalLeaseSet2::EncryptionKeys keySections; for (const auto& it: m_EncryptionKeys) - keySections.push_back ({it.first, (uint16_t)it.second->pub.size (), it.second->pub.data ()} ); + keySections.push_back (it.second); auto publishedTimestamp = i2p::util::GetSecondsSinceEpoch (); if (publishedTimestamp <= m_LastPublishedTimestamp) @@ -1503,7 +1503,7 @@ namespace client bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { - std::shared_ptr encryptionKey; + std::shared_ptr encryptionKey; if (!m_EncryptionKeys.empty ()) { if (m_EncryptionKeys.rbegin ()->first == preferredCrypto) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index a76a1be4..33e8bf08 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -230,21 +230,6 @@ namespace client class ClientDestination: public LeaseSetDestination { - struct EncryptionKey - { - std::vector pub, priv; - i2p::data::CryptoKeyType keyType; - std::shared_ptr decryptor; - - EncryptionKey (i2p::data::CryptoKeyType t): keyType(t) - { - pub.resize (i2p::crypto::GetCryptoPublicKeyLen (keyType)); - priv.resize (i2p::crypto::GetCryptoPrivateKeyLen (keyType)); - } - void GenerateKeys () { i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv.data (), pub.data ()); }; - void CreateDecryptor () { decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv.data ()); }; - }; - public: ClientDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, @@ -310,7 +295,7 @@ namespace client std::shared_ptr GetSharedFromThis () { return std::static_pointer_cast(shared_from_this ()); } - void PersistTemporaryKeys (std::shared_ptr keys); + void PersistTemporaryKeys (std::shared_ptr keys); void ReadAuthKey (const std::string& group, const std::map * params); template @@ -319,7 +304,7 @@ namespace client private: i2p::data::PrivateKeys m_Keys; - std::map > m_EncryptionKeys; // last is most preferable + std::map > m_EncryptionKeys; // last is most preferable i2p::data::CryptoKeyType m_PreferredCryptoType; int m_StreamingAckDelay,m_StreamingOutboundSpeed, m_StreamingInboundSpeed, m_StreamingMaxConcurrentStreams; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index db8c1aad..fc0e722d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -848,7 +848,7 @@ namespace data } LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, const std::vector >& tunnels, + const EncryptionKeys& encryptionKeys, const std::vector >& tunnels, bool isPublic, uint64_t publishedTimestamp, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { @@ -858,7 +858,7 @@ namespace data if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES; size_t keySectionsLen = 0; for (const auto& it: encryptionKeys) - keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; + keySectionsLen += 2/*key type*/ + 2/*key len*/ + it->pub.size()/*key*/; m_BufferLen = identity->GetFullLen () + 4/*published*/ + 2/*expires*/ + 2/*flag*/ + 2/*properties len*/ + 1/*num keys*/ + keySectionsLen + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); uint16_t flags = 0; @@ -893,9 +893,9 @@ namespace data m_Buffer[offset] = encryptionKeys.size (); offset++; // 1 key for (const auto& it: encryptionKeys) { - htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type - htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len - memcpy (m_Buffer + offset, it.encryptionPublicKey, it.keyLen); offset += it.keyLen; // key + htobe16buf (m_Buffer + offset, it->keyType); offset += 2; // key type + htobe16buf (m_Buffer + offset, it->pub.size()); offset += 2; // key len + memcpy (m_Buffer + offset, it->pub.data(), it->pub.size()); offset += it->pub.size(); // key } // leases uint32_t expirationTime = 0; // in seconds diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 1a89229a..3594083c 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -12,12 +12,14 @@ #include #include #include +#include #include #include #include "Identity.h" #include "Timestamp.h" #include "I2PEndian.h" #include "Blinding.h" +#include "CryptoKey.h" namespace i2p { @@ -247,15 +249,10 @@ namespace data { public: - struct KeySection - { - uint16_t keyType, keyLen; - const uint8_t * encryptionPublicKey; - }; - typedef std::vector KeySections; + typedef std::list > EncryptionKeys; LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, + const EncryptionKeys& encryptionKeys, const std::vector >& tunnels, bool isPublic, uint64_t publishedTimestamp, bool isPublishedEncrypted = false); From e69b56c4e37bfc5df155b54c912660363a6649b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Apr 2025 16:44:01 -0400 Subject: [PATCH 1147/1160] publish preferred key first --- libi2pd/Destination.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b23d31ed..3d910e54 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1475,10 +1475,27 @@ namespace client else { // standard LS2 (type 3) first + if (m_EncryptionKeys.empty ()) + { + LogPrint (eLogError, "Destinations: No encryption keys"); + return; + } + i2p::data::LocalLeaseSet2::EncryptionKeys keySections; - for (const auto& it: m_EncryptionKeys) - keySections.push_back (it.second); - + std::shared_ptr preferredSection; + if (m_EncryptionKeys.size () == 1) + preferredSection = m_EncryptionKeys.begin ()->second; // only key + else + { + for (const auto& it: m_EncryptionKeys) + if (it.first == m_PreferredCryptoType) + preferredSection = it.second; + else + keySections.push_back (it.second); + } + if (preferredSection) + keySections.push_front (preferredSection); // make preferred first + auto publishedTimestamp = i2p::util::GetSecondsSinceEpoch (); if (publishedTimestamp <= m_LastPublishedTimestamp) { From 1c162f9fd5b0507feb12f2d9cf0f8cada522597b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Apr 2025 21:59:10 -0400 Subject: [PATCH 1148/1160] get preferred crypto key type from ratchets session --- libi2pd/Destination.cpp | 18 ++++++++++++------ libi2pd/Destination.h | 5 +++-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 ++-- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + libi2pd/Garlic.cpp | 5 +++-- libi2pd/Garlic.h | 5 +++-- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 3d910e54..f89fc0f0 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,6 +13,7 @@ #include #include #include "Crypto.h" +#include "ECIESX25519AEADRatchetSession.h" #include "Log.h" #include "FS.h" #include "Timestamp.h" @@ -377,10 +378,12 @@ namespace client { I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]); uint32_t msgID = bufbe32toh (buf + I2NP_HEADER_MSGID_OFFSET); - LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID); + LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, + GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID, nullptr); } - bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) + bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, + size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) { switch (typeID) { @@ -395,7 +398,7 @@ namespace client m_Pool->ProcessTunnelTest (bufbe32toh (payload + TUNNEL_TEST_MSGID_OFFSET), bufbe64toh (payload + TUNNEL_TEST_TIMESTAMP_OFFSET)); break; case eI2NPDatabaseStore: - HandleDatabaseStoreMessage (payload, len); + HandleDatabaseStoreMessage (payload, len, from); break; case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (payload, len); @@ -410,7 +413,8 @@ namespace client return true; } - void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) + void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len, + i2p::garlic::ECIESX25519AEADRatchetSession * from) { if (len < DATABASE_STORE_HEADER_SIZE) { @@ -465,7 +469,8 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else - leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2 + leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], + buf + offset, len - offset, true, from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType () ); // LeaseSet2 if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ()) { if (leaseSet->GetIdentHash () != GetIdentHash ()) @@ -494,7 +499,8 @@ namespace client if (request->requestedBlindedKey) { auto ls2 = std::make_shared (buf + offset, len - offset, - request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ()); + request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr, + from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType ()); if (ls2->IsValid () && !ls2->IsExpired ()) { leaseSet = ls2; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 33e8bf08..abb63af2 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -164,7 +164,8 @@ namespace client // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len) override; - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) override; + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, + size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) override; void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; @@ -184,7 +185,7 @@ namespace client void HandlePublishConfirmationTimer (const boost::system::error_code& ecode); void HandlePublishVerificationTimer (const boost::system::error_code& ecode); void HandlePublishDelayTimer (const boost::system::error_code& ecode); - void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len); + void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from); void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len); void HandleDeliveryStatusMessage (uint32_t msgID); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d38abd13..266caeaa 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -163,7 +163,7 @@ namespace garlic return false; } if (m_Destination) - m_Destination->HandleECIESx25519GarlicClove (buf + offset, size); + m_Destination->HandleECIESx25519GarlicClove (buf + offset, size, nullptr); return true; } @@ -390,7 +390,7 @@ namespace garlic { case eECIESx25519BlkGalicClove: if (GetOwner ()) - GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); + GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size, this); break; case eECIESx25519BlkNextKey: LogPrint (eLogDebug, "Garlic: Next key"); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index b7704534..1b810cd0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -170,6 +170,7 @@ namespace garlic std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } + i2p::data::CryptoKeyType GetRemoteStaticKeyType () const { return m_RemoteStaticKeyType; } void SetRemoteStaticKey (i2p::data::CryptoKeyType keyType, const uint8_t * key) { m_RemoteStaticKeyType = keyType; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5a3e4cae..3675b0b0 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1003,7 +1003,8 @@ namespace garlic i2p::fs::Remove (it); } - void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len, + ECIESX25519AEADRatchetSession * from) { const uint8_t * buf1 = buf; uint8_t flag = buf[0]; buf++; // flag @@ -1023,7 +1024,7 @@ namespace garlic buf += 4; // expiration ptrdiff_t offset = buf - buf1; if (offset <= (int)len) - HandleCloveI2NPMessage (typeID, buf, len - offset, msgID); + HandleCloveI2NPMessage (typeID, buf, len - offset, msgID, from); else LogPrint (eLogError, "Garlic: Clove is too long"); break; diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 0eef4871..dc6b9bba 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -257,7 +257,7 @@ namespace garlic uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); - void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); + void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len, ECIESX25519AEADRatchetSession * from); uint8_t * GetPayloadBuffer (); virtual void ProcessGarlicMessage (std::shared_ptr msg); @@ -272,7 +272,8 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only - virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) = 0; + virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, + size_t len, uint32_t msgID, ECIESX25519AEADRatchetSession * from) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); From 67fe6faf2d3f1bf54a10129dde60ae0eab33e726 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Apr 2025 22:08:16 -0400 Subject: [PATCH 1149/1160] get preferred crypto key type from ratchets session --- libi2pd/RouterContext.cpp | 3 ++- libi2pd/RouterContext.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index af90a46a..33fb5487 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1194,7 +1194,8 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); } - bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) + bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, + size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) { if (typeID == eI2NPTunnelTest) { diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index c3336336..754c49da 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -204,7 +204,8 @@ namespace garlic // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len) override; - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) override; + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, + size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) override; private: From bbfe81cb795da01d8011e94ea814f0349cd7c601 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Apr 2025 22:15:17 -0400 Subject: [PATCH 1150/1160] handle any incoming post quantum crypto type --- libi2pd/Destination.cpp | 9 ++-- libi2pd/Destination.h | 2 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 56 ++++++++++------------- libi2pd/Garlic.cpp | 5 +- libi2pd/Garlic.h | 7 ++- libi2pd_client/I2CP.h | 5 +- 6 files changed, 41 insertions(+), 43 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f89fc0f0..b88865b6 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1556,11 +1556,12 @@ namespace client #endif } - bool ClientDestination::SupportsRatchets () const + i2p::data::CryptoKeyType ClientDestination::GetRatchetsHighestCryptoType () const { - if (m_EncryptionKeys.empty ()) return false; - return m_EncryptionKeys.rbegin ()->first >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; - } + if (m_EncryptionKeys.empty ()) return 0; + auto cryptoType = m_EncryptionKeys.rbegin ()->first; + return cryptoType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? cryptoType : 0; + } const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index abb63af2..35557859 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -283,7 +283,7 @@ namespace client protected: // GarlicDestionation - bool SupportsRatchets () const override; + i2p::data::CryptoKeyType GetRatchetsHighestCryptoType () const override; // LeaseSetDestination void CleanupDestination () override; i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 266caeaa..7436e775 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -266,40 +266,40 @@ namespace garlic } buf += 32; len -= 32; - uint64_t n = 0; uint8_t sharedSecret[32]; bool decrypted = false; + auto cryptoType = GetOwner ()->GetRatchetsHighestCryptoType (); #if OPENSSL_PQ - if (GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) + if (cryptoType > i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // we support post quantum { - i2p::crypto::InitNoiseIKStateMLKEM (GetNoiseState (), i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD, - GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)); // bpk + i2p::crypto::InitNoiseIKStateMLKEM (GetNoiseState (), cryptoType, GetOwner ()->GetEncryptionPublicKey (cryptoType)); // bpk MixHash (m_Aepk, 32); // h = SHA256(h || aepk) - if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)) // x25519(bsk, aepk) + if (GetOwner ()->Decrypt (m_Aepk, sharedSecret, cryptoType)) // x25519(bsk, aepk) { MixKey (sharedSecret); - - uint8_t nonce[12], encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; - CreateNonce (n, nonce); - if (Decrypt (buf, encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH)) + + auto keyLen = i2p::crypto::GetMLKEMPublicKeyLen (cryptoType); + std::vector encapsKey(keyLen); + if (Decrypt (buf, encapsKey.data (), keyLen)) { decrypted = true; // encaps section has right hash - MixHash (buf, i2p::crypto::MLKEM512_KEY_LENGTH + 16); - buf += i2p::crypto::MLKEM512_KEY_LENGTH + 16; - len -= i2p::crypto::MLKEM512_KEY_LENGTH + 16; - n++; + MixHash (buf, keyLen + 16); + buf += keyLen + 16; + len -= keyLen + 16; - m_PQKeys = i2p::crypto::CreateMLKEMKeys (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD); - m_PQKeys->SetPublicKey (encapsKey); + m_PQKeys = i2p::crypto::CreateMLKEMKeys (cryptoType); + m_PQKeys->SetPublicKey (encapsKey.data ()); } } } #endif if (!decrypted) { - if (GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + if (cryptoType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD || + GetOwner ()->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { + cryptoType = i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; i2p::crypto::InitNoiseIKState (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk MixHash (m_Aepk, 32); // h = SHA256(h || aepk) @@ -318,8 +318,7 @@ namespace garlic } // decrypt flags/static - uint8_t nonce[12], fs[32]; - CreateNonce (n, nonce); + uint8_t fs[32]; if (!Decrypt (buf, fs, 32)) { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); @@ -332,16 +331,8 @@ namespace garlic bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); if (isStatic) { - // static key, fs is apk -#if OPENSSL_PQ - if (m_PQKeys) - { - SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD, fs); - CreateNonce (0, nonce); // reset nonce - } - else -#endif - SetRemoteStaticKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD, fs); + // static key, fs is apk + SetRemoteStaticKey (cryptoType, fs); if (!GetOwner ()->Decrypt (fs, sharedSecret, m_RemoteStaticKeyType)) // x25519(bsk, apk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); @@ -349,8 +340,6 @@ namespace garlic } MixKey (sharedSecret); } - else // all zeros flags - CreateNonce (1, nonce); // decrypt payload std::vector payload (len - 16); // we must save original ciphertext @@ -966,7 +955,8 @@ namespace garlic size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload); if (!len) return nullptr; #if OPENSSL_PQ - auto m = NewI2NPMessage (len + (m_State == eSessionStateEstablished ? 28 : i2p::crypto::MLKEM512_KEY_LENGTH + 116)); + auto m = NewI2NPMessage (len + (m_State == eSessionStateEstablished ? 28 : + i2p::crypto::GetMLKEMPublicKeyLen (m_RemoteStaticKeyType) + 116)); #else auto m = NewI2NPMessage (len + 100); // 96 + 4 #endif @@ -994,8 +984,8 @@ namespace garlic return nullptr; len += 72; #if OPENSSL_PQ - if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) - len += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16; + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + len += i2p::crypto::GetMLKEMPublicKeyLen (m_RemoteStaticKeyType) + 16; #endif break; case eSessionStateNewSessionReplySent: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 3675b0b0..8c8602e8 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -498,7 +498,8 @@ namespace garlic buf += 4; // length bool found = false; - if (SupportsRatchets ()) + bool supportsRatchets = SupportsRatchets (); + if (supportsRatchets) // try ECIESx25519 tag found = HandleECIESx25519TagMessage (buf, length); if (!found) @@ -535,7 +536,7 @@ namespace garlic decryption->Decrypt(buf + 514, length - 514, iv, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } - else if (SupportsRatchets ()) + else if (supportsRatchets) { // otherwise ECIESx25519 auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index dc6b9bba..25106c45 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -266,6 +266,10 @@ namespace garlic virtual std::shared_ptr GetLeaseSet () = 0; // TODO virtual std::shared_ptr GetTunnelPool () const = 0; + virtual i2p::data::CryptoKeyType GetRatchetsHighestCryptoType () const + { + return GetIdentity ()->GetCryptoKeyType () >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? GetIdentity ()->GetCryptoKeyType () : 0; + } protected: @@ -279,11 +283,10 @@ namespace garlic void SaveTags (); void LoadTags (); - - virtual bool SupportsRatchets () const { return GetIdentity ()->GetCryptoKeyType () >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; } private: + bool SupportsRatchets () const { return GetRatchetsHighestCryptoType () > 0; } void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, std::shared_ptr from); void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr from); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 84243e6f..37c14dbb 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -109,7 +109,10 @@ namespace client protected: // GarlicDestination - bool SupportsRatchets () const override { return (bool)m_ECIESx25519Decryptor; } + i2p::data::CryptoKeyType GetRatchetsHighestCryptoType () const override + { + return m_ECIESx25519Decryptor ? i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD : 0; + } // LeaseSetDestination void CleanupDestination () override; i2p::data::CryptoKeyType GetPreferredCryptoType () const override; From 58818514e783d76654dab4d5a6aa171912a03fab Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Apr 2025 22:34:39 -0400 Subject: [PATCH 1151/1160] correct NSR size --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7436e775..87c99d51 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -985,13 +985,17 @@ namespace garlic len += 72; #if OPENSSL_PQ if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) - len += i2p::crypto::GetMLKEMPublicKeyLen (m_RemoteStaticKeyType) + 16; + len += i2p::crypto::GetMLKEMCipherTextLen (m_RemoteStaticKeyType) + 16; #endif break; case eSessionStateNewSessionReplySent: if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; +#if OPENSSL_PQ + if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) + len += i2p::crypto::GetMLKEMCipherTextLen (m_RemoteStaticKeyType) + 16; +#endif break; case eSessionStateOneTime: if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false)) From 9b967059ada5c1acfd49d75466bd99c58085135d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Apr 2025 21:52:44 +0300 Subject: [PATCH 1152/1160] [gha] Update docker containers build --- .github/workflows/docker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 34923f31..c6d55664 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -108,7 +108,7 @@ jobs: uses: Noelware/docker-manifest-action@master with: inputs: purplei2p/i2pd:latest - images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + tags: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push latest manifest image to GHCR @@ -116,7 +116,7 @@ jobs: uses: Noelware/docker-manifest-action@master with: inputs: ghcr.io/purplei2p/i2pd:latest - images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + tags: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true - name: Store release version to env @@ -128,7 +128,7 @@ jobs: uses: Noelware/docker-manifest-action@master with: inputs: purplei2p/i2pd:latest,purplei2p/i2pd:latest-release,purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - images: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 + tags: purplei2p/i2pd:latest-amd64,purplei2p/i2pd:latest-i386,purplei2p/i2pd:latest-arm64,purplei2p/i2pd:latest-armv7 push: true - name: Create and push release manifest to GHCR @@ -136,5 +136,5 @@ jobs: uses: Noelware/docker-manifest-action@master with: inputs: ghcr.io/purplei2p/i2pd:latest,ghcr.io/purplei2p/i2pd:latest-release,ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} - images: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 + tags: ghcr.io/purplei2p/i2pd:latest-amd64,ghcr.io/purplei2p/i2pd:latest-i386,ghcr.io/purplei2p/i2pd:latest-arm64,ghcr.io/purplei2p/i2pd:latest-armv7 push: true From 2afdd5b723ca55151aad7a71ffc817bacaf8381b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Apr 2025 12:33:09 -0400 Subject: [PATCH 1153/1160] cleanup NSR keys --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 25 +++++++++++++++++++---- libi2pd/ECIESX25519AEADRatchetSession.h | 7 ++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 87c99d51..08af4be3 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -95,6 +95,17 @@ namespace garlic m_ItermediateSymmKeys.erase (index); } + ReceiveRatchetTagSet::ReceiveRatchetTagSet (std::shared_ptr session, bool isNS): + m_Session (session), m_IsNS (isNS) + { + } + + ReceiveRatchetTagSet::~ReceiveRatchetTagSet () + { + if (m_IsNS && m_Session) + m_Session->CleanupReceiveNSRKeys (); + } + void ReceiveRatchetTagSet::Expire () { if (!m_ExpirationTimestamp) @@ -252,6 +263,14 @@ namespace garlic } return false; } + + void ECIESX25519AEADRatchetSession::CleanupReceiveNSRKeys () + { + m_EphemeralKeys = nullptr; +#if OPENSSL_PQ + m_PQKeys = nullptr; +#endif + } bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) { @@ -824,10 +843,8 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; - //m_EphemeralKeys = nullptr; // TODO: delete after a while -#if OPENSSL_PQ - // m_PQKeys = nullptr; // TODO: delete after a while -#endif + // don't delete m_EpehemralKey and m_PQKeys because delayd NSR's migth come + // done in CleanupReceiveNSRKeys called from NSR tagset destructor m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 1b810cd0..fd9cc45d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -81,8 +81,8 @@ namespace garlic { public: - ReceiveRatchetTagSet (std::shared_ptr session, bool isNS = false): - m_Session (session), m_IsNS (isNS) {}; + ReceiveRatchetTagSet (std::shared_ptr session, bool isNS = false); + ~ReceiveRatchetTagSet () override; bool IsNS () const { return m_IsNS; }; std::shared_ptr GetSession () { return m_Session; }; @@ -184,7 +184,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } - + void CleanupReceiveNSRKeys (); // called from ReceiveRatchetTagSet at Alice's side + bool IsRatchets () const override { return true; }; bool IsReadyToSend () const override { return m_State != eSessionStateNewSessionSent; }; bool IsTerminated () const override { return m_IsTerminated; } From 9bd2b8df761c36c59361d0946d6b190e78dee57b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 20 Apr 2025 18:53:21 -0400 Subject: [PATCH 1154/1160] create and handle ML-DSA identities and signatures --- libi2pd/Identity.cpp | 109 +++++++++++++++++++++++++++++++------------ libi2pd/Identity.h | 10 ++-- libi2pd/LeaseSet.h | 2 +- 3 files changed, 88 insertions(+), 33 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 798d9505..de84b53b 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -127,6 +127,7 @@ namespace data excessLen = i2p::crypto::MLDSA44_PUBLIC_KEY_LENGTH - 384; excessBuf = new uint8_t[excessLen]; memcpy (excessBuf, signingKey + 384, excessLen); + cryptoType = 0xFF; // crypto key is not used break; } #endif @@ -142,12 +143,15 @@ namespace data htobe16buf (m_ExtendedBuffer + 2, cryptoType); if (excessLen && excessBuf) { - if (excessLen > MAX_EXTENDED_BUFFER_SIZE - 4) + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) { - LogPrint (eLogError, "Identity: Unexpected excessive signing key len ", excessLen); - excessLen = MAX_EXTENDED_BUFFER_SIZE - 4; + auto newBuf = new uint8_t[m_ExtendedLen]; + memcpy (newBuf, m_ExtendedBuffer, 4); + memcpy (newBuf + 4, excessBuf, excessLen); + m_ExtendedBufferPtr = newBuf; } - memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen); + else + memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen); delete[] excessBuf; } // calculate ident hash @@ -195,6 +199,8 @@ namespace data IdentityEx::~IdentityEx () { + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) + delete[] m_ExtendedBufferPtr; } IdentityEx& IdentityEx::operator=(const IdentityEx& other) @@ -202,11 +208,29 @@ namespace data memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE); m_IdentHash = other.m_IdentHash; + size_t oldLen = m_ExtendedLen; m_ExtendedLen = other.m_ExtendedLen; if (m_ExtendedLen > 0) { - if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; - memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) + { + if (oldLen > MAX_EXTENDED_BUFFER_SIZE) + { + if (m_ExtendedLen > oldLen) + { + delete[] m_ExtendedBufferPtr; + m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; + } + } + else + m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; + memcpy (m_ExtendedBufferPtr, other.m_ExtendedBufferPtr, m_ExtendedLen); + } + else + { + if (oldLen > MAX_EXTENDED_BUFFER_SIZE) delete[] m_ExtendedBufferPtr; + memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); + } } m_Verifier = nullptr; CreateVerifier (); @@ -235,13 +259,28 @@ namespace data } memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE); + size_t oldLen = m_ExtendedLen; m_ExtendedLen = bufbe16toh (m_StandardIdentity.certificate + 1); if (m_ExtendedLen) { if (m_ExtendedLen + DEFAULT_IDENTITY_SIZE <= len) { - if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; - memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) + { + if (oldLen > MAX_EXTENDED_BUFFER_SIZE) + { + if (m_ExtendedLen > oldLen) + { + delete[] m_ExtendedBufferPtr; + m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; + } + } + else + m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; + memcpy (m_ExtendedBufferPtr, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); + } + else + memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); } else { @@ -266,7 +305,12 @@ namespace data if (fullLen > len) return 0; // buffer is too small and may overflow somewhere else memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE); if (m_ExtendedLen > 0) - memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen); + { + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) + memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBufferPtr, m_ExtendedLen); + else + memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen); + } return fullLen; } @@ -295,7 +339,7 @@ namespace data const uint8_t * IdentityEx::GetSigningPublicKeyBuffer () const { auto keyLen = GetSigningPublicKeyLen (); - if (keyLen > 128) return nullptr; // P521 + if (keyLen > 128) return nullptr; // P521 or PQ return m_StandardIdentity.signingKey + 128 - keyLen; } @@ -322,7 +366,7 @@ namespace data SigningKeyType IdentityEx::GetSigningKeyType () const { if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedLen >= 2) - return bufbe16toh (m_ExtendedBuffer); // signing key + return bufbe16toh (m_ExtendedLen <= MAX_EXTENDED_BUFFER_SIZE ? m_ExtendedBuffer : m_ExtendedBufferPtr); // signing key return SIGNING_KEY_TYPE_DSA_SHA1; } @@ -335,7 +379,7 @@ namespace data CryptoKeyType IdentityEx::GetCryptoKeyType () const { if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedLen >= 4) - return bufbe16toh (m_ExtendedBuffer + 2); // crypto key + return bufbe16toh (m_ExtendedLen <= MAX_EXTENDED_BUFFER_SIZE ? m_ExtendedBuffer + 2 : m_ExtendedBufferPtr + 2); // crypto key return CRYPTO_KEY_TYPE_ELGAMAL; } @@ -359,7 +403,7 @@ namespace data return new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512); case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: return new i2p::crypto::RedDSA25519Verifier (); -#if OPENSSL_PQ +#if OPENSSL_PQ case SIGNING_KEY_TYPE_MLDSA44: return new i2p::crypto::MLDSA44Verifier (); #endif @@ -391,7 +435,7 @@ namespace data uint8_t * signingKey = new uint8_t[keyLen]; memcpy (signingKey, m_StandardIdentity.signingKey, 384); size_t excessLen = keyLen - 384; - memcpy (signingKey + 384, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types + memcpy (signingKey + 384, m_ExtendedBufferPtr + 4, excessLen); // right after signing and crypto key types verifier->SetPublicKey (signingKey); delete[] signingKey; } @@ -451,7 +495,9 @@ namespace data { m_Public = std::make_shared(Identity (keys)); memcpy (m_PrivateKey, keys.privateKey, 256); // 256 - memcpy (m_SigningPrivateKey, keys.signingPrivateKey, m_Public->GetSigningPrivateKeyLen ()); + size_t keyLen = m_Public->GetSigningPrivateKeyLen (); + if (keyLen > 128) m_SigningPrivateKey.resize (keyLen); + memcpy (m_SigningPrivateKey.data (), keys.signingPrivateKey, keyLen); m_OfflineSignature.resize (0); m_TransientSignatureLen = 0; m_TransientSigningPrivateKeyLen = 0; @@ -467,7 +513,7 @@ namespace data m_OfflineSignature = other.m_OfflineSignature; m_TransientSignatureLen = other.m_TransientSignatureLen; m_TransientSigningPrivateKeyLen = other.m_TransientSigningPrivateKeyLen; - memcpy (m_SigningPrivateKey, other.m_SigningPrivateKey, m_TransientSigningPrivateKeyLen > 0 ? m_TransientSigningPrivateKeyLen : m_Public->GetSigningPrivateKeyLen ()); + m_SigningPrivateKey = other.m_SigningPrivateKey; m_Signer = nullptr; CreateSigner (); return *this; @@ -490,8 +536,9 @@ namespace data memcpy (m_PrivateKey, buf + ret, cryptoKeyLen); ret += cryptoKeyLen; size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen (); - if(signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0; // overflow - memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize); + if (signingPrivateKeySize + ret > len) return 0; // overflow + m_SigningPrivateKey.resize (signingPrivateKeySize); + memcpy (m_SigningPrivateKey.data (), buf + ret, signingPrivateKeySize); ret += signingPrivateKeySize; m_Signer = nullptr; // check if signing private key is all zeros @@ -532,8 +579,9 @@ namespace data memcpy (m_OfflineSignature.data (), offlineInfo, offlineInfoLen); // override signing private key m_TransientSigningPrivateKeyLen = transientVerifier->GetPrivateKeyLen (); - if (m_TransientSigningPrivateKeyLen + ret > len || m_TransientSigningPrivateKeyLen > 128) return 0; - memcpy (m_SigningPrivateKey, buf + ret, m_TransientSigningPrivateKeyLen); + if (m_TransientSigningPrivateKeyLen + ret > len) return 0; + if (m_TransientSigningPrivateKeyLen > 128) m_SigningPrivateKey.resize (m_TransientSigningPrivateKeyLen); + memcpy (m_SigningPrivateKey.data (), buf + ret, m_TransientSigningPrivateKeyLen); ret += m_TransientSigningPrivateKeyLen; CreateSigner (keyType); } @@ -553,7 +601,7 @@ namespace data if (IsOfflineSignature ()) memset (buf + ret, 0, signingPrivateKeySize); else - memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize); + memcpy (buf + ret, m_SigningPrivateKey.data (), signingPrivateKeySize); ret += signingPrivateKeySize; if (IsOfflineSignature ()) { @@ -564,7 +612,7 @@ namespace data ret += offlineSignatureLen; // transient private key if (ret + m_TransientSigningPrivateKeyLen > len) return 0; - memcpy (buf + ret, m_SigningPrivateKey, m_TransientSigningPrivateKeyLen); + memcpy (buf + ret, m_SigningPrivateKey.data (), m_TransientSigningPrivateKeyLen); ret += m_TransientSigningPrivateKeyLen; } return ret; @@ -603,13 +651,13 @@ namespace data { if (m_Signer) return; if (keyType == SIGNING_KEY_TYPE_DSA_SHA1) - m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); + m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey.data (), m_Public->GetStandardIdentity ().signingKey)); else if (keyType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 && !IsOfflineSignature ()) - m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey + (sizeof(Identity::signingKey) - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH))); // TODO: remove public key check + m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey.data (), m_Public->GetStandardIdentity ().signingKey + (sizeof(Identity::signingKey) - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH))); // TODO: remove public key check else { // public key is not required - auto signer = CreateSigner (keyType, m_SigningPrivateKey); + auto signer = CreateSigner (keyType, m_SigningPrivateKey.data ()); if (signer) m_Signer.reset (signer); } } @@ -708,8 +756,10 @@ namespace data { PrivateKeys keys; // signature - uint8_t signingPublicKey[512]; // signing public key is 512 bytes max - GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, signingPublicKey); + std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); + std::vector signingPublicKey(verifier->GetPublicKeyLen ()); + keys.m_SigningPrivateKey.resize (verifier->GetPrivateKeyLen ()); + GenerateSigningKeyPair (type, keys.m_SigningPrivateKey.data (), signingPublicKey.data ()); // encryption uint8_t publicKey[256]; if (isDestination) @@ -717,7 +767,7 @@ namespace data else GenerateCryptoKeyPair (cryptoType, keys.m_PrivateKey, publicKey); // identity - keys.m_Public = std::make_shared (isDestination ? nullptr : publicKey, signingPublicKey, type, cryptoType); + keys.m_Public = std::make_shared (isDestination ? nullptr : publicKey, signingPublicKey.data (), type, cryptoType); keys.CreateSigner (); return keys; @@ -798,9 +848,10 @@ namespace data keys.m_TransientSigningPrivateKeyLen = verifier->GetPrivateKeyLen (); keys.m_TransientSignatureLen = verifier->GetSignatureLen (); keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6); + keys.m_SigningPrivateKey.resize (verifier->GetPrivateKeyLen ()); htobe32buf (keys.m_OfflineSignature.data (), expires); // expires htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type - GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key + GenerateSigningKeyPair (type, keys.m_SigningPrivateKey.data (), keys.m_OfflineSignature.data () + 6); // public key Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature // recreate signer keys.m_Signer = nullptr; diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 173559e9..c95ce000 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -142,7 +142,11 @@ namespace data IdentHash m_IdentHash; std::unique_ptr m_Verifier; size_t m_ExtendedLen; - uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; // TODO: support PQ keys + union + { + uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; + uint8_t * m_ExtendedBufferPtr; + }; }; size_t GetIdentityBufferLen (const uint8_t * buf, size_t len); // return actual identity length in buffer @@ -160,7 +164,7 @@ namespace data std::shared_ptr GetPublic () const { return m_Public; }; const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; - const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; + const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey.data (); }; size_t GetSignatureLen () const; // might not match identity bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; }; uint8_t * GetPadding(); @@ -196,7 +200,7 @@ namespace data std::shared_ptr m_Public; uint8_t m_PrivateKey[256]; - uint8_t m_SigningPrivateKey[128]; // assume private key doesn't exceed 128 bytes + std::vector m_SigningPrivateKey; mutable std::unique_ptr m_Signer; std::vector m_OfflineSignature; // non zero length, if applicable size_t m_TransientSignatureLen = 0; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 3594083c..c24c8696 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -60,7 +60,7 @@ namespace data typedef std::function LeaseInspectFunc; - const size_t MAX_LS_BUFFER_SIZE = 3072; + const size_t MAX_LS_BUFFER_SIZE = 4096; const size_t LEASE_SIZE = 44; // 32 + 4 + 8 const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 const uint8_t MAX_NUM_LEASES = 16; From 724d8bde4edf58a2f9a6fc0b32aa6a5839b5ba6d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Apr 2025 21:25:51 -0400 Subject: [PATCH 1155/1160] handle incoming packets with ML-DSA signature --- libi2pd/Identity.cpp | 2 +- libi2pd/LeaseSet.h | 5 ++++- libi2pd/Streaming.cpp | 49 +++++++++++++++++++++++++++---------------- libi2pd/Streaming.h | 4 ++++ 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index de84b53b..865beeb8 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -433,7 +433,7 @@ namespace data { // for post-quantum uint8_t * signingKey = new uint8_t[keyLen]; - memcpy (signingKey, m_StandardIdentity.signingKey, 384); + memcpy (signingKey, m_StandardIdentity, 384); size_t excessLen = keyLen - 384; memcpy (signingKey + 384, m_ExtendedBufferPtr + 4, excessLen); // right after signing and crypto key types verifier->SetPublicKey (signingKey); diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index c24c8696..f5197eb5 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -59,8 +59,11 @@ namespace data }; typedef std::function LeaseInspectFunc; - +#if OPENSSL_PQ + const size_t MAX_LS_BUFFER_SIZE = 8192; +#else const size_t MAX_LS_BUFFER_SIZE = 4096; +#endif const size_t LEASE_SIZE = 44; // 32 + 4 + 8 const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 const uint8_t MAX_NUM_LEASES = 16; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index d21cfa62..99da5fd2 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -450,29 +450,42 @@ namespace stream if (flags & PACKET_FLAG_SIGNATURE_INCLUDED) { - uint8_t signature[256]; + bool verified = false; auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen (); - if(signatureLen <= sizeof(signature)) - { - memcpy (signature, optionData, signatureLen); - memset (const_cast(optionData), 0, signatureLen); - bool verified = m_TransientVerifier ? - m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) : - m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature); - if (!verified) - { - LogPrint (eLogError, "Streaming: Signature verification failed, sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID); - Close (); - flags |= PACKET_FLAG_CLOSE; - } - memcpy (const_cast(optionData), signature, signatureLen); - optionData += signatureLen; - } - else + if (signatureLen > packet->GetLength ()) { LogPrint (eLogError, "Streaming: Signature too big, ", signatureLen, " bytes"); return false; + } + if(signatureLen <= 256) + { + // standard + uint8_t signature[256]; + memcpy (signature, optionData, signatureLen); + memset (const_cast(optionData), 0, signatureLen); + verified = m_TransientVerifier ? + m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) : + m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature); + if (verified) + memcpy (const_cast(optionData), signature, signatureLen); } + else + { + // post quantum + std::vector signature(signatureLen); + memcpy (signature.data (), optionData, signatureLen); + memset (const_cast(optionData), 0, signatureLen); + verified = m_TransientVerifier ? + m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()) : + m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()); + } + if (verified) + optionData += signatureLen; + else + { + LogPrint (eLogError, "Streaming: Signature verification failed, sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID); + return false; + } } if (immediateAckRequested) SendQuickAck (); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 8280477b..8a5c355c 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -51,7 +51,11 @@ namespace stream const size_t STREAMING_MTU = 1730; const size_t STREAMING_MTU_RATCHETS = 1812; +#if OPENSSL_PQ + const size_t MAX_PACKET_SIZE = 8192; +#else const size_t MAX_PACKET_SIZE = 4096; +#endif const size_t COMPRESSION_THRESHOLD_SIZE = 66; const int MAX_NUM_RESEND_ATTEMPTS = 10; const int INITIAL_WINDOW_SIZE = 10; From a5fa4ddb4cb5f0362ab7d763bf20f462e7a7b68b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 22 Apr 2025 21:21:51 -0400 Subject: [PATCH 1156/1160] compare LeaseSet's static keys with ratchets session it was received from --- libi2pd/Destination.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b88865b6..91cc8380 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -469,9 +469,21 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else + { leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType () ); // LeaseSet2 - if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ()) + if (from) + { + uint8_t pub[32]; + leaseSet->Encrypt (nullptr, pub); + if (memcmp (from->GetRemoteStaticKey (), pub, 32)) + { + LogPrint (eLogError, "Destination: Remote LeaseSet static key mismatch"); + leaseSet = nullptr; + } + } + } + if (leaseSet && leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ()) { if (leaseSet->GetIdentHash () != GetIdentHash ()) { From 9d44a32e4cf63f2b34f66e428b2911c6a8e3f036 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 24 Apr 2025 16:37:50 -0400 Subject: [PATCH 1157/1160] fixed #2183. Give more time to close streams after session disconnect if needed --- libi2pd/Streaming.h | 1 + libi2pd_client/SAM.cpp | 50 +++++++++++++++++++++++++++++------------- libi2pd_client/SAM.h | 6 ++++- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 8a5c355c..570fdd1d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -326,6 +326,7 @@ namespace stream void SendPing (std::shared_ptr remote); void DeleteStream (std::shared_ptr stream); bool DeleteStream (uint32_t recvStreamID); + size_t GetNumStreams () const { return m_Streams.size (); }; void SetAcceptor (const Acceptor& acceptor); void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 3114bb5a..2c0f8d92 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -43,23 +43,21 @@ namespace client m_Stream->AsyncClose (); m_Stream = nullptr; } - auto Session = m_Owner.FindSession(m_ID); switch (m_SocketType) { case eSAMSocketTypeSession: m_Owner.CloseSession (m_ID); break; case eSAMSocketTypeStream: - { - break; - } + break; case eSAMSocketTypeAcceptor: case eSAMSocketTypeForward: { - if (Session) + auto session = m_Owner.FindSession(m_ID); + if (session) { - if (m_IsAccepting && Session->GetLocalDestination ()) - Session->GetLocalDestination ()->StopAcceptingStreams (); + if (m_IsAccepting && session->GetLocalDestination ()) + session->GetLocalDestination ()->StopAcceptingStreams (); } break; } @@ -1479,17 +1477,39 @@ namespace client session->StopLocalDestination (); session->Close (); if (m_IsSingleThread) - { - auto timer = std::make_shared(GetService ()); - timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds - timer->async_wait ([timer, session](const boost::system::error_code& ecode) - { - // session's destructor is called here - }); - } + ScheduleSessionCleanupTimer (session); // let all session's streams close } } + void SAMBridge::ScheduleSessionCleanupTimer (std::shared_ptr session) + { + auto timer = std::make_shared(GetService ()); + timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds + timer->async_wait (std::bind (&SAMBridge::HandleSessionCleanupTimer, this, std::placeholders::_1, session, timer)); + } + + void SAMBridge::HandleSessionCleanupTimer (const boost::system::error_code& ecode, + std::shared_ptr session, std::shared_ptr timer) + { + if (ecode != boost::asio::error::operation_aborted && session) + { + auto dest = session->GetLocalDestination (); + if (dest) + { + auto streamingDest = dest->GetStreamingDestination (); + auto numStreams = streamingDest->GetNumStreams (); + if (numStreams > 0) + { + LogPrint (eLogInfo, "SAM: Session ", session->Name, " still has ", numStreams, " streams"); + ScheduleSessionCleanupTimer (session); + } + else + LogPrint (eLogDebug, "SAM: Session ", session->Name, " terminated"); + } + } + // session's destructor is called here unless rescheduled + } + std::shared_ptr SAMBridge::FindSession (const std::string& id) const { std::unique_lock l(m_SessionsMutex); diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 10ef4957..1886324a 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -271,6 +271,10 @@ namespace client void ReceiveDatagram (); void HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ScheduleSessionCleanupTimer (std::shared_ptr session); + void HandleSessionCleanupTimer (const boost::system::error_code& ecode, + std::shared_ptr session, std::shared_ptr timer); + private: bool m_IsSingleThread; From 929ff6e3587332f24deeb89f566f8ae58ac79916 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Apr 2025 08:39:11 -0400 Subject: [PATCH 1158/1160] encrypted LeaseSet never comes through a session --- libi2pd/Destination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 91cc8380..fd23e228 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -512,7 +512,7 @@ namespace client { auto ls2 = std::make_shared (buf + offset, len - offset, request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr, - from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType ()); + GetPreferredCryptoType ()); if (ls2->IsValid () && !ls2->IsExpired ()) { leaseSet = ls2; From f164b420b19d2a1497611f717ff307d891dacd38 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Apr 2025 08:43:32 -0400 Subject: [PATCH 1159/1160] cubicchaos.net reseed added --- .../reseed/unixeno_at_cubicchaos.net.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 3 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 contrib/certificates/reseed/unixeno_at_cubicchaos.net.crt diff --git a/contrib/certificates/reseed/unixeno_at_cubicchaos.net.crt b/contrib/certificates/reseed/unixeno_at_cubicchaos.net.crt new file mode 100644 index 00000000..c94d319e --- /dev/null +++ b/contrib/certificates/reseed/unixeno_at_cubicchaos.net.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQVpTNnJZlUTDqmZiHRU4wCjANBgkqhkiG9w0BAQsFADB2 +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEfMB0GA1UEAwwW +dW5peGVub0BjdWJpY2NoYW9zLm5ldDAeFw0yNTAzMDQxODU5NDZaFw0zNTAzMDQx +ODU5NDZaMHYxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgx +HjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMR8w +HQYDVQQDDBZ1bml4ZW5vQGN1YmljY2hhb3MubmV0MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAr/JoAzLDtHXoAc7QcP4IxO+xNTeiYs78Wlg/Sl/sa6qz +gJoGaKH/X++z4Xe9lBSZalXCamnO4QMTgsWOIeoMy6XVbGzNTXPl8JUcblTIXwkP +pv848b1nxLfgLHzPRz1mJMpMikBugJ3Iz1sQzDVlUdye2fgbGChWliz9P4ClEODv +A/4+7i6uvJgEZ7A+jx3vBCXhiJppE3wTuz5D9BQqG8NuEwwjwBTBByoCC4oxOe0h +Qu1k7kEr+n4qpSEg/1eJ/RYSm+I8BftK1RUfykTwxlfmyEmKsfLBQWczE8Ca9nUB +5V34UH2bRy1cvavJYcNW3EPsGNf4naRs+Gy8XIFrb315GgWC1Z6+tzk+QFli9YeF +0DgtYEZciqu/407o8ZEURTnPjB7GhLDDp1LAQ7CQRhzaraXjHj0hyO+6rFpFdD0D +mXhvI/Eph3QIldsgnQc7nPhU2csN8Vi6bNDgm0HZ8cdmIBpI2Uxn/acZX/9G40oj +czrhsCBEecu/BluLJsfaWCYg90rvONP8Fc4edHAMonzYZR4r0q4hbv7AM8GmDRDN +J9/DZFi+Qs9NAe06jJC3jSsj7IdIs8TMhw8FX3xWOlXwjmVETAgY/dta/MpLJ6tJ +i+E+TH/Ndntj/D6WUwdQq+LyCR6gqHUWR6rl6EDQz+08DWb7j/72JSLb/DaXrDUC +AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB8GA1UdDgQYBBZ1bml4ZW5vQGN1Ymlj +Y2hhb3MubmV0MA0GCSqGSIb3DQEBCwUAA4ICAQBBVoPeuOkmJDUdzIrzmxTmjMyz +gpfrZnjirTQKWhbv53sAWNeJ3kZ9l9m+0YpqEtFDrZPL5LTBXcSci5gGuxPkp+i/ +f/axsdcFMKbI9B/M53fyXLLJY0EM4mdhNAWtph1kTowFPhhReefCdqxYIy9uk2pL +gfb6NYJf+w9//fKYFZXb9SsiRchfv81+lbN+PIprnCpV3cTZWmpLRi2hN86pMW20 +3rh7rqJ4dPnA/NoyM+JstL10IU/4StqInweEvoo4W44+cC0zYGvfkkrKL4LB8w5S +6DKebtk7NQDtzuw2QnA9Ms4bmqWQpbL6/7uGaauS0+nmF+2gkqi9hcv0W5ZoBb/D +IVRauySnCtp9PbYM7pIJP9a1U6naLj7L1VixqsJGfPQ8V9TCOOi5bDc3RTetI/DX +bXHhAqHYzboakptylCp+Ao5h2hu0+w4rqnG63HwsHDJWcETbdVFQfzlzUmbx53yV +GnBsUxDgMOiHTZdKLkEnH4Q/XI76uc0ntTRlK9ktKWZPSISUlHrFnFl6I5UdeBMy +6vpB9sJO5L5RPRi4945K5Xdennywdi508mNXtMMmNCqrk1SMYbwaY6ZtIvXEGam9 +uHQTiTEX9LED/VXzFGqzdyDbG43HgS0PksgzedelHWfVAEnc06U3JX2lqUyihYHa +N4jAXWQ7s5p4GYaf4Q== +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 3da74da0..bd9329a1 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -243,7 +243,8 @@ namespace config { "https://www2.mk16.de/," "https://i2p.ghativega.in/," "https://i2p.novg.net/," - "https://reseed.stormycloud.org/" + "https://reseed.stormycloud.org/," + "https://cubicchaos.net:8443/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( "http://[324:71e:281a:9ed3::ace]:7070/," From fdbf4366ebaf9857edcb1a932193259a57749097 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 28 Apr 2025 20:41:36 -0400 Subject: [PATCH 1160/1160] remove reseed.memcpy.io --- .../reseed/hottuna_at_mail.i2p.crt | 33 ------------------- libi2pd/Config.cpp | 1 - 2 files changed, 34 deletions(-) delete mode 100644 contrib/certificates/reseed/hottuna_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/hottuna_at_mail.i2p.crt b/contrib/certificates/reseed/hottuna_at_mail.i2p.crt deleted file mode 100644 index d0ff7c33..00000000 --- a/contrib/certificates/reseed/hottuna_at_mail.i2p.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFxzCCA6+gAwIBAgIQZfqn0yiJL3dGgCjeOeWS6DANBgkqhkiG9w0BAQsFADBw -MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK -ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQ -aG90dHVuYUBtYWlsLmkycDAeFw0xNjExMDkwMzE1MzJaFw0yNjExMDkwMzE1MzJa -MHAxCzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNV -BAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQD -DBBob3R0dW5hQG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEA21Bfgcc9VVH4l2u1YvYlTw2OPUyQb16X2IOW0PzdsUO5W78Loueu974BkiKi -84lQZanLr0OwEopdfutGc6gegSLmwaWx5YCG5uwpLOPkDiObfX+nptH6As/B1cn+ -mzejYdVKRnWd7EtHW0iseSsILBK1YbGw4AGpXJ8k18DJSzUt2+spOkpBW6XqectN -8y2JDSTns8yiNxietVeRN/clolDXT9ZwWHkd+QMHTKhgl3Uz1knOffU0L9l4ij4E -oFgPfQo8NL63kLM24hF1hM/At7XvE4iOlObFwPXE+H5EGZpT5+A7Oezepvd/VMzM -tCJ49hM0OlR393tKFONye5GCYeSDJGdPEB6+rBptpRrlch63tG9ktpCRrg2wQWgC -e3aOE1xVRrmwiTZ+jpfsOCbZrrSA/C4Bmp6AfGchyHuDGGkRU/FJwa1YLJe0dkWG -ITLWeh4zeVuAS5mctdv9NQ5wflSGz9S8HjsPBS5+CDOFHh4cexXRG3ITfk6aLhuY -KTMlkIO4SHKmnwAvy1sFlsqj6PbfVjpHPLg625fdNxBpe57TLxtIdBB3C7ccQSRW -+UG6Cmbcmh80PbsSR132NLMlzLhbaOjxeCWWJRo6cLuHBptAFMNwqsXt8xVf9M0N -NdJoKUmblyvjnq0N8aMEqtQ1uGMTaCB39cutHQq+reD/uzsCAwEAAaNdMFswDgYD -VR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNV -HRMBAf8EBTADAQH/MBkGA1UdDgQSBBBob3R0dW5hQG1haWwuaTJwMA0GCSqGSIb3 -DQEBCwUAA4ICAQCibFV8t4pajP176u3jx31x1kgqX6Nd+0YFARPZQjq99kUyoZer -GyHGsMWgM281RxiZkveHxR7Hm7pEd1nkhG3rm+d7GdJ2p2hujr9xUvl0zEqAAqtm -lkYI6uJ13WBjFc9/QuRIdeIeSUN+eazSXNg2nJhoV4pF9n2Q2xDc9dH4GWO93cMX -JPKVGujT3s0b7LWsEguZBPdaPW7wwZd902Cg/M5fE1hZQ8/SIAGUtylb/ZilVeTS -spxWP1gX3NT1SSvv0s6oL7eADCgtggWaMxEjZhi6WMnPUeeFY8X+6trkTlnF9+r/ -HiVvvzQKrPPtB3j1xfQCAF6gUKN4iY+2AOExv4rl/l+JJbPhpd/FuvD8AVkLMZ8X -uPe0Ew2xv30cc8JjGDzQvoSpBmVTra4f+xqH+w8UEmxnx97Ye2aUCtnPykACnFte -oT97K5052B1zq+4fu4xaHZnEzPYVK5POzOufNLPgciJsWrR5GDWtHd+ht/ZD37+b -+j1BXpeBWUBQgluFv+lNMVNPJxc2OMELR1EtEwXD7mTuuUEtF5Pi63IerQ5LzD3G -KBvXhMB0XhpE6WG6pBwAvkGf5zVv/CxClJH4BQbdZwj9HYddfEQlPl0z/XFR2M0+ -9/8nBfGSPYIt6KeHBCeyQWTdE9gqSzMwTMFsennXmaT8gyc7eKqKF6adqw== ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index bd9329a1..939cd9ff 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -234,7 +234,6 @@ namespace config { "https://reseed2.i2p.net/," "https://reseed.diva.exchange/," "https://reseed-fr.i2pd.xyz/," - "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," "https://reseed.i2pgit.org/,"